Agent 核心概念
Agent 到底是什么?LLM + 工具 + 记忆 + 规划只是开场。真正决定成败的是 Loop、Harness、Action、Skill 这四个工程概念,以及步数、上下文、工具数量这些不写在论文里的边界数字。
先把定义说清楚
Agent = LLM + 工具 + 记忆 + 规划,这句话你肯定听过。但它只回答了「由什么组成」,没回答「怎么运转」。真正让 Agent 成为 Agent 的,是下面这个循环:
这就是 Agentic Loop。普通的 LLM 调用是「一问一答」,Agent 是「自己决定下一步干什么,干完看结果,再决定再下一步」。Loop 是 Agent 与普通 Chatbot 的分水岭。
这个区别听起来简单,但后果很深:模型本质上是一个「给定上下文、输出下一个 token」的函数,它本身没有目标、没有状态、不知道任务是否完成。是 Loop 把这坨概率函数变成了一个「系统」——每转一圈,环境的新信息(工具结果、报错、文件内容)被写进上下文,模型基于一个更大的证据集合重新决策。Agent 的智能,一半在模型里,另一半在这个循环的信息流设计里。
也正因为是循环,所有工程问题都被放大了:一次调用的小概率犯错,在循环里会以幂次累积。假设单步决策准确率是 95%,一个需要 20 步的任务,全程不出错的概率只剩约 0.95^20 ≈ 36%。这就是为什么 Agent 系统对「每一步的可靠性」的要求远高于普通对话应用,也是后面所有机制(停止条件、上下文管理、错误回填)存在的根本原因。
ReAct:Loop 的经典实现
ReAct(Reasoning + Acting,Google 2022 年的论文,arXiv:2210.03629)是最早把 Loop 形式化的范式:让模型每一步都显式输出三段内容——
- Thought:我现在掌握什么信息,下一步该干什么
- Action:调用哪个工具,参数是什么
- Observation:(由环境回填)工具返回了什么
Thought: 用户问北京天气,我需要先调用天气工具
Action: get_weather(city="北京")
Observation: {"temp": 32, "condition": "晴"}
Thought: 已拿到结果,可以回答了
原论文的实验设计值得细看,因为它定义了后来所有 Agent 评测的套路。作者在两类任务上做了验证:
知识问答类(HotpotQA、FEVER):只给模型三个 Wikipedia 工具——search(按词条名搜索)、lookup(在词条内找关键词)、finish(提交答案)。工具被刻意设计得很弱(搜索不到同义词就抓瞎),逼模型用 Thought 来绕路和纠错。结论是:纯 CoT(Chain-of-Thought,只推理不行动)在 HotpotQA 上 Answer 准确率略高于纯 ReAct,但幻觉率明显更高——因为它只能「脑内编」事实;ReAct 的事实性来自真实检索,FEVER 上反超 CoT。而把两者混合(CoT 为主、卡壳时切 ReAct 查资料)效果最好。这个「推理派 vs 检索派各有短板、混合最优」的结论,至今仍是工程实践的指导原则。
决策类(ALFWorld、WebShop):文字游戏环境里做具身任务,比如在虚拟家庭里「把干净的杯子放进咖啡机」。用 1-2 个专家轨迹做 few-shot,ReAct 在 ALFWorld 上拿到 71% 成功率,比当时最好的模仿学习基线高出 34 个绝对百分点;WebShop(模拟网购)上 40%,接近人类专家 59% 的水平,而纯模仿学习只有 29%。关键发现是:显式的 Thought 让模型能从失败轨迹里泛化——同一个错误,模仿学习会原样复制,ReAct 会在 Thought 里「反思」然后绕开。
今天的 Function Calling 把这个流程「结构化」了(Action 不再是一段文本,而是协议化的 tool_call),但思想没变:推理和行动交替进行,每一步行动都为下一步推理提供新证据。
ReAct 的两个重要变体
Reflexion(2023,arXiv:2303.11366):给 Loop 外面再套一层 Loop。任务失败后,模型生成一段自然语言的「自我反思」(哪里错了、下次怎么改),存进一个外部记忆区,下一次尝试时带着这段反思重跑。相当于用自然语言当梯度,做「言语强化学习」。论文报告 GPT-4 + Reflexion 在 HumanEval 上 pass@1 达到 91%,超过 GPT-4 裸跑的 80%。代价是任务要跑多轮,token 成本直接乘上尝试次数。
Tree of Thoughts(2023,arXiv:2305.10601):把单线 Loop 变成搜索树。每一步生成多个候选 Thought,用一个「价值评估」步骤给分支打分,再决定展开哪个。在 24 点游戏上,GPT-4 用 CoT 只解出 4%,ToT(宽度 5)解出 74%。但树搜索的 token 消耗是线性的几十倍,所以工程上只在「单步价值极高、错了不可逆」的场景(比如复杂规划、数学证明)值得用,日常 Agent 任务单线 ReAct 足够。
一个共同的启示:这些变体都没有改模型,只改了 Harness 层的循环结构。 这再次印证开头那句话——Agent 的智能有一半在循环结构里。
Harness:Agent 的脚手架
模型本身不会循环,也不会执行工具——它只会输出 token。真正跑 Loop 的是模型外面的那层程序,叫 Harness(脚手架/挽具)。
一个最小可运行的 Harness 就这么多(TypeScript):
const MAX_STEPS = 30; // 熔断:任何 Agent 都必须有
while (messages.length && step < MAX_STEPS) {
const resp = await llm.chat({ messages, tools });
if (!resp.tool_calls?.length) return resp.content; // 模型认为完成
for (const call of resp.tool_calls) {
const result = await runTool(call.name, call.arguments); // 真正执行的是代码
messages.push({ role: "tool", tool_call_id: call.id, content: truncate(result) });
}
step++;
}
throw new Error("超出步数上限,任务中止"); // 宁可选失败,不烧钱死循环
麻雀虽小,Harness 的核心职责都在了:
- 组装上下文:系统提示词 + 历史消息 + 工具结果,每一轮重新拼装
- 调用模型,解析输出里的 tool_call
- 在真实环境里执行工具,拿到结果
- 把结果裁剪后塞回上下文,回到第 1 步
- 判断何时停止:模型说"完成了" / 超过步数上限 / 连续报错 / 超出预算
Claude Code、Cursor、Devin 的本质差异不在模型,而在 Harness:工具集设计、上下文管理、停止条件、权限控制,全是 Harness 层的工程决策。同一个模型,换个 Harness,能力天差地别——SWE-bench 榜单上同模型不同 Harness 的成绩差 10-20 个百分点是常事。
开头那个公式里的「记忆」,在这一层才有真正的着落。Agent 的记忆其实分两层:短期记忆就是上下文本身——Loop 每转一圈,历史消息和工具结果留在上下文里,模型才能"记得"自己刚才干过什么;长期记忆则是上下文之外的东西,比如写到磁盘上的笔记文件、一个可检索的知识库、或者下次会话开始时读回来的摘要。模型权重里并不存在"这个任务的进展",所以记忆管理的本质是信息管理:什么东西留在上下文里、什么落盘、什么扔掉。这个决策每轮都在发生,也是 Harness 设计里最考验功力的地方。
Harness 的两个深水区
上下文管理。 工具结果是上下文膨胀的头号来源:一次 grep 可能返回几百行,跑个测试又是几千行日志。而长上下文不是免费的——Chroma 2025 年的 Context Rot 研究报告系统测试了 18 个主流模型,发现即使输入远低于上下文窗口上限,模型性能也随输入变长而持续下降,且长输入下对干扰信息的抵抗力明显变弱。换句话说,标称 200K 的窗口,「有效上下文」可能只有其中一部分。所以工业级 Harness 都会做三件事:工具结果截断(只留头部 N 行 + 总行数提示)、历史消息摘要压缩(Claude Code 的 compaction)、把大段中间产物落到文件系统、上下文里只留路径。
停止条件。 Loop 的失控有三种典型形态:模型反复调同一个工具(死磕)、在两个工具之间来回横跳(振荡)、不断"再检查一遍"迟迟不收尾(完美主义陷阱)。步数上限能兜住所有情况但太粗暴,更好的做法是多层熔断:单工具连续 N 次失败强制换路、总步数上限(经验值 20-50 步,取决于任务类型)、token/费用预算上限、以及超时。给一个参考量级:Claude Code 这类编码 Agent 的公开演示里,完成一个中等任务通常在十几到几十步;如果你的任务常态超过 50 步,大概率不是步数上限不够,而是任务该拆了。
Action:模型与世界的接口
Action 是 Agent 能够作用于外部世界的最小单元。设计 Action 空间时有个关键权衡:
- 太细(如
read_line、move_cursor):Loop 步数爆炸,模型容易迷失——还记得 0.95^n 的累积错误吗,步数本身就是错误率的敌人 - 太粗(如
fix_bug):工具内部变成黑盒,模型失去控制,失败时无法定位是哪一环出了问题
经验法则是:Action 的粒度应该接近"人类工程师的一次原子操作"——读文件、跑测试、搜代码、改一个函数。Claude Code 的 Bash / Read / Edit / Grep 就是这个粒度的经典设计。
第二个权衡是工具数量。ReAct 论文里只有 3 个工具,模型选起来毫无压力;但真实系统里工具一多,模型的选择准确率会明显下降——社区的经验数字是超过 20-30 个工具后,选错工具、参数乱编的现象显著增多(经验值,与模型能力正相关,具体拐点建议用自己的评测集实测)。解法不是硬塞,而是做工具筛选:先用轻量步骤(关键词匹配、embedding 检索或一个 router 模型)从全量工具里选出相关的三五个,再放进主 Loop。按需给工具,而不是一次性全给。
第三个常被忽视的点是 Action 的可逆性分层。读文件、搜代码这类只读 Action 可以放心让模型自由发挥;写文件、发请求、删数据这类写 Action,要么要求幂等(防止重试造成重复执行),要么需要人类确认。把「读」和「写」在 Harness 层分开授权,是 Agent 权限设计的第一课。
Skill:可复用的能力包
如果说工具是「手脚」,Skill 就是「经验」:一份用自然语言写成的操作说明书(通常是 Markdown + 配套脚本),告诉 Agent 遇到某类任务时该按什么步骤做、注意什么坑。
Skill 的价值在于把领域知识从代码里解放出来:加一个新能力 = 加一份说明书,不用改主流程。Agent 启动时按需加载相关 Skill,相当于给通才模型临时注入专家经验。
工程上有两个细节决定 Skill 是否好用:
- 按需加载,而不是全量注入。 一份典型 Skill 可能有几千 token,全塞进系统提示词会挤占上下文、稀释注意力。好的设计是只在系统提示词里放 Skill 的名字和一句话描述(几十个 token),模型判断相关时再主动加载全文。这叫渐进式披露(progressive disclosure),和「工具筛选」是同一个思想:上下文是稀缺资源,所有东西都要按需进场。
- Skill 里可以沉淀 Harness 的边界知识。 比如「这个工具返回超过 500 行时要先用 grep 过滤」「这个环境跑测试前必须先装依赖」——这些坑写进 Skill,比让模型每次用 token 重新趟一遍便宜得多。
单 Agent vs 固定工作流
不是所有场景都需要 Agentic Loop。Anthropic 在《Building Effective Agents》里划了条清晰的界线:
- Workflow(工作流):步骤是预先编排好的,LLM 只是其中的环节。可控、可测试、便宜
- Agent:模型自己决定走几步、走哪步。灵活,但不可预测、成本高
工程原则:能用 Workflow 解决的问题,不要上 Agent。 只有当步骤无法预先穷举(比如调试一个陌生 bug、探索一个陌生代码库)时,Loop 的自主性才有正收益。
延伸争论:单 Agent vs 多 Agent
这是 2025 年吵得很凶的一个话题,正反双方都有硬证据:
支持多 Agent 的一方最有力的数据来自 Anthropic 自己的研究系统:用一个 lead agent 把问题拆给多个并行 subagent,在其内部研究评测上比单 Agent 提升 90.2%。适合多 Agent 的场景特征很明确——任务可以并行拆解、子任务之间上下文独立、需要读取的信息总量远超单一上下文窗口(广度优先的调研类任务是典型)。代价也写得明明白白:多 Agent 系统的 token 消耗约是单 Agent 的 4 倍、普通对话的 15 倍。
反对的一方以 Cognition(Devin 团队)的《Don't Build Multi-Agents》为代表:LLM 是「无状态、靠完整上下文理解」的,把上下文切碎分给多个 subagent,每个子 Agent 只拿到局部信息,决策彼此矛盾,合并阶段处处是坑。他们的主张是单线程 Agent + 精心维护的共享上下文,宁可压缩上下文也不切分上下文。
我的看法:这不是路线之争,是任务结构问题。 子任务之间上下文耦合度高(改同一个代码库、共享隐含的决策前提)→ 单 Agent;子任务天然独立、产出可以客观合并(分别调研十个主题再汇总)→ 多 Agent 的并行红利才成立。拿不准就先单 Agent,多 Agent 的调试成本会惩罚每一个贸然上车的人。
延伸争论:框架 vs 裸写
另一个争议是「要不要用 LangChain 这类 Agent 框架」。框架派的理由:状态持久化、人机协作断点、可观测性这些脏活框架都帮你做了,自己写一遍是重复造轮子。裸写派的理由:前面那个 20 行的 Loop 就是 Agent 的全部本质,框架的抽象层会挡住你理解上下文里到底发生了什么——而 Agent 开发 90% 的调试工作就是看上下文。Anthropic 在《Building Effective Agents》里的建议偏后者:从裸 Loop 开始,痛了再引框架。这个顺序我同意——先用 100 行代码理解本质,再决定为框架的哪些能力付费。
把概念串起来:一个 bug 修复任务的一生
抽象概念讲完了,用一个具体任务把它们过一遍:「修复登录接口在并发下偶发 500 的问题」。
任务进来,Harness 组装好初始上下文(系统提示词 + 任务描述 + 工具清单)并启动 Loop。模型第一步的 Thought 是「先复现」,于是选择 Action run_test——这个粒度的选择就是 Action 空间设计的结果。测试日志被截断后回填为 Observation,成为短期记忆的一部分。模型接着 grep 相关代码、read_file 定位到竞态条件,过程中如果 Harness 加载了「并发问题排查」这份 Skill,模型会知道「先查共享状态、再看锁粒度」这个套路,少走弯路。改动完成后跑全量测试验证,模型输出「完成」,Harness 命中停止条件收尾;如果模型反复横跳超过 30 步,熔断会强制中止并把现场留给人类。整个过程中,如果中间产物太多,Harness 会把分析报告落盘(长期记忆),上下文里只留路径。
可以看到,模型只做了「每一步选什么」这一件事,其余全是工程。这也是为什么 Agent 系统的评测、调试、优化都围绕 Harness 展开——模型会换代升级,但这层工程沉淀是你的。
常见误区
- 把 Agent 当 Chatbot 做:没有 Loop、没有工具结果回填,只是套了层"Agent"的话术
- Loop 不设上限:一定要给 Harness 加最大步数 / 最大 token / 超时熔断,否则一个死循环烧掉的钱超乎想象
- 忽视累积错误率:单步 95% 准确率的 Agent,跑 20 步全程无错的概率只有三分之一左右。长任务要么拆短,要么加验证步骤
- 工具越多越好:工具超过几十个后,模型的选择准确率会明显下降,需要做工具筛选或分组
- 迷信大窗口:上下文窗口标称 200K 不代表 200K 都能用好,长上下文下性能持续下滑(Context Rot),该压缩就压缩
- 上来就搭多 Agent:并行红利只覆盖独立子任务,上下文耦合的任务上多 Agent 是花钱买矛盾
术语表
| 名词 | 定义 | 一句话直觉 | 常见混淆 |
|---|---|---|---|
| Agentic Loop | 观察-思考-行动-再观察的自主循环,Agent 的运转方式 | 自动驾驶:不是画好整条路线,而是边开边看路况 | 与固定 Workflow 混淆:Workflow 的步骤是人预先编排的,Loop 的下一步由模型现场决定 |
| ReAct | 让模型交替输出 Thought/Action/Observation 的范式(2022) | 让侦探把推理过程喊出来,每查一条线索再想下一步 | 与 CoT 混淆:CoT 只有推理没有行动,ReAct 每步行动都会带回新证据 |
| CoT(思维链) | 让模型分步推理再作答的提示技术 | 考试要求写演算过程,不许直接填答案 | 与 ReAct 混淆:CoT 是「脑内推演」,不接触外部世界,容易编事实 |
| Thought / Action / Observation | ReAct 循环的三段式:推理、工具调用、环境返回 | 医生的「我怀疑是 X → 开个检查单 → 看化验结果」 | Observation 不是模型写的,是 Harness 回填的,很多人误以为三段都是模型输出 |
| Function Calling | 模型输出结构化 tool_call(JSON),由外部代码真正执行的协议 | 服务员不亲自下厨,只把规范的点菜单递进厨房 | 以为模型「调用」了函数——模型只生成 JSON,执行、错误处理、权限全是代码的责任 |
| Harness | 模型外面跑 Loop、执行工具、管理上下文的程序层 | F1 赛车:模型是引擎,Harness 是底盘、变速箱和方向盘 | 与 Agent 框架混淆:Harness 是概念(那层程序),框架是实现 Harness 的现成库(如 LangChain、Agent SDK) |
| Action 空间 | Agent 可调用的全部工具及其参数的集合 | 游戏角色的技能栏 | 与工具实现混淆:Action 空间是「暴露给模型的接口设计」,和工具内部怎么实现是两回事 |
| 工具粒度 | 单个工具职责的粗细程度 | 瑞士军刀 vs 整套工具箱 | 以为越细越灵活:太细会让 Loop 步数爆炸、累积错误率飙升 |
| Skill | 用自然语言写的可复用操作说明书,按需注入上下文 | 给通才员工临时发一本某业务的 SOP 手册 | 与工具混淆:工具是「能干什么」(可执行的函数),Skill 是「该怎么干」(流程知识) |
| 记忆(短期/长期) | 短期记忆 = 上下文里的历史与工具结果;长期记忆 = 落盘的笔记、知识库等上下文外存储 | 桌面上的草稿纸 vs 书架上的笔记本 | 以为模型"记得"任务进展:权重里没有状态,记忆全是 Harness 管理的信息流 |
| Context Rot | 模型性能随输入变长而持续下降的现象(Chroma 2025 报告) | 会议室坐 200 人,谁说话都听不清了 | 以为没超窗口上限就没事:有效上下文远小于标称窗口 |
| 熔断(停止条件) | 强制终止 Loop 的机制:步数上限、预算上限、超时、连续报错 | 电路里的保险丝,宁可断电也不烧房子 | 以为「模型自己会知道何时停」:模型没有全局状态,停止是 Harness 的责任 |
| Reflexion | 失败后生成文字版自我反思、存入记忆再重试的方法(2023) | 错题本:下次考试前先翻一遍 | 与微调混淆:Reflexion 不改权重,「经验」只存在上下文/外部记忆里 |
| Tree of Thoughts | 把单线推理扩展成可评估、可回溯的搜索树(2023) | 下棋时算多个分支再选最优,而非一条路走到黑 | 与 ReAct 混淆:ToT 组织的是「想法的搜索空间」,ReAct 组织的是「与环境的交互流」 |
| 多 Agent 系统 | 多个 Agent 分工协作,通常含 lead agent + 并行 subagent | 项目经理把任务拆给几个调研员分头跑 | 以为是免费的性能提升:token 成本数倍于单 Agent,且子任务上下文耦合时会互相矛盾 |
参考材料
- ReAct: Synergizing Reasoning and Acting in Language Models — ReAct 原始论文,HotpotQA/FEVER/ALFWorld/WebShop 的实验设计值得精读
- Reflexion: Language Agents with Verbal Reinforcement Learning — 用自然语言反思做「无梯度强化学习」
- Tree of Thoughts: Deliberate Problem Solving with Large Language Models — 把推理从单线变成搜索树
- Building Effective Agents — Anthropic 的 Agent 工程实践总结,Workflow vs Agent 的权威划分
- How we built our multi-agent research system — 多 Agent 阵营最有力的工程实证,含 90.2% 提升与 token 成本数据
- Don't Build Multi-Agents — Cognition 的反方檄文,上下文切分批判
- Context Rot: How Increasing Input Tokens Impacts LLM Performance — Chroma 的长上下文性能研究报告
- LLM Powered Autonomous Agents — Lilian Weng 的经典综述,Agent 概念的体系化梳理
- Claude Agent SDK 文档 — 看一个工业级 Harness 长什么样
小结
记住四个词:Loop 让 Agent 转起来,Harness 让 Loop 落地,Action 定义 Agent 能做什么,Skill 教 Agent 怎么做好。
再记住三组数字:单步准确率会以幂次在循环中累积衰减,所以每一步的可靠性都比单次调用重要得多;20-30 个工具是模型选择准确率开始下滑的经验拐点;200K 窗口不等于 200K 有效上下文。Agent 工程的功力,全在这些数字背后。后面的章节会逐个展开这些概念。