第 2 章 · 心智模型:LLM + 工具 + 循环
本章观点
“LLM + 工具 + 循环”是理解 Agent 的最小骨架,但它还不是完整设计。真正决定一个 Agent 能不能跑稳的,往往不是模型够不够聪明,而是四个工程细节:
- 状态是否记录清楚。
- 工具返回是否结构化。
- 权限是否分级。
- 停止条件是否明确。
所以本章的核心观点是:Agent 的智能来自模型,可靠性来自工程边界,持续改进来自反馈与记忆。
ReAct 和 Reflexion 可以放在同一张心智图里理解:
短循环:Thought -> Action -> Observation
中循环:Trajectory -> Evaluation -> Reflection
长循环:Reflection -> Memory -> Better Next Trial短循环让 Agent 在当前任务里边做边修正;中循环让 Agent 在一次完整尝试后复盘;长循环让复盘结果进入记忆,影响下一次任务。一个成熟的 Agent 不应该只有工具调用,还应该有评估、反思和记忆。
2.1 三个部件的分工
第 0 章我们说 Agent = LLM + 工具 + 循环。这一章把这个心智模型拆开讲清楚。
- LLM 是大脑:负责决策。它读当前状态,决定下一步干什么(调用什么工具、回复什么内容、是否停止)。
- 工具是行动接口:负责执行。LLM 自身只能生成文本,不能直接查数据库、读文件、发邮件。工具让 LLM 能作用于外部系统。
- 循环是推进机制:负责自主性。LLM 调一次工具拿到结果,再根据结果决定下一步——这个“调工具 → 看结果 → 再决策”的过程,就是 Agent 从一次性回复变成持续任务执行的关键。
这个公式适合入门,但不够完整。结合 ReAct 和 Reflexion,本教程会把它扩展成:
Agent = LLM + 工具 + 反馈循环 + 状态记忆 + 停止边界。
缺任何一个都不叫可靠的 agent:
- 只有 LLM + 工具,没有循环 → 一次性函数调用,不是 agent
- 只有 LLM + 循环,没有工具 → LLM 自己跟自己聊,干不了实事
- 只有工具 + 循环,没有 LLM → 那就是个普通程序
- 只有 LLM + 工具 + 循环,没有状态 → 每次都像从零开始
- 只有 LLM + 工具 + 循环,没有停止边界 → 容易无限探索或成本失控
2.1.1 再加一个隐藏部件:状态
严格说,Agent 不只是 LLM + 工具 + 循环,还需要一个隐藏部件:状态(state)。
状态记录“任务已经进行到哪了”。没有状态,循环就只是重复调用;有状态,Agent 才知道自己已经查过什么、失败过什么、下一步还缺什么。
常见状态包括:
| 状态字段 | 作用 | 例子 |
|---|---|---|
task | 原始任务目标 | 每周追踪 visual tracking 新论文 |
messages | 对话和工具调用历史 | 用户请求、LLM 决策、工具结果 |
facts | 已确认的信息 | 找到 12 篇论文,其中 3 篇相关 |
attempts | 尝试次数 | arXiv 搜索失败 1 次,换 Semantic Scholar |
budget | 成本和步数限制 | 最多 20 轮,最多调用 5 次搜索 |
pending_approval | 等待人工确认的操作 | 是否发送邮件、是否写数据库 |
很多 Agent 跑不稳,不是模型不够强,而是状态设计太粗:它不知道自己已经做了什么,也不知道什么时候该停。
2.2 一个 30 行伪代码
把心智模型落到代码上。这是一段伪代码,不是能跑的真代码,但它就是所有 agent 的骨架:
def agent_loop(user_task):
messages = [{"role": "user", "content": user_task}]
while True: # 循环
# LLM 决策:看当前 messages,决定下一步
response = llm.create(
model="claude-sonnet-4-5",
messages=messages,
tools=[search_tool, read_file_tool, send_email_tool] # 工具
)
# 如果 LLM 决定停,就停
if response.stop_reason == "end_turn":
return response.content # 返回最终答案
# 如果 LLM 决定调工具,就执行工具
if response.stop_reason == "tool_use":
tool_results = execute_tools(response.tool_calls) # 执行工具
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
# 继续下一轮循环就这 30 行,包含了 agent 的全部精髓:
while True是循环llm.create(...)是 LLM 决策tools=[...]是工具execute_tools(...)是真的动手- 停止条件靠
stop_reason判断
后面所有的 agent 框架(LangGraph、CrewAI、Claude Agent SDK),底层都是这个循环,只是封装了不同的抽象。
2.2.1 ReAct:为什么要把思考和行动交替起来
ReAct 的重要启发是:Agent 不应该只“先想完再做”,也不应该只“不断行动直到成功”。更稳的方式是交替:
Thought: 我现在缺少论文列表,需要先搜索。
Action: search_arxiv("visual tracking 2025")
Observation: 返回 20 篇候选论文。
Thought: 需要按相关性筛选,并排除 survey。
Action: filter_papers(criteria)
Observation: 剩下 6 篇。Thought 的作用不是表演推理,而是让局部计划可检查;Action 的作用不是展示工具多,而是接触外部环境;Observation 的作用是把外部事实带回上下文,迫使模型更新下一步。
这对工程设计有直接影响:
- 工具返回要清楚,否则 Observation 无法支撑下一步判断。
- 每一步 Thought 应该短而具体,否则会浪费上下文。
- 运行轨迹应该可记录,否则很难调试 Agent 为什么失败。
2.2.2 messages 为什么是核心
很多初学者会把 Agent 理解成“模型每轮重新思考”。更准确地说,模型每轮都在读一个逐渐变长的上下文:
messages = [
{"role": "user", "content": "帮我找最近的论文"},
{"role": "assistant", "content": "我需要先搜索 arXiv", "tool_use": "search_arxiv"},
{"role": "user", "content": "工具结果:找到 20 篇论文"},
{"role": "assistant", "content": "我需要按相关性筛选"}
]这段历史就是 Agent 的工作记忆。它让 LLM 知道:用户要什么、自己做过什么、工具返回了什么、下一步为什么这么选。
但上下文不是越长越好。上下文太长会带来三个问题:
- 成本上升:每轮都要把历史发给模型。
- 注意力稀释:关键信息被无关历史淹没。
- 上下文污染:工具返回的网页、日志、用户输入里可能夹带误导指令。
所以生产级 Agent 通常会做上下文管理:保留关键事实,压缩旧历史,丢弃无关细节,把外部内容标记为“数据而不是指令”。
2.3 三部件缺一不可的对照
看几个真实场景,感受缺了会怎样:
场景 A:只有 LLM + 工具,没有循环
用户:帮我查今天北京天气
LLM:[调 weather_tool] → 25度晴
LLM:今天北京 25 度晴。 ← 停了
用户:那明天呢?
LLM:[调 weather_tool] → ...每次都要用户推一下,这不是 agent,是 chatbot + 工具。
场景 B:只有 LLM + 循环,没有工具
用户:帮我订明天早上 9 点的会议室
LLM:(思考) 我应该订会议室... 但我没有订会议室的工具
LLM:(继续思考) 我建议你联系行政...LLM 自己转圈,干不了实事。这叫"幻觉式空转"。
场景 C:LLM + 工具 + 循环(真 agent)
用户:帮我订明天早上 9 点的会议室,要能容纳 8 人
LLM:[list_rooms(capacity=8)] → [A, B, C]
LLM:[check_availability(room=A, time=tomorrow_9am)] → 可用
LLM:[book_room(room=A, time=tomorrow_9am)] → 成功
LLM:已为你订好 A 会议室,明天 9 点。LLM 自己拆步骤、调工具、根据结果继续——这才是 agent。
2.3.1 三种典型失败
失败 1:没有停止条件
Agent 一直觉得“还可以再查一点”,于是不断搜索、总结、再搜索。解决办法是设置最大轮数、最大工具调用次数、最大成本,以及“信息足够时必须总结”的规则。
失败 2:工具返回太随意
工具只返回一段自然语言:“好像成功了”。LLM 不知道到底成功还是失败,也不知道失败原因。更好的工具返回应该结构化:
{
"ok": false,
"error_code": "RATE_LIMIT",
"message": "API quota exceeded",
"retry_after_seconds": 60
}这样 Agent 才能决定是等待、重试、换工具,还是向用户报告。
失败 4:失败没有沉淀成经验
普通重试只是“再跑一次”。Reflexion 的启发是:失败后应该生成一条可行动的反思,并把它放入记忆。
不好的反思:
我下次应该更小心。好的反思:
上次失败是因为搜索结果包含大量 survey,下一次筛选时先排除 title 中包含 survey / review 的论文,再评估方法贡献。这样的经验可以进入 memory,下一次同类任务就不会从零开始。注意,记忆不是越多越好;记忆需要压缩、筛选和过期机制,否则会污染上下文。
失败 3:LLM 权限太大
如果 Agent 能直接删除文件、发送邮件、扣款、修改数据库,就必须加审批。一个好规则是:读操作可以自动化,写操作默认要审查;可逆操作可以宽一点,不可逆操作必须严格。
2.4 路径图详解
第 0 章给过一张路径图:Prompt → RAG → Workflow → Agent → Multi-Agent。这里详细解释每一级加了什么、难度跳点在哪。
Level 1:Prompt(提示词)
- 加什么:进行一次 LLM 调用,由用户输入触发模型回复。
- 能干什么:问答、翻译、写代码片段。
- 难度:★
- 本质:LLM 单次调用。
Level 2:RAG(检索增强)
- 加什么:在 LLM 调用前,先去检索一批相关文档,塞进 prompt。
- 能干什么:基于私有知识库问答。
- 难度:★★
- 本质:还是 LLM 单次调用,只是 prompt 变长了。RAG 不是 agent——它没有循环、没有工具(检索是预先做的,不是 LLM 自己决定的)。
Level 3:Workflow(工作流)
- 加什么:多个 LLM 调用 + 工具,按开发者写死的路径串起来。
- 能干什么:客服系统、文档处理流水线、代码生成 + 审校。
- 难度:★★★
- 本质:LLM + 工具,但没有真循环——路径是 if/else 写死的。第 1 章讲的五种 Workflow 模式就在这级。
Level 4:Agent(智能体)
- 加什么:循环。LLM 自己决定下一步干什么、什么时候停。
- 能干什么:开放式任务、需要临时决策的场景。
- 难度:★★★★
- 本质:LLM + 工具 + 循环。这是本教程的主战场。
- 难度跳点:从 Workflow 到 Agent 的跳点在于"放弃控制权"——你不再写死路径,让 LLM 自己决定。这带来灵活性,也带来不确定性(token 消耗、行为不可预测)。
Level 5:Multi-Agent(多智能体)
- 加什么:多个 agent 协作。一个 orchestrator 拆任务,多个 worker 并行干。
- 能干什么:复杂研究、软件工程、大规模信息整合。
- 难度:★★★★★
- 本质:多个 Agent 互相通信。
- 代价:Anthropic 数据显示,多 agent 系统用的 token 是普通聊天的约 15 倍。慎用。
2.5 你现在的位置
你在这里 ↓
Prompt → RAG → Workflow → [Agent] → Multi-Agent本教程第 0-4 章带你从 Prompt 走到 Agent,第 5-9 章让你把 Agent 做扎实,第 10 章给你看 Agent 和 Multi-Agent 的实战。
2.5.1 每一层多了什么,也多了什么风险
| 层级 | 新增能力 | 新增风险 |
|---|---|---|
| Prompt | 生成与理解 | 幻觉、不可复现 |
| RAG | 引入外部知识 | 检索质量、引用错误、上下文污染 |
| Workflow | 固定流程自动化 | 流程僵硬、异常分支变多 |
| Agent | 动态决策、工具循环、观察反馈 | 成本失控、行为不可预测、权限风险 |
| Multi-Agent | 并行分工和协作 | 通信成本、角色冲突、调试困难 |
| Reflexive Agent | 从失败轨迹中形成经验记忆 | 记忆污染、错误反思、过度依赖自评估 |
学习路线应该跟风险同步升级。你不需要一开始就做多 Agent,先把单 Agent 的工具、状态、停止条件和评估做好,收益更高。
2.6 设计自己的最小 Agent
你可以用下面这张清单设计第一个 Agent:
| 问题 | 示例答案 |
|---|---|
| 用户目标是什么? | 每周生成一次目标方向论文摘要 |
| Agent 能用哪些工具? | 搜索论文、读取 PDF、生成摘要、写邮件草稿 |
| 哪些工具只能读? | 搜索、读取 PDF |
| 哪些操作要人工确认? | 发送邮件、写入数据库 |
| 状态要记录什么? | 已搜索关键词、候选论文、筛选理由、失败日志、可复用反思 |
| 最大运行成本是多少? | 最多 20 轮、最多 10 次外部 API 调用 |
| 成功标准是什么? | 输出 5 篇相关论文,每篇有摘要、贡献、推荐理由 |
| 失败时怎么办? | 返回失败原因和已完成步骤;必要时生成反思,写入经验记忆 |
如果你能把这张表填清楚,代码反而不难。很多 Agent 项目失败,是因为还没想清楚这些边界就开始写循环。
前人智慧 / Prior Art
本章把 Agent 拆成"LLM + 工具 + 循环 + 状态 + 停止边界",并区分了短/中/长三个循环。这个心智模型不是本教程原创,它来自几篇关键论文的共同启发。
Toolformer:模型自己学会用工具
Schick et al. 2023 的 Toolformer 论文是工具使用研究的里程碑。核心贡献:让模型自己学会在什么时候、用什么参数、调什么工具,而不是人工写死调用规则。
Toolformer 的训练流程:
- 给模型一批含工具调用占位符的文本
- 让模型预测占位符位置和参数
- 执行工具调用,把结果插回文本
- 用"有工具结果"和"无工具结果"两版对比,筛选有用的样本
- 用筛选后的样本微调模型
Toolformer 的意义不在它的具体实现(后来被 Function Calling 替代),而在它证明了:模型能学会"什么时候需要外部工具"。这是本章"工具是行动接口"的论文支撑——工具调用不是工程师写死的,是模型动态决定的。
Tree of Thoughts:探索多分支
Yao et al. 2023 的 Tree of Thoughts (ToT) 论文扩展了 CoT 的线性推理:
- CoT:一条推理链,错了就错了
- ToT:一棵推理树,可以分支探索、回溯、剪枝
ToT 在 24 点游戏上把 CoT 的 4% 准确率提到 74%。这个跳变说明:复杂任务需要探索多个可能路径,而不是一条路走到黑。
对本章"短中长三个循环"的支撑:ToT 是"中循环"(Trajectory → Evaluation → Reflection)的论文源头——一次完整尝试后评估,不行就回溯到分支点换路径。
ReAct 的循环结构
ReAct 论文(第 0 章和演化史章详细拆过)定义了本章"短循环"的结构:
Thought → Action → Observation → Thought → ...本章 2.2.1 节的伪代码示例就是这个结构的工程化。ReAct 的贡献不是发明了循环,而是证明了推理和行动交替比任一单独更优。
Reflexion 的长循环
Reflexion 论文 定义了本章"长循环":
Reflection → Memory → Better Next TrialReflexion 把"失败"从"重试"升级成"学习"。本章 2.3.1 节"失败 4:失败没有沉淀成经验"正是 Reflexion 的工程化——失败后生成可行动反思,写入 memory,影响下一次。
Reflexion 的量化收益:87% -> 95% 07-09
Reflexion 不只是模式,还有量化证据。吴恩达 Agentic AI 课程(Bilibili BV1DfrdByE2H,Module 4)引用的对照实验:
- 基线(无反射):HumanEval 编程任务通过率约 87%
- 加反射后:通过率约 95%
- 错误率从 13% 降到 5%,几乎减半
这个数据的工程含义:
- 反射不是锦上添花:8 个百分点在很多场景下是"能不能上线"的差距
- 反射成本可控:只多一次 LLM 调用 + 一次重试,token 成本约 1.5-2 倍,延迟也约 1.5-2 倍
- 反射有适用边界:从 87% 到 95% 是典型收益区间,不会一次反射把 50% 的系统变成 95%
反射 vs 重试的本质区别:
- 重试:同样输入再跑一次,期待随机性带来成功 -- 失败概率不变
- 反射:失败后生成具体反思("上次错在 X,下次应该 Y"),把反思加入 context 再跑 -- 失败概率真的降低
87% -> 95% 的提升来自"反思让下一次真的不同",不是"多跑几次碰运气"。
Lilian Weng 的四块拆解与本章的对应
Lilian Weng 2023 把 Agent 拆成 Planning / Memory / Tool Use / Action 四块。本章的心智模型和它的对应:
| Lilian 四块 | 本章对应 |
|---|---|
| Planning | LLM(决策)+ 循环(推进) |
| Tool Use | 工具(执行) |
| Memory | 状态(记录) + Reflexion 的经验记忆 |
| Action | 工具执行的物理层(第 9 章 Runtime & Sandbox 讲) |
Lilian 的拆法偏概念(Agent 有什么能力),本章偏工程(这些部件怎么组装 + 缺一不可的失败模式)。两者互补。
"缺一不可"的失败模式实证
本章 2.3 节列了三种典型失败:没停止条件 / 工具返回太随意 / 失败没沉淀。这三种失败都有对应的论文研究:
- 没停止条件 → AutoGPT 翻车的首要原因(演化史章详拆)
- 工具返回太随意 → Toolformer 训练时筛掉"无帮助工具调用",反向证明结构化工具返回的价值
- 失败没沉淀 → Reflexion 证明"反思+记忆"比"机械重试"准确率高 20+ 个百分点
这些不是本教程拍脑袋的判断,是有论文实证的工程经验。
短中长三循环的工程意义
本章提出的三循环模型:
短循环:Thought → Action → Observation
中循环:Trajectory → Evaluation → Reflection
长循环:Reflection → Memory → Better Next Trial对应了 ReAct(短)/ ToT(中)/ Reflexion(长)三篇论文。把三篇论文的循环结构合起来,就是 Agent 完整的反馈系统。一个成熟 Agent 不应该只有工具调用(短循环),还要有评估(中循环)和经验记忆(长循环)。
这条主线贯穿后续所有章节——MCP 扩展短循环的工具,Skills 沉淀中循环的方法,Memory 文件层支撑长循环的经验。
- 把“订会议室”任务写成状态表:至少包含
task、facts、attempts、pending_approval。 - 给
book_room工具设计一个结构化返回格式,包含成功和失败两种情况。 - 写出 3 个停止条件:正常完成、预算耗尽、需要人工确认。
- 参考 Reflexion,为一次失败的论文搜索任务写一条“可行动反思”。
- 判断一个 RAG 系统为什么通常不是 Agent,并说明怎样改造才会接近 Agent。
2.8 小结
- Agent 的基础骨架是 LLM(决策)+ 工具(执行)+ 循环(推进),但可靠 Agent 还需要状态、观察、反思和停止边界。
- 30 行伪代码展示的是短循环;ReAct 补充了 Thought/Action/Observation 的交替结构,Reflexion 补充了失败后的反思记忆。
- 路径图 5 级:Prompt → RAG → Workflow → Agent → Multi-Agent,每级加一层能力。
- RAG 不是 agent,Workflow 不一定是 agent——区别在循环和自主性。
下一章我们把 30 行伪代码变成能跑的真代码,看 agent loop 怎么真正转起来。