Langchain 1.0后astream_events事件类型及生命周期简析

本文为博客园用户“孤舟晓月”原创,发布于博客园,备份与B站。若你在其他站点看到,说明它被盗了......

前置知识

langchain使用流式输出通常采用stream(同步)和astream(异步)两种模式,类似与下面的代码段:

print("开始流式输出...")
# 流式输出
for chunk in graph.stream(initial_state, config=my_config):
    print(f"流式块: {chunk}")
print("流式输出测试完成!")

chunk就是大模型返回的信息。通常只包含少量的必需字段。也就存在很多问题:
比如无法取得token的细分使用量,部分模型(比如deepseek-reasoner)的封装无法在流式输出中实时呈现推理内容等等。

一、astream_event产生的事件类型

当然,langchain在1.0中也给出了解法,即使用astream_events方法。该方法会返回一系列的关键事件,以便咱们精准检测整个智能体的运行情况乃至修改相关数据。
langchain官方的参考地址为:astream_events


1. 官方文档

放个截图,方便后面的内容展开
Pasted image 20260209170006

其中我遇到过的事件类型部分摘录如下:

  • on_chat_model_start
  • on_chat_model_stream
  • on_chat_model_end
  • on_chain_start
  • on_chain_stream
  • on_chain_end
  • on_tool_start
  • on_tool_end
    .......

2. 所有事件的共性字段

上面的文档翻译一下,就是:astream_event 会迭代返回多个StreamEvent对象,所有的StreamEvent都具有下列共有字段:

字段名 类型 描述与作用
event string 事件类型的唯一标识,如 ”on_chain_start”
name string 产生事件的组件或对象的名称,例如 ”LangGraph””model””tools””ChatDeepSeekCustomized””weather_tool”
run_id string 当前事件运行的唯一ID。用于标识一个特定的执行实例。
parent_ids array 父级运行的ID列表。清晰展示了执行的层级和调用关系。例如,ChatDeepSeekCustomized 事件的 parent_ids 会包含其所属的 model 链和顶级 LangGraph 的 run_id
tags array 标签列表,用于分类或标记运行。常见标签如 ”graph: step: 1″”seq: step: 1″
metadata object 元数据字典,包含执行的上下文信息。不同事件类型的元数据丰富程度不同,但以下LangGraph相关字段非常常见:
• thread_id: 执行线程ID。
• langgraph_node: 当前所在的图节点名。
• langgraph_step: 执行步骤。
• langgraph_checkpoint_ns: 检查点命名空间。
data object 与该事件相关的数据。该字段的内容 这取决于活动的类型。!!!重要!!!

在官方文档中,密密麻麻列举了N多事件,遗憾的是截止2026年2月9日,官方文档并没有给出这些事件的生命周期。 于是就有了本篇文章。

接下来,我会先给出测试的DEMO和框架的输出,当然,输出已经被转换为标准的JSON格式。

坐稳,这就出发!


二、测试DEMO

"""  
使用LangGraph create_agent方法创建智能体,ChatDeepSeekCustomized与多个工具的协作  
该测试模拟一个复杂的任务场景,需要智能体调用多个工具才能完成  

ChatDeepSeekCustomized为我基于langchain框架定制的deepseek封装,支持使用reasoner模型发起的tool-call和推理思维链透传。

如果你想运行这个测试,请:
1. 切换为langchain-deepseek库提供的ChatDeepseek封装。
2. 自行注册deepseek的API
"""  
import asyncio  
import os  
import sys  
  
# 添加项目根目录到Python路径  
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))  
  
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage  
from langchain_core.tools import tool  
from langchain.agents import create_agent  
from langgraph.checkpoint.memory import MemorySaver  
from extends.custom_deepseek_chat import ChatDeepSeekCustomized  
  
  
@tool  
def calculator_tool(operation: str) -> str:  
    """计算器工具,执行基本数学运算"""  
    try:  
        # 解析操作  
        result = eval(operation)  
        return f"计算结果: {result}"  
    except Exception as e:  
        return f"计算错误: {str(e)}"  
  
  
@tool  
def search_tool(query: str) -> str:  
    """搜索工具,模拟信息检索"""  
    return f"搜索结果: 关于'{query}'的信息是模拟的,实际应用中应连接真实搜索引擎"  
  
  
@tool  
def analysis_tool(data: str) -> str:  
    """分析工具,对数据进行分析"""  
    return f"分析结果: '{data}'的数据分析已完成"  
  
  
@tool  
def weather_tool(city: str) -> str:  
    """天气工具,模拟查询天气"""  
    return f"天气预报: {city}的天气是晴朗的,温度约22°C"  
  
  
@tool  
def database_query_tool(table: str, condition: str) -> str:  
    """数据库查询工具,模拟数据库查询"""  
    return f"数据库查询结果: 从表'{table}'中找到满足条件'{condition}'的记录共5条"  
  
  
def create_complex_task_agent():  
    """创建一个需要多次工具调用才能完成复杂任务的智能体"""  
    print("创建使用ChatDeepSeekCustomed的LangGraph智能体...")  
  
    # 设置API密钥 
    # !!!----------填入自己的API KEY-----------!!!
    DEEPSEEK_API_KEY = "sk-你的API KEY"  
  
    # 为了获得比较清晰的events,直接使用ChatDeepSeekCustomized,启用reasoning
    model = ChatDeepSeekCustomized(  
        model="deepseek-reasoner",  
        api_key=DEEPSEEK_API_KEY,  
        temperature=0.1,  
        include_reasoning_content=True  # 启用推理内容输出  
    )  
  
    # 定义工具列表  
    tools = [calculator_tool, search_tool, analysis_tool, weather_tool, database_query_tool]  
  
    # 创建系统提示 - 字符串格式  
    system_prompt_str = """  
    你是一个高级AI助手,能够使用多种工具解决问题。你需要合理规划工具调用顺序,完成复杂任务。  
    在每次调用工具后,你会收到结果,然后根据结果决定下一步行动。    请使用推理来决定如何最好地解决问题。    你可以进行多步思考,并在必要时调用工具。  
    """  
    # 定义checkpoint存储类型  
    my_cp_memory = MemorySaver()  
  
    # 创建Agent - 使用正确的参数名  
    graph = create_agent(  
        tools=tools,  
        model=model,  # 使用我们的自定义模型  
        system_prompt=system_prompt_str,  
        checkpointer=my_cp_memory  
    )  
  
    return graph, tools  
  
  
  
async def test_streaming():  
    """测试流式输出,观察推理内容是否正常输出"""  
    print("\n开始测试流式输出...")  
    print("开始测试复杂任务...")  
    try:  
        from langchain.agents import AgentState  
        from langchain_core.runnables import RunnableConfig  
  
        # 创建智能体  
        graph, tools = create_complex_task_agent()  
  
        # 定义一个复杂任务,需要多次工具调用  
        complex_task = (  
            "我需要规划一次去北京的旅行。请帮我:\n"  
            "1. 查询北京的当前天气\n"  
            "2. 计算从上海到北京的距离(假设直线距离约为1000公里)\n"  
            "3. 基于距离计算旅行所需的油费(假设每公里油耗费用为0.8元)\n"  
            "4. 分析旅游预算的合理性\n"  
            "5. 最后给我一个完整的旅行建议"  
        )  
  
        print(f"任务: {complex_task}")  
        print("\n开始执行任务...")  
  
  
        class StateInAgent(AgentState):  
            pass  
  
        initial_state = StateInAgent(messages=[HumanMessage(content=complex_task)])  
  
        # 配置  
        my_config = RunnableConfig()  
        my_config["configurable"] = {  
            "thread_id": "test_streaming",  
        }  
  
        print("开始流式输出...")  
        events = []  
        # 测试流式输出  
        async for event in graph.astream_events(initial_state, config=my_config):  
            if event['event'] == 'on_chat_model_stream':  
                if not should_stop_append_on_chat_model_stream(events):  
                    events.append(event)  
                    print(event)  
            else:  
                events.append(event)  
                print(event)  
        print("流式输出测试完成!")  
        return True  
    except Exception as e:  
        print(f"流式输出测试失败: {e}")  
        import traceback  
        traceback.print_exc()  
        return False  
  
def should_stop_append_on_chat_model_stream(event_list, max_count=10):  
   """
   因为大模型一次简单的推理就可能产生数百个on_chat_model_stream事件,这里做一个
   定制化判断,如果事件队列末尾有连续10个on_chat_model_stream事件了,就停止入队列。
   """  
    stop_flag =  False  
    # 判断最近的12个事件中,有多少个on_chat_model_stream事件,如果超过10个,则返回true  
    last_max_events = event_list[-max_count:]  
    for event in last_max_events:  
        if event['event'] == 'on_chat_model_stream':  
            stop_flag = True  
        else:  
            stop_flag = False  
    return stop_flag  
  
async def main():  
    """主函数"""  
    print("🧪 测试使用ChatDeepSeekCustomed的LangGraph智能体")  
    print("=" * 70)  
  
    await test_streaming()  
  
    print("=" * 70)  
    print(f"测试结束")  
  
  
  
  
if __name__ == "__main__":  
    asyncio.run(main())

astream_events的输出

运行上述DEMO,并在print("流式输出测试完成!") 处断点,可以发现整个任务输出了上千个StreamEvent
(嘉靖帝咆哮:那些都是朕的Token啊,是朕的钱!!)
为了方便,我对事件内容进行了简化,去掉了很多跟本文无关的字段,并保留第一轮思考和调用结果;但即便如此,json长度还是很可怕,因此我把它放到了文章末尾,方便各位看官查看对照。

好了,现在我们对出现的事件进行分析,并请出deepseek帮我们绘制更加直观的流程图。

1. 事件类型、数量及出现顺序

在根据DEMO生成的json中,共出现了8种不同的事件类型。基本模式为:链/组件启动 -> 内部执行(模型流式生成/工具调用) -> 链/组件结束并流式输出

以下是各类事件的数量、占比及简要描述:

序号 事件类型 (event) 出现次数 描述
1 on_chain_start 13 一个“链”(Chain)或组件(如LangGraphmodeltools)开始执行。
2 on_chain_stream 31 “链”在执行过程中产生中间结果(chunk),进行流式输出。
3 on_chain_end 13 一个“链”或组件执行结束,包含完整的输入和输出。
4 on_chat_model_start 6 聊天模型(如ChatDeepSeekCustomized)开始调用。
5 on_chat_model_stream 6 聊天模型产生流式输出块(chunk)。
6 on_chat_model_end 6 聊天模型调用结束,包含完整的输入和输出。
7 on_tool_start 6 工具(如weather_toolcalculator_tool)开始执行。
8 on_tool_end 6 工具执行结束,包含输入和结果。

2. 各类事件的特有字段(data 内容)

所有事件的核心差异体现在 data 字段的内容上,它承载了事件的具体信息。

  • on_chain_start / on_chain_end / on_chain_stream

    • data.input: 链开始执行时的输入。
    • data.output (on_chain_end独有): 链执行完成后的完整输出。
    • data.chunk (on_chain_stream独有): 链在流式输出过程中产生的中间数据块。其内部结构根据流出的节点不同而异(例如 chunk.model 或 chunk.tools)。
    • 说明:这三者共同描述“链”的生命周期,inputoutputstartend中成对出现,chunkstream中出现。
  • on_chat_model_start / on_chat_model_end / on_chat_model_stream

    • data.input: 模型调用时的输入,通常是格式化的消息列表。
    • data.output (on_chat_model_end独有): 模型调用结束后的完整输出(AIMessage),包含contenttool_callsusage_metadata等。
    • data.chunk (on_chat_model_stream独有): 模型流式生成过程中的一个数据块(AIMessageChunk),可能只包含部分内容。
    • _说明:
      • (1) 这三者共同描述“聊天模型”的生命周期。_
      • (2)usage_metadata中包含了模型的输入、输出等token调用,如果要进行限流,那么就应该实时检测这个字段中的内容!
  • on_tool_start / on_tool_end

    • data.input: 工具调用时的输入参数。
    • data.output (on_tool_end独有): 工具执行完成后的结果(ToolMessage),包含contentnametool_call_id等。
    • 说明:这两者共同描述“工具”的执行生命周期。

三、总结

1. 各个事件执行顺序的生命周期流程图

graph TD Start["🎬 工作流循环开始"] --> A["🔗 1. on_chain_start<br/>最外层链(LangGraph)开始"] --> B["🔗 2. on_chain_start<br/>Model节点开始"] --> C["🧠 3. on_chat_model_start<br/>AI模型开始推理"] --> D["💭 4. on_chat_model_stream<br/>模型流式思考"] --> E["✅ 5. on_chat_model_end<br/>模型推理完成<br/>↓可能包含工具调用"] --> F["📤 6. on_chain_stream<br/>Model节点流式输出"] --> G["🏁 7. on_chain_end<br/>Model节点结束"] G --> Decision{"❓ 需要工具调用吗?"} Decision -- "✅ 是" --> H["🔗 8. on_chain_start<br/>Tools节点开始"] --> I["🔧 9. on_tool_start<br/>具体工具开始"] --> J["⚙️ 10. on_tool_end<br/>工具执行完成"] --> K["📤 11. on_chain_stream<br/>Tools节点流式输出"] --> L["🏁 12. on_chain_end<br/>Tools节点结束"] --> M["📤 13. on_chain_stream<br/>最外层链传递结果"] --> N["🔄 回到步骤2<br/>开始新一轮推理"] Decision -- "❌ 否" --> O["🏁 14. on_chain_end<br/>最外层链结束"] --> End["🏁 工作流完成"] N --> B subgraph "🔁 完整循环 (1个工具调用)" A --> O end style Start fill:#e1f5fe style End fill:#e8f5e8 style Decision fill:#fff3e0 style A fill:#f3e5f5 style B fill:#e8eaf6 style C fill:#e3f2fd style H fill:#f1f8e9 style I fill:#fff8e1

2. 关键执行路径说明:

🔵 正常执行路径(完成任务):

  • 步骤1-7:AI模型接收输入并进行推理

  • 步骤14:模型直接给出最终答案,工作流结束

  • 总步骤:7步完成

🟡 工具调用路径(需多次循环):

  • 步骤1-7:AI模型推理后决定调用工具

  • 步骤8-13:执行具体工具并返回结果

  • 步骤N:返回步骤2开始新一轮推理

  • 可能多次循环:直到模型不再需要工具调用

  • 最终步骤:从Decision节点跳转到步骤14结束

循环特点总结:

  1. 📊 事件成对出现:每个组件都有startend事件

  2. 🌀 嵌套结构:Model/Tools节点嵌套在最外层链中

  3. 🔄 可重复循环:Tools节点执行后结果回流到Model节点

  4. 🎯 决策点关键:Decision节点决定工作流走向

实际案例中的循环次数:

在本文完整的JSON数据中,这个循环重复执行了4次

  1. 第一轮:调用weather_tool(查询天气)

  2. 第二轮:调用calculator_tool(计算油费)

  3. 第三轮:调用search_tool(搜索旅游花费)

  4. 第四轮:调用analysis_tool(分析预算合理性)

每次循环都完整经历了上述流程图中的所有步骤(除最后的结束步骤外),直到第5轮模型不再调用工具,直接输出最终旅行建议,工作流结束。

附件

简化版的事件列表JSON

[
  {
    "event": "on_chain_start",
    "data": {
      "input": {
        "messages": [
          {
            "content": "我需要规划一次去北京的旅行。请帮我:\n1.查询北京的当前天气\n2.计算从上海到北京的距离(假设直线距离约为1000公里)\n3.基于距离计算旅行所需的油费(假设每公里油耗费用为0.8元)\n4.分析旅游预算的合理性\n5.最后给我一个完整的旅行建议",
            "additional_kwargs": {},
            "response_metadata": {},
            "_constructed_type": "HumanMessage"
          }
        ]
      }
    },
    "metadata": {
      "thread_id": "test_streaming"
    }
  },
  {
    "event": "on_chain_start",
    "data": {
      "input": {
        "messages": [
          {
            "content": "我需要规划一次去北京的旅行。请帮我:\n1.查询北京的当前天气\n2.计算从上海到北京的距离(假设直线距离约为1000公里)\n3.基于距离计算旅行所需的油费(假设每公里油耗费用为0.8元)\n4.分析旅游预算的合理性\n5.最后给我一个完整的旅行建议",
            "additional_kwargs": {},
            "response_metadata": {},
            "_constructed_type": "HumanMessage"
          }
        ]
      }
    }
    },
  {
    "event": "on_chat_model_start",
    "data": {
      "input": {
        "messages": [
          [
            {
              "content": "\n你是一个高级AI助手,能够使用多种工具解决问题。你需要合理规划工具调用顺序,完成复杂任务。\n在每次调用工具后,你会收到结果,然后根据结果决定下一步行动。\n请使用推理来决定如何最好地解决问题。\n你可以进行多步思考,并在必要时调用工具。\n",
              "additional_kwargs": {},
              "response_metadata": {},
              "_constructed_type": "SystemMessage"
            },
            {
              "content": "我需要规划一次去北京的旅行。请帮我:\n1.查询北京的当前天气\n2.计算从上海到北京的距离(假设直线距离约为1000公里)\n3.基于距离计算旅行所需的油费(假设每公里油耗费用为0.8元)\n4.分析旅游预算的合理性\n5.最后给我一个完整的旅行建议",
              "additional_kwargs": {},
              "response_metadata": {},
              "_constructed_type": "HumanMessage"
           }
          ]
        ]
      }
    }
  },
  {
    "event": "on_chat_model_stream",
    "data": {
      "chunk": {
        "content": "",
        "additional_kwargs": {
          "reasoning_content": ""
        },
        "tool_calls": [],
        "invalid_tool_calls": [],
        "tool_call_chunks": [],
        "_constructed_type": "AIMessageChunk"
      }
    }
  },  
  {
    "event": "on_chat_model_end",
    "data": {
      "input": {
        "messages": [
          [
            {
              "content": "\n你是一个高级AI助手,能够使用多种工具解决问题。你需要合理规划工具调用顺序,完成复杂任务。\n在每次调用工具后,你会收到结果,然后根据结果决定下一步行动。\n请使用推理来决定如何最好地解决问题。\n你可以进行多步思考,并在必要时调用工具。\n",
              "_constructed_type": "SystemMessage"
            },
            {
              "content": "我需要规划一次去北京的旅行。请帮我:\n1.查询北京的当前天气\n2.计算从上海到北京的距离(假设直线距离约为1000公里)\n3.基于距离计算旅行所需的油费(假设每公里油耗费用为0.8元)\n4.分析旅游预算的合理性\n5.最后给我一个完整的旅行建议",
              "_constructed_type": "HumanMessage"
            }
          ]
        ]
      },
      "output": {
        "content": "",
        "additional_kwargs": {
          "reasoning_content": "我来规划这次去北京的旅行。首先,我需要查询北京的当前天气。然后计算距离和油费,再分析预算,最后给出完整的旅行建议。\n\n让我从查询北京天气开始。"
        },
        "tool_calls": [
          {
            "name": "weather_tool",
            "args": {
              "city": "北京"
            },
            "type": "tool_call"
          }
        ],
        "invalid_tool_calls": [],
        "usage_metadata": {
          "input_tokens": 648,
          "output_tokens": 84,
          "total_tokens": 732,
          "input_token_details": {
            "cache_read": 640
          },
          "output_token_details": {
            "reasoning": 39
          }
        },
        "_constructed_type": "AIMessage"
      }
    }
  },
{
    "event": "on_chain_stream",
    "data": {
      "chunk": {
        "messages": [
          {
            "content": "",
            "additional_kwargs": {
              "reasoning_content": "我来规划这次去北京的旅行。首先,我需要查询北京的当前天气。然后计算距离和油费,再分析预算,最后给出完整的旅行建议。\n\n让我从查询北京天气开始。"
            },
            "response_metadata": {
              "finish_reason": "tool_calls"
            },
            "tool_calls": [
              {
                "name": "weather_tool",
                "args": {
                  "city": "北京"
                },
                "type": "tool_call"
              }
            ],
            "_constructed_type": "AIMessage"
          }
        ]
      }
    }
  },
  {
    "event": "on_chain_end",
    "data": {
      "input": {
        "messages": [
          {
            "content": "我需要规划一次去北京的旅行。请帮我:\n1.查询北京的当前天气\n2.计算从上海到北京的距离(假设直线距离约为1000公里)\n3.基于距离计算旅行所需的油费(假设每公里油耗费用为0.8元)\n4.分析旅游预算的合理性\n5.最后给我一个完整的旅行建议",
            "additional_kwargs": {},
            "response_metadata": {},
            "_constructed_type": "HumanMessage"
          }
        ]
      },
      "output": {
        "messages": [
          {
            "content": "",
            "additional_kwargs": {
              "reasoning_content": "我来规划这次去北京的旅行。首先,我需要查询北京的当前天气。然后计算距离和油费,再分析预算,最后给出完整的旅行建议。\n\n让我从查询北京天气开始。
            },
            "tool_calls": [
              {
                "name": "weather_tool",
                "args": {
                  "city": "北京"
                },
                "type": "tool_call"
              }
            ],
            "_constructed_type": "AIMessage"
          }
        ]
      }
    }
  },
 {
    "event": "on_chain_stream",
    "data": {
      "chunk": {
        "model": {
          "messages": [
            {
              "content": "",
              "additional_kwargs": {
                "reasoning_content": "我来规划这次去北京的旅行。首先,我需要查询北京的当前天气。然后计算距离和油费,再分析预算,最后给出完整的旅行建议。\n\n让我从查询北京天气开始。"
              },
              "response_metadata": {
                "finish_reason": "tool_calls"
              },
              "tool_calls": [
                {
                  "name": "weather_tool",
                  "args": {
                    "city": "北京"
                  },
                  "type": "tool_call"
                }
              ],
              "_constructed_type": "AIMessage"
            }
          ]
        }
      }
    }
  },
  {
    "event": "on_chain_start",
    "data": {
      "input": {
        "__type": "tool_call_with_context",
        "state": {
          "messages": [
            {
              "content": "我需要规划一次去北京的旅行。请帮我:\n1.查询北京的当前天气\n2.计算从上海到北京的距离(假设直线距离约为1000公里)\n3.基于距离计算旅行所需的油费(假设每公里油耗费用为0.8元)\n4.分析旅游预算的合理性\n5.最后给我一个完整的旅行建议",
              "_constructed_type": "HumanMessage"
            },
            {
              "content": "",
              "additional_kwargs": {
                "reasoning_content": "我来规划这次去北京的旅行。首先,我需要查询北京的当前天气。然后计算距离和油费,再分析预算,最后给出完整的旅行建议。\n\n让我从查询北京天气开始。"
              },
              "tool_calls": [
                {
                  "name": "weather_tool",
                  "args": {
                    "city": "北京"
                  },
                  "type": "tool_call"
                }
              ],
              "_constructed_type": "AIMessage"
            }
          ]
        },
        "tool_call": {
          "args": {
            "city": "北京"
          },
          "name": "weather_tool",
          "type": "tool_call"
        }
      }
    },
    "name": "tools",
  },
  {
    "event": "on_tool_start",
    "data": {
      "input": {
        "city": "北京"
      }
    },
    "name": "weather_tool"
  },
  {
    "event": "on_tool_end",
    "data": {
      "input": {
        "city": "北京"
      },
      "output": {
        "content": "天气预报: 北京的天气是晴朗的,温度约22°C",
        "name": "weather_tool",
        "_constructed_type": "ToolMessage"
      }
    },
    "name": "weather_tool",
  },
  {
    "event": "on_chain_stream",
    "data": {
      "chunk": {
        "messages": [
          {
            "content": "天气预报: 北京的天气是晴朗的,温度约22°C",
            "name": "weather_tool",
            "_constructed_type": "ToolMessage"
          }
        ]
      }
    },
    "name": "tools"
  },
{
    "event": "on_chain_end",
    "data": {
      "input": {
        "__type": "tool_call_with_context",
        "state": {
          "messages": [
            {
              "content": "我需要规划一次去北京的旅行。请帮我:\n1.查询北京的当前天气\n2.计算从上海到北京的距离(假设直线距离约为1000公里)\n3.基于距离计算旅行所需的油费(假设每公里油耗费用为0.8元)\n4.分析旅游预算的合理性\n5.最后给我一个完整的旅行建议",
              "_constructed_type": "HumanMessage"
            },
            {
              "content": "",
              "additional_kwargs": {
                "reasoning_content": "我来规划这次去北京的旅行。首先,我需要查询北京的当前天气。然后计算距离和油费,再分析预算,最后给出完整的旅行建议。\n\n让我从查询北京天气开始。"
              },
              "tool_calls": [
                {
                  "name": "weather_tool",
                  "args": {
                    "city": "北京"
                  },
                  "type": "tool_call"
                }
              ],
              "_constructed_type": "AIMessage"
            }
          ]
        },
        "tool_call": {
          "args": {
            "city": "北京"
          },
          "name": "weather_tool",
          "type": "tool_call"
        }
      },
      "output": {
        "messages": [
          {
            "content": "天气预报: 北京的天气是晴朗的,温度约22°C",
            "name": "weather_tool",
            "_constructed_type": "ToolMessage"
          }
        ]
      }
    },
    "name": "tools",
  }
]
posted @ 2026-02-09 18:06  孤舟晓月  阅读(10)  评论(0)    收藏  举报