LLM 应用(03):Agent 框架——工具调用、ReAct、记忆、多智能体与 LangChain/LangGraph 生态
更新时间:2026-09-02。本文是
data-ai/llm-app/第 03 篇,在LLM 应用索引下。RAG 让模型"会查资料",Agent 让模型"会动手做事"——调用 API、查库、跑代码、多步完成任务。本文讲 Agent 的运行机制、核心模式,以及为什么它强大又难控。
本文要回答的问题
- Function Calling(工具调用)是怎么工作的?
- ReAct 循环是什么?Agent 怎么"边想边做"?
- Agent 的记忆有哪些?怎么让它记住上下文和长期事实?
- 单 Agent 和多智能体怎么选?
- LangChain / LangGraph / LlamaIndex 分别解决什么?生产化有什么坑?
一、从"会说"到"会做":工具调用
LLM 本身只能生成文本。**Function Calling(工具调用)**让模型能请求外部函数:开发者定义工具的名字、用途、参数 schema,模型根据用户意图决定"调哪个工具、传什么参数",程序执行后把结果回喂模型。
用户:北京现在多少度?要带伞吗?
|
模型:我需要查天气 -> 调用 get_weather(city="北京")
| |
| 程序真正执行天气 API,返回 {temp:18, rain:true}
|<-----------------------------|
模型:北京现在 18 度,有雨,建议带伞。工具定义是一份带 JSON Schema 的"说明书":
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询某城市当前天气",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string", "description": "城市名"}},
"required": ["city"]
}
}
}]关键认知:模型并不执行代码,它只输出"我想调这个函数、参数是这些"的结构化请求;真正执行的是你的程序。 因此工具是能力边界,也是安全边界。
二、ReAct:推理与行动的循环
单个工具调用不够,复杂任务需要"想一步、做一步、看结果、再想"。ReAct(Reason + Act) 是最经典的 Agent 模式:
循环(直到模型给出最终答案或达到步数上限):
Thought(思考):我现在需要什么信息/该做什么
Action(行动) :调用某个工具(带参数)
Observation(观察):工具返回结果
-> 基于观察继续 Thought ...
...
Final Answer:信息够了,输出最终答案例:"帮我查 star 最多的那个 Python 爬虫仓库的作者最近还开源了什么":
Thought: 需要先找 star 最多的 Python 爬虫仓库
Action: search_repos(query="python crawler", sort="stars")
Observation: 结果第一是 repoX,作者 userY
Thought: 现在查 userY 还开源了什么
Action: list_user_repos(user="userY", sort="updated")
Observation: repoA, repoB, repoC...
Thought: 信息足够,可以回答
Final Answer: 作者 userY 最近还开源了 repoA...这个"模型驱动的 while 循环"就是 Agent 与普通工作流的本质区别:下一步做什么由模型根据中间结果动态决定,而不是开发者预先写死。
工程上必须有:最大步数/超时限制、每步可观测日志、失败重试与异常捕获,否则模型可能无限循环或卡在错误工具上。
三、规划、反思与记忆
1. 规划(Planning)
复杂任务先让模型拆成子任务清单(plan),再逐项执行,比直接 ReAct 更稳。执行中可根据结果修订计划。
2. 反思(Reflection)
让模型在得到结果后自我检查:"这个结果对吗?有没有遗漏/错误?不满意就换个方法重试。" 自我批判循环能提升代码生成、长任务的质量(类似给 Agent 加了个"reviewer")。
3. 记忆(Memory)
| 类型 | 内容 | 实现 |
|---|---|---|
| 短期记忆 | 当前对话/本次任务上下文 | 放在 context window 里(受窗口限制) |
| 长期记忆 | 跨会话的事实、用户偏好 | 外部存储:向量库存语义记忆、KV/数据库存结构化事实 |
| 工作记忆 | 中间步骤、工具结果 | scratchpad / 状态对象 |
长任务超出上下文窗口时,需要摘要压缩旧步骤、把关键事实写入外部记忆,需要时再检索回来(记忆本质也是一种 RAG)。
四、单 Agent vs 多智能体
单 Agent:一个模型 + 一组工具 + 一个循环
适合:流程不太复杂、工具数量适中、可控性要求高
优点:简单、好调试、成本低
多智能体(Multi-Agent):多个角色分工协作
如:规划者(Planner) + 执行者(Coder) + 审查者(Reviewer) + 检索者(Researcher)
适合:任务可清晰分解、需要不同 prompt/工具/专长
优点:各司其职、可并行、易加专门能力
风险:链路长 -> 延迟高、成本高、错误级联、难调试务实建议:能用单 Agent + 良好工具设计解决的,不要上多智能体。多智能体的协调成本和不确定性很高,多数业务场景"工作流编排(确定性图)+ 关键节点用 LLM"比"全自动多 Agent"更可靠。
五、框架生态
| 框架 | 定位 | 何时用 |
|---|---|---|
| LangChain | 通用 LLM 应用胶水:模型/工具/加载器/链的抽象 | 快速搭原型、集成各类组件 |
| LangGraph | 基于"图/状态机"编排有状态、可循环、可分支的 Agent | 生产级复杂 Agent,要可控、可持久化、可人机协同 |
| LlamaIndex | 偏数据/RAG:文档加载、索引、检索 | 以知识库/RAG 为核心的应用 |
| 各家原生 SDK(OpenAI/Anthropic 等) | 直接调 function calling | 逻辑简单、想少依赖、要完全可控 |
趋势:早期大家用 LangChain 串链,生产化后越来越多用 LangGraph 这类显式状态图(把 Agent 的状态转移画成图,可断点、可恢复、可审计),或直接用原生 SDK 手写循环——因为 Agent 最难的是可控性和可观测性,黑盒框架反而碍事。
六、生产化风险与对策
| 风险 | 说明 | 对策 |
|---|---|---|
| 不可控/跑偏 | 模型可能选错误工具、死循环 | 状态机约束、最大步数、白名单工具 |
| 安全 | 工具能操作真实系统(删数据、下单) | 最小权限、只读优先、高危操作人工确认(human-in-the-loop) |
| 成本/延迟 | 多轮调用 token 暴涨 | 限制步数、缓存、小模型做路由、超时熔断 |
| 难调试 | 出错不知哪一步坏 | 全链路 trace(每步 thought/action/observation 落日志) |
| 注入 | 工具返回/网页内容含恶意指令 | 工具结果当数据不当指令、过滤 |
| 评测难 | 多步任务正确性难自动判定 | 轨迹评估 + 关键结果断言 + 回归集 |
小结
Agent 的本质是**"LLM 当大脑做决策 + 外部工具当手脚做执行 + 一个 ReAct 式循环把它们串起来"**:Function Calling 提供动手能力,ReAct/规划/反思提供多步推理,记忆解决跨步骤/跨会话上下文,多智能体用于可清晰分工的复杂任务但代价高。落地记住三条:能工作流就别全自动、能单 Agent 就别多 Agent、一切工具最小权限且高危需人确认,并把可观测性和步数/成本限制当一等公民。下一篇讲把这些跑稳的工程面:LLM 应用工程。