* LangChain Agent智能体详解(上):创建调用、工具绑定与系统提示词

一、理解 Agents

通用人工智能(AGI)将是AI的终极形态,几乎已成为业界共识。同样,构建智能体(Agent)则是AI

工程应用当下的"终极形态" ,即Agent是大模型应用开发的核心。

1.1 什么是Agent?

在大模型应用开发中,智能体通常指一种以大语言模型为推理与决策核心,结合记忆、工具调用与

环境交互能力,能够进行规划决策并执行复杂任务以达成目标的软件系统。

Agent的关键能力

  • 理解用户问题

  • 如何拆解任务

  • 判断是否需要工具

  • 需要调用哪些工具

  • 如何利用好工具结果生成回答&推进任务

1.2 Agent的核心组件

前面讲过现在AI Agent的架构:

实际开发中几个要素并不需要同时出现,一句话总结

  • 必须的:行动(Action)

  • 几乎总是存在的:工具(Tool)

  • 有条件存在的:规划决策(Planning)

  • 最容易被省略的:记忆(Memory)

1.3 Agent创建与调用

1.3.1 历史上的调用

在 LangChain 0.x 时代,框架内的 Agent 系统经历了"碎片化"阶段。当时的设计理念是 "针对场景设计

特定 Agent":

  • 如果你要实现思维链推理(ReAct),就用 create_react_agent ;

  • 如果需要结构化输出,就用 create_structured_chat_agent ;

  • 要工具调用,则用 create_tool_calling_agent 。

举例:❌ v0.x 的复杂方式

text 复制代码
  1  # 需要多个步骤
  2  from langchain_openai import ChatOpenAI
  3  from langchain.agents import AgentExecutor, create_react_agent
  4  from langchain_core.prompts import PromptTemplate
  5
  6  # 1. 模型初始化
  7  model = ChatOpenAI(model="gpt-4o-mini")
  8
  9  # 2. 创建提示词模板
 10  prompt = PromptTemplate.from_template("""
 11  You are a helpful assistant.
 12
 13  Tools: {tools}
 14  Tool Names: {tool_names}
 15
 16  {agent_scratchpad}
 17  """)
 18
 19  # 3. 创建 agent
 20  agent = create_react_agent(
 21      llm=model,
 22      tools=tools,
 23      prompt=prompt
 24  )
 25
 26  # 4. 创建 executor
 27  executor = AgentExecutor(
 28      agent=agent,
 29      tools=tools,
 30      verbose=True
 31  )
 32
 33  # 5. 调用
 34  result = executor.invoke({"input": "问题"})
 35

这种方式灵活,但也带来了三个明显问题:

  1. 心智负担高------每种 Agent 都要单独记忆 API 与参数;
  2. 可组合性差------多个 Agent 之间无法统一调度;
  3. 生态碎片化------不同模块难以复用或协同演化。

1.3.2 全新的调用

LangChain 在 1.0 版本后,团队做出了彻底重构:将所有 Agent 的创建方式统一为一个入口:

create_agent()。它取代了旧版本中的 create_react_agent 、create_json_agent 、

create_tool_calling_agent 等多种分支函数,真正让开发者用一行代码即可创建任何类型的智能体。

同时在底层通过"中间件机制(Middleware)"和"标准模型接口(invoke / stream)"实现全局统一。这

让框架更轻、更稳,也更易于被集成到其他 Agent 平台中。

举例:✅ v1.x 的简洁方式:

text 复制代码
  1  from langchain.chat_models import init_chat_model
  2  from langchain.agents import create_agent
  3
  4  # 1. 初始化模型
  5  model = init_chat_model("gpt-4o-mini", model_provider="openai")
  6
  7  # 2. 创建 agent(一步完成)
  8  agent = create_agent(
  9      model=model,
 10      tools=[tool1, tool2],
 11      system_prompt="Agent 的行为指令"  # 可选
 12  )
 13
 14  # 3. 调用
 15  result = agent.invoke({
 16      "messages": [{"role": "user", "content": "问题"}]
 17  })

二、Agent 的模型传入方式

在 LangChain 1.2 中,create_agent 是构建智能体的核心方式,底层基于LangGraph 实现。

create_agent 完整参数:

text 复制代码
  1  from langchain.agents import create_agent
  2
  3  agent = create_agent(
  4      model: str | BaseChatModel,            # 必需:聊天模型
  5      tools: List[BaseTool],                 # 必需:工具列表
  6      *,
  7      system_prompt: str = "",               # 系统提示词
  8      middleware: Seguence[AgentMiddleware[StateT_co, ContextT]] = () # 中间件
  9      interrupt_before: List[str] = None,    # 在某些工具前暂停(人机协作)
 10      interrupt_after: List[str] = None,     # 在某些工具后暂停
 11      debug: bool = False                    # 调试模式
 12      name: str 丨 None = None,              # 设置模型名称
 13  )

Agent在创建时,涉及到模型(Agent使用的模型) 、可调用工具、系统提示词等参数的设置。

更多参数参考:https://reference.langchain.com/python/langchain/agents/factory/create_agent

Agent中模型的传入方式:

本节我们只关注模型的传入。

模型是 Agent 的"大脑",负责决策和推理。根据模型传入agent方式的不同,分为两种方式。

2.1 传入模型字符串

Agent根据传入的模型字符串,自主创建模型对象

text 复制代码
  1  from langchain.agents import create_agent
  2
  3  from dotenv import load_dotenv
  4
  5  load_dotenv(override=True)
  6
  7  agent = create_agent("deepseek-v4-flash")
  8  print(type(agent))
  9
 10  from IPython.display import Image, display
 11  display(Image(agent.get_graph().draw_mermaid_png()))

输出

text 复制代码
 1  <class 'langgraph.graph.state.CompiledStateGraph'>

由上可知,agent本质上是LangGraph的CompiledStateGraph实例,底层实现是一个图结构。

通过上述代码最后一行可以看到agent的图结构。

2.2 传入模型对象

text 复制代码
  1  from langchain.chat_models import init_chat_model
  2  from langchain.agents import create_agent
  3  from langchain_deepseek import ChatDeepSeek
  4  from dotenv import load_dotenv
  5  import os
  6  load_dotenv(override=True)
  7
  8  # 以ChatDeepSeek为例
  9  # model = ChatDeepSeek(model="deepseek-v4-flash")
 10
 11  # 以init_chat_model为例
 12  model = init_chat_model(
 13      model="gpt-5.4-mini",
 14      model_provider="openai",
 15      api_key=os.getenv("CLOSEAI_API_KEY"),
 16      base_url=os.getenv("CLOSEAI_BASE_URL")
 17  )
 18
 19
 20  agent = create_agent(model)
 21
 22  print(type(agent))
 23
 24  from IPython.display import Image, display
 25  display(Image(agent.get_graph().draw_mermaid_png()))

输出同上

text 复制代码
 1  <class 'langgraph.graph.state.CompiledStateGraph'>

三、如何调用 Agent

agent.invoke() 是Agent 最基本的同步调用方法,它会阻塞程序执行直到返回最终结果。具体的:

  • 输入:传入的参数为字典类型,字典内通过messages字段传递消息列表。即:" {"messages":

    {"role": "...", "content": "..."}} "

  • 输出:通过invoke调用Agent,底层可能会经历多轮交互,返回的是完整的消息列表,被封装在

    字典中,是messages字段的值。

text 复制代码
  1  response = agent.invoke({"messages": [...]})
  2
  3  # response 是字典类型
  4  {
  5      "messages": [
  6          HumanMessage(...),       # 用户问题
  7          AIMessage(...),          # AI 工具调用
  8          ToolMessage(...),        # 工具返回结果
  9          AIMessage(...)           # 最终回答 ← 通常取这个
 10      ]
 11  }
 12
 13  # 获取最终回答
 14  final_answer = response['messages'][-1].content

举例1:

text 复制代码
  1  from langchain.agents import create_agent
  2  from langchain.chat_models import init_chat_model
  3  from dotenv import load_dotenv
  4  import os
  5  load_dotenv(override=True)
  6  from rich import print as rprint
  7
  8  # 以init_chat_model为例
  9  model = init_chat_model(
 10      model="gpt-5.4-mini",
 11      model_provider="openai",
 12      api_key=os.getenv("CLOSEAI_API_KEY"),
 13      base_url=os.getenv("CLOSEAI_BASE_URL")
 14  )
 15
 16  agent = create_agent(model=model)
 17
 18  response = agent.invoke({"messages": ["你好"]}) # 默认是HumanMessage
 19  print(type(response))
 20  rprint(response)

输出如下

text 复制代码
  1  {
  2   'messages': [
  3       HumanMessage(
  4           content='你好',
  5           additional_kwargs={},
  6           response_metadata={},
  7           id='93ffcb22-179a-4cab-81a7-a3bd3a1795d4'
  8       ),
  9       AIMessage(
 10           content='你好!有什么我可以帮你的吗?',
 11           additional_kwargs={'refusal': None},
 12           response_metadata={
 13               'token_usage': {
 14                   'completion_tokens': 13,
 15                   'prompt_tokens': 7,
 16                   'total_tokens': 20,
 17                   'completion_tokens_details': {
 18                       'accepted_prediction_tokens': 0,
 19                       'audio_tokens': 0,
 20                       'reasoning_tokens': 0,
 21                       'rejected_prediction_tokens': 0
 22                   },
 23                   'prompt_tokens_details': {'audio_tokens': 0,
     'cached_tokens': 0},
 24                   'latency_checkpoint': {
 25                       'engine_tbt_ms': 3,
 26                       'engine_ttft_ms': 48,
 27                       'engine_ttlt_ms': 90,
 28                       'pre_inference_ms': 95,
 29                       'service_tbt_ms': 4,
 30                       'service_ttft_ms': 673,
 31                       'service_ttlt_ms': 712,
 32                       'total_duration_ms': 626,
 33                       'user_visible_ttft_ms': 578
 34                   }
 35               },
 36               'model_provider': 'openai',
 37               'model_name': 'gpt-5.4-mini-2026-03-17',
 38               'system_fingerprint': None,
 39               'id': 'chatcmpl-DlUJdEGrlJtKPHQ9wgdp1KsrEjIDc',
 40               'service_tier': 'default',
 41               'finish_reason': 'stop',
 42               'logprobs': None
 43           },
 44           id='lc_run--019e7ccd-c08b-7f60-8b07-32324cccf2c2-0',
 45           tool_calls=[],
 46           invalid_tool_calls=[],
 47           usage_metadata={
 48               'input_tokens': 7,
 49               'output_tokens': 13,
 50               'total_tokens': 20,
 51               'input_token_details': {'audio': 0, 'cache_read': 0},
 52               'output_token_details': {'audio': 0, 'reasoning': 0}
 53           }
 54       )
 55   ]
 56  }

举例2:

invoke调用的核心就是输入一系列消息(messages),每条消息通常包含 role(如 "user", "assistant",

"system", "tool")和 "content"。

我们也可以在message列表的开头加入"system"角色的消息来定义Agent的行为。

text 复制代码
  1  from langchain.agents import create_agent
  2  from langchain.chat_models import init_chat_model
  3  from dotenv import load_dotenv
  4  import os
  5  load_dotenv(override=True)
  6  from rich import print as rprint
  7
  8  # 以init_chat_model为例
  9  model = init_chat_model(
 10      model="gpt-5.4-mini",
 11      model_provider="openai",
 12      api_key=os.getenv("CLOSEAI_API_KEY"),
 13      base_url=os.getenv("CLOSEAI_BASE_URL")
 14  )
 15
 16  agent = create_agent(model)
 17
 18  resp = agent.invoke( {
 19      "messages": [
 20          {"role": "system", "content": "你是一个小学数学老师,耐心,幽默,讲解深入浅
     出"},
 21          {"role": "user", "content": "100加上50等于多少?"}
 22      ]
 23  })
 24
 25  rprint(resp)
text 复制代码
  1  {
  2   'messages': [
  3       SystemMessage(
  4           content='你是一个小学数学老师,耐心,幽默,讲解深入浅出',
  5           additional_kwargs={},
  6           response_metadata={},
  7           id='6e02c29f-0360-499a-9d31-f6fcf5921310'
  8       ),
  9       HumanMessage(
 10           content='100加上50等于多少?',
 11           additional_kwargs={},
 12           response_metadata={},
 13           id='7a70d206-28d9-4081-9bb3-2f387aba2fd3'
 14       ),
 15       AIMessage(
 16           content='100 加上 50 等于 **150**。  \n\n可以这样想:  \n- 100 是
     1 个百  \n- 再加 50,也就是 5 个十
 17  \n- 合起来就是 **150**\n\n如果你愿意,我还可以教你怎么用"数数法"快速算这种题。',
 18           additional_kwargs={'refusal': None},
 19           response_metadata={
 20               'token_usage': {
 21                   'completion_tokens': 71,
 22                   'prompt_tokens': 36,
 23                   'total_tokens': 107,
 24                   'completion_tokens_details': {
 25                       'accepted_prediction_tokens': 0,
 26                       'audio_tokens': 0,
 27                       'reasoning_tokens': 0,
 28                       'rejected_prediction_tokens': 0
 29                   },
 30                   'prompt_tokens_details': {'audio_tokens': 0,
     'cached_tokens': 0},
 31                   'latency_checkpoint': {
 32                       'engine_tbt_ms': 6,
 33                       'engine_ttft_ms': 33,
 34                       'engine_ttlt_ms': 426,
 35                       'pre_inference_ms': 75,
 36                       'service_tbt_ms': 6,
 37                       'service_ttft_ms': 253,
 38                       'service_ttlt_ms': 638,
 39                       'total_duration_ms': 572,
 40                       'user_visible_ttft_ms': 178
 41                   }
 42               },
 43               'model_provider': 'openai',
 44               'model_name': 'gpt-5.4-mini-2026-03-17',
 45               'system_fingerprint': None,
 46               'id': 'chatcmpl-DlUOHPXmUQEGFyu46rJf2kmbbjWrG',
 47               'service_tier': 'default',
 48               'finish_reason': 'stop',
 49               'logprobs': None
 50           },
 51           id='lc_run--019e7cd2-260e-7ae0-a8c0-e247fbdf767e-0',
 52           tool_calls=[],
 53           invalid_tool_calls=[],
 54           usage_metadata={
 55               'input_tokens': 36,
 56               'output_tokens': 71,
 57               'total_tokens': 107,
 58               'input_token_details': {'audio': 0, 'cache_read': 0},
 59               'output_token_details': {'audio': 0, 'reasoning': 0}
 60           }
 61       )
 62   ]
 63  }

四、Agent 绑定工具

只有接入了一些工具,create_agent完成Agent创建才算完整。

Agent支持静态和动态绑定工具,后者需要用到中间件,后面会讲。在执行时:

这里的工具可以是LangChain内置的,也可以是自定义的。LangChain生态中已经内置集成了非常多的

实用工具,开发者可以快速调用这些工具完成更加复杂工作流的开发。

LangChain内置工具列表:https://docs.langchain.com/oss/python/integrations/tools

其中典型的工具如下:

4.1 基本用法

Agents支持绑定一或多个工具。

4.1.1 举例1:绑定一个工具

调用查询天气工具进行天气查询

text 复制代码
  1  from langchain.agents import create_agent
  2  from langchain.tools import tool
  3  from rich import print as rprint
  4
  5
  6  @tool(parse_docstring=True)
  7  def get_weather(city: str) -> str:
  8      """
  9      天气查询工具
 10
 11      Args:
 12          city: 城市名称
 13      """
 14      return f"{city}的天气为晴朗,25°C。"
 15
 16
 17  agent = create_agent(
 18      model = model,
 19      tools=[get_weather]
 20  )
 21
 22  resp = agent.invoke( {
 23      "messages": [
 24          {"role": "system", "content": "你是一个天气查询助手,只回答天气相关的问题,
     其他问题请直接回答:我不清楚这问题答案。"},
 25          {"role": "user", "content": "北京的天气怎么样?"}
 26          # {"role": "user", "content": "100加上50等于多少?"}
 27      ]
 28  })
 29
 30  rprint(resp)

以上代码运行结果如下:

text 复制代码
   1  {
   2   'messages': [
   3       SystemMessage(
   4           content='你是一个天气查询助手,只回答天气相关的问题,其他问题请直接回
       答:我不清楚这问题答案。',
   5           additional_kwargs={},
   6           response_metadata={},
   7           id='6f754fe0-7cd2-4e6b-a3a0-7592a71a7d20'
   8       ),
   9       HumanMessage(
  10           content='北京的天气怎么样?',
  11           additional_kwargs={},
  12           response_metadata={},
  13           id='ecf89457-2901-41d3-b960-ac8f7484d48e'
  14       ),
  15       AIMessage(
  16           content='',
  17           additional_kwargs={'refusal': None},
  18           response_metadata={
  19               'token_usage': {
  20                   'completion_tokens': 18,
  21                   'prompt_tokens': 162,
  22                   'total_tokens': 180,
  23                   'completion_tokens_details': {
  24                       'accepted_prediction_tokens': 0,
  25                       'audio_tokens': 0,
  26                       'reasoning_tokens': 0,
  27                       'rejected_prediction_tokens': 0
  28                   },
  29                   'prompt_tokens_details': {'audio_tokens': 0,
       'cached_tokens': 0},
  30                   'latency_checkpoint': {
  31                       'engine_tbt_ms': 3,
  32                       'engine_ttft_ms': 48,
  33                       'engine_ttlt_ms': 110,
  34                       'pre_inference_ms': 102,
  35                       'service_tbt_ms': 4,
  36                       'service_ttft_ms': 312,
  37                       'service_ttlt_ms': 368,
  38                       'total_duration_ms': 274,
  39                       'user_visible_ttft_ms': 210
  40                   }
  41               },
  42               'model_provider': 'openai',
  43               'model_name': 'gpt-5.4-mini-2026-03-17',
  44               'system_fingerprint': None,
  45               'id': 'chatcmpl-DlavpIfl1rVj1nwpU8F39s8IAkexg',
  46               'service_tier': 'default',
  47               'finish_reason': 'tool_calls',
  48               'logprobs': None
  49           },
  50           id='lc_run--019e7e51-d485-7331-aa8b-cf03d9e23d7f-0',
  51           tool_calls=[
  52               {
  53                   'name': 'get_weather',
  54                   'args': {'city': '北京'},
  55                   'id': 'call_4dp4PGy6Ghaj5m6WcNkrwKFe',
  56                   'type': 'tool_call'
  57               }
  58           ],
  59           invalid_tool_calls=[],
  60           usage_metadata={
  61               'input_tokens': 162,
  62               'output_tokens': 18,
  63               'total_tokens': 180,
  64               'input_token_details': {'audio': 0, 'cache_read': 0},
  65               'output_token_details': {'audio': 0, 'reasoning': 0}
  66           }
  67       ),
  68       ToolMessage(
  69           content='北京的天气为晴朗,25°C。',
  70           name='get_weather',
  71           id='b5b82403-973c-463b-b9f2-2aa76e0bff77',
  72           tool_call_id='call_4dp4PGy6Ghaj5m6WcNkrwKFe'
  73       ),
  74       AIMessage(
  75           content='北京天气晴朗,25°C。',
  76           additional_kwargs={'refusal': None},
  77           response_metadata={
  78               'token_usage': {
  79                   'completion_tokens': 12,
  80                   'prompt_tokens': 200,
  81                   'total_tokens': 212,
  82                   'completion_tokens_details': {
  83                       'accepted_prediction_tokens': 0,
  84                       'audio_tokens': 0,
  85                       'reasoning_tokens': 0,
  86                       'rejected_prediction_tokens': 0
  87                   },
  88                   'prompt_tokens_details': {'audio_tokens': 0,
       'cached_tokens': 0},
  89                   'latency_checkpoint': {
  90                       'engine_tbt_ms': 3,
  91                       'engine_ttft_ms': 34,
  92                       'engine_ttlt_ms': 71,
  93                       'pre_inference_ms': 94,
  94                       'service_tbt_ms': 3,
  95                       'service_ttft_ms': 272,
  96                       'service_ttlt_ms': 303,
  97                       'total_duration_ms': 219,
  98                       'user_visible_ttft_ms': 178
  99                   }
 100               },
 101               'model_provider': 'openai',
 102               'model_name': 'gpt-5.4-mini-2026-03-17',
 103               'system_fingerprint': None,
 104               'id': 'chatcmpl-Dlavq02DEdjb4JOBx3MTblngJKbTQ',
 105               'service_tier': 'default',
 106               'finish_reason': 'stop',
 107               'logprobs': None
 108           },
 109           id='lc_run--019e7e51-d9d7-7e81-bed0-cc990abfa293-0',
 110           tool_calls=[],
 111           invalid_tool_calls=[],
 112           usage_metadata={
 113               'input_tokens': 200,
 114               'output_tokens': 12,
 115               'total_tokens': 212,
 116               'input_token_details': {'audio': 0, 'cache_read': 0},
 117               'output_token_details': {'audio': 0, 'reasoning': 0}
 118           }
 119       )
 120   ]
 121  }

进一步:

text 复制代码
 1  from IPython.display import Image, display
 2
 3  display(Image(agent.get_graph().draw_mermaid_png()))

4.1.2 举例2:接入内置工具

绑定内置的TavilySearch搜索工具,可以借助Tavily进行网络搜索和信息爬取。

这里我们需要先在tavily官网注册并获得API-KEY(每月有免费额度):https://www.tavily.com/。

然后将API-KEY写到本地.env中的TAVILY_API_KEY 变量中,即可进行调用了。

text 复制代码
  1  from langchain_tavily import TavilySearch
  2  from dotenv import load_dotenv
  3  import os
  4
  5  load_dotenv(override=True)
  6
  7  web_search = TavilySearch(
  8      tavily_api_key=os.getenv("TAVILY_API_KEY"),
  9      max_results=2
 10  )
 11
 12  #这是一个高度封装的网络搜索工具,可以直接调用:
 13  web_search.invoke("请问2026年足球世界杯有哪些参赛队?")
text 复制代码
  1  {'query': '请问2026年足球世界杯有哪些参赛队?',
  2  'follow_up_questions': None,
  3  'answer': None,
  4  'images': [],
  5  'results': [{'url': 'https://www.instagram.com/p/DWk8mU-geNg',
  6  'title': '你準備好了嗎? 2026 FIFA世界盃™ 48支隊伍全數到齊 ... - Instagram',
  7  'content': '本屆賽事由美國、加拿大、墨西哥三國聯合主辦,總共48 支球隊、104 場比
     賽、39 天賽程,這次的世界盃賽程本身就是前所未見的規模。',
  8  'score': 0.9974885,
  9  'raw_content': None},
 10  {'url': 'https://zh.wikipedia.org/zh-
     hans/2026%E5%B9%B4%E5%9C%8B%E9%9A%9B%E8%B6%B3%E5%8D%94%E4%B8%96%E7%95%8
     C%E7%9B%83%E5%A4%96%E5%9C%8D%E8%B3%BD',
 11  'title': '2026年国际足联世界杯预选赛 - 维基百科',
 12  'content': '2026年国际足联世界杯预选赛是一项国家队足球预选赛赛事,以决定出哪些球队
     能够参与由加拿大、墨西哥和美国联合举办的2026年国际足联世界杯。本届世界杯决赛周名额
     增',
 13  'score': 0.9974291,
 14  'raw_content': None}],
 15  'response_time': 0.79,
 16  'request_id': 'dc00f93f-1b75-4222-86cc-4b6af567edf1'}

可以直接带入create_agent中作为外部工具。

text 复制代码
  1  from langchain.chat_models import init_chat_model
  2  from langchain.agents import create_agent
  3  from langchain_tavily import TavilySearch
  4  from dotenv import load_dotenv
  5  import os
  6  load_dotenv(override=True)
  7  from rich import print as rprint
  8
  9  # 1.模型初始化
 10  model = init_chat_model(
 11      model="gpt-5.4-mini",
 12      model_provider="openai",
 13      api_key=os.getenv("CLOSEAI_API_KEY"),
 14      base_url=os.getenv("CLOSEAI_BASE_URL")
 15  )
 16  # 2.工具实例化
 17  web_search = TavilySearch(max_results=2)
 18
 19  # 3.创建Agent
 20  agent = create_agent(
 21      model=model,
 22      tools=[web_search],
 23      #system_prompt="你是一名多才多艺的智能助手,可以调用工具帮助用户解决问题。"
 24  )
 25
 26  # 4.运行Agent获得结果
 27  result = agent.invoke(
 28      {"messages": [{"role": "user", "content": "请帮我查询2024年诺贝尔物理学奖得主
     是谁?"}]}
 29  )
 30
 31  # rprint(result)
 32  print(result['messages'][-1].content)
text 复制代码
 1  2024年诺贝尔物理学奖得主是:
 2
 3  - **John J. Hopfield**
 4  - **Geoffrey E. Hinton**
 5
 6  授奖理由是:**"为实现机器学习的人工神经网络奠定基础性的发现和发明"**。

如果仔细观察本次运行过程,本次工具调用仍然是一次典型的Function calling执行流程,包括用户首次

发起消息在内,总共创建了4条消息,分别是human message、ai message (涉及function call

message)、tool message(涉及function response message)以及ai message(涉及final

responses)。

一次完整的Function calling 执行流程如下:

4.1.3 举例3:绑定多个工具

text 复制代码
  1  from langchain.agents import create_agent
  2  from langchain.tools import tool
  3  from dotenv import load_dotenv
  4  from rich import print as rprint
  5
  6  load_dotenv()
  7
  8  @tool(parse_docstring=True)
  9  def get_weather(city: str):
 10      """
 11      天气查询工具
 12
 13      Args:
 14          city: 城市名称
 15      """
 16      return f"{city}今天天气挺好"
 17
 18  @tool(parse_docstring=True)
 19  def get_news():
 20      """
 21      新闻查询工具
 22      """
 23      return "近期,受全球储蓄芯片短缺等多重因素影响,多地回收商称废旧手机回收市场迎来"火热
     潮",回收价格普遍上涨,旧手机成"香饽饽"。"
 24
 25  agent = create_agent(
 26      model,
 27      tools=[get_weather, get_news]
 28  )
 29  response = agent.invoke({
 30      "messages": ["你好,杭州今天的天气如何?今天有哪些新闻?"]
 31  })
 32
 33  rprint(response)
 34

输出

text 复制代码
   1  {
   2   'messages': [
   3       HumanMessage(
   4           content='你好,杭州今天的天气如何?今天有哪些新闻?',
   5           additional_kwargs={},
   6           response_metadata={},
   7           id='6f69ed6d-76fe-4d1d-9e31-c00a4bedf623'
   8       ),
   9       AIMessage(
  10           content='',
  11           additional_kwargs={'refusal': None},
  12           response_metadata={
  13               'token_usage': {
  14                   'completion_tokens': 46,
  15                   'prompt_tokens': 152,
  16                   'total_tokens': 198,
  17                   'completion_tokens_details': {
  18                       'accepted_prediction_tokens': 0,
  19                       'audio_tokens': 0,
  20                       'reasoning_tokens': 0,
  21                       'rejected_prediction_tokens': 0
  22                   },
  23                   'prompt_tokens_details': {'audio_tokens': 0,
       'cached_tokens': 0},
  24                   'latency_checkpoint': {
  25                       'engine_tbt_ms': 4,
  26                       'engine_ttft_ms': 32,
  27                       'engine_ttlt_ms': 197,
  28                       'pre_inference_ms': 90,
  29                       'service_tbt_ms': 4,
  30                       'service_ttft_ms': 272,
  31                       'service_ttlt_ms': 429,
  32                       'total_duration_ms': 348,
  33                       'user_visible_ttft_ms': 182
  34                   }
  35               },
  36               'model_provider': 'openai',
  37               'model_name': 'gpt-5.4-mini-2026-03-17',
  38               'system_fingerprint': None,
  39               'id': 'chatcmpl-DlcRS3bbpm4iVX6laeXtWj2vYnYMm',
  40               'service_tier': 'default',
  41               'finish_reason': 'tool_calls',
  42               'logprobs': None
  43           },
  44           id='lc_run--019e7eaa-6712-7323-91e6-8af52084b894-0',
  45           tool_calls=[
  46               {
  47                   'name': 'get_weather',
  48                   'args': {'city': '杭州'},
  49                   'id': 'call_w9ARuAgN8iqfG2GR7gv00iBq',
  50                   'type': 'tool_call'
  51               },
  52               {'name': 'get_news', 'args': {}, 'id':
       'call_vOLekRymIme8bWuVQdIew4vu', 'type': 'tool_call'}
  53           ],
  54           invalid_tool_calls=[],
  55           usage_metadata={
  56               'input_tokens': 152,
  57               'output_tokens': 46,
  58               'total_tokens': 198,
  59               'input_token_details': {'audio': 0, 'cache_read': 0},
  60               'output_token_details': {'audio': 0, 'reasoning': 0}
  61           }
  62       ),
  63       ToolMessage(
  64           content='杭州今天天气挺好',
  65           name='get_weather',
  66           id='21da1cc4-1d26-4d5b-a04a-a836644274fc',
  67           tool_call_id='call_w9ARuAgN8iqfG2GR7gv00iBq'
  68       ),
  69       ToolMessage(
  70           content='近期,受全球储蓄芯片短缺等多重因素影响,多地回收商称废旧手机回
       收市场迎来"火热潮",回收价格普遍
  71  上涨,旧手机成"香饽饽"。',
  72           name='get_news',
  73           id='d1fd947b-3d0f-47f5-9942-c4330f4d7fc6',
  74           tool_call_id='call_vOLekRymIme8bWuVQdIew4vu'
  75       ),
  76       AIMessage(
  77           content='杭州今天天气挺好。\n\n今天的新闻:\n1.
  78  近期受全球储蓄芯片短缺等多重因素影响,多地回收商称废旧手机回收市场迎来"火热潮",回收
       价格普遍上涨,旧手机成了"香饽饽
  79  "。\n\n如果你愿意,我也可以帮你继续整理成"天气 + 新闻摘要"的简版。',
  80           additional_kwargs={'refusal': None},
  81           response_metadata={
  82               'token_usage': {
  83                   'completion_tokens': 91,
  84                   'prompt_tokens': 272,
  85                   'total_tokens': 363,
  86                   'completion_tokens_details': {
  87                       'accepted_prediction_tokens': 0,
  88                       'audio_tokens': 0,
  89                       'reasoning_tokens': 0,
  90                       'rejected_prediction_tokens': 0
  91                   },
  92                   'prompt_tokens_details': {'audio_tokens': 0,
       'cached_tokens': 0},
  93                   'latency_checkpoint': {
  94                       'engine_tbt_ms': 5,
  95                       'engine_ttft_ms': 38,
  96                       'engine_ttlt_ms': 466,
  97                       'pre_inference_ms': 83,
  98                       'service_tbt_ms': 5,
  99                       'service_ttft_ms': 265,
 100                       'service_ttlt_ms': 686,
 101                       'total_duration_ms': 610,
 102                       'user_visible_ttft_ms': 183
 103                   }
 104               },
 105               'model_provider': 'openai',
 106               'model_name': 'gpt-5.4-mini-2026-03-17',
 107               'system_fingerprint': None,
 108               'id': 'chatcmpl-DlcRTgUZZHsugIYnroPNDk3PXXQwW',
 109               'service_tier': 'default',
 110               'finish_reason': 'stop',
 111               'logprobs': None
 112           },
 113           id='lc_run--019e7eaa-6cac-7901-b58c-d677bf6135be-0',
 114           tool_calls=[],
 115           invalid_tool_calls=[],
 116           usage_metadata={
 117               'input_tokens': 272,
 118               'output_tokens': 91,
 119               'total_tokens': 363,
 120               'input_token_details': {'audio': 0, 'cache_read': 0},
 121               'output_token_details': {'audio': 0, 'reasoning': 0}
 122           }
 123       )
 124   ]
 125  }
text 复制代码
 1  from IPython.display import Image, display
 2
 3  display(Image(agent.get_graph().draw_mermaid_png()))

注意:只给 Agent 需要的工具,工具太多会混淆。一般2-5 个工具最佳

4.2 工具调用流程分析

LangChain 的 Agent 会将模型与工具结合起来,在实现上由一个基于 LangGraph 的图结构来编排执

行流程,如下所示。

这与前文得到的 Agent 图结构是一致的,本质上就是经典的 ReAct 结构:一个具备" 思考-行动-观察"

不断循环的自主工作者。

text 复制代码
 1  用户问题 → AI 思考 → 调用工具 → 观察结果 → 继续思考 → ... → 最终答案

当用户提出一个复杂需求时,Agent会像人类一样,先理解任务、规划步骤、使用合适的工具(如搜索

网络、查询数据库、执行计算)获取信息,Agent 会在一个循环中反复调用模型和工具,直到某次模

型输出中不再包含工具调用则结束,最后综合所有信息给出最终答案。

完整流程:

举例:用户问题:"找出当前最流行的无线耳机并检查库存"的任务。

1、输入解析与初始推理

  • 输入:用户查询:"找出当前最流行的无线耳机并检查库存"。

  • 推理:LLM分析任务后认为:"要找出'最流行'的产品,需要最新的市场信息,我应该先使用搜索工

    具。"

2、第一次行动(action)与观察(observation)

  • 行动:Agent调用search_products工具,参数为"wireless headphones"。

  • 观察:工具返回结果:"找到5款匹配产品。Top结果:WH-1000XM5, ..."

3、迭代推理

  • 推理:LLM根据搜索结果分析:"WH-1000XM5是排名第一的型号。现在需要确认其库存状态才能
    回答用户问题。"

4、第二次行动(action)与观察(observation)

  • 行动:Agent调用check_inventory工具,参数为"WH-1000XM5"。

  • 观察:工具返回:"产品WH-1000XM5:库存10件。"

5、最终输出

  • 推理:LLM综合所有信息后认为:"已获得所需信息,可以生成最终答案。"

  • 行动:模型生成最终答案,不再调用工具。

4.3 重试机制

Agent可以在工具调用结果不满足要求时,自主重试。

text 复制代码
  1  from langchain.agents import create_agent
  2  from langchain.tools import tool
  3  from langchain.messages import SystemMessage, HumanMessage
  4  from dotenv import load_dotenv
  5  from rich import print as rprint
  6
  7  load_dotenv(override=True)
  8
  9  flag = 0
 10
 11  @tool
 12  def get_weather(city: str):
 13      """
 14      天气查询工具
 15
 16      Args:
 17          city: 城市名称
 18      """
 19      global flag
 20      flag += 1
 21
 22      if flag < 3:
 23          # raise Exception("暂时无法访问")
 24          return "TEMP_UNAVAILABLE: 天气服务暂时不可用,请稍后重试"
 25
 26      return f"{city}今天天气挺好"
 27
 28
 29  messages = [
 30      SystemMessage("""
 31      你是一个天气助手。
 32      当工具返回以 'TEMP_UNAVAILABLE:' 开头的结果时,
 33      说明是临时故障,不要立即放弃;
 34      你应再次调用同一个工具,最多重试 3 次。
 35      如果 3 次后仍失败,再向用户说明服务暂时不可用。
 36      """),
 37      HumanMessage("你好,杭州今天的天气如何?")
 38  ]
 39  agent = create_agent(model, tools=[get_weather])
 40  response = agent.invoke({"messages": messages})
 41
 42  # rprint(response)
 43
 44  for msg in response["messages"]:
 45      msg.pretty_print()

输出

text 复制代码
  1  ================================ System Message
     ================================
  2
  3
  4   你是一个天气助手。
  5   当工具返回以 'TEMP_UNAVAILABLE:' 开头的结果时,
  6   说明是临时故障,不要立即放弃;
  7   你应再次调用同一个工具,最多重试 3 次。
  8   如果 3 次后仍失败,再向用户说明服务暂时不可用。
  9
 10  ================================ Human Message
     =================================
 11
 12  你好,杭州今天的天气如何?
 13  ================================== Ai Message
     ==================================
 14  Tool Calls:
 15    get_weather (call_cvICuCPSk4U7aWk6YYkAzI5o)
 16  Call ID: call_cvICuCPSk4U7aWk6YYkAzI5o
 17  Args:
 18   city: 杭州
 19  ================================= Tool Message
     =================================
 20  Name: get_weather
 21
 22  TEMP_UNAVAILABLE: 天气服务暂时不可用,请稍后重试
 23  ================================== Ai Message
     ==================================
 24  Tool Calls:
 25  get_weather (call_UQL2QTDxKaTCOXbY5Crwbae0)
 26  Call ID: call_UQL2QTDxKaTCOXbY5Crwbae0
 27    Args:
 28   city: 杭州
 29  ================================= Tool Message
     =================================
 30  Name: get_weather
 31
 32  TEMP_UNAVAILABLE: 天气服务暂时不可用,请稍后重试
 33  ================================== Ai Message
     ==================================
 34  Tool Calls:
 35  get_weather (call_gZKuGbhp36wEyhjYgeupfu3b)
 36  Call ID: call_gZKuGbhp36wEyhjYgeupfu3b
 37  Args:
 38     city: 杭州
 39  ================================= Tool Message
     =================================
 40  Name: get_weather
 41
 42  杭州今天天气挺好
 43  ================================== Ai Message
     ==================================
 44
 45  杭州今天天气挺好。

模型三次调用get_weather ,最终获得了满意的结果。

4.4 常见问题

问题1:Agent 如何选择工具?

依据:工具的 docstring

text 复制代码
 1  @tool
 2  def get_weather(city: str) -> str:
 3      """获取指定城市的天气信息"""  # ← AI Agent读这个!
 4      ...
 5
 6  @tool
 7  def calculator(operation: str, a: float, b: float) -> str:
 8      """执行基本的数学计算"""  # ← AI Agent也读这个!
 9      ...

AI 会根据:

  1. 问题内容
  2. 每个工具的描述
  3. 自动选择最匹配的工具

问题2:Agent 为什么没有调用工具?

原因:

  • 工具的 docstring 不清晰

  • 问题表述不明确

  • 模型认为不需要工具

解决:

text 复制代码
  1  # ❌ 不好
  2  @tool
  3  def tool1(x: str) -> str:
  4      """做一些事情"""  # 太模糊
  5
  6
  7  # ✅ 好
  8  @tool
  9  def get_weather(city: str) -> str:
 10      """
 11      获取指定城市的实时天气信息
 12
 13      Args:
 14          city: 城市名称,如"北京"、"上海"
 15      """

问题3:Agent 选错工具?

原因:

  • 多个工具的功能描述相似

  • 工具太多导致混淆

解决:

  • 只给必要的工具

  • 工具描述要有明确区分

  • 在 system_prompt 中说明工具使用场景

text 复制代码
  1  # ✅ 好:只给需要的工具
  2  agent = create_agent(
  3      model=model,
  4      tools=[get_weather, calculator]  # 2-5 个工具最佳
  5  )
  6
  7  # ❌ 不好:工具太多
  8  agent = create_agent(
  9      model=model,
 10      tools=[tool1, tool2, ..., tool20]  # 会混淆
 11  )

问题4:如何知道 Agent 何时完成?

当 AIMessage 不包含 tool_calls 时:

text 复制代码
 1  for msg in response['messages']:
 2      if isinstance(msg, AIMessage):
 3          if hasattr(msg, 'tool_calls') and msg.tool_calls:
 4              print("还在调用工具...")
 5          else:
 6              print("完成!最终答案:", msg.content)

问题5:Agent 可以调用多少次工具?

默认没有限制,直到得到最终答案。但可能会:

  • 超时

  • 达到 token 限制

  • 模型决定停止

问题6:如何限制工具调用次数?

LangChain 1.0 的 create_agent 默认使用 LangGraph,可以通过配置限制:

text 复制代码
 1  # 注意:这是高级用法,后续会详细学习
 2  config = {
 3      "recursion_limit": 5  # 最多 5 步
 4  }
 5
 6  response = agent.invoke(input, config=config)

五、设置 Agent 名称

创建Agent时,LangChain允许用户指定其名称

5.1 用法

text 复制代码
  1  from langchain.agents import create_agent
  2  from langchain.chat_models import init_chat_model
  3  from dotenv import load_dotenv
  4  import os
  5  from rich import print as rprint
  6
  7  # 从.env文件中加载环境变量
  8  load_dotenv(override=True)
  9
 10  model = init_chat_model(
 11      model="gpt-5.4-mini",
 12      model_provider="openai",
 13      api_key=os.getenv("CLOSEAI_API_KEY"),
 14      base_url=os.getenv("CLOSEAI_BASE_URL")
 15  )
 16
 17
 18  agent = create_agent(
 19      model=model,
 20      name = "chat_assistant"
 21  )
 22
 23  response = agent.invoke({"messages": ["你好"]})
 24
 25  # rprint(response)
 26
 27  for msg in response["messages"]:
 28      msg.pretty_print()

输出

text 复制代码
 1  ================================ Human Message
    =================================
 2
 3  你好
 4  ================================== Ai Message
    ==================================
 5  Name: chat_assistant
 6
 7  你好!有什么我可以帮你的吗?

输出的AI Message带有Name信息。

5.2 经典使用场景

name 在 Multi-Agent 场景中最常被提及,用于区分不同的 Agent。但它的作用并不局限于多 Agent

编排。在实际工程中,出现如下场景,通常都建议为 Agent 设置一个清晰且稳定的 name 。

1. 流式输出归因

在启用流式输出时,name 可用于标识当前输出内容来自哪个 Agent 。

这在多 Agent 协作、Agent 嵌套调用,或前端需要实时展示不同执行主体输出时尤其有用,便于准确区

分 token 或事件的来源。

2. 消息身份标记

设置 name 后,Agent 产生的 AIMessage 会携带对应的name信息。

这使得系统在保存会话记录、回放执行过程、构建审计日志或前端展示消息角色时,能够明确识

别消息的生成者。

3. 调试与trace可读性

在调试、日志分析和链路追踪过程中,name 可以作为 Agent 的稳定标识,帮助开发者快速判断当前执

行的是哪个 Agent 。

当系统中存在多个能力相近的 Agent,或一个 Agent 被嵌套在更复杂的工作流中时,名称能够显著提升

trace 的可读性和问题定位效率。

4. 组件化封装

在工程实践中,Agent 常被封装为可复用的能力模块,例如检索助手、SQL 助手、报告生成助手等。

为 Agent 设置 name ,有助于在模块注册、运行监控、日志归档和能力复用时保持一致的身份标识。

如果后续需要将该 Agent 进一步作为子图节点、工具能力或子模块接入更复杂系统,也能降低维护和迁

移成本。

5. 前端展示与运行态可观测性

在带有可视化界面的应用中,name 还可以直接作为运行时展示标识使用。

例如,在执行面板中显示"当前活跃 Agent""本轮输出来源"或"调用链路中的执行节点"时,name 能帮助

开发者和用户更直观地理解系统当前的执行状态。

6. 作为稳定的运行时身份标识

从更通用的角度看,name 可以理解为 Agent 在系统中的" 运行时身份 ID "。

相比临时性的展示名称,一个稳定、规范的 name 更适合用于日志检索、监控统计、链路分析和

跨模块协作,因此在生产环境中通常建议显式设置,而不是依赖默认行为。

六、Agent 的系统提示词

使用 create_agent 创建 Agent 时,需传入模型和工具、可选地传入系统提示词。提示词为Agent

提供了任务背景、行为准则和操作指南。

系统指令,即SystemMessage,通过 system_prompt 设置,定义 Agent 行为。这个参数可以是str

或者SystemMessage类型。

使用建议:

  • 明确说明 Agent 的角色

  • 定义输出格式

  • 说明何时使用工具

比如:

text 复制代码
  1  agent = create_agent(
  2      model=model,
  3      tools=[get_weather],
  4      system_prompt="""你是天气助手。
  5
  6  工作流程:
  7  1. 理解用户的城市查询
  8  2. 使用 get_weather 工具获取数据
  9  3. 简洁清晰地回答
 10
 11  输出格式:
 12  - 天气状况
 13  - 温度
 14  - 注意事项(如有)
 15  """
 16  )

提示词设置有两种方式:静态设置和动态设置。动态设置需要借助中间件,后续讲解。

举例1:

text 复制代码
  1  from langchain_tavily import TavilySearch
  2  from langchain.agents import create_agent
  3  from langchain.chat_models import init_chat_model
  4  from dotenv import load_dotenv
  5  import os
  6  load_dotenv(override=True)
  7
  8
  9  # 1.导入模型
 10  model = init_chat_model(
 11      model="gpt-5.4-mini",
 12      model_provider="openai",
 13      api_key=os.getenv("CLOSEAI_API_KEY"),
 14      base_url=os.getenv("CLOSEAI_BASE_URL")
 15  )
 16
 17  # 2.导入工具
 18  web_search = TavilySearch(max_results=2)
 19
 20  # 3.创建Agent
 21  agent = create_agent(
 22      model=model,
 23      tools=[web_search],
 24      system_prompt="你是一名多才多艺的智能助手,可以调用工具帮助用户解决问题。"
 25  )
 26
 27  # 4.运行Agent获得结果
 28  result = agent.invoke(
 29      {"messages": [
 30          {"role": "user", "content": "请帮我查询2026年足球世界杯是哪个国家举办的?"}
 31      ]}
 32  )
 33
 34  print(result['messages'][-1].content)
text 复制代码
 1  2026年足球世界杯由**三个国家联合举办**:**加拿大、墨西哥和美国**。

举例2:

text 复制代码
  1  from langchain.agents import create_agent
  2  from langchain_core.messages import SystemMessage
  3  from langchain_core.tools import tool
  4  from rich import print as rprint
  5
  6  # 工具:实现两数相加
  7  @tool
  8  def add_numbers(a: int, b: int) -> str:
  9      """计算并返回两个数的和。"""
 10      return f"和为:{a + b}"
 11
 12
 13  # 创建客服助手Agent
 14  agent = create_agent(
 15      model=model,
 16      tools=[add_numbers],  # 工具列表
 17      # system_prompt="你是一个数学助手,解决日常的算术问题"
 18      system_prompt=SystemMessage(content="你是一个数学助手,解决日常的算术问题")
 19  )
 20
 21  response = agent.invoke(
 22      {"messages": [
 23          {"role": "user", "content": "10加上20再加上30是多少?"}
 24      ]},
 25  )
 26
 27  rprint(response)
 28  # print(response["messages"][-1].content)

结果如下:

text 复制代码
   1  {
   2   'messages': [
   3       HumanMessage(
   4           content='10加上20再加上30是多少?',
   5           additional_kwargs={},
   6           response_metadata={},
   7           id='bd84f000-da12-450c-aeef-0719afcfecfd'
   8       ),
   9       AIMessage(
  10           content='',
  11           additional_kwargs={'refusal': None},
  12           response_metadata={
  13               'token_usage': {
  14                   'completion_tokens': 22,
  15                   'prompt_tokens': 158,
  16                   'total_tokens': 180,
  17                   'completion_tokens_details': {
  18                       'accepted_prediction_tokens': 0,
  19                       'audio_tokens': 0,
  20                       'reasoning_tokens': 0,
  21                       'rejected_prediction_tokens': 0
  22                   },
  23                   'prompt_tokens_details': {'audio_tokens': 0,
       'cached_tokens': 0},
  24                   'latency_checkpoint': {
  25                       'engine_tbt_ms': 3,
  26                       'engine_ttft_ms': 31,
  27                       'engine_ttlt_ms': 106,
  28                       'pre_inference_ms': 94,
  29                       'service_tbt_ms': 4,
  30                       'service_ttft_ms': 282,
  31                       'service_ttlt_ms': 352,
  32                       'total_duration_ms': 267,
  33                       'user_visible_ttft_ms': 188
  34                   }
  35               },
  36               'model_provider': 'openai',
  37               'model_name': 'gpt-5.4-mini-2026-03-17',
  38               'system_fingerprint': None,
  39               'id': 'chatcmpl-DmKgu0QquKeWrXBncvxCak9zkIkEf',
  40               'service_tier': 'default',
  41               'finish_reason': 'tool_calls',
  42               'logprobs': None
  43           },
  44           id='lc_run--019e88cd-d248-76b0-836c-71c63856787a-0',
  45           tool_calls=[
  46               {
  47                   'name': 'add_numbers',
  48                   'args': {'a': 10, 'b': 20},
  49                   'id': 'call_PWuscHI7NFdVbAV9wsMzOWKy',
  50                   'type': 'tool_call'
  51               }
  52           ],
  53           invalid_tool_calls=[],
  54           usage_metadata={
  55               'input_tokens': 158,
  56               'output_tokens': 22,
  57               'total_tokens': 180,
  58               'input_token_details': {'audio': 0, 'cache_read': 0},
  59               'output_token_details': {'audio': 0, 'reasoning': 0}
  60           }
  61       ),
  62       ToolMessage(
  63           content='和为:30',
  64           name='add_numbers',
  65           id='12635dff-6bd8-4325-b64b-bf203d4cacbb',
  66           tool_call_id='call_PWuscHI7NFdVbAV9wsMzOWKy'
  67       ),
  68       AIMessage(
  69           content='',
  70           additional_kwargs={'refusal': None},
  71           response_metadata={
  72               'token_usage': {
  73                   'completion_tokens': 22,
  74                   'prompt_tokens': 194,
  75                   'total_tokens': 216,
  76                   'completion_tokens_details': {
  77                       'accepted_prediction_tokens': 0,
  78                       'audio_tokens': 0,
  79                       'reasoning_tokens': 0,
  80                       'rejected_prediction_tokens': 0
  81                   },
  82                   'prompt_tokens_details': {'audio_tokens': 0,
       'cached_tokens': 0},
  83                   'latency_checkpoint': {
  84                       'engine_tbt_ms': 3,
  85                       'engine_ttft_ms': 31,
  86                       'engine_ttlt_ms': 105,
  87                       'pre_inference_ms': 82,
  88                       'service_tbt_ms': 4,
  89                       'service_ttft_ms': 257,
  90                       'service_ttlt_ms': 336,
  91                       'total_duration_ms': 269,
  92                       'user_visible_ttft_ms': 176
  93                   }
  94               },
  95               'model_provider': 'openai',
  96               'model_name': 'gpt-5.4-mini-2026-03-17',
  97               'system_fingerprint': None,
  98               'id': 'chatcmpl-DmKgvO5dZRkveTKDtLdPF4BObFmdZ',
  99               'service_tier': 'default',
 100               'finish_reason': 'tool_calls',
 101               'logprobs': None
 102           },
 103           id='lc_run--019e88cd-d880-7601-a250-d4ddea91669d-0',
 104           tool_calls=[
 105               {
 106                   'name': 'add_numbers',
 107                   'args': {'a': 30, 'b': 30},
 108                   'id': 'call_dZDyMZS1BYRJHdW32uj4z8R8',
 109                   'type': 'tool_call'
 110               }
 111           ],
 112           invalid_tool_calls=[],
 113           usage_metadata={
 114               'input_tokens': 194,
 115               'output_tokens': 22,
 116               'total_tokens': 216,
 117               'input_token_details': {'audio': 0, 'cache_read': 0},
 118               'output_token_details': {'audio': 0, 'reasoning': 0}
 119           }
 120       ),
 121       ToolMessage(
 122           content='和为:60',
 123           name='add_numbers',
 124           id='ffa8b21a-d3fe-4970-bddf-57d3e121f3bf',
 125           tool_call_id='call_dZDyMZS1BYRJHdW32uj4z8R8'
 126       ),
 127       AIMessage(
 128           content='10加上20再加上30等于 **60**。',
 129           additional_kwargs={'refusal': None},
 130           response_metadata={
 131               'token_usage': {
 132                   'completion_tokens': 18,
 133                   'prompt_tokens': 230,
 134                   'total_tokens': 248,
 135                   'completion_tokens_details': {
 136                       'accepted_prediction_tokens': 0,
 137                       'audio_tokens': 0,
 138                       'reasoning_tokens': 0,
 139                       'rejected_prediction_tokens': 0
 140                   },
 141                   'prompt_tokens_details': {'audio_tokens': 0,
       'cached_tokens': 0},
 142                   'latency_checkpoint': {
 143                       'engine_tbt_ms': 4,
 144                       'engine_ttft_ms': 41,
 145                       'engine_ttlt_ms': 115,
 146                       'pre_inference_ms': 91,
 147                       'service_tbt_ms': 4,
 148                       'service_ttft_ms': 294,
 149                       'service_ttlt_ms': 360,
 150                       'total_duration_ms': 278,
 151                       'user_visible_ttft_ms': 203
 152                   }
 153               },
 154               'model_provider': 'openai',
 155               'model_name': 'gpt-5.4-mini-2026-03-17',
 156               'system_fingerprint': None,
 157               'id': 'chatcmpl-DmKgwNFV9EzDelG0YCsReEfggh4Gg',
 158               'service_tier': 'default',
 159               'finish_reason': 'stop',
 160               'logprobs': None
 161           },
 162           id='lc_run--019e88cd-dd3b-7271-80ec-76a8b980a858-0',
 163           tool_calls=[],
 164           invalid_tool_calls=[],
 165           usage_metadata={
 166               'input_tokens': 230,
 167               'output_tokens': 18,
 168               'total_tokens': 248,
 169               'input_token_details': {'audio': 0, 'cache_read': 0},
 170               'output_token_details': {'audio': 0, 'reasoning': 0}
 171           }
 172       )
 173   ]
 174  }

举例3:

text 复制代码
  1  from langchain.agents import create_agent
  2  from langchain.tools import tool
  3  from langchain.messages import SystemMessage, HumanMessage
  4
  5  flag = 0
  6
  7  @tool
  8  def get_weather(city: str):
  9      """
 10      天气查询工具
 11
 12      Args:
 13          city: 城市名称
 14      """
 15      global flag
 16      flag += 1
 17
 18      if flag < 3:
 19          # raise Exception("暂时无法访问")
 20          return "TEMP_UNAVAILABLE: 天气服务暂时不可用,请稍后重试"
 21
 22      return f"{city}今天天气挺好"
 23
 24
 25  messages = [
 26      HumanMessage("你好,杭州今天的天气如何?")
 27  ]
 28
 29  agent = create_agent(
 30      model=model,
 31      tools=[get_weather],
 32      system_prompt=SystemMessage(
 33          "你是一个天气助手。"
 34          "当工具返回以 'TEMP_UNAVAILABLE:' 开头的结果时,"
 35          "说明是临时故障,不要立即放弃;"
 36          "你应再次调用同一个工具,最多重试 3 次。"
 37          "如果 3 次后仍失败,再向用户说明服务暂时不可用。"
 38      )
 39  )
 40  response = agent.invoke({"messages": messages})
 41  # print(response)
 42  for msg in response["messages"]:
 43      msg.pretty_print()

输出如下

text 复制代码
  1  ================================ Human Message
     =================================
  2
  3  你好,杭州今天的天气如何?
  4  ================================== Ai Message
     ==================================
  5  Tool Calls:
  6  get_weather (call_1NZMHHj1xByT0Zx7WhiK6AO1)
  7  Call ID: call_1NZMHHj1xByT0Zx7WhiK6AO1
  8  Args:
  9     city: 杭州
 10  ================================= Tool Message
     =================================
 11  Name: get_weather
 12
 13  TEMP_UNAVAILABLE: 天气服务暂时不可用,请稍后重试
 14  ================================== Ai Message
     ==================================
 15  Tool Calls:
 16  get_weather (call_Lgfn3Ll8WTJqQRVVwLIzRQnX)
 17  Call ID: call_Lgfn3Ll8WTJqQRVVwLIzRQnX
 18  Args:
 19   city: 杭州
 20  ================================= Tool Message
     =================================
 21  Name: get_weather
 22
 23  TEMP_UNAVAILABLE: 天气服务暂时不可用,请稍后重试
 24  ================================== Ai Message
     ==================================
 25  Tool Calls:
 26  get_weather (call_PghYww2kjkigDZK8h6P5Lth0)
 27  Call ID: call_PghYww2kjkigDZK8h6P5Lth0
 28  Args:
 29   city: 杭州
 30  ================================= Tool Message
     =================================
 31  Name: get_weather
 32
 33  杭州今天天气挺好
 34  ================================== Ai Message
     ==================================
 35
 36  杭州今天天气挺好。
相关推荐
Data_Journal1 小时前
如何使用 Python Requests 绕过 CAPTCHA
python
七夜zippoe1 小时前
Agent 自主决策机制:什么时候该检索、什么时候该直接回答
人工智能·ai·agent·检索·自主决策
happylifetree1 小时前
Python06(补充4):PyCharm里的删除
python·pycharm
沉默王二1 小时前
再见了 WebUI,DeepSeek 桌面版真不错。
openai·agent·deepseek
打工仔折腾 AI2 小时前
蓝耘元生代实测:用WorkBuddy与TextIn xParse拆解43页建模论文
人工智能·后端·python·数学建模·langchain·ai agent 实战
用户0332126663672 小时前
Python 实现 Excel 转 XML:快速上手
python·excel
效率工作实验室2 小时前
用 AI Agent 做游戏数据分析,哪些场景效果最好?
ai·agent·智能体·游戏数据·游戏数据分析
Zhou1411362 小时前
MyBatisPlus_02_条件构造器与高级功能
java·开发语言·python
the局外人2 小时前
读懂LangGraph 的分支执行逻辑
后端·langchain·llm