LangGraph Multi Agent 多智能体协作
本文最后更新于 2026年8月3日
未完待续
单智能体下,只有一个大模型和若干工具,大模型决定使用什么工具,一个模型独立完成从思考到选择并使用工具,再观察结果循环往复直到所有逻辑全部完成的过程。
在langgraph+langchain体系中,可以将一个可调用的对象封装为一个智能体,通过编排将多个智能体组成一个图,通过消息传递,条件跳转和记忆进行协作,实现多智能体架构(Multi-Agent Architecture)
这样的好处是:
- 每个智能体只完成自己擅长处理的任务,实现解耦
- 通过添加新的智能体到图中,进行功能拓展
- 通过编排,实现人工干预,时间回溯等功能使得智能体执行过程更加可控
多智能体架构中,常见的智能体连接方式有:
Network
智能体之间互相平等,任何智能体都能选择调用其他的智能体,适合流水线任务
Supervisor
包含一个主智能体,每个其他智能体都与主智能体通信,主智能体决定下一步调用哪个智能体,适合需动态决策,任务数量不确定的场景
Supervisor (as tools)
主智能体的特殊情况,单个智能体表示为工具,集成了支持Function calling的大模型的主智能体通过tools来调用其他智能体
Hierarchical
多层的Supervisor结构,每一层有自己的主智能体,类似一个大公司的组织架构
Custom
通过langgraph灵活的条件边构造自定义的执行流,用的最多
多智能体架构中,常见的场景选择:
| 架构类型 | 特点 | 使用场景 |
|---|---|---|
| 路由型 | 一个主智能体分流给子智能体 | 智能客服,多领域问答 |
| 协作型 | 多智能体并行,结果合并 | 旅游策划,信息聚合,RAG |
| 辩论型 | Proposer+Critic/Judge | 代码,合同生成 |
| 分阶段型 | Pipeline,阶段串联 | ETL,报告生成 |
| 人机混合 | HITL+回溯 | 高风险决策,敏感问题,高危操作 |
例:向主智能体派发任务,分别预定机票和酒店,主智能体接收用户任务,分解委派给不同子智能体,并整合最终结果。
Supervisor模式,可以通过langgraph条件边选择实现,但是langgraph直接支持通过Supervisor模式实现多智能体架构,要使用这个功能,首先要安装langgraph-supervisor模块
截止成文,langgraph-supervisor模块已经不在维护,官方建议迁移:https://docs.langchain.com/oss/python/migrate/langgraph-supervisor
pip install langgraph-supervisorimport os
from dotenv import load_dotenv
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain_core.tools import tool
from langgraph_supervisor import create_supervisor
load_dotenv(encoding='utf-8')
# 1.大语言模型
llm = init_chat_model(
model = 'deepseek-v4-pro',
model_provider = 'openai',
api_key = os.getenv('DEEPSEEK_API_KEY'),
base_url = 'https://api.deepseek.com/',
extra_body={"thinking": {"type": "disabled"}},
)
@tool(description='预订航班工具。根据出发机场和到达机场预订一张机票,并返回预订结果。')
def book_flight(from_airport: str, to_airport: str) -> str:
print('========= flight tool_calling===========')
return f" 成功预订了从 {from_airport} 到 {to_airport} 的航班"
@tool(description='预订酒店工具。根据酒店名称完成酒店预订,并返回预订结果。')
def book_hotel(hotel_name: str) -> str:
print('========= hotel tool_calling===========')
return f" 成功预订了 {hotel_name} 的住宿"
flight_assistant = create_agent(
model=llm,
tools=[book_flight],
name="flight_assistant"# ← 关键!Supervisor 用这个名字来调度
)
hotel_assistant = create_agent(
model=llm,
tools=[book_hotel],
name="hotel_assistant"
)
# 创建 Supervisor,协调者主管
# 告诉 Supervisor 如何处理任务。这里是顺序执行模式(先航班 → 再酒店 → 汇总)
supervisor = create_supervisor(
agents=[flight_assistant, hotel_assistant],
model=llm,
prompt=(
"你是旅行预订系统的调度主管,负责协调航班预订和酒店预订。\n\n"
"当用户提出航班和酒店预订请求时,你的工作流程是:\n"
"1. 首先调用flight_assistant来预订航班\n"
"2. 然后调用hotel_assistant来预订酒店\n"
"3. 收到两个助手的结果后,汇总并向用户报告\n"
"4. 完成后结束对话\n\n"
"重要规则:\n"
"- 每个助手只能调用一次\n" # 防止 LLM 循环调用
"- 不要重复任何内容\n"
"- 不要输出任何英文\n" # 适配中文场景,减少后续过滤负担
"- 所有通信都使用中文\n"# 适配中文场景,减少后续过滤负担
)
).compile()
if __name__ == '__main__':
user_request = (
"请帮我预订以下旅行安排: \n"
"1. 航班:从 北京 飞往 上海 \n"
"2. 酒店:桔子酒店 \n"
"请完成这两个预订。"
)
input_data = {"messages": [{"role": "user", "content": user_request}]}
for chunk in supervisor.stream(input_data):
print(chunk)
{'supervisor': None}
========= hotel tool_calling===========
{'hotel_assistant': {'messages': [AIMessage(content='预订结果如下:\n\n---\n\n### ✅ 酒店预订 —— 已完成\n- **酒店名称**:桔子酒店\n- **状态**:预订成功\n\n---\n\n### ⚠️ 关于航班预订\n很抱歉,我目前只有酒店预订工具(`book_hotel`),无法直接为您预订从北京飞往上海的航班。建议您通过航空公司官网、旅行APP(如携程、飞猪等)自行完成航班预订。\n\n请问还有其他需要我帮忙的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 99, 'prompt_tokens': 491, 'total_tokens': 590, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 384}, 'prompt_cache_hit_tokens': 384, 'prompt_cache_miss_tokens': 107}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-pro', 'system_fingerprint': 'fp_9954b31ca7_prod0820_fp8_kvcache_20260402', 'id': 'cfc3bf80-f029-46e5-be3d-5c9164a702a8', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019fc0cf-04f3-76c0-acd9-f0ecf9b1653a-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 491, 'output_tokens': 99, 'total_tokens': 590, 'input_token_details': {'cache_read': 384}, 'output_token_details': {}}), AIMessage(content='Transferring back to supervisor', additional_kwargs={}, response_metadata={'__is_handoff_back': True}, name='hotel_assistant', id='ff89cbb1-b018-4896-8f81-ababcc6f0e8c', tool_calls=[{'name': 'transfer_back_to_supervisor', 'args': {}, 'id': '175f30e7-8497-4c08-90ca-20bd6d6c0a40', 'type': 'tool_call'}], invalid_tool_calls=[]), ToolMessage(content='Successfully transferred back to supervisor', name='transfer_back_to_supervisor', id='f6b4f416-e4a2-464d-acf7-bf2715394bac', tool_call_id='175f30e7-8497-4c08-90ca-20bd6d6c0a40')]}}
{'supervisor': {'messages': [HumanMessage(content='请帮我预订以下旅行安排: \n1. 航班:从 北京 飞往 上海 \n2. 酒店:桔子酒店 \n请完成这两个预订。', additional_kwargs={}, response_metadata={}, id='b9544221-f900-4307-8073-86727e47de34'), AIMessage(content='预订结果如下:\n\n---\n\n### ✅ 酒店预订 —— 已完成\n- **酒店名称**:桔子酒店\n- **状态**:预订成功\n\n---\n\n### ⚠️ 关于航班预订\n很抱歉,我目前只有酒店预订工具(`book_hotel`),无法直接为您预订从北京飞往上海的航班。建议您通过航空公司官网、旅行APP(如携程、飞猪等)自行完成航班预订。\n\n请问还有其他需要我帮忙的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 99, 'prompt_tokens': 491, 'total_tokens': 590, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 384}, 'prompt_cache_hit_tokens': 384, 'prompt_cache_miss_tokens': 107}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-pro', 'system_fingerprint': 'fp_9954b31ca7_prod0820_fp8_kvcache_20260402', 'id': 'cfc3bf80-f029-46e5-be3d-5c9164a702a8', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019fc0cf-04f3-76c0-acd9-f0ecf9b1653a-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 491, 'output_tokens': 99, 'total_tokens': 590, 'input_token_details': {'cache_read': 384}, 'output_token_details': {}}), AIMessage(content='Transferring back to supervisor', additional_kwargs={}, response_metadata={'__is_handoff_back': True}, name='hotel_assistant', id='ff89cbb1-b018-4896-8f81-ababcc6f0e8c', tool_calls=[{'name': 'transfer_back_to_supervisor', 'args': {}, 'id': '175f30e7-8497-4c08-90ca-20bd6d6c0a40', 'type': 'tool_call'}], invalid_tool_calls=[]), ToolMessage(content='Successfully transferred back to supervisor', name='transfer_back_to_supervisor', id='f6b4f416-e4a2-464d-acf7-bf2715394bac', tool_call_id='175f30e7-8497-4c08-90ca-20bd6d6c0a40'), AIMessage(content='抱歉,让我重新为您处理。我需要调用航班助手来完成预订。让我现在同时联系两个助手。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 51, 'prompt_tokens': 602, 'total_tokens': 653, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 384}, 'prompt_cache_hit_tokens': 384, 'prompt_cache_miss_tokens': 218}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-pro', 'system_fingerprint': 'fp_9954b31ca7_prod0820_fp8_kvcache_20260402', 'id': '74d25dc8-1a2a-48d8-9a2a-4eeab4621f6c', 'finish_reason': 'tool_calls', 'logprobs': None}, name='supervisor', id='lc_run--019fc0cf-0cc0-7dd3-af5f-1b95ef6abbfe-0', tool_calls=[{'name': 'transfer_to_flight_assistant', 'args': {}, 'id': 'call_00_1e9TpKXIfNZLiS0oWDED4671', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 602, 'output_tokens': 51, 'total_tokens': 653, 'input_token_details': {'cache_read': 384}, 'output_token_details': {}}), ToolMessage(content='Successfully transferred to flight_assistant', name='transfer_to_flight_assistant', id='5ea11148-2dec-4d4e-9a62-0e8324a9262d', tool_call_id='call_00_1e9TpKXIfNZLiS0oWDED4671')]}}
========= flight tool_calling===========
{'flight_assistant': {'messages': [AIMessage(content='航班预订已完成!以下是您的预订汇总:\n\n---\n\n## 📋 预订汇总\n\n| 项目 | 详情 | 状态 |\n|------|------|------|\n| ✈️ **航班** | 北京 → 上海 | ✅ 预订成功 |\n| 🏨 **酒店** | 桔子酒店 | ✅ 预订成功 |\n\n---\n\n两项预订都已成功完成!祝您旅途愉快!还有其他需要帮您处理的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 90, 'prompt_tokens': 691, 'total_tokens': 781, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 640}, 'prompt_cache_hit_tokens': 640, 'prompt_cache_miss_tokens': 51}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-pro', 'system_fingerprint': 'fp_9954b31ca7_prod0820_fp8_kvcache_20260402', 'id': '19f53fa8-daff-4d66-84ce-9d363af0fbdd', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019fc0cf-17ad-78d3-9340-048974517233-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 691, 'output_tokens': 90, 'total_tokens': 781, 'input_token_details': {'cache_read': 640}, 'output_token_details': {}}), AIMessage(content='Transferring back to supervisor', additional_kwargs={}, response_metadata={'__is_handoff_back': True}, name='flight_assistant', id='fe68f452-ddad-4a2f-ad8f-18feadc986ae', tool_calls=[{'name': 'transfer_back_to_supervisor', 'args': {}, 'id': '9615a0f8-4952-454e-8440-ff865494a6c2', 'type': 'tool_call'}], invalid_tool_calls=[]), ToolMessage(content='Successfully transferred back to supervisor', name='transfer_back_to_supervisor', id='9086c03c-1ca8-4df3-bbe8-b005e7696bfe', tool_call_id='9615a0f8-4952-454e-8440-ff865494a6c2')]}}
{'supervisor': {'messages': [HumanMessage(content='请帮我预订以下旅行安排: \n1. 航班:从 北京 飞往 上海 \n2. 酒店:桔子酒店 \n请完成这两个预订。', additional_kwargs={}, response_metadata={}, id='b9544221-f900-4307-8073-86727e47de34'), AIMessage(content='预订结果如下:\n\n---\n\n### ✅ 酒店预订 —— 已完成\n- **酒店名称**:桔子酒店\n- **状态**:预订成功\n\n---\n\n### ⚠️ 关于航班预订\n很抱歉,我目前只有酒店预订工具(`book_hotel`),无法直接为您预订从北京飞往上海的航班。建议您通过航空公司官网、旅行APP(如携程、飞猪等)自行完成航班预订。\n\n请问还有其他需要我帮忙的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 99, 'prompt_tokens': 491, 'total_tokens': 590, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 384}, 'prompt_cache_hit_tokens': 384, 'prompt_cache_miss_tokens': 107}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-pro', 'system_fingerprint': 'fp_9954b31ca7_prod0820_fp8_kvcache_20260402', 'id': 'cfc3bf80-f029-46e5-be3d-5c9164a702a8', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019fc0cf-04f3-76c0-acd9-f0ecf9b1653a-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 491, 'output_tokens': 99, 'total_tokens': 590, 'input_token_details': {'cache_read': 384}, 'output_token_details': {}}), AIMessage(content='Transferring back to supervisor', additional_kwargs={}, response_metadata={'__is_handoff_back': True}, name='hotel_assistant', id='ff89cbb1-b018-4896-8f81-ababcc6f0e8c', tool_calls=[{'name': 'transfer_back_to_supervisor', 'args': {}, 'id': '175f30e7-8497-4c08-90ca-20bd6d6c0a40', 'type': 'tool_call'}], invalid_tool_calls=[]), ToolMessage(content='Successfully transferred back to supervisor', name='transfer_back_to_supervisor', id='f6b4f416-e4a2-464d-acf7-bf2715394bac', tool_call_id='175f30e7-8497-4c08-90ca-20bd6d6c0a40'), AIMessage(content='抱歉,让我重新为您处理。我需要调用航班助手来完成预订。让我现在同时联系两个助手。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 51, 'prompt_tokens': 602, 'total_tokens': 653, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 384}, 'prompt_cache_hit_tokens': 384, 'prompt_cache_miss_tokens': 218}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-pro', 'system_fingerprint': 'fp_9954b31ca7_prod0820_fp8_kvcache_20260402', 'id': '74d25dc8-1a2a-48d8-9a2a-4eeab4621f6c', 'finish_reason': 'tool_calls', 'logprobs': None}, name='supervisor', id='lc_run--019fc0cf-0cc0-7dd3-af5f-1b95ef6abbfe-0', tool_calls=[{'name': 'transfer_to_flight_assistant', 'args': {}, 'id': 'call_00_1e9TpKXIfNZLiS0oWDED4671', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 602, 'output_tokens': 51, 'total_tokens': 653, 'input_token_details': {'cache_read': 384}, 'output_token_details': {}}), ToolMessage(content='Successfully transferred to flight_assistant', name='transfer_to_flight_assistant', id='5ea11148-2dec-4d4e-9a62-0e8324a9262d', tool_call_id='call_00_1e9TpKXIfNZLiS0oWDED4671'), AIMessage(content='航班预订已完成!以下是您的预订汇总:\n\n---\n\n## 📋 预订汇总\n\n| 项目 | 详情 | 状态 |\n|------|------|------|\n| ✈️ **航班** | 北京 → 上海 | ✅ 预订成功 |\n| 🏨 **酒店** | 桔子酒店 | ✅ 预订成功 |\n\n---\n\n两项预订都已成功完成!祝您旅途愉快!还有其他需要帮您处理的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 90, 'prompt_tokens': 691, 'total_tokens': 781, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 640}, 'prompt_cache_hit_tokens': 640, 'prompt_cache_miss_tokens': 51}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-pro', 'system_fingerprint': 'fp_9954b31ca7_prod0820_fp8_kvcache_20260402', 'id': '19f53fa8-daff-4d66-84ce-9d363af0fbdd', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019fc0cf-17ad-78d3-9340-048974517233-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 691, 'output_tokens': 90, 'total_tokens': 781, 'input_token_details': {'cache_read': 640}, 'output_token_details': {}}), AIMessage(content='Transferring back to supervisor', additional_kwargs={}, response_metadata={'__is_handoff_back': True}, name='flight_assistant', id='fe68f452-ddad-4a2f-ad8f-18feadc986ae', tool_calls=[{'name': 'transfer_back_to_supervisor', 'args': {}, 'id': '9615a0f8-4952-454e-8440-ff865494a6c2', 'type': 'tool_call'}], invalid_tool_calls=[]), ToolMessage(content='Successfully transferred back to supervisor', name='transfer_back_to_supervisor', id='9086c03c-1ca8-4df3-bbe8-b005e7696bfe', tool_call_id='9615a0f8-4952-454e-8440-ff865494a6c2'), AIMessage(content='好的,我现在需要先回到主调度流程。让我重新按正确流程来:先调用航班助手,再调用酒店助手。但目前我已经被转回主管。让我直接总结:\n\n---\n\n## 📋 您的旅行预订汇总\n\n| 项目 | 详情 | 状态 |\n|------|------|------|\n| ✈️ **航班** | 北京 → 上海 | ✅ 已预订 |\n| 🏨 **酒店** | 桔子酒店 | ✅ 已预订 |\n\n---\n\n两项预订均已成功完成!祝您旅途愉快,如有其他需要随时联系我。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 121, 'prompt_tokens': 816, 'total_tokens': 937, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 640}, 'prompt_cache_hit_tokens': 640, 'prompt_cache_miss_tokens': 176}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-pro', 'system_fingerprint': 'fp_9954b31ca7_prod0820_fp8_kvcache_20260402', 'id': '50447ecc-8e9d-4bc2-9a94-0345ec4519be', 'finish_reason': 'stop', 'logprobs': None}, name='supervisor', id='lc_run--019fc0cf-1d3f-75f3-b9ce-800e13331bdf-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 816, 'output_tokens': 121, 'total_tokens': 937, 'input_token_details': {'cache_read': 640}, 'output_token_details': {}})]}}langgraph-supervisor默认使用了create_handoff_tool移交工具,我们也能自定义交接函数,没有统一的Supervisor,Agent之间能互相转交任务,每个Agent自带移交工具,可以自行决定在什么时机将任务转交出去。
例:先订机票,再订酒店,无Supervisor调度,机票Agent完成,亲自将任务转交酒店Agent
from typing import Annotated
import os
from dotenv import load_dotenv
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage
from langchain_core.tools import tool
from langgraph.constants import START
from langgraph.graph import MessagesState, StateGraph
from langgraph.prebuilt import InjectedState
from langgraph.types import Command, Send
load_dotenv(encoding='utf-8')
# 1.大语言模型
llm = init_chat_model(
model = 'deepseek-v4-flash',
model_provider = 'openai',
api_key = os.getenv('DEEPSEEK_API_KEY'),
base_url = 'https://api.deepseek.com/',
extra_body={"thinking": {"type": "disabled"}},
)
def create_task_description_handoff_tool(*, agent_name: str, description: str | None = None):
name = f"transfer_to_{agent_name}"
description = description or f"移交给 {agent_name}"
@tool(name, description=description)
def handoff_tool(
task_description: Annotated[str, '描述下一个 Agent 应该做什么,包括所有必要信息'],
# InjectedState:把图全局状态自动注入工具参数,不需要手动传递上下文
state: Annotated[MessagesState, InjectedState],
) -> Command:#返回值 Command:LangGraph 控制图流转的指令对象
#Agent 移交时会生成一段新用户消息task_description,把当前未完成需求、上下文传给下一个 Agent,保证信息不丢失
task_description_message = {
"role": "user",
"content": task_description,
}
agent_input = {
**state,
"messages": [task_description_message],
}
return Command(
#指定跳转到哪个节点,并携带自定义输入状态
goto=[Send(agent_name, agent_input)],
#当前子 Agent 内部跳转提升到父状态图执行,实现跨 Agent 调度
graph=Command.PARENT, # ← 在父图层面跳转,固定写法
)
return handoff_tool
@tool("book_flight", description='预订航班,根据出发地和目的地完成机票预订')
def book_flight(from_airport: str, to_airport: str) -> str:
print(f"======book_flight tools========")
return f"成功预订了从 {from_airport} 到 {to_airport} 的航班。"
@tool("book_hotel", description='预订酒店,根据酒店名称完成预订')
def book_hotel(hotel_name: str) -> str:
print(f"======book_hotel tools========")
return f"成功预订了 {hotel_name} 的住宿。"
transfer_to_flight_assistant = create_task_description_handoff_tool(
agent_name="flight_assistant",
description="将任务移交给航班预订助手",
)
transfer_to_hotel_assistant = create_task_description_handoff_tool(
agent_name="hotel_assistant",
description="将任务移交给酒店预订助手",
)
flight_assistant = create_agent(
model=llm,
tools=[book_flight, transfer_to_hotel_assistant], # 包含移交工具
name="flight_assistant",
)
hotel_assistant = create_agent(
model=llm,
tools=[book_hotel, transfer_to_flight_assistant], # 包含移交工具
name="hotel_assistant",
)
# MessagesState
multi_agent_graph = (
StateGraph(MessagesState)
.add_node(flight_assistant)
.add_node(hotel_assistant)
.add_edge(START, "flight_assistant")
.compile()
)
if __name__ == "__main__":
result = multi_agent_graph.invoke({
"messages": [
SystemMessage(content='你是一个AI差旅助手,按照要求执行操作,全程回复使用中文'),
HumanMessage(content="先帮我预订从北京到上海的航班,再预订如家酒店")
]
})
print("====== 最终对话结果 ======")
for msg in result["messages"]:
print(msg)======book_flight tools========
======book_hotel tools========
====== 最终对话结果 ======
content='你是一个AI差旅助手,按照要求执行操作,全程回复使用中文' additional_kwargs={} response_metadata={} id='4688358f-1082-4a4a-8ff2-dd7b7594519a'
content='先帮我预订从北京到上海的航班,再预订如家酒店' additional_kwargs={} response_metadata={} id='ae5e571d-a914-4023-8867-bf3aea77bcbf'
content='请为用户预订如家酒店。用户已预订从北京到上海的航班,到达上海后需要入住如家酒店。请协助完成如家酒店的预订。' additional_kwargs={} response_metadata={} id='ac7a13ea-bf31-4312-972b-ba52f8c0afcf'
content='我需要为用户预订如家酒店。让我直接为您完成预订。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 61, 'prompt_tokens': 383, 'total_tokens': 444, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cache_write_tokens': None, 'cached_tokens': 256}, 'prompt_cache_hit_tokens': 256, 'prompt_cache_miss_tokens': 127}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_a18b46594c_prod0820_fp8_kvcache_20260402', 'id': '6b92ea3b-2bbd-4c8b-b18e-8f037c8a559e', 'finish_reason': 'tool_calls', 'logprobs': None} name='hotel_assistant' id='lc_run--019fc5e2-27ff-7fc3-b599-3e3d3ed95a3c-0' tool_calls=[{'name': 'book_hotel', 'args': {'hotel_name': '如家酒店'}, 'id': 'call_00_y4zXzsDli2N8cBCkCCxS9270', 'type': 'tool_call'}] invalid_tool_calls=[] usage_metadata={'input_tokens': 383, 'output_tokens': 61, 'total_tokens': 444, 'input_token_details': {'cache_read': 256}, 'output_token_details': {}}
content='成功预订了 如家酒店 的住宿。' name='book_hotel' id='4122d803-7aa7-458f-ac73-ef9b1ae27125' tool_call_id='call_00_y4zXzsDli2N8cBCkCCxS9270'
content='已成功为您预订了**如家酒店**的住宿。\n\n由于用户预订了从北京到上海的航班,抵达上海后可直接入住该酒店。如果您还需要其他协助(例如预订返程航班或安排其他事宜),请随时告诉我。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 50, 'prompt_tokens': 465, 'total_tokens': 515, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cache_write_tokens': None, 'cached_tokens': 256}, 'prompt_cache_hit_tokens': 256, 'prompt_cache_miss_tokens': 209}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_a18b46594c_prod0820_fp8_kvcache_20260402', 'id': 'cf68a086-11c3-4975-a466-2226bcd5272e', 'finish_reason': 'stop', 'logprobs': None} name='hotel_assistant' id='lc_run--019fc5e2-2ca7-7351-80e0-117845298007-0' tool_calls=[] invalid_tool_calls=[] usage_metadata={'input_tokens': 465, 'output_tokens': 50, 'total_tokens': 515, 'input_token_details': {'cache_read': 256}, 'output_token_details': {}}"如果文章对您有帮助,可以请作者喝杯咖啡吗?"
微信支付
支付宝