Agent 与工具调用¶
面试高频考点¶
- Agent 和普通 LLM 的区别?
- ReAct 框架的原理?
- 工具调用(Function Calling)如何实现?
- Plan-and-Execute vs ReAct?
- Agent 的常见失败模式?
外部图解:ReAct Agent 循环¶

图源:Intelligent Machines - ReAct Agents Explained。这张图适合理解 Agent 不是一次回答,而是“思考 -> 调工具 -> 观察 -> 再思考”的循环。
一、什么是 Agent?¶
细化理解: Agent 是模型围绕目标进行规划、调用工具、观察结果并继续决策的闭环系统。普通 LLM 主要生成文本,Agent 还要决定下一步动作。工程上最关键的是边界控制:工具什么时候能调用、调用失败怎么恢复、循环何时停止、权限和成本如何限制。
普通 LLM 是一次性输入输出(无状态、无工具、无规划),而 Agent 是一个具备感知-决策-执行-观察闭环的自主系统。
LLM Agent = LLM(大脑) + 工具(双手) + 记忆(笔记本) + 规划(决策链)
┌──────────────────────────────────────────┐
│ Agent 运行循环 │
│ │
│ 用户目标 │
│ ↓ │
│ [LLM 思考] ←──────────────┐ │
│ ↓ │ │
│ 决定下一步动作 │ │
│ ↓ │ │
│ ┌──────┐ ┌──────┐ │ │
│ │调用工具│ │生成回复│ │ │
│ └──┬───┘ └──┬───┘ │ │
│ ↓ ↓ │ │
│ 工具返回结果 返回给用户 │ │
│ ↓ │ │
│ 观察结果 ──────────────────┘ │
│ │
│ 循环终止条件:目标完成 / 超出最大步数 │
└──────────────────────────────────────────┘
Agent 和普通 LLM 的本质区别¶
| 维度 | 普通 LLM | Agent |
|---|---|---|
| 交互方式 | 单轮/多轮对话 | 自主循环决策 |
| 状态 | 只有对话历史 | 有记忆、有任务状态 |
| 能力 | 文本生成 | 文本生成 + 工具调用 + 环境感知 |
| 自主性 | 被动响应 | 主动规划和执行 |
| 失败模式 | 回答错误 | 无限循环、错误行动、状态丢失 |
二、ReAct(Reasoning + Acting)¶
细化理解: ReAct 把推理和行动交替进行:模型先思考当前状态,再调用工具,再基于观察继续推理。它适合信息不完整、需要边查边做的任务;缺点是容易陷入循环,且每一步错误都会传递到后续步骤。上线时必须配合最大步数、工具白名单和日志追踪。
基本框架¶
ReAct 是 Agent 最基础的范式,将推理(Reasoning)和行动(Acting)交织在一起:
ReAct 模板:
System: 你可以使用以下工具:
1. search(query: str) → 搜索结果
2. calculator(expression: str) → 计算结果
User: 2024年北京GDP占全国GDP的比例是多少?
模型输出:
Thought: 我需要先查询2024年北京GDP和全国GDP
Action: search("2024年北京GDP")
Observation: 2024年北京GDP为4.38万亿元
Thought: 还需要查询全国GDP
Action: search("2024年全国GDP")
Observation: 2024年全国GDP为134.9万亿元
Thought: 现在可以计算比例了
Action: calculator("4.38 / 134.9 * 100")
Observation: 3.25%
Thought: 已获得所有需要的信息
Final Answer: 2024年北京GDP约占全国GDP的3.25%
ReAct 的优缺点¶
优点: - 推理过程透明可解释,出错时容易定位是"想错了"还是"做错了" - 灵活性高,能处理未见过的任务组合 - 与 LLM 的文本生成能力天然兼容
缺点: - 串行执行,延迟高(每步都要等 LLM 推理) - 容易陷入无限循环(Thought-Action-Observation 反复,始终不给 Final Answer) - 长任务时上下文窗口容易溢出
三、Plan-and-Execute(计划与执行)¶
与 ReAct 的"边走边想"不同,Plan-and-Execute 先制定完整计划,再逐步执行:
Phase 1 - Planning(计划制定):
User: 帮我分析特斯拉2024Q4的财务表现
Planner:
计划:
1. 搜索特斯拉2024Q4财报新闻
2. 提取关键财务指标(营收、利润、毛利率、交付量)
3. 对比2023Q4数据,计算同比变化
4. 搜索分析师观点
5. 综合以上信息,写一份简要分析报告
Phase 2 - Execution(计划执行):
Step 1 → 搜索结果:特斯拉Q4营收257亿...
Step 2 → 提取:营收257亿、利润23亿...
Step 3 → 同比:营收增长2%,利润下降...
Step 4 → 分析师观点:...
Step 5 → 生成报告
ReAct vs Plan-and-Execute¶
| 维度 | ReAct | Plan-and-Execute |
|---|---|---|
| 规划时机 | 边走边想(在线) | 先规划后执行(离线) |
| 灵活性 | 高(能适应环境变化) | 低(计划可能过时) |
| 全局最优性 | 弱(贪心每一步) | 强(考虑全局) |
| LLM 调用数 | 多(每步都调用) | 少(计划一次 + 执行时可选) |
| 可审查性 | 差(需要追踪全链) | 好(计划可单独审查和修改) |
| 适用场景 | 探索性任务、不确定环境 | 目标明确的复杂任务 |
四、Function Calling(工具调用)¶
实现原理¶
Function Calling 本质是让 LLM 输出结构化的工具调用请求,而非自由文本。通过 SFT 训练使模型学会:
- 何时使用哪个工具
- 如何填写工具参数的 JSON
- 如何理解工具返回结果并继续推理
完整流程¶
┌─────────────────────────────────────────────┐
│ Function Calling 完整流程 │
│ │
│ 1. 定义工具(JSON Schema) │
│ { │
│ "name": "get_weather", │
│ "description": "获取指定城市的天气", │
│ "parameters": { │
│ "city": {"type": "string"}, │
│ "date": {"type": "string"} │
│ } │
│ } │
│ │
│ 2. 发送给 LLM(system prompt + 工具定义) │
│ → LLM 决定是否调用工具 │
│ → 如果是:输出结构化的 function_call │
│ → 如果否:输出普通文本 │
│ │
│ 3. 执行工具调用(由调用方/框架执行) │
│ result = get_weather("北京", "2024-12-01")│
│ │
│ 4. 将工具返回结果作为新消息发给 LLM │
│ → LLM 基于结果生成最终回复 │
│ │
│ 5. 可能循环(多轮工具调用) │
└─────────────────────────────────────────────┘
OpenAI 风格的 Function Calling 示例¶
import openai
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
}
}]
response = openai.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "北京今天多少度?"}],
tools=tools,
tool_choice="auto" # 让模型决定是否调用工具
)
# 模型返回 tool_calls 而非文本
# tool_calls[0].function.name = "get_weather"
# tool_calls[0].function.arguments = '{"city": "北京", "unit": "celsius"}'
五、Agent 记忆系统¶
┌─────────────────────────────────────────┐
│ Agent 的三层记忆 │
│ │
│ 短期记忆(Working Memory) │
│ ├── 当前对话历史(上下文窗口内) │
│ ├── 当前任务状态和中间结果 │
│ └── 容量:~128K tokens(模型窗口限制) │
│ │
│ 长期记忆(Long-term Memory) │
│ ├── 向量数据库存储的会话摘要和历史 │
│ ├── 用户偏好、项目上下文 │
│ └── 检索 + 注入相关记忆到当前上下文 │
│ │
│ 工作记忆(Scratchpad) │
│ ├── 当前任务的中间推理结果 │
│ ├── 工具调用的返回值缓存 │
│ └── 通常存在 Agent 框架的状态对象中 │
└─────────────────────────────────────────┘
六、Agent 的主要挑战与应对¶
| 挑战 | 描述 | 应对方法 |
|---|---|---|
| 幻觉行动 | 模型编造不存在的工具/参数 | 严格的 JSON Schema 校验 + 工具名模糊匹配 |
| 无限循环 | 反复调用工具不给出最终答案 | max_iterations 限制 + 循环检测 + 重复行为惩罚 |
| 上下文溢出 | 多轮调用后历史超过窗口大小 | 定期摘要压缩 + 滑动窗口 + 只保留关键工具返回 |
| 错误传播 | 一步错误影响后续全部推理 | 每步做 sanity check + 允许回溯 + 并行尝试多个方案 |
| 工具调用幂等性 | 同一操作被执行多次(发两封邮件) | 工具侧保证幂等 + 写操作前二次确认 |
| 权限过大 | Agent 拥有超出需要的工具权限 | 最小权限原则 + 敏感操作需人工审批 |
七、面试延伸¶
Q:如何防止 Agent 进入无限循环?
① 设置最大步数限制(如 max_steps=10),超限强制终止;② 检测连续重复调用模式(连续 3 次调用同一工具且参数相同 → 触发干预);③ 每步评估任务进度,让 LLM 做 termination check;④ 对循环行为施加额外惩罚(降低 action 的 logit 分数)。
Q:RAG 和 Agent 的关系是什么?
RAG 是 Agent 能力的一个子集——当 Agent 需要查询知识库时,RAG 就是它的"知识检索工具"。Agent 可以调用多种工具(搜索、计算、API、代码执行),RAG 检索只是其中之一。但 RAG 的工程复杂度显著低于 Agent,不需要处理动作规划和多步推理。工程原则:能用 RAG 解决的问题,不要引入 Agent。
Q:Multi-Agent 系统什么情况下值得投入?
当任务天然需要多个专业角色协作(如软件开发 = 产品经理 + 架构师 + 程序员 + 测试)、或需要并行探索多条路径(如科研文献综述)、或需要多视角交叉验证(如法律合规审查)时,Multi-Agent 有收益。但单 Agent + 好工具往往已经够用,Multi-Agent 引入了通信开销和更复杂的调试难度。
Q:什么是 Tool Use / Function Calling 的实现原理?
本质上是通过 SFT 训练让模型学会:① 识别用户意图中需要工具的部分;② 输出符合 JSON Schema 的函数调用(而非自由文本);③ 理解工具的返回结果(文本或 JSON)并整合进后续推理。训练数据通常包含 {用户请求, 工具定义, 模型调用, 工具返回, 最终回复} 的完整链。推理时,框架检测到模型输出 function_call 标记后,提取调用参数,执行工具,将结果注入对话历史,让模型继续推理。
原始论文¶
| 论文 | 链接 |
|---|---|
| ReAct: Synergizing Reasoning and Acting in Language Models (Yao et al., NeurIPS 2023) | arxiv.org/abs/2210.03629 |
| Toolformer: Language Models Can Teach Themselves to Use Tools (Schick et al., NeurIPS 2023) | arxiv.org/abs/2302.04761 |
| Plan-and-Solve Prompting (Wang et al., ACL 2023) | arxiv.org/abs/2305.04091 |
| AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation (Wu et al., 2023) | arxiv.org/abs/2308.08155 |
| Magentic-One: A Generalist Multi-Agent System (Fourney et al., 2024) | arxiv.org/abs/2411.04468 |
延伸阅读与视频¶
| 平台 | 标题 | 说明 |
|---|---|---|
| 📺 B站 | 挑战19分钟搞定LangGraph快速入门与原理剖析 | 2万播放,Agent编排框架快速上手 |
| 📺 B站 | 90分钟手撸企业级Agent多智能体(LangGraph+MCP+RAG) | 3.7万播放,从0到1的Agent工程实战 |
| 📖 LangGraph Docs | LangGraph concepts | 官方概念文档,解释 graph、state、node、edge |