本文是「Agent 基本概念」系列第二篇。
第一篇给出的核心公式是:
Agent = LLM(或策略)+ 规划 + 记忆 + 工具 + 执行循环
为了便于展开,这一篇把它细化为七个部分:
Agent = 感知 + LLM/策略 + 规划 + 记忆 + 工具 + 行动 + 执行循环
其中 LLM 与规划合并为"大脑与调度器"一节,其余各部分独立展开。
系列规划:① 什么是 AI Agent → ② 核心组件 → ③ 决策与规划 → ④ 记忆与工具 → ⑤ 架构与落地。
前言:Agent 不是"一个模型",而是一套系统
很多人第一次接触 Agent,会以为:
"Agent 就是一个更聪明的 LLM。"
但真正跑起来你会发现,LLM 只是其中一块。
一个能完成真实任务的 Agent,至少需要六个部分协同:
- 感知:接收输入和环境状态;
- LLM 与规划:推理、决策、任务分解;
- 记忆:保存上下文、状态和经验;
- 工具:与外部世界交互;
- 行动:真正执行并改变环境;
- 执行循环:把上面五步串起来,持续运转。
这六个部分,可以对应成一个人:
- LLM 是大脑;
- 规划是调度器;
- 记忆是经验与状态;
- 工具是手脚;
- 行动是执行;
- 循环是心跳。
2025 年的 Agent 架构综述论文也采用了类似的组件划分:当代 Agent 框架的核心组件包括感知、推理引擎、记忆层次、规划模块和工具接口。另一篇综述则将 Agent 能力组织为规划、工具使用、记忆、推理、自我改进和感知。
下面我们逐个拆解。
一、感知:Agent 的输入层
1.1 感知什么?
Agent 的感知来源通常有三类:
| 来源 | 例子 |
|---|---|
| 用户输入 | 文本、语音、图片、文件、表单 |
| 工具返回 | API JSON、网页 HTML、数据库结果、代码执行输出 |
| 环境状态 | 当前时间、系统状态、页面 DOM、传感器数据 |
感知的核心任务不是"看见",而是把原始信息变成 Agent 能理解、能决策的结构化输入。有综述指出,感知系统负责将环境感知转化为有意义的表示。
1.2 感知层的关键设计
-
归一化
把不同来源的数据统一成模型能处理的格式。
比如 API 返回的 JSON、网页文本、文件内容,最终都要转成文本或结构化上下文。
-
过滤与压缩
上下文窗口有限,不能把所有原始数据都塞进去。
需要:
- 去掉无关 HTML 标签;
- 截断超长日志;
- 只保留关键字段;
- 用摘要代替全文。
-
标注来源与时间
模型需要知道"这条信息来自哪里、什么时候"。
例如:
text[来源: 航班搜索 API][时间: <当前时间>] {"flight": "CA1234", "depart": "08:00"} -
异常感知
工具报错、超时、空结果,都是重要信号,不能直接吞掉。
1.3 常见工程坑
- 上下文爆炸:把整个网页、整个数据库结果直接塞给模型,token 瞬间爆掉。
- 噪声干扰:无关信息太多,模型注意力被稀释。
- 格式不一致:同一个工具在不同情况下返回不同结构,导致模型解析失败。
- 丢失关键元信息:只给内容,不给来源和时间,模型无法判断可信度。
一句话原则:
感知层要做的,是把世界翻译成模型能用的上下文,而不是把整个世界搬给模型。
二、LLM 与规划:大脑与调度器
2.1 LLM:Agent 的推理核心
LLM 是 Agent 的推理引擎。有综述将 LLM 视为 Agent 系统的"认知核心"(cognitive core),使 Agent 能够感知输入、用自然语言推理,并通过输出或工具使用来行动。
它负责:
- 理解用户意图;
- 分析当前状态;
- 决定下一步动作;
- 生成工具调用参数;
- 总结结果并输出。
但 LLM 不是唯一策略。
在传统强化学习中,策略可以是一个神经网络;在简单规则系统中,策略可以是 if-else。
但在现代 AI Agent 语境下,LLM 通常扮演策略网络 + 推理引擎的双重角色。
2.2 规划:把"大目标"拆成"小步骤"
规划回答的是:
"目标是什么?现在在哪?下一步该做什么?"
它把一个大目标拆成可执行的步骤,并在执行过程中动态调整。
2.3 规划的四个层次
| 层次 | 说明 | 例子 |
|---|---|---|
| 任务分解 | 把大目标拆成子任务 | 订机票 → 查日期、搜航班、选座、支付 |
| 优先级排序 | 决定先做哪个 | 先查天气,再决定带不带伞 |
| 路径选择 | 多条路选一条 | 直飞 vs 转机 |
| 重规划 | 执行失败后调整 | 航班售罄 → 换航班或换日期 |
2.4 常见规划模式
ReAct(Reason + Act)
Yao 等人在 2022 年提出的框架,让 LLM 以交错方式生成推理轨迹和任务特定动作。推理轨迹帮助模型归纳、跟踪和更新行动计划,同时处理异常;动作则允许模型与外部源交互以获取额外信息。适合边查边做的任务。
Plan-and-Execute
LangChain 官方博客将其定义为将高层规划与短期执行分离的 Agent 架构。规划器(planner)几乎总是使用语言模型,利用其推理能力规划步骤并处理歧义和边缘情况;执行器(executor)则接收高层目标,决定使用哪些工具完成。这种方式适合更复杂的长期规划,代价是更多的模型调用。
Reflexion
Shinn 等人在 NeurIPS 2023 提出的框架,不通过更新权重,而是通过语言反馈 来强化语言 Agent。Agent 对任务反馈信号进行言语反思 ,将反思文本保存在情景记忆缓冲区 中,以引导后续试验中更好的决策。在 HumanEval 编码基准上达到 91% pass@1 准确率,超过 GPT-4 的 80%。
Tree of Thoughts(ToT)
Yao 等人在 NeurIPS 2023 提出,让 LLM 进行审慎的问题求解,通过同时探索多条推理路径来做出决策。成本较高,适合高价值任务。
Anthropic 在其官方工程指南中指出,Agent 设计模式并非越复杂越好,大多数生产环境的应用主要由少数几种基础构建块组成,包括 ReAct 和 Reflection 等。
2.5 常见工程坑
- 过度规划:任务很简单,却生成几十步计划,浪费 token 和时间。
- 计划僵化:执行中环境变了,还死守原计划。
- 无限重规划:一直反思、一直调整,永远不行动。
- 规划与执行脱节:计划很漂亮,但工具根本调不通。
一句话原则:
规划不是越详细越好,而是在不确定性和成本之间找平衡。
三、记忆:Agent 的状态与经验
3.1 为什么 Agent 需要记忆?
没有记忆的 Agent 就像金鱼:
- 每轮对话都从零开始;
- 不记得用户偏好;
- 不记得任务进度;
- 不记得上次失败的原因。
记忆让 Agent 能积累状态、复用经验、保持一致性。有综述指出,复杂的记忆架构支持纵向的经验积累。
3.2 记忆的三层结构
| 类型 | 作用 | 存储位置 | 例子 |
|---|---|---|---|
| 短期记忆 | 当前对话上下文 | 上下文窗口 | 用户刚说的"不要转机" |
| 工作记忆 | 当前任务状态 | 内存/状态对象 | 已选航班、支付进度 |
| 长期记忆 | 跨会话知识与偏好 | 向量库/数据库 | 用户常坐靠窗、喜欢早班机 |
三层记忆不是互斥的,而是协同工作的。此外还可以分:
- 情景记忆:过去发生过什么(Reflexion 的情景记忆缓冲区即属此类);
- 语义记忆:事实和知识;
- 程序记忆:如何做某件事。
3.3 记忆的五个操作
- 写入:把新信息存入记忆;
- 检索:根据当前任务取出相关记忆;
- 压缩:把长对话摘要成短文本;
- 更新:修正过时或错误信息;
- 遗忘:删除不再需要或敏感的信息。
3.4 技术选型
| 方案 | 适用场景 | 注意点 |
|---|---|---|
| 上下文窗口 | 短期记忆 | 成本高、有长度限制 |
| 摘要压缩 | 长对话 | 可能丢细节 |
| 向量数据库 | 长期语义检索 | 检索质量依赖 embedding |
| KV / 数据库 | 结构化状态 | 需要自己管理 schema |
| 知识图谱 | 关系推理 | 构建成本高 |
3.5 常见工程坑
- 记忆污染:把错误信息写进长期记忆,之后一直错。
- 检索不准:向量检索召回不相关的内容,干扰决策。
- 上下文超限:不压缩、不遗忘,最终撑爆窗口。
- 隐私与合规:长期记忆可能存敏感信息,需要加密、脱敏、可删除。
- 记忆不一致:短期记忆和长期记忆冲突,模型不知道该信谁。
一句话原则:
记忆不是越多越好,而是在正确的时间,取出正确的信息。
四、工具:Agent 的手脚
4.1 工具让 Agent 从"会说"变成"会做"
LLM 本身不能发请求、读文件、点按钮。
工具是它与外部世界交互的接口。
4.2 常见工具类型
根据 OpenAI 官方文档,构建 Agent 时可以通过内置工具、函数调用、程序化工具调用、工具搜索和远程 MCP 服务器来扩展模型能力。这些能力使模型能够搜索网页、从文件中检索、在运行时加载延迟的工具定义、调用自定义函数、在 JavaScript 中组合工具调用,或访问第三方服务。
| 类型 | 说明 | 例子 |
|---|---|---|
| Function Calling | 调用预定义函数 | 查天气、算汇率 |
| HTTP API | 访问外部服务 | 航班搜索、支付 |
| 浏览器 | 操作网页 | 填表单、点击、截图 |
| 代码解释器 | 执行代码 | Python 计算、绘图 |
| 数据库 | 查询与写入 | SQL 查询 |
| 文件系统 | 读写文件 | 保存报告 |
| 通过 MCP 接入的工具 | 标准化协议接入外部工具与上下文 | Model Context Protocol |
MCP(Model Context Protocol)是一个开放协议 ,实现 LLM 应用与外部数据源和工具之间的无缝集成。规范定义了权威的协议要求,基于 TypeScript schema 进行定义。
4.3 函数调用的工作流程
根据 OpenAI 官方文档,函数调用的流程如下:
- 定义函数:你定义函数及其参数,指定函数名、描述和 JSON Schema 格式的参数;
- Agent 请求调用:模型根据用户输入和工具定义,生成对函数的调用请求;
- 代码返回结果:你的代码执行函数,将结果返回给模型;
- harness 继续本轮对话:模型基于函数返回结果继续生成响应。
用伪代码表示:
text
LLM 输出: { "tool": "book_flight", "args": {...} }
运行时层: 校验参数 → 检查权限 → 调用 API → 返回结果
LLM 基于结果继续生成
其中"校验参数"和"检查权限"属于运行时层的应用层实现,官方文档明确了"Agent 请求调用 → 代码返回结果 → harness 继续"的核心循环。
4.4 工具设计要点
-
清晰的描述
模型靠描述决定用哪个工具。描述要说明:
- 做什么;
- 什么时候用;
- 输入输出是什么;
- 有什么限制。
-
严格的参数 Schema
用 JSON Schema 定义参数类型、必填项、枚举值,并设置
additionalProperties: false来减少模型瞎填参数。OpenAI 文档中的函数定义即采用了这一模式。 -
错误处理
工具失败时,返回结构化错误,而不是抛异常:
json{"error": "FLIGHT_SOLD_OUT", "message": "该航班已售罄"} -
权限最小化
只给 Agent 必要的权限。
能读就不能写,能查就不能删。
-
幂等与超时
支付、下单等操作要支持幂等,避免重复执行。
所有工具都要设超时。
4.5 常见工程坑
- 工具误用:模型选了不合适的工具。
- 参数幻觉:模型编造不存在的参数值。
- 权限过大:Agent 能删库、能转账,风险极高。
- 超时与重试:工具卡住,Agent 一直等。
- 副作用不可逆:发了邮件、下了单,无法撤回。
- 工具描述冲突:多个工具功能相似,模型不知道选哪个。
一句话原则:
工具是 Agent 能力的边界,也是风险的边界。工具设计得好,Agent 才可靠。
五、行动:Agent 的输出与执行
5.1 行动不只是"输出文本"
Agent 的行动包括:
- 输出答案;
- 调用工具;
- 修改环境(写文件、发请求、点按钮);
- 请求人工确认。
5.2 谁在执行?
LLM 只负责生成行动意图,真正执行的是外部运行时。这与 OpenAI 文档中函数调用的设计一致:模型请求调用,代码返回结果,harness 继续本轮对话。
5.3 执行的关键设计
- 沙箱
代码执行、浏览器操作要在隔离环境中进行。 - 人工确认
高风险动作必须人工确认:支付、删除、发送。 - 审计日志
记录谁、什么时候、执行了什么、结果如何。 - 回滚与补偿
对可逆操作设计回滚;对不可逆操作提前拦截。
5.4 常见工程坑
- 副作用失控:Agent 自动执行了不该执行的操作。
- 缺少确认:直接付款、直接删数据。
- 执行结果不反馈:执行完不把结果告诉 Agent,循环断掉。
- 状态不一致:工具执行成功,但本地状态没更新。
一句话原则:
行动层要可控、可审计、可回滚,尤其是高风险场景。
六、执行循环:Agent 的心跳
6.1 循环结构
一个典型的 Agent 循环:
text
观察 → 思考 → 行动 → 观察 → 思考 → 行动 → ... → 完成
具体步骤:
- 观察:读取用户输入、工具返回、环境状态;
- 思考:LLM 推理下一步;
- 行动:调用工具或输出内容;
- 观察:获取行动结果;
- 判断:是否完成?未完成则回到第 1 步或第 2 步。
6.2 循环的终止条件
必须明确设置终止条件,否则会死循环:
- 任务完成;
- 达到最大步数;
- 超过时间预算;
- 超过成本预算;
- 连续失败次数超限;
- 需要人工介入。
6.3 循环控制
| 控制项 | 作用 |
|---|---|
| 最大步数 | 防止无限循环 |
| 超时 | 防止卡死 |
| Token 预算 | 防止成本失控 |
| 工具调用次数限制 | 防止滥用 |
| 人工确认节点 | 高风险拦截 |
6.4 常见工程坑
- 死循环:Agent 反复调用同一个工具,永远不结束。
- 成本失控:循环几十次,token 费用爆炸。
- 状态漂移:多轮之后,Agent 忘了最初目标。
- 错误累积:一步错,步步错。
- 缺少可观测性:出问题了不知道哪一步出错。
一句话原则:
循环是 Agent 的心脏,但必须装上刹车、仪表盘和安全气囊。
七、整合:一个最小 Agent 架构
把上面六个组件串起来,一个最小 Agent 架构如下:
text
markdown
┌─────────────────────────────────────────────┐
│ 用户 / 环境 │
└───────────────────┬─────────────────────────┘
↓
┌─────────────────┐
│ 感知层 │ 归一化、过滤、标注
└────────┬────────┘
↓
┌─────────────────┐
│ LLM / 策略 │ 推理、决策、任务分解
└────────┬────────┘
↓
┌─────────────────┐
│ 规划模块 │ 任务分解、优先级、路径选择
└────────┬────────┘
↓
┌─────────────────┐
│ 记忆系统 │ 短期 / 工作 / 长期
└────────┬────────┘
↓
┌─────────────────┐
│ 工具层 │ API、浏览器、代码、MCP
└────────┬────────┘
↓
┌─────────────────┐
│ 执行器 │ 沙箱、权限、审计、确认
└────────┬────────┘
↓
┌─────────────────┐
│ 执行循环控制 │ 最大步数、预算、终止
└────────┬────────┘
↓
是否完成?
/ \
否 是
↓ ↓
回到感知 输出结果
7.1 伪代码示例
python
def run_agent(user_input, max_steps=10):
memory = Memory()
context = Perceive(user_input) # 初始感知
for step in range(max_steps):
memory.write(context)
thought = Think(context, memory) # LLM 推理
plan = Plan(thought, memory) # 任务分解与调度
action = Decide(plan, memory) # 选择工具或输出
if action.type == "finish":
return action.output
result = Execute(action) # 工具调用 / 输出
context = Perceive(result) # 感知行动结果
memory.update(result)
return "达到最大步数,任务未完成"
7.2 各部分协作关系
- 感知提供输入;
- LLM 负责推理和决策;
- 规划决定方向;
- 记忆提供状态和历史;
- 工具提供能力;
- 行动执行并产生结果;
- 循环把一切串起来。
任何一个组件薄弱,Agent 都会表现出明显短板:
| 薄弱组件 | 表现 |
|---|---|
| 感知差 | 看不懂输入,漏掉关键信息 |
| LLM/规划差 | 步骤混乱,反复绕路 |
| 记忆差 | 重复提问,忘记目标 |
| 工具差 | 调不对 API,参数总错 |
| 行动差 | 执行失败,副作用失控 |
| 循环差 | 死循环,成本爆炸 |
八、总结:组件设计的核心原则
回到主线:
Agent 不是一个大模型,而是一套由感知、LLM/规划、记忆、工具、行动、循环组成的系统。
Anthropic 在其官方工程指南中强调:大多数生产环境的应用主要由少数几种基础构建块组成,应该从评估开始,通过代表性任务识别 Agent 的能力差距,而不是一开始就追求复杂架构。
设计时记住五条原则:
- 可观测:每一步都要有日志、有轨迹、能回放。
- 可控制:最大步数、预算、权限、人工确认。
- 可恢复:失败能重试,状态能回滚。
- 最小权限:工具权限只给必要的。
- 从简单开始:先工作流,再逐步增加自主性。
下一篇,我们会深入 Agent 的决策与规划模式:ReAct、Plan-and-Execute、Reflection、Tree of Thoughts,看看它们分别适合什么场景,以及如何选型。
本文是「Agent 基本概念」系列第 2 篇。
如果你觉得有帮助,欢迎点赞、收藏、关注。