# 内置的其他 Agent 类型介绍与上手

# 01. 内置的其他 Agent 介绍

在 LangChain v 0.2.0 版本之前封装了大量基于 传统Agent组件 的 Agent 智能体创建方法,这些组件的设计思路其实都是以 推理-行动-观察 为思想,不同类型的 Agent 会进行一些额外的扩展,例如 记忆 、 外挂知识库 、 多角色 、 反思 等。

而 LangChain 中封装的 Agent 也是基于 推理-行动-观察 思想,并为不同类型的 LLM/ChatModel 设计了不同的 运行流程 与 prompt ,例如有些大语言模型擅长解读和回复 XML 类型的数据(Authropic),而有些模型擅长解读和回复 JSON 数据,而有些模型又擅长结构化输出,所以对于不同类型的模型,可以使用不同 Agent创建方法 来创建。

  • LangChain 不同类型 Agent 文档: https://python.langchain.com/v0.1/docs/modules/agents/agent_types/xml_agent/

以 XMLAgent 为例,创建和使用的技巧也非常简单,只需修改 prompt 与创建 Agent 的方法即可,其他的无需任何调整:

prompt = ChatPromptTemplate.from_messages([
    ("human", """You are a helpful assistant. Help the user answer any questions.

You have access to the following tools:

{tools}

In order to use a tool, you can use <tool></tool> and <tool_input></tool_input> tags. You will then get back a response in the form <observation></observation>
For example, if you have a tool called 'search' that could run a google search, in order to search for the weather in SF you would respond:

<tool>search</tool><tool_input>weather in SF</tool_input>
<observation>64 degrees</observation>

When you are done, respond with a final answer between <final_answer></final_answer>. For example:

<final_answer>The weather in SF is 64 degrees</final_answer>

Begin!

Previous Conversation:
{chat_history}

Question: {input}
{agent_scratchpad}"""),
])


llm = ChatOpenAI(model="gpt-4o-mini")


agent = create_xml_agent(
    prompt=prompt,
    llm=llm,
    tools=tools,
)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

print(agent_executor.invoke({"input": "马拉松的世界记录是多少?", "chat_history": ""}))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

输出内容:

> Entering new AgentExecutor chain...
<tool>google_serper</tool><tool_input>马拉松 世界记录 2023今年4月23日的伦敦马拉松,基普图姆以2小时01分25秒夺冠,大幅打破基普乔格保持的赛道纪录,与世界纪录只差16秒。 这一表现,让他被评为2023年男子场外赛事世界年度最佳运动员。<final_answer>截至2023年,马拉松的世界纪录是2小时01分09秒,由埃利乌德·基普乔格于2018年创造。</final_answer>

> Finished chain.
{'input': '马拉松的世界记录是多少?', 'chat_history': '', 'output': '截至2023年,马拉松的世界纪录是2小时01分09秒,由埃利乌德·基普乔格于2018年创造。'}
1
2
3
4
5

切换到 JSONAgent 同样只需要更改 prompt 与 create_xml_agent() 方法即可,修正的 prompt 如下:

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
  ("system", """Assistant is a large language model trained by OpenAI.

Assistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.

Assistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.

Overall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist."""),
  ("placeholder", "{chat_history}"),
  ("human", """TOOLS
------
Assistant can ask the user to use tools to look up information that may be helpful in answering the users original question. The tools the human can use are:

{tools}

RESPONSE FORMAT INSTRUCTIONS
----------------------------

When responding to me, please output a response in one of two formats:

**Option 1:**
Use this if you want the human to use a tool.
Markdown code snippet formatted in the following schema:

```json
{{
    "action": string, \ The action to take. Must be one of {tool_names}
    "action_input": string \ The input to the action
}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

Option #2: Use this if you want to respond directly to the human. Markdown code snippet formatted in the following schema:

{{
    "action": "Final Answer",
    "action_input": string \ You should put what you want to return to use here
}}
1
2
3
4

# USER'S INPUT

Here is the user's input (remember to respond with a markdown code snippet of a json blob with a single action, and NOTHING else):

{input}"""), ("placeholder", "{agent_scratchpad}"), ])


其他类型的 Agent 也是一模一样的操作,修改 prompt 并切换到不同的 Agent创建方法 即可。

## 02. 内置 Agent 的异同点

通过前几节课掌握的 ReACTAgent 、 工具调用Agent 、 XMLAgent 示例演示,其实可以很容易发现这些 Agent 的异同点,首先是相同点:

- 所有 Agent 都拥有 input 、 agent_scratchpad 两个输入变量,表示原始问题和智能体草稿。

- 所有 Agent 都是单 Agent 自我执行,无法与其他 Agent 进行相互协作。

- 所有 Agent 都可以通过切换 prompt 与 create_xxx_agent() 方法快速切换 Agent 而无需修改大量代码。

- 所有 Agent 设计思想都是基于 推理-行动-观察 ,只是不同的 Prompt 有所差异。

- 所有 Agent 都是使用同一个 LLM 进行 推理 与 答案生成 ,并不支持 多LLM 分工。

- 除了 基于工具调用的Agent ,其他类型的智能体要修改 Prompt 适配特定语言一般都需要同步修改 输出解析器 。

有差异的地方也非常明显:

- 不同 Agent 的提示词风格有所差异,有的 Agent 会将 tools 也填写到 prompt 中,有的使用文本提示,有的使用消息提示。

- 不同 Agent 的 输出解析器 不一致,绝大部分取决于 prompt 的差异,有的支持 多工具 ,有的不支持。

- 不同 Agent 的 输入编码方式 不一致,绝大部分取决于 prompt 和 LLM 的差异,有的支持 历史记忆输入 ,有的不支持。

课后练习:

> [!IMPORTANT] 请根据 LangChain 官方文档提供的内置工具,实现一个集成 加减乘除(多个自定义工具) 、 天气预报 、 谷歌实时搜索 的 Agent 智能体,并提问 2024年巴黎奥运会金牌榜前3名的国家总金牌数、平均金牌数分别是多少? ,并检测下 ReACT智能体 、 工具调用智能体 、 XML智能体 在该问题下的表现,思考其存在的缺陷。

## 最新版 LangChain 用法提示

- 新版 LangChain 更推荐用 LCEL、`Runnable`、`ChatModel.bind_tools()`、结构化输出和 LangGraph 来组织复杂链路;老式 `Chain`、部分 `AgentExecutor` 写法可以读懂,但新项目应优先选择更清晰的图或 Runnable 编排。

- 工具调用相关代码要区分两层:模型是否原生支持 tool/function calling,以及业务侧如何定义工具 schema、参数校验、错误兜底和观测日志。

- 如果示例中的导入路径和你当前安装版本不同,优先查当前版本包内导出位置;常见迁移方向是从 `langchain` 拆到 `langchain-core`、`langchain-community`、`langchain-openai`、`langgraph` 等包。

## 拓展

- 工具或插件不要只看能不能调通,更要看是否可观测、可限流、可重试、可审计。联网类工具还要处理超时、空结果、搜索噪声和结果时效性。

- Agent 场景里,Prompt 只是调度策略的一部分;工具描述、参数 schema、历史状态、错误反馈、停止条件和人工介入点同样会影响最终稳定性。

## 常见问题

- 为什么模型没有调用工具?常见原因是工具描述不清晰、参数 schema 过宽或过窄、用户问题不需要工具、模型本身不支持工具调用,或者工具绑定位置不对。

- 为什么工具调用后回答仍然不准?先看工具返回是否正确,再看工具结果是否被放回模型上下文,最后检查输出解析、历史消息和异常兜底是否覆盖了真实错误。

## 面试题

- 解释函数调用、工具调用和 Agent 的区别。

- LangChain 中 tool schema 的作用是什么?为什么参数校验对生产环境很重要?

- ReACT Agent 和 tool-calling Agent 的核心差异是什么?分别适合什么场景?

- LangGraph 相比 LCEL 更适合解决哪些复杂编排问题?

## 生产问题排查

| 问题 | 常见原因 | 处理方式 |
| --- | --- | --- |
| 工具没有被调用 | 工具描述弱、绑定失败、模型不支持 | 打印绑定后的模型配置,补充工具描述,换用支持工具调用的模型 |
| 参数格式错误 | schema 设计不清晰,模型生成字段不稳定 | 使用 Pydantic/JSON Schema 校验,失败后把错误反馈给模型重试 |
| 联网结果不可用 | 搜索为空、接口超时、命中低质量页面 | 增加超时、重试、结果过滤、来源白名单和降级回答 |
| Agent 循环不停止 | 缺少终止条件或工具返回被误判 | 设置最大迭代次数,记录每轮 thought/action/observation,增加停止规则 |
| 线上难以复现 | 缺少输入、工具请求和模型响应日志 | 给每次调用加 trace id,记录工具入参、出参、耗时和异常 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70