Agent Harness 学习报告:从概念边界到工程落地
从概念边界到工程落地,梳理当前 Agent 系统的组成、主要难点与解决思路。报告区分论文和实验中的证据、厂商或作者自报数据,以及需要进一步核实的判断,便于读者结合自己的任务与预算使用这些结论。
阅读指南
这份报告不是论文综述,也不是产品选型指南。它想回答三个问题:
- 现在的 Agent 到底是由什么构成的? 模型之外那一大坨东西,有没有一个稳定的分类方式。
- 它在哪里坏掉? 不是笼统地说”幻觉””不稳定”,而是具体到某一层、某一类失败、某一个可以观测的信号。
- 别人怎么修的?每种修法付出了什么代价? 这一条最重要。工程上几乎没有”更好的方案”,只有”在某个约束下更划算的方案”。
阅读顺序建议:如果你时间很少,读第零章和第二章;如果你要动手做,读第一章、第三章、第八章;如果你要做研究,读第四到第七章。
报告里的观点有强弱之分。带数字的多数是别人的实验结论,写”建议””我倾向于”的是我的工程判断。两者要分开用:前者可以引用,但要核对版本与预算;后者只能作为你在自己场景里验证的起点。
报告分为三部分、九章,配有 20 张图和四个附录。第一部分介绍 Harness 的定义、分层和现状;第二部分讨论上下文与工具、长程任务、多智能体、长期记忆、评测与自进化;第三部分聚焦安全治理、开源实现、参考架构和落地路径。附录 B 汇总论文、博客与源码链接。建议先按阅读目标跳读,再回到相关章节查阅细节。
图示索引
如果你只有十分钟,先看这七张:
| 图 | 位置 | 内容 |
|---|---|---|
| 图 2 | 1.8 九层逐一说明 | 九层结构与调用关系 |
| 图 6 | 2.11 难点地图:十个瓶颈 | 瓶颈地图 |
| 图 10 | 4.4 解法 A:用任务结构对抗退化 | 长程任务的运行闭环 |
| 图 12 | 5.9 什么时候值得用多 Agent | 要不要上多 Agent |
| 图 17 | 7.11 五代方法 | 自进化闭环 |
| 图 19 | 8.13 五层架构 | 五层参考架构与依赖方向 |
| 图 20 | 8.16 分阶段路线 | 22 周落地节奏 |
全部 20 张:
| 图 | 位置 | 内容 |
|---|---|---|
| 图 1 | 1.6 Agent 循环的谱系:从 ReAct 到 SWE-agent | 从 ReAct 到 SWE-Gym 的谱系 |
| 图 2 | 1.8 九层逐一说明 | 九层结构与调用关系 |
| 图 3 | 1.10 一次请求的完整数据流 | 一次请求的时序 |
| 图 4 | 2.3 起点:人类与模型的巨大差距 | 基准发布时人类与最好模型的成功率 |
| 图 5 | 2.5 τ-bench:为什么要看 pass^k | pass^k 随 k 衰减 |
| 图 6 | 2.11 难点地图:十个瓶颈 | 瓶颈地图 |
| 图 7 | 3.2 四个动作:Write、Select、Compress、Isolate | 上下文工程的四个动作 |
| 图 8 | 3.5 上下文腐化的实证 | 上下文压缩的决策流程 |
| 图 9 | 3.10 成本这一面:把账算清楚 | 一个 50 步任务的 token 成本(演算) |
| 图 10 | 4.4 解法 A:用任务结构对抗退化 | 长程任务的运行闭环 |
| 图 11 | 5.4 一个决策流程 | Workflow 与 Agent 的选型流程 |
| 图 12 | 5.9 什么时候值得用多 Agent | 要不要上多 Agent |
| 图 13 | 5.18 代价的量化证据 | 多智能体相对单智能体的表现变化 |
| 图 14 | 6.4 经验与技能:记忆里最有价值的部分 | 记忆的沉淀流水线 |
| 图 15 | 7.1 五个层次 | 评测的五个层次 |
| 图 16 | 7.2 从真实业务轨迹造评测集 | 从真实轨迹到评测集的八步 |
| 图 17 | 7.11 五代方法 | 自进化闭环 |
| 图 18 | 7.19 训练侧:SWE-Gym 与 harness 的分工 | 训练侧与 harness 侧的分工 |
| 图 19 | 8.13 五层架构 | 五层参考架构与依赖方向 |
| 图 20 | 8.16 分阶段路线 | 22 周落地节奏 |
其中图 1、4、5、9、13 是数据图,配有 PNG 图片和可点击查看的 SVG 原图;其余 15 张用 Mermaid 写成,纯文本、可 diff、可改。支持 Mermaid 的 Markdown 阅读器(GitHub、GitLab、Obsidian、Typora、VS Code 插件)直接渲染;不支持的环境里它仍是一段可读的结构描述,不会变成乱码。
证据分级
这份报告里的每个关键论断,我尽量标注它的证据强度。分四级:
| 级别 | 含义 | 你应该怎么用 |
|---|---|---|
| A | 我读过原文、摘要或仓库文件,数字与出处一致 | 可以直接引用 |
| B | 我核对过标题、编号、仓库可访问,但没读全文 | 引用前回查原文 |
| C | 厂商或作者自报,未见独立复现 | 当作方向性证据,不当基准 |
| D | 仅见于转述、二手博客,本轮未能核实 | 只能当线索,不要写进方案 |
这样做的原因很实际:Agent 领域的数字污染非常严重。同一篇论文在不同博客里有三个版本的数字,同一张榜单在不同聚合站上有两套完全不同的模型名单。如果不标证据等级,读得越多反而越糊涂。
0 一页结论
如果只看一页,看这十条。
1. Harness 是模型之外的全部运行时。 它包括工具接口、上下文组装、控制循环、验证、权限、持久化。业界把它叫 harness、scaffold、runtime、framework,多数场合可以互换,但严格说,”framework”偏向开发库,”runtime”偏向执行环境,”harness”偏向”把模型套进去跑起来的那套装置”。
2. 同一个模型换一套 harness,成绩可以差出一个模型代际。 这不是修辞。Databricks 的一个说法是,优化 harness 后中等模型能超过弱 harness 下的更强模型(C 级证据,未独立复现)。更可靠的证据是 AHE 的消融:把 harness 组件文件化并自动演化十轮,Terminal-Bench 2 的 pass@1 从 69.7% 到 77.0%,而且增益被定位到工具、中间件和长期记忆,不是系统提示词(A 级,读的是摘要)。
3. 上下文工程是投入产出比最高的一块。 工具延迟加载、程序化工具调用、大输出落文件、压缩与规则置顶,这几件事不需要改模型,几周内就能拿到可测量的收益。代价是它很快会撞到天花板,因为上下文策略不能创造模型不具备的能力。
4. 长程任务的主要敌人不是”想不出来”,是”记不住约束”和”过早宣布完成”。 前者靠规则置顶、类型化压缩、周期性重注入目标;后者靠默认失败的进度清单加独立只读评估者。这两条是目前最有效的组合。
5. 多智能体默认是错的。 独立并行会把错误放大约 17 倍,集中式编排约 4.4 倍(B 级)。它适合读多写少、可分解、有独立验证器的任务。不适合顺序依赖、共享写入、需要全局一致性的任务。
6. 记忆系统的公开榜单不可信。 Mem0 和 Zep 互相质疑对方在 LoCoMo 上的数字,一份审计称 LoCoMo 约 6.4% 的题目本身有错。正确做法是拿自己的留出任务,和”全上下文””文件 + grep”两个基线比。
7. Harness 自进化是真的,但不是万能的。 同等预算下,它在 Terminal-Bench 这类短任务上没有赢过简单的 test-time scaling,泛化也弱;但在长程游戏任务上,任务特定的进化比搜索基线高 80%(ARC-AGI-3)和 11%(EdgeBench)。这个反差本身就是最重要的结论:进化的收益取决于任务有没有结构性的提升空间。
8. 评测是这一切的地基,也是最容易被做坏的部分。 一个 Agent 的分数等于模型 × harness × 工具 × 环境 × 预算 × 评分器。少了任何一维,”某模型达到 X%”都没有意义。
9. 安全不是附加项。 能自我修改的 harness 是一个能改自己权限边界的系统。沙箱、评测脚本不可被修改、人工审批合入,这三条是底线,不是加分项。
10. 现阶段最划算的路线是:先把尺子做出来,再优化上下文,再做长程稳定性,最后才做自进化。 顺序反了,你会用一套不可信的评测去优化一个你还不理解的系统。
第一部分 认识 Harness
1 定义、边界与九层模型
这一章回答三个问题:Harness 到底指什么、它由哪些层组成、这些概念是怎么一路演化过来的。读完你应该能把任何一个 Agent 系统放进九层模型里对号入座。
1.1 三个层次,别混在一起
讨论 Agent 时最常见的混乱,是把三个层次的东西放在一句话里比较。
第一层:模型(model)。 一个把 token 序列映射到下一个 token 分布的函数。它无状态、无记忆、不能执行任何东西。它的”能力”是在训练时固化下来的。
第二层:harness。 围绕模型的那套软件。它负责:把任务描述和工具定义拼成提示;调用模型;解析模型输出;如果是工具调用,执行工具,把结果塞回上下文;重复,直到满足终止条件;期间管理上下文长度、权限、日志、错误重试。
第三层:产品(product)。 用户看到的东西。UI、账号体系、计费、多租户、审计后台。产品包含 harness,harness 包含模型调用。
用一句话概括:Agent = 模型 + Harness,产品 = Agent + 外围系统。
这个划分的价值在于它把”能力问题”和”工程问题”分开了。模型不会用某个工具,是能力问题;模型想用但 harness 没把工具描述清楚,是工程问题。这两类问题的修法完全不同,但表现出来都是”Agent 失败了”。
1.2 同义词辨析:harness、scaffold、runtime、framework
这四个词在业界的用法高度重叠,但语感不同。
- Harness(挽具):原意是套在马身上、把马的力气导向车辆的装置。这个比喻很准确——模型是马,力气很大但方向不受控,harness 把它的输出导向可执行的动作。Anthropic 的工程博客用的就是这个词。
- Scaffold(脚手架):强调”临时搭建、支撑结构”。微软的文档里常见。它暗示这套东西是可以替换、可以拆除的。
- Runtime(运行时):强调”程序运行期间存在的那一层”。它比 harness 更中性,包含调度、资源管理、生命周期。
- Framework(框架):严格说这是给开发者用的库,比如 LangChain、AutoGen。框架是”用来写 harness 的材料”,不是 harness 本身。但很多人把两者混用。
我的建议:在正式文档里用 harness 指代”模型之外的运行时与执行逻辑”,用 framework 只指开发库,用 runtime 指部署形态。三者不要混。
还有两个容易混的概念:
- Context engineering(上下文工程) 是 harness 的一个子集,专管”往模型的上下文里放什么、按什么顺序放、什么时候删”。
- Coding-agent harness 是 harness 的一个特化,面向代码任务,额外包含仓库索引、补丁格式、测试执行、沙箱。OpenAI 的 Codex CLI、Anthropic 的 Claude Code 都属于这一类。
1.3 边界的五个判定测试
“这算不算 harness”这个问题,靠定义吵不出结果。我建议用五个可操作的测试。
测试一:换模型测试。 把这个组件换掉模型还能不能工作?能,它是 harness。换掉就不工作,它是模型的一部分(比如模型的训练数据、微调权重)。
测试二:换 harness 测试。 同一个模型,换一套 harness,行为会不会变?会变,说明这个组件在 harness 里。这个测试也解释了为什么”模型排行榜”经常不可比——榜单测的往往是”模型 + 某个特定 harness”。
测试三:删除测试。 删掉这个组件,Agent 还能不能完成任务?删掉就完全不能跑,它是核心层(循环、工具调用)。删掉能跑但质量下降,它是增强层(压缩、记忆、验证)。删掉毫无影响,它是装饰。
测试四:可复现测试。 同样的输入,跑两次结果一样吗?不一样,说明这里有随机性或者外部状态。harness 的职责之一就是把随机性收敛到可接受范围(固定温度、固定工具版本、固定环境快照)。
测试五:权限测试。 这个组件能不能改变 Agent 的权限边界?能,它属于治理层。这一条很重要,因为自进化系统会试图修改自己的一切,包括权限。治理层必须在被进化对象之外。
1.4 四个常见误解
误解一:harness 就是系统提示词。 不是。提示词只是 harness 输出的一部分。真正的 harness 还包括工具 schema、循环控制、错误处理、上下文裁剪、权限检查。一个精心写的提示词放进一个糟糕的循环里,照样失败。
误解二:用了 Agent 框架就等于有了 harness。 不是。LangChain、AutoGen 提供的是积木。循环怎么写、上下文怎么裁、失败怎么重试,仍然要你自己决定。很多”框架项目”最终失败,是因为把框架默认值当成了设计。
误解三:harness 越复杂越好。 反了。复杂度是有成本的:调试变难、延迟变高、失效点变多。好的 harness 是”刚好够用”,每一层都能说清楚为什么存在。
误解四:自进化就是让模型改自己的提示词。 那只是最浅的一层。真正有价值的自进化改的是代码、工具实现、中间件和拓扑。改提示词的收益很快饱和,而且最容易过拟合基准。
1.5 为什么这个概念在 2025–2026 突然重要
三个原因。
第一,模型在收敛。 头部模型在通用能力上的差距在缩小,同一梯队内,换 harness 带来的差异经常大于换模型。这直接改变了优化方向:过去是”等更强的模型”,现在是”把 harness 做对”。
第二,评测在混杂。 当一个榜单同时测模型、harness、工具和预算时,分数就无法归因。厂商有动力把 harness 做得很重,然后在”模型榜”上拿分。这导致同一模型在不同榜单上的名次可以差很多。
第三,成本在显性化。 一个长程任务的成本可以到几万美元量级(Anthropic 的 C 编译器案例约 2 万美元,C 级)。当成本进入决策,harness 的效率设计(缓存、并行、压缩)就从”优化项”变成”必选项”。
1.6 Agent 循环的谱系:从 ReAct 到 SWE-agent
图 1:从 ReAct 到 SWE-Gym 的谱系
读图要点:这十一个点不是随手挑的,它们回答的是同一个问题的不同侧面——怎样让模型的每一步动作都有反馈、能纠错、能复用。ReAct 解决”边想边做”,Toolformer 解决”会不会调工具”,Self-Refine 解决”做完能不能自己改”,ReWOO 解决”能不能少花 token”,Voyager 解决”做过的事能不能留下来”,SWE-agent 解决”接口该怎么设计”,Agentless 反问”这些是不是都必要”,SWE-Gym 则把问题推到训练侧。
1.6.1 ReAct:把推理和动作织在一起
ReAct(arXiv 2210.03629,Yao 等,2022 年 10 月)的核心想法朴素得惊人:让模型交替输出”思考”和”动作”。思考帮助它制定、跟踪、修正计划,动作让它从外部拿到新信息。摘要给出的结果有两类:在 HotpotQA 和 Fever 上接一个简单的维基百科接口,ReAct 比纯思维链减少了幻觉与错误传播;在 ALFWorld 和 WebShop 上,仅用一两个上下文示例,成功率分别比模仿学习和强化学习方法高出绝对 34% 和 10%。
今天几乎所有 harness 的主循环都是 ReAct 的后代:组装上下文,调一次模型,若是工具调用就执行并把结果写回,否则结束。 第 1.13 节那段最小 Harness 代码,本质就是这个循环加上预算与持久化。
ReAct 的局限也是后面一系列工作的起点。第一,思考与观察交替意味着每一步都要把完整历史重新送进模型,成本随步数线性甚至更快增长。第二,思考是自由文本,没有任何东西保证它和动作一致。第三,它没有”回头改”的机制,错了只能往前走。
1.6.2 Toolformer:工具使用能不能”学”出来
Toolformer(arXiv 2302.04761,Schick 等,2023 年 2 月)走的是训练路线:模型自己决定调用哪个 API、什么时候调、传什么参数,以及怎样把返回结果并入后续预测。训练是自监督的,每种 API 只需要少量演示。涉及的工具有计算器、问答系统、两个搜索引擎、翻译系统和日历。摘要称它在多个下游任务上显著提升了零样本表现,同时保持了语言建模能力。
这条路线今天看是被 API 原生的函数调用取代了:模型厂商直接在后训练阶段把工具调用格式教给模型,开发者只需要提供工具的 JSON 描述。但 Toolformer 留下了一个重要观念:工具调用是一种可以被训练和评测的能力,不只是提示词技巧。第 7 章讲训练侧时会回到这一点。
1.6.3 Self-Refine:同一个模型生成、批评、修改
Self-Refine(arXiv 2303.17651,Madaan 等,2023 年 3 月)让同一个模型先生成,再批评自己的输出,再据此改写,循环若干轮。不需要监督数据、额外训练或强化学习。摘要在 7 个任务上用 GPT-3.5、ChatGPT 和 GPT-4 测试,称人类和自动指标都偏好 Self-Refine 的输出,平均绝对提升约 20%。
这里必须加一个工程上的警告,也是第 4.5 节”独立验证”的由来:自我批评的收益依赖”批评者能发现错误”,而同一个模型往往对自己的盲点同样盲。 Self-Refine 的 7 个任务大多是开放式生成,质量由人或指标判断;当任务有客观的对错(代码能不能跑、数据库状态对不对)时,真正可靠的反馈来自环境,不是来自模型自评。Anthropic 的《Building Effective Agents》把这个意思说得很直白:智能体需要在每一步从环境拿到”ground truth”。
1.6.4 ReWOO:把推理和观察拆开
ReWOO(arXiv 2305.18323,Xu 等,2023 年 5 月)盯住的是 ReAct 的成本问题。摘要说,推理与工具调用交替会带来”冗余提示和重复执行”导致的巨大计算开销;ReWOO 把推理步骤与外部观察分离,先一次性规划出带占位符的调用链,再统一执行并汇总。在 HotpotQA 上它达到 5 倍的 token 效率和 4% 的准确率提升,并且在工具失败时更稳。另一个副产品是:因为参数化的推理与非参数化的工具调用分开,可以把 1750 亿参数的 GPT-3.5 的推理能力通过指令微调迁移到 70 亿参数的 LLaMA。
ReWOO 在今天的意义是**”先规划后执行”是一个真实的成本杠杆**,而不只是风格选择。第 3 章讲过程序化工具调用能省约 37% 的 token,思路相通:让模型少看中间结果,只看最终需要的部分。它的代价是计划僵化——环境中途变化时,预先写好的调用链不会自适应。
1.6.5 Voyager:把做过的事存成可执行技能
Voyager(arXiv 2305.16291,Wang 等,2023 年 5 月)是第 6 章”经验与技能”一节的源头。它在 Minecraft 里由三部分构成:自动课程(决定下一步探索什么)、技能库(可执行代码,按描述检索与组合)、迭代提示(用环境反馈、执行报错和自我验证改进程序)。它只把 GPT-4 当黑盒调用,不改参数。摘要的数字是:独特物品数量是此前最佳的 3.3 倍,行进距离 2.3 倍,关键科技树里程碑最快达到 15.3 倍。更重要的是学到的技能库可以带进新世界,从零解决新任务。
Voyager 的价值不在 Minecraft,而在把”经验”表示成可执行、可组合、可验证的代码。后来的 AWM、ExpeL、ReasoningBank、ACE 都能看到它的影子。它也留下一个没解决的问题:技能库会不会越积越乱、越积越错。第 6.11 节”四种失败”讲的就是这件事。
1.6.6 CodeAct:动作空间用代码,而不是 JSON
CodeAct(arXiv 2402.01030,Wang 等,ICML 2024)提出让智能体直接输出可执行的 Python 代码作为统一动作空间。摘要的理由是:JSON 或格式化文本把智能体限制在预定义工具集里,组合多个工具很别扭;代码可以组合、循环、判断,还能在多轮里根据观察修改之前的动作。作者在 17 个模型上对比,称成功率最高比常见替代方案高 20%,还构造了 7000 条多轮交互的 CodeActInstruct 数据集。
这条线和第 3 章的”程序化工具调用”是同一个思想的两面:让模型写代码去处理数据,而不是让它把数据读进上下文再处理。 代价是执行环境必须是真沙箱——模型写的代码什么都可能做,第 8 章的权限与沙箱要求在这里直接升级。
1.6.7 SWE-agent:接口设计本身就是性能
SWE-agent(arXiv 2405.15793,Yang 等,2024 年 5 月)提出”智能体—计算机接口(ACI)”的概念:语言模型是一类新的用户,它们需要为自己设计的接口,就像人类开发者需要 IDE。摘要称,定制的 ACI 显著提升了智能体创建与编辑文件、浏览仓库、运行测试的能力,在当时 SWE-bench 上达到 12.5% 的 pass@1,在 HumanEvalFix 上达到 87.7%。
这两个数字今天看已经很低,不要用它们做横向比较,要看的是它建立的方法论:同一个模型,换一套命令集、换一种反馈格式、换一种报错信息,成绩就不同。这是第 1 章”harness 与模型的边界”最硬的一份证据。第 3 章会展开 ACI 的具体设计原则。
1.6.8 Agentless:先问”智能体真的必要吗”
Agentless(arXiv 2407.01489,Xia 等,2024 年 7 月)是一份重要的反证。它不让模型自主决策,而是把流程固定成三步:定位、修复、补丁验证。摘要报告在 SWE-bench Lite 上解决 32.00%(96 个),成本 0.70 美元,当时在开源方案中成绩最高、成本很低。作者还人工分类了 Lite 里的问题,发现有些题目的描述里直接包含了标准补丁,有些描述不足或有误导,于是构造了更严格的 SWE-bench Lite-S。
这份工作提醒我们两件事。第一,”智能体”不是默认更好,固定流程在目标明确的任务上可以又便宜又强。第二,基准本身有噪声,题目泄漏答案、描述缺失都会污染分数,第 2.7 节”读分数的七个陷阱”里的”污染”一条在这里有了具体样本。
1.6.9 OpenHands:把这一切做成平台
OpenHands(arXiv 2407.16741,原名 OpenDevin,ICLR 2025)是把前面这些想法工程化的开源平台。摘要给出的信息是:支持实现新智能体、与沙箱执行环境安全交互、多智能体协调、接入评测基准;在软件工程(如 SWE-Bench)和网页浏览(如 WebArena)等 15 个任务上评估;MIT 许可,超过 188 名贡献者、2100 多次贡献。
把它放在谱系末尾,是因为它代表了一个转折:研究原型变成了社区维护的基础设施。 此后”自己造一个 harness”和”基于现成平台改”之间的成本差距被大大拉开,第 8.17 节”自建还是用框架”的判断,就是在这个背景下做的。
1.6.10 这条谱系给我们的三个启示
第一,每一次进步都是在补一个具体的缺口,而不是在堆能力。 ReAct 补反馈,Self-Refine 补纠错,ReWOO 补成本,Voyager 补复用,SWE-agent 补接口,Agentless 补”过度设计”。你在设计自己的 harness 时,也应该先说清楚”我要补哪个缺口”。
第二,被替代的东西不一定错,只是条件变了。 Toolformer 的训练式工具调用被函数调用取代,但”工具调用能被训练和评测”的观念留了下来;Self-Refine 的自评在有环境反馈时让位给执行验证,但在开放生成任务里仍然有用。
第三,反证和正面工作同样重要。 Agentless 的 32% 与 0.70 美元,是任何”我们需要一个复杂多 Agent 系统”的论证都必须先面对的基线。第 9 章的”十个争议”里,有好几条都能追溯到这里。
1.7 为什么要分层
不分层的讨论会退化成清单。”harness 有工具、有记忆、有验证”——这句话对,但没法指导设计,因为没说清楚谁依赖谁、改动一处会影响哪里。
分层的价值在于三件事:定位失败(问题出在哪一层)、划定改动面(改这一层会不会破坏别的层)、分配责任(这一层该由谁负责,模型、框架还是业务代码)。
下面这个九层模型是我综合多份资料后的归纳,不是某一篇论文的原分类。它有争议,但比清单好用。
1.8 九层逐一说明
1.8.1 L1 执行环境层
职责:给 Agent 一个可以真正”做事”的地方。文件系统、shell、解释器、浏览器、网络出口。
典型实现:Docker 容器、Kubernetes Pod、microVM(Firecracker 一类)、本地进程加 seccomp、远程沙箱服务。
设计要点:
- 隔离粒度。一个任务一个容器,还是一个会话一个容器?前者干净但启动慢,后者快但会串味。
- 网络策略。默认拒绝还是默认允许?默认允许会让提示注入的后果放大一个数量级。
- 文件系统快照。能不能在任务开始前打快照、结束后回滚?这决定了失败重试的成本。
- 资源配额。CPU、内存、磁盘、进程数。缺一项就可能被一个死循环拖垮整台机器。
典型失败:环境不干净导致”上次的残留文件让这次通过了”;并行构建把磁盘 I/O 打满(Cursor 报告过 I/O 而不是 token 成为瓶颈,C 级);容器内没有网络导致工具静默失败。
1.8.2 L2 工具接口层
职责:把外部能力包装成模型能理解和调用的形式。注册、schema、参数校验、超时、错误格式化、结果截断。
典型实现:JSON Schema 函数调用、MCP(Model Context Protocol)、OpenAPI 转换、CLI 包装。
设计要点:
- 描述质量决定选择质量。工具描述是给模型看的”用户手册”,写得含糊,模型就会选错或填错参数。Anthropic 的工具写作指南里有一条很实用:描述要说明”什么时候该用”和”什么时候不该用”,不只是”这个工具做什么”。
- 数量要控制。工具超过十几个,选择准确率开始下降。解法是延迟加载(先给名字和一句话描述,需要时再展开完整 schema)或按场景分组。
- 返回值要有界。一个工具返回 200KB 日志,会直接吃掉上下文。正确做法是落文件、返回路径加头尾片段。
- 错误要可读。
Error 500对模型没有信息量;文件不存在: /src/config.yaml,可用文件: /src/config.yml才能让它自我修正。
典型失败:schema 与实现漂移(文档说返回数组,实际返回对象);工具名相似导致误选;工具执行成功但语义失败(比如 git commit 成功但没改到目标文件)。
1.8.3 L3 上下文层
职责:决定模型每一步看到什么。组装、排序、压缩、缓存、检索。
典型实现:消息数组拼接、系统提示模板、摘要压缩、工具结果裁剪、向量检索、文件系统按需读取。
设计要点:
- 顺序影响效果。稳定的前缀(工具定义、系统提示)放在最前,能吃到前缀缓存;易变的内容(用户输入、工具结果)放后面。
- 压缩是有损的。任何压缩都会丢信息,问题是丢的是不是关键信息。经验是:约束和禁止项最先丢,所以要把它们置顶并在压缩后重注入。
- 缓存是钱。前缀缓存的读取价格通常是写入的十分之一量级。一次不小心的改动(比如在系统提示里插入时间戳)会让整段缓存失效。
典型失败:压缩后安全规则消失;工具结果累积到几十万 token;检索召回了相似但过时的内容,模型照抄。
1.8.4 L4 控制层
职责:主循环。调用模型、解析动作、执行、回填、判断是否继续。
典型实现:ReAct 循环、显式状态机、事件驱动的 actor、图执行(LangGraph 一类)。
设计要点:
- 终止条件要多样。只靠”模型说完成了”不够,还要有步数上限、时间上限、token 上限、重复动作检测、无进展检测。
- 错误不能吞。工具报错要么回填给模型让它改,要么中止。最糟的是 catch 住然后返回空字符串。
- 状态要显式。把”当前在第几步、已完成什么、还剩什么”写进状态对象,而不是隐含在消息历史里。隐含状态在压缩时必然丢失。
典型失败:模型反复调用同一个失败的工具(循环);模型在第 3 步就宣布完成;一个工具异常导致整个会话静默结束。
1.8.5 L5 编排层
职责:任务分解、子 Agent 派生、并发调度、结果合并。
典型实现:orchestrator-worker、递归 planner、agent teams、任务队列加 worker 池。
设计要点:
- 分解质量决定上限。能分解成”有独立验证器的小任务”就可以并行;只能分解成”互相依赖的步骤”就不要并行。
- 上下文隔离。子 Agent 应该拿到干净上下文加一份任务说明,而不是父 Agent 的全部历史。这是并行最大的收益来源,也是最容易被忽略的。
- 合并要有裁决。两个子 Agent 给出冲突结论时,谁说了算?没有裁决机制的并行只会制造混乱。
典型失败:父 Agent 把全部历史复制给子 Agent,上下文爆炸;子 Agent 之间同时改同一个文件;编排者自己成了瓶颈。
1.8.6 L6 验证层
职责:判断”做完了没有””做对了没有”。测试、静态检查、评审、评分器、门禁。
典型实现:单元测试、端到端测试、lint、类型检查、LLM 评委、独立只读评估 Agent。
设计要点:
- 默认失败。任务开始时所有检查项都是”未通过”,只有证据出现才变成”通过”。这比”默认通过、发现问题再改”可靠得多。
- 评估者只读。能改测试的 Agent 一定会改测试。评估者必须有独立上下文、只读权限。
- 结果验证优于路径验证。除非路径本身是要求(比如必须走审批),否则只看终态。
典型失败:Agent 删掉失败的测试;Agent 把断言改宽松;LLM 评委被”看起来很有道理”的答案骗过;测试本身有 bug,一直通过。
1.8.7 L7 观测层
职责:记录发生了什么。轨迹、指标、成本归因、回放。
典型实现:结构化日志、OpenTelemetry span、事件溯源(每个动作一条不可变事件)、trace 查看器。
设计要点:
- 轨迹要能重建现场。只记录”调用了什么工具”不够,还要记录”当时上下文里有什么”。否则无法解释为什么模型做了那个决定。
- 成本要能归因。按步骤、按工具、按子 Agent 分摊 token。不然优化时不知道钱花在哪。
- 失败要能分类。Cursor 的做法是给工具错误建分类体系,每周自动分诊。这是把”感觉经常出错”变成”某类错误占 37%”的唯一办法。
典型失败:日志里只有最终答案;trace 缺少关键 span;指标口径不一致导致团队争论。
1.8.8 L8 治理层
职责:权限、审批、审计、预算、紧急停止。
典型实现:能力令牌、文件系统白名单、命令白名单、人工审批点、kill switch、预算上限。
设计要点:
- 最小权限。默认只能读,写要显式授权;默认只能访问工作目录,出目录要审批。
- 危险动作分级。读文件、写文件、执行命令、访问网络、发送外部消息,风险依次上升,审批策略应该不同。
- 可撤销。任何外部副作用都要能回滚,或者至少在发生前留下可审计的记录。
典型失败:权限过宽导致一次注入就能删库;审批点太多导致流程卡死;治理规则写在提示词里(模型可以忽略)而不是代码里。
1.8.9 L9 持久化层
职责:检查点、恢复、幂等、迁移。
典型实现:git 提交、数据库快照、LangGraph checkpointer、Temporal 工作流、事件日志重放。
设计要点:
- 幂等。同一个工具调用重放两次,结果应该一样。做不到就要有去重键。
- 原子写。写文件先写临时文件再 rename,避免崩溃时留下半个文件。
- 可恢复。恢复不只是”接着跑”,还要”重验状态”——外部世界可能已经变了。
典型失败:重试导致重复下单;恢复后基于过期的文件状态继续操作;检查点与真实环境不一致。
图 2:九层结构与调用关系
flowchart TB
U["用户 / 外部调度"] --> GOV["L8 治理层
权限 · 审批 · 预算 · 审计"]
GOV --> ORC["L5 编排层
任务分解 · 子 Agent · 并发"]
ORC --> CTL["L4 控制层
主循环 · 终止条件 · 重试"]
CTL --> CTX["L3 上下文层
组装 · 压缩 · 缓存 · 检索"]
CTX --> LLM["模型"]
LLM --> CTL
CTL --> TOOL["L2 工具接口层
schema · 校验 · 结果格式化"]
TOOL --> ENV["L1 执行环境层
沙箱 · 文件系统 · REPL · 网络"]
ENV --> TOOL
TOOL --> CTX
CTL --> VER["L6 验证层
测试 · 评审 · 门禁"]
VER --> CTL
CTL --> OBS["L7 观测层
轨迹 · 指标 · 成本"]
CTL --> PER["L9 持久化层
检查点 · 幂等 · 恢复"]
PER -.-> CTL
OBS -.-> VER
读图要点:实线是请求路径,虚线是反馈路径。 治理层在模型之外、循环之外——这是它唯一有效的放置方式;一旦写进提示词,它就从”约束”降级成”建议”。上下文层不在模型内部,而是每次调用前临时组装出来的,所以它能被压缩、被替换、被审计。
1.9 层间契约与三个反模式
层与层之间应该有明确契约。三个最常见的反模式:
反模式一:上下文层直接读工具层的内部状态。 比如压缩器去解析某个工具的私有日志格式。一旦工具升级,压缩器就坏了。正确做法是工具层输出统一的结构化结果,上下文层只消费这个结构。
反模式二:验证层依赖模型自述。 “模型说自己测试通过了”不是证据。验证层必须能独立执行检查,并且结果不能被被测对象修改。
反模式三:治理层写在提示词里。 “请不要删除重要文件”是一条建议,不是一条策略。真正的治理要在代码层拦截,模型看不到也改不了。
1.10 一次请求的完整数据流
把九层串起来,一次典型请求是这样的:
- 治理层检查任务是否被允许、预算多少、需要哪些审批。
- 持久化层创建检查点,记录初始状态。
- 编排层判断是否需要分解;如果不需要,进入单 Agent 路径。
- 上下文层组装初始提示:系统提示、工具定义、任务描述、相关记忆。
- 控制层调用模型。
- 模型返回工具调用。控制层解析,交给工具接口层。
- 工具接口层校验参数、检查权限,交给执行环境层。
- 执行环境层在沙箱里执行,返回结果。
- 工具接口层格式化结果(截断、落文件、错误分类)。
- 上下文层决定这个结果怎么进上下文(全文、摘要、还是只留路径)。
- 观测层记录一条完整事件。
- 控制层判断终止条件;未终止则回到第 5 步。
这条链路里,任何一步的失败都会表现为”Agent 不行”。所以定位问题时,要按链路顺序排查,而不是一上来就换模型。
图 3:一次请求的时序
sequenceDiagram
autonumber
participant C as 控制层
participant X as 上下文层
participant M as 模型
participant T as 工具接口层
participant E as 执行环境
participant O as 观测/持久化
C->>X: 请求组装(目标+约束+历史)
X-->>C: 完整提示
C->>M: 调用
M-->>C: 工具调用 或 最终答案
alt 工具调用
C->>T: 校验参数 + 检查权限
T->>E: 沙箱内执行
E-->>T: 原始结果
T-->>C: 截断/落文件/错误分类
C->>X: 结果回填
C->>O: 记录事件与成本
Note over C: 检查步数/预算/重复动作
C->>C: 进入下一轮
else 最终答案
C->>O: 记录终态
Note over C: 交给验证层判定
end
读图要点:每一轮模型调用都是一次完整的”组装—调用—执行—回填”。 成本随轮数累积,上下文随时间腐化,两者都发生在这一圈的重复里。所谓”Agent 变笨”,绝大多数时候不是模型变了,是这一圈的某个环节退化了。
1.11 各层失败模式速查
| 层 | 最典型的表现 | 第一排查点 |
|---|---|---|
| L1 执行环境 | 时好时坏、无法复现 | 环境是否干净、资源是否够 |
| L2 工具接口 | 选错工具、参数错、结果太大 | 工具描述、schema、返回体大小 |
| L3 上下文 | 越到后面越笨、忘记约束 | 压缩策略、缓存命中、顺序 |
| L4 控制 | 死循环、提前结束 | 终止条件、错误处理 |
| L5 编排 | 并行没提速、结论冲突 | 分解粒度、上下文隔离、裁决 |
| L6 验证 | 测试通过但结果是错的 | 评估者是否只读、测试是否可被改 |
| L7 观测 | 出了问题查不出原因 | 轨迹是否完整、成本是否归因 |
| L8 治理 | 越权、误删、外泄 | 权限是否最小、审批是否在代码层 |
| L9 持久化 | 重试后重复副作用 | 幂等键、原子写、恢复后重验 |
1.12 一次失败排查的实录
分层模型的价值在排查时才显现。下面是一个虚构但高度典型的案例,步骤可以直接套用。
现象:一个代码修复 Agent 的成功率一周内从 70% 掉到 45%,模型版本没变,代码没大改。
第一步,先怀疑评测,不要怀疑系统。 查评测集:这一周新增了 20 道题,其中 14 道是多文件修改。难度分布变了,成功率自然下降。这是最常见的”假故障”。把新旧题目分开统计,老题的成功率只掉了 3 个点,说明真正的退化很小。
第二步,看老题的那 3 个点掉在哪。 拉轨迹,按失败模式分类。发现失败集中在”读过文件之后的 5 步内”,而且错误类型是”修改了不存在的函数”。
第三步,顺着链路往上找。 模型没变,工具没变,那就是上下文变了。查配置历史:一周前有人把工具结果的清理阈值从 10 万 token 调到了 4 万 token。
第四步,确认机制。 阈值调低后,模型刚读完的文件内容在几步之后就被清掉了。模型于是凭”记忆”改代码,写出不存在的函数。这不是模型能力问题,是上下文层把仍在使用的信息删了。
第五步,修复。 两个改法:清理时保护最近 N 次读取的文件内容;或者清理时不删全文,改成”路径 + 内容摘要 + 关键符号表”。前者简单,后者更省 token。选了后者,同时把阈值调回 6 万。
第六步,加回归。 加一条探针任务:读一个文件,中间插入三次无关的工具调用,然后要求修改该文件里的一个函数。这条任务专门检测”读取内容是否还在上下文里”。
这个案例的教训有三条:第一,成功率下降先查评测,能省掉一半的无效排查;第二,上下文层的改动最隐蔽,因为它不报错,只是让模型”变笨”;第三,每一个上下文策略都应该有一条对应的探针任务,否则你不知道它什么时候坏了。
1.13 从零搭一个最小 Harness
理解架构最快的方法是写一个。一个能跑的 harness,核心不到 200 行。骨架如下:
1 | state = { |
这二十行里已经包含了五个关键决策:
assemble 决定顺序。 稳定内容在前,易变内容在后;约束置顶;超出预算时先清工具结果,再摘要。
dispatch 决定权限。 每个工具调用前检查白名单、参数范围、是否需要审批。这一步不能省,也不能放到提示词里。
truncate 决定上下文形状。 大结果落文件返回路径,中等结果截断加提示,小结果原样保留。
record 决定可观测性。 每条事件记录时间、类型、输入摘要、输出摘要、当时的上下文用量、成本。这是后面所有排查和进化的基础。
done 决定终止。 至少要有四个条件:模型声明完成且验证通过、步数超限、预算耗尽、检测到重复动作。只靠第一个,系统会卡死。
写完这二十行,再逐层加东西:加沙箱、加压缩、加子 Agent、加评测。每加一层,问一句”没有它会在哪里坏”。答不上来的层,就不要加。
这个练习的价值不在于得到一个能用的系统,而在于让你对”哪一层在做什么”形成肌肉记忆。之后读任何开源 harness,你都能在十分钟内定位到对应代码。
2 现状与难点
这一章先看现在的 Agent 能做到什么、基准怎么读、钱花在哪,再把失败按“哪里会坏”整理成十个瓶颈。后面第三到第七章,都是在展开这些瓶颈的解法。
2.1 三条曲线
评价”Agent 现在到什么水平”,要同时看三条曲线,只看一条必然误判。
能力曲线:在标准任务上的成功率。这条曲线过去两年涨得很快,尤其在代码、检索、结构化操作上。
成本曲线:完成一个任务的 token 与工具调用开销。这条曲线没有同步下降,长任务的成本经常是线性甚至超线性增长。
可靠性曲线:同一个任务重复多次的成功率。这条曲线涨得最慢。能力曲线说的是”最好的一次能做到”,可靠性曲线说的是”每次都能做到”。
工程上真正决定能不能上线的,是第三条。一个 80% 成功率的 Agent,跑十步的端到端成功率是 0.8¹⁰ ≈ 11%。这就是为什么很多演示惊艳的系统一上线就崩。
2.2 基准地图
下面这张表只写”测什么、怎么评分、已知缺陷”,不写排名。原因是 2026 年的榜单聚合站彼此矛盾——同一个 Terminal-Bench 4.0,官方博客列的模型名单和第三方聚合站列的是两套完全不同的模型,数字也对不上。要引用分数,只认官方仓库或官方博客。
| 基准 | 测什么 | 评分方式 | 已知缺陷 |
|---|---|---|---|
| SWE-bench | 真实 GitHub issue 修复 | 跑仓库测试,看 fail-to-pass | 训练集污染严重;Python 偏多 |
| SWE-bench Verified | 人工筛过的 500 题 | 同上 | 仍被质疑饱和;厂商开始转向 Pro |
| SWE-bench Pro | 更难、防污染的子集 | 同上 | 新,独立复现少 |
| Terminal-Bench 4.0 | 66 个容器化终端任务 | 5 次运行取解决率,95% 置信区间 | 4.0 与 2.x/3.0 不可比;有审计称部分任务可作弊 |
| WebArena | 自托管网站上的功能任务 | 终态检查 | 环境固定,易被针对性优化 |
| OSWorld | 真实桌面应用操作 | 脚本验收终态 | 版本间不可比;GUI grounding 仍是瓶颈 |
| GAIA | 需要浏览、多模态、工具组合的问答 | 精确匹配 | 题目公开,污染风险高 |
| TheAgentCompany | 模拟公司里的跨应用工作流 | 任务完成 + 部分分 | 模拟环境,不能外推到真实企业 |
| tau-bench / tau2 | 客服、电信等工具调用对话 | pass^k(k 次全对的概率) | 依赖用户模拟器,模拟器换模型分数会变 |
| GDPval | 44 个职业的真实交付物 | 专家 rubric | 评分贵、周期长 |
| METR 时间视野 | 50% 成功率对应的人类任务时长 | 拟合曲线 | 样本少、外推强 |
| SWE-Marathon | 超长程软件任务 | 完成率 + reward hacking 检测 | 极难,前沿 agent 解决率低于 30% |
关于 Terminal-Bench 4.0,值得单独说一句:它 2026 年 8 月 28 日发布,是”校准版”而不是新题库——重标了资源限制,统一了 8 小时超时,修了 19 个任务,删了 8 个饱和或损坏的任务。官方明确说 4.0 的分数不能和 3.0、2.x 直接比。这一条几乎所有人引用时都会漏掉。
2.3 起点:人类与模型的巨大差距
下面这张图收集了三个基准在发布时,人类与当时最好模型的成绩,全部来自论文摘要。
图 4:基准发布时人类与最好模型的成功率
读图要点:三个基准里,模型成绩都在 12% 到 15% 之间,人类成绩在 72% 到 92% 之间。差距是 60 到 77 个百分点。 这些基准是 2023 到 2024 年发布的,它们当时的作用就是证明”智能体还差得很远”。之后的进展幅度很大,具体数字请以各基准的官方榜单为准——我没有在本轮核对到最新榜单,所以不在这里写,免得误导。
三篇摘要还各给了一个”为什么差”的线索:
WebArena(2307.13854):四个领域(电商、社区论坛、协作开发、内容管理)的真实可运行网站,任务长程,按功能正确性评分。最佳 GPT-4 智能体 14.41%,人类 78.24%。
OSWorld(2404.07972):369 个真实计算机任务,跨 Ubuntu、Windows、macOS,每个任务有初始状态配置和自定义的执行式评分脚本。作者归因为模型的主要困难在界面元素定位(GUI grounding)和操作知识。
GAIA(2311.12983):466 道对人简单、对 AI 困难的真实问题,要求推理、多模态、网页浏览和工具使用;其中 300 题的答案不公开,以支撑排行榜。人类 92%,带插件的 GPT-4 15%。
2.4 SWE-bench:一个基准的演化
SWE-bench(2310.06770)是演化最清楚的例子。原始版本有 2294 个来自 12 个流行 Python 仓库的真实 GitHub issue 与 PR,摘要报告当时最好的 Claude 2 只解决了 1.96%。此后,SWE-agent 在其上达到 12.5%,Agentless 在其子集 Lite 上达到 32.00%,SWE-Gym 训练出的智能体加验证器在 Verified 上达到 32.0%——这些数字都来自各自的摘要。
这段演化暴露了三个读基准时的要点:
第一,子集与版本很多。 Full、Lite、Verified、Lite-S、Pro,每个都有不同的难度和噪声。同样叫”SWE-bench 成绩”,不指明子集就没有意义。
第二,基准的噪声是被研究出来的。 Agentless 的作者人工分类后发现,部分题目的描述里直接含有标准补丁,另一些描述不足或有误导。这类问题会让分数既偏高(泄漏)又偏低(无解)。
第三,分数的增长混合了模型、harness 与训练三种来源。 第 2.6 节”一个分数到底包含什么”讲过分解方法,这里是它的历史注脚。
2.5 τ-bench:为什么要看 pass^k
前面几个基准问的是”能不能做成”,τ-bench(2406.12045)问的是”能不能稳定地做成”。它模拟用户与智能体的多轮对话,智能体有领域 API 和策略规定,评分不看对话,而是比较对话结束时的数据库状态与标注的目标状态。
它提出的 pass^k 衡量”同一任务重复 k 次全部成功”的概率。摘要的结论很扎眼:当时最好的函数调用智能体(如 gpt-4o)单次成功率不到 50%,在零售域的 pass^8 低于 25%。
图 5:pass^k 随 k 衰减
读图要点:图里画的是理论值——假设每次尝试相互独立,k 次全对的概率是单次成功率的 k 次方。单次 90% 看着不错,重复 8 次全对只剩 43%;单次 70% 则只剩 6%。真实系统的各次尝试并不独立(同一任务往往卡在同一个难点),所以真实曲线通常比这个乐观一些,但趋势是对的:可靠性是乘出来的,不是平均出来的。
这给产品化提供了一个直接的判断:如果你的场景要求”每次都对”(客服改订单、运维执行变更),看 pass@1 会严重高估;应该看 pass^k,而且 k 要对应实际的重复频率。
2.6 一个分数到底包含什么
我建议用这个乘法模型来读任何 Agent 分数:
分数 = 模型 × Harness × 工具集 × 环境 × 预算 × 评分器
- 模型:权重、版本、推理档位(同一个模型开不开 extended thinking 差很多)。
- Harness:循环怎么写的、上下文怎么裁的、重试几次。
- 工具集:给了哪些工具、描述写得好不好。
- 环境:容器镜像、依赖版本、网络。
- 预算:最大步数、最大 token、超时。
- 评分器:测什么、宽还是严、有没有被优化过。
这六个里任何一个变了,分数就不可比。”某模型在 Terminal-Bench 上 70%”这句话,如果没有后五项,等于没说。
2.7 读分数的七个陷阱
陷阱一:版本漂移。 论文说 v2,博客说 v4,读者以为是同一件事。Terminal-Bench 4.0 明确不可比,但很多二手文章照样把 2.x 的数字和 4.0 的数字放在一张表里。
陷阱二:污染。 题目进了训练集,分数就虚高。SWE-bench 是重灾区,这也是 OpenAI 停止报告 Verified、转推 Pro 的背景(C 级,来源是社交媒体声明)。
陷阱三:harness 混杂。 榜单测的是”模型 + 某套 harness”。有些系统把大量工程优化塞进 harness,然后在”模型能力”榜上刷分。
陷阱四:预算不一致。 一个系统跑 200 步,一个跑 50 步,成功率当然不同。成本必须一起报。
陷阱五:用户模拟器不可靠。 tau-bench 这类基准依赖模拟用户。有研究显示换一个模拟器模型,分数最多变化约 9 个百分点(B 级)。这意味着”对话能力”的测量本身有噪声。
陷阱六:评分器过宽或过严。 LLM 评委倾向于给”看起来合理”的答案高分。有审计指出,某些记忆基准的 LLM 评委放过了大量主题相关但事实错误的答案。
陷阱七:选择性报告。 只报最好的一次,或者只报通过的子集。正确做法是报 k 次运行的分布、失败样本、以及被排除的样本及原因。
2.8 读新基准的六个问题
每当出现一个新基准,我建议依次问:
1. 评分看什么? 看最终状态(τ-bench 的数据库、OSWorld 的执行脚本)通常比看对话或让评委打分更可靠。
2. 题目从哪来? 真实任务(GitHub issue、真实网站)比合成任务更有效度,但也更容易有噪声。
3. 有没有人类基线? WebArena、OSWorld、GAIA 都给了,这让”差多远”有参照。没有人类基线的分数无法解读。
4. 答案是否公开? GAIA 保留了 300 题答案,是防污染的常见做法。全部公开的基准迟早会被训练数据吸收。
5. 环境能否复现? 容器化、固定版本、固定时间。Terminal-Bench 4.0 的”与旧版本不可比”就是这类问题的官方承认。
6. 报告了成本和重复次数吗? 只报一个最高分、不报成本和方差的结果,第 2.7 节已经讲过怎么打折。
2.9 对现状的诚实判断
能做的:
- 有明确验证器的任务(代码修复、数据转换、结构化抽取)已经可以稳定产出价值。
- 读多写少的检索与综合可以做到很高水平,代价是 token。
- 长程任务在有好 harness 的前提下可以跑几小时到几天,但需要大量工程支撑。
还不能做的:
- 没有 oracle 的开放式任务,成功率仍然低,而且难以判断失败原因。
- 需要跨系统一致性的写操作,容易在半途留下不一致状态。
- 真正的自主长期运行,仍然需要人设定边界、检查关键节点。
这不是悲观,是校准。把边界说清楚,才能把工程投在能产生回报的地方。
2.10 算一笔账:成本从哪里来
很多人对 Agent 成本的直觉是错的。用一个简化模型算一遍就清楚了。
假设一个任务跑 50 步,每步请求平均带 2 万 token 输入、产出 1000 token 输出。输入单价记为 1 个单位,缓存命中价按 1/10 计。
无优化:50 × 2 万 = 100 万输入单位。输出 5 万 token,按单价 4 倍算,折合 20 万单位。合计约 120 万。
只加前缀缓存:稳定前缀约占 80%,命中部分按 1/10 计价。每步成本从 2 万降到 0.8×0.1×2 万 + 0.2×2 万 = 5600。50 步合计 28 万,加输出 20 万,约 48 万。省了 60%。
缓存加压缩:把平均上下文从 2 万压到 1 万,缓存结构不变。每步 2800,50 步 14 万,加输出约 34 万。相比无优化省了 72%。
再加工具结果外置:大输出不再进上下文,平均上下文降到 6000。50 步约 8.4 万,加输出约 28 万。省了 77%。
这个计算说明三件事。第一,缓存是最大的单项杠杆,比压缩更有效,而且几乎不损失信息。第二,压缩的边际收益递减,从 2 万压到 1 万省一半,从 1 万压到 6000 只再省 40%。第三,输出 token 在后期会成为主要成本,因为输入已经被压得很低,而输出压不下去。
所以优化顺序应该是:缓存 → 外置大结果 → 压缩 → 换更便宜的模型做执行。反过来做,你会发现压了半天,账单没怎么变。
2.11 难点地图:十个瓶颈
这一章不按方向分,按”哪里会坏”分。每个瓶颈写四件事:现象、根因、现有解法、为什么还没彻底解决。后面的第三到第七章,本质上是在展开这些解法的细节。
图 6:瓶颈地图
flowchart TD
R["Agent 失败"] --> A["上下文"]
R --> B["长程"]
R --> C["验证与评测"]
R --> D["工程系统"]
R --> E["协同与安全"]
A --> A1["窗口有限"]
A --> A2["上下文腐化"]
A --> A3["压缩丢约束"]
B --> B1["误差累积 / 自我条件化"]
B --> B2["过早宣布完成"]
B --> B3["目标漂移"]
C --> C1["没有 oracle"]
C --> C2["污染与过拟合"]
C --> C3["评分器偏差"]
D --> D1["工具语义碎片化"]
D --> D2["成本非线性"]
D --> D3["状态不幂等"]
E --> E1["多 Agent 协调开销"]
E --> E2["记忆错误固化"]
E --> E3["注入与越权"]
读图要点:右侧四组里,只有”上下文”和”长程”是模型侧的问题,其余三组都是工程侧。 这解释了一个常见误判——很多团队把 80% 的精力花在换模型上,而实际的失败分布里,工程侧占了大头。
2.11.1 上下文有限且会腐化
现象:任务跑到中后段,Agent 开始忘记最初的要求,重复已经做过的事,或者抓住一个次要细节不放。
根因:三层叠加。第一,注意力不是均匀分布的,中间位置的信息最容易被忽略(Lost in the Middle 的 U 型曲线,B 级)。第二,上下文越长,单位 token 的有效信息密度越低,即使总窗口没满,性能也会下降(Context Rot,B 级)。第三,压缩是有损的,而损失往往落在”约束”上——因为约束通常出现在开头,最容易被当成”已经说过了”而删掉。
现有解法:规则置顶并在压缩后重注入;结构化压缩(保留决策、约束、产物,而不是保留对话);把长内容外置成文件,按需检索;用子 Agent 隔离上下文。
为什么没解决:压缩的”该丢什么”本质上是一个语义判断,目前没有可靠的自动方法。所有压缩器都在”丢得太多”和”丢得太少”之间摇摆,而这个平衡点随任务变化。
2.11.2 长程误差累积
现象:单步成功率 95%,跑 50 步就只剩 8%。任务越到后面越容易崩。
根因:两个机制。一是误差的独立累积,这是纯概率问题。二是”自我条件化”——模型看到自己前面的错误输出,会把它当成既定事实继续推理,错误被放大而不是被纠正(B 级)。
现有解法:子任务用新上下文,只传已验证的摘要;周期性重规划;独立评估者在关键节点检查;步级信用分配(训练侧)。
为什么没解决:错误检测本身需要 oracle。没有测试、没有外部验证的任务,Agent 无法知道自己错了,也就无法触发纠正。
2.11.3 验证困难:没有 oracle
现象:代码任务可以用测试判断对错,但”这份报告写得好不好””这个方案是否合理”没有自动判据。
根因:开放式任务的正确性是一个分布,不是一个点。而且评分本身需要专业知识。
现有解法:rubric 加 LLM 评委;专家抽样;Agent-as-a-Judge 做过程评分;把开放任务拆成若干可判定的子断言。
为什么没解决:LLM 评委有系统性偏差——偏好长答案、偏好格式整齐、偏好与自己风格相似的输出。校准成本很高,而且校准一次不等于永久有效。
2.11.4 评测污染与过拟合
现象:分数一直涨,真实业务没变化。
根因:三个来源。训练数据里混进了测试题;harness 针对榜单做了特化;自进化系统直接优化了评测集。
现有解法:私有留出集;定期换题;防污染的子集(如 SWE-bench Pro);在自进化里分离进化集、验证集、测试集;RRSI 式的编辑预算与批评者过滤。
为什么没解决:只要评测是公开的、静态的,就一定会被优化。这是一个对抗问题,不是工程问题。
2.11.5 工具生态碎片化
现象:接一个新系统要写一堆适配;同一个能力有五个工具,模型选错;工具报错信息没法用。
根因:没有统一的语义层。MCP 统一了传输和调用格式,但没有统一”这个工具到底做什么、什么时候用”。
现有解法:MCP 做协议层;工具描述规范化;工具检索(按任务检索相关工具);程序化工具调用(让模型写代码编排)。
为什么没解决:语义统一需要领域建模,这是人的工作,协议解决不了。
2.11.6 成本非线性
现象:任务长度翻倍,成本涨三到五倍。
根因:每一轮都要把历史重新送进模型,成本随轮数近似平方增长;工具返回的大结果会进一步放大;多 Agent 会成倍复制上下文。
现有解法:前缀缓存;上下文压缩;工具结果外置;批处理;强模型做规划、弱模型做执行;按任务设预算。
为什么没解决:缓存会被上下文变化打破,压缩会损失信息,两者都在省钱和保真之间做交换。
2.11.7 状态与幂等
现象:重试之后重复下单、重复发消息;恢复之后基于过期状态继续操作。
根因:外部副作用不是幂等的,而 Agent 的重试是常态。
现有解法:幂等键;去重表;事务性工具;检查点加恢复后重验;把写操作集中到少数可审计的工具里。
为什么没解决:很多外部系统本身不提供幂等接口,只能在 harness 层做补偿,而补偿逻辑本身会出错。
2.11.8 多 Agent 协调开销
现象:上了多 Agent,速度没变快,成本涨了五倍,结论还互相矛盾。
根因:协调本身有成本(通信、同步、冲突解决),而且错误会被放大而不是被平均掉。
现有解法:只在可分解任务上用;层级化(planner → worker);用 git 或消息队列做状态平面;限制并行度;给每个 Agent 独立验证器。
为什么没解决:任务的可分解性很难自动判断,目前主要靠人预先设计。
2.11.9 记忆写入的错误固化
现象:Agent 把一次错误的经验写进记忆,之后反复犯同样的错。
根因:写入时没有质量信号。一次偶然成功被当成规律,一次特殊失败被当成通则。
现有解法:写入前验证;用后续任务结果做质量标签;记忆条目带来源和有效期;可回滚;定期修剪。
为什么没解决:验证一条经验是否正确,需要它在多个任务上被检验,而这本身很贵。
2.11.10 安全与权限边界
现象:一次提示注入就让 Agent 执行了危险命令;自进化系统改掉了自己的限制。
根因:模型无法可靠区分”指令”和”数据”。任何进入上下文的内容都可能被当成指令。
现有解法:输入隔离(把外部内容标记为不可信);最小权限;危险动作人工审批;沙箱;治理层写在代码里而不是提示词里。
为什么没解决:这是一个开放对抗问题。防御能降低概率,不能归零。
2.12 三种典型误诊
瓶颈清单容易看,难的是判断当前这个故障属于哪一条。三种最常见的误诊:
误诊一:把上下文问题当模型问题。 表现是”越到后面越笨”。直觉反应是换更强的模型。换了之后可能好一点,但只是把断崖往后推了几步。正确做法是查上下文:压缩阈值、清理策略、约束是否还在。判断方法很简单——看失败样本的步数分布,如果集中在某个步数之后,几乎一定是上下文问题。
误诊二:把评测问题当系统问题。 表现是”成功率突然下降”。第一反应应该是查评测集有没有变、评分器有没有改、环境依赖有没有升级。这三项排除了,再查系统。很多团队花了几天优化 harness,最后发现是新加的题目更难。
误诊三:把工具问题当推理问题。 表现是”模型反复做错同一个操作”。看上去像推理能力不足,实际上是工具返回的信息有歧义。比如一个查询工具在没有结果时返回空数组而不是明确的”未找到”,模型就会反复重试。修工具的错误语义,比换模型有效得多。
这三种误诊的共同点是:症状出现在模型身上,病因在模型之外。 所以排查顺序永远是”从外往里”——评测、环境、工具、上下文、最后才是模型。
第二部分 解决思路(按问题)
3 上下文工程与工具接口
上下文和工具接口是 harness 里投入产出比最高的两层,所以放在一起讲:先讲上下文怎么管,再讲工具怎么设计,最后把两者的证据与空白放在一张表里。
3.1 三个物理约束
上下文工程不是”提示词写得更好”,它是在三个硬约束下做资源分配。
约束一:注意力不均匀。 模型对上下文不同位置的敏感度不同。开头和结尾的信息更容易被利用,中间的信息容易被忽略。这不是模型”不想看”,是注意力机制的结构性特征。
约束二:信息密度随长度下降。 即使窗口没满,长上下文里的噪声也会稀释信号。检索增强里有个常见现象:给模型 20 篇文档,效果不如给 5 篇精选的。
约束三:每一 token 都要付钱,而且历史会重复付。 第 10 轮请求要带上前 9 轮的全部内容。不做缓存和压缩,成本随轮数近似平方增长。
这三个约束决定了上下文工程的四个动作。
3.2 四个动作:Write、Select、Compress、Isolate
这是 LangChain 提出的分类,我认为是目前最好用的框架。
3.2.1 Write:把状态写到上下文之外
核心思想是:不要让模型”记住”,让它”查得到”。
具体做法:
- 待办清单文件。把任务拆解写进
todo.md,每完成一项打勾。模型每轮读这个文件,而不是从历史里回忆。 - 进度日志。记录”做到了哪一步、下一步是什么、遇到过什么问题”。
- 产物落盘。生成的代码、报告、数据都写成文件,上下文里只留路径。
- 结构化笔记。把关键决策写成”决策 + 理由 + 证据”,而不是散落在对话里。
优点:无损、可审计、可人为编辑、跨会话可用。
缺点:需要模型主动去读;文件多了之后”读哪个”又变成检索问题;写入本身要花 token。
3.2.2 Select:只放该放的东西
- 工具延迟加载。先只给工具名和一句话描述,模型需要时再展开完整 schema。工具定义从几万 token 降到几千。
- 即时检索。不预加载整个知识库,只给文件路径和目录结构,让模型自己 grep。
- 按相关性排序。检索结果按相关度排序,只取前几条。
- 动态工具集。按当前任务阶段切换可用工具。
优点:直接减少 token,通常还能提升准确率(信息少了,干扰也少了)。
缺点:选择错误会导致”该看的没看到”;检索质量成为新的瓶颈。
3.2.3 Compress:有损但可控
- 摘要。把长对话压成要点。
- 工具结果清理。读过的文件内容、执行过的命令输出,用完就删,只留结论。
- 结构化压缩。按”目标 / 约束 / 已完成 / 待办 / 关键产物”五个字段重写,而不是自由摘要。
- 学习式折叠。训练模型学会”什么时候折叠、折叠成什么”。
优点:能处理任意长的历史。
缺点:有损;压缩本身要花一次模型调用;压缩后的内容可能引入幻觉;破坏前缀缓存。
3.2.4 Isolate:用隔离代替压缩
- 子 Agent。把子任务交给一个全新上下文的 Agent,只回收结论。
- 沙箱执行。让模型写代码在沙箱里处理大数据,只返回结果,不把原始数据放进上下文。
- 分支后折叠。探索多个方案时各开一个分支,选定后只保留被选中分支的结论。
优点:最彻底,子 Agent 的上下文可以任意长而不影响主 Agent。
缺点:信息在边界上会丢失;子 Agent 的失败模式更难调试;成本更高。
图 7:上下文工程的四个动作
flowchart LR
B["上下文预算有限"] --> W["Write
写到外部"]
B --> S["Select
只放该放的"]
B --> C["Compress
有损压缩"]
B --> I["Isolate
隔离代替压缩"]
W --> W1["todo.md / 进度日志
产物落盘 / 结构化笔记"]
S --> S1["工具延迟加载
即时检索 / 按相关度取 top-k"]
C --> C1["工具结果清理
结构化摘要 / 学习式折叠"]
I --> I1["子 Agent 干净窗口
沙箱执行 / 分支后折叠"]
读图要点:四个动作不是四选一,是有顺序的。 先 Write(把不需要即时可见的挪出去),再 Select(根本别放进来),再 Compress(放进来之后压),最后 Isolate(压都压不动就换窗口)。顺序反了会浪费——先压缩一堆本来就该外置的内容,等于白花一次模型调用。
3.3 七种压缩方式的对比
| 方式 | 原理 | 优点 | 缺点 | 适用 |
|---|---|---|---|---|
| 滑动窗口 | 只保留最近 N 轮 | 实现最简单、不花钱 | 早期约束必丢 | 短任务、无长期约束 |
| 自由摘要 | 让模型总结历史 | 能保留大意 | 会幻觉、丢细节、不可控 | 闲聊式长对话 |
| 结构化压缩 | 按固定字段重写 | 约束和产物保留率高 | 需要设计 schema;不适合探索型任务 | 工程任务、长程任务 |
| 工具结果清理 | 删除旧的工具输出 | 便宜、安全(旧读取多半已过时) | 破坏缓存;可能删掉仍需要的内容 | 读多写少的探索 |
| 学习式折叠 | 训练模型决定折什么 | 效果上限最高 | 需要训练资源;泛化未知 | 有训练能力的团队 |
| 外置加检索 | 全量存文件,按需取 | 无损 | 检索可能漏;多一次往返 | 知识密集型任务 |
| 子 Agent 隔离 | 换一个干净上下文 | 彻底、可并行 | 信息损失、成本高、难调试 | 可分解的独立子任务 |
一条实践经验:先清理,再摘要,最后才折叠。 顺序反了会浪费钱——你花一次模型调用去摘要一堆本来就该删掉的工具输出。
3.4 缓存经济学
前缀缓存是目前最被低估的优化。它的规则很简单:从开头开始,逐 token 匹配,遇到第一个不同就失效。
这带来几条硬性设计约束:
- 顺序固定:工具定义 → 系统提示 → 历史 → 当前输入。不要把易变内容放在前面。
- 不要放时间戳。
当前时间:2026-11-14 15:03:27会让每一秒的缓存都失效。需要时间就放在最后一条消息里。 - 不要中途增删工具。工具列表变了,整个前缀就变了。需要动态工具时,用工具检索的结果放在历史之后,而不是改工具定义区。
- JSON 键序固定。序列化不稳定会导致缓存 miss。
- 批量驱逐。压缩时一次删够,不要每轮删一点,否则每轮都 miss。
Anthropic 文档里的量级是:缓存读取价格约为写入的十分之一。Manus 的报告里给的是 $0.30 vs $3 每百万 token(C 级)。这个差距意味着,一个缓存友好的 harness 和一个缓存不友好的 harness,成本可以差一个数量级。
3.5 上下文腐化的实证
有三类证据值得记住。
第一类:位置效应。 Lost in the Middle 的实验显示,把关键信息放在长文档中间,模型的表现明显低于放在开头或结尾。这解释了为什么”规则置顶”有效。
第二类:长度效应。 Chroma 的 Context Rot 实验显示,即使任务很简单,输入变长后性能也会下降,而且不同模型下降幅度不同。这说明”窗口够大”不等于”能处理长上下文”。
第三类:压缩的破坏性。 有一项研究观察 Claude Code 的 /compact,发现连续压缩五轮之后,安全相关的规则只剩约 10%(C 级,单一研究,未见复现)。这个数字很惊人,但机制是合理的:摘要器会优先保留”当前在做什么”,而把”不许做什么”当成背景信息丢掉。
这三类证据指向同一个设计原则:约束和禁止项必须放在压缩器碰不到的地方,或者在每次压缩后重新注入。
图 8:上下文压缩的决策流程
flowchart TD
A["每轮结束
统计上下文用量"] --> B{"用量 > 60%?"}
B -- 否 --> Z["继续下一轮"]
B -- 是 --> C["清理旧工具结果
保留最近 3 次"]
C --> D{"仍 > 80%?"}
D -- 否 --> Z
D -- 是 --> E["结构化摘要
目标/约束/已完成/待办/产物"]
E --> F["重注入约束
规则置顶"]
F --> G{"摘要后仍放不下?"}
G -- 否 --> Z
G -- 是 --> H["外置到文件
只留路径"]
H --> I{"还放不下?"}
I -- 否 --> Z
I -- 是 --> J["子 Agent 隔离
换新窗口"]
J --> Z
读图要点:两档水位、四级手段。 60% 清工具结果(最便宜、几乎无损),80% 才摘要(有损、要花钱),压完还不够才外置和隔离。关键是每次压缩后都要重注入约束——这是防止”压缩悬崖”的唯一有效动作。
3.6 “声称的上下文长度”和”有效的上下文长度”
RULER(arXiv 2404.06654,Hsieh 等,COLM 2024)的出发点是:流行的”大海捞针(NIAH)”测试只反映了一种浅层的长上下文理解。RULER 把它扩展成可调长度和复杂度的合成基准,加入多种针的类型与数量,并增加多跳追踪和聚合任务,共 13 个代表性任务,评测了 17 个长上下文模型。
摘要的两个结论值得原样记住:所有模型在普通 NIAH 上几乎满分,但随上下文增长,几乎都出现陡峭的准确率下降;每个模型都声称上下文不少于 32K,但只有大约一半在 32K 时保持令人满意的表现。 它还专门分析了声称支持 200K 的 Yi-34B,指出随输入长度和任务难度增加,仍有很大改进空间。
这条证据的使用边界要说清楚:RULER 是合成任务,它测的是模型在长文本里检索、追踪和聚合的能力,不等同于真实 Agent 轨迹里的表现。但它证明了一件事——“窗口大小”和”可用长度”是两个不同的数。第 2.11 节的”上下文腐化”和第 3.5 节的实证,在方法论上就是这件事的延伸。
3.7 十条工程配方
以下每一条都可以直接落地,数字来自来源方自报,当作起点而不是定律。
- 固定前缀顺序,工具 → 系统 → 历史 → 输入。任何动态内容都往后放。
- 工具超过 10 个或定义超过 1 万 token 时启用延迟加载,常驻 3–5 个高频工具。Anthropic 报告工具定义 token 约降 85%(C 级)。
- 数据密集链路用程序化工具调用:让模型写代码在沙箱里聚合,只返回结果。Anthropic 报告平均省约 37% token(C 级)。
- 大输出一律落文件,返回路径加头尾各若干行,让模型自己 grep。Cursor 报告 MCP 场景总 token 降约 47%(C 级)。
- 先清工具结果,再摘要。触发线可以设在上下文用量的 60%–70%,清理时保留最近 3 次工具调用。
- 压缩后重注入约束:把”不许做什么”和”验收标准”贴在压缩摘要的末尾。
- 每 N 步复述目标。在上下文末尾重写一遍当前目标和待办,对抗中间位置丢失。
- 保留错误信息。失败的工具调用和报错要留在上下文里,否则模型会重复同样的错误。
- 压缩用固定 schema:目标、约束、已完成、待办、关键产物、未决问题。六个字段比自由摘要稳定得多。
- 把缓存命中率当成一等指标。和成功率、成本一起看,否则优化会悄悄破坏缓存。
3.8 怎么评测上下文策略
上下文策略很难评,因为它影响的是”多步之后的表现”。三个方法:
探针问答:在长上下文里埋几个必须记住的事实(比如”第三步用的端口是多少”),压缩后提问。答对率直接反映保真度。
同预算对比:固定总 token 预算,比较不同策略的完成率。不限预算的对比没有意义,因为谁都可以把所有东西留着。
长程基准:用 LOCA-bench 这类专门测长上下文的基准,或者自己构造需要跨几十步保持约束的任务。
3.9 五类任务的上下文策略
抽象原则要落到具体任务上才有用。下面五类是最常见的形态,各自的策略重心不同。
代码修复。 上下文的主体不是对话,是代码。策略是:用 repo map 或符号索引给出仓库概览,按需读取具体文件;保留最近的 diff;测试输出只留失败用例和关键堆栈。不要做的:把整个文件塞进上下文、把完整测试日志保留超过两轮。代码任务的一个特殊点是,文件内容会随时变化,所以”读到的东西可能已过时”要显式提示模型重新读。
检索研究。 上下文的主体是证据。策略是:用只读子 Agent 并行检索,每个子 Agent 只回一份结构化证据卡(结论、原文引用、来源、可信度);主 Agent 只持有证据卡,不持有原始网页。这样主上下文可以很小,而覆盖面很大。代价是子 Agent 可能漏掉关键证据,所以需要一轮”覆盖度检查”。
数据分析。 上下文的主体是 schema 和中间结果。策略是:只把表结构和样本行放进上下文,聚合计算全部在沙箱里用代码完成,只回结果和形状。不要做的:把原始数据行塞进上下文让它”看着算”,那既贵又容易算错。
客服对话。 上下文的主体是结构化状态。策略是:维护一个槽位对象(用户身份、订单号、诉求、已尝试方案、当前情绪),每轮更新;对话原文只留最近 3–5 轮;政策和禁止事项置顶并在压缩后重注入。客服场景的一个关键是”不许做什么”比”要做什么”更重要,所以约束必须放在压缩器碰不到的位置。
长文档生成。 上下文的主体是大纲和已完成部分。策略是:先固定大纲和术语表,每写完一章就生成一份”本章摘要 + 用到的术语 + 与前文的衔接点”,后续章节只读摘要不读全文。这样能保持一致性,又不会爆上下文。不要在最后统一检查一致性,那时已经改不动了。
这五类的共同点是:上下文里应该放”决策需要的最小信息”,而不是”所有相关信息”。 判断标准很简单——如果这条信息不影响下一步做什么,它就不该在上下文里。
3.10 成本这一面:把账算清楚
前面几章讲的都是”能力”,这里补”成本”。下面这张图复现了第 2.10 节的演算。
图 9:一个 50 步任务的 token 成本(演算)
读图要点:图里的数字是演算,不是实测。假设每步输入 20000 token,其中 80% 命中缓存且缓存价为未命中的 0.1 倍,输出共 20 万 token。在这个假设下,仅靠前缀缓存约 48 万(等价)token,而完全没有缓存是 120 万;再加压缩到约 34 万,再把大输出外置到文件约 28.4 万,相对仅前缀缓存又省约 41%,相对无缓存共省约 76%。你自己的数字会不同,重要的是结构:缓存命中、压缩、外置这三项乘起来才是成本,缺一项就显著吃亏。
和 ReWOO 摘要的”5 倍 token 效率”对照看会更有意思:ReWOO 是在 HotpotQA 这类短任务上做到的,它的杠杆是少调用几次模型;上图的杠杆是每次调用少送多少。两者可以叠加,但需要各自验证,不要把 5 倍直接乘上去。
3.11 上下文工程的优缺点总结
优点:
- 不需要改模型,几周内可见效。
- 收益可测量(token、成本、成功率)。
- 风险低,最坏情况是没效果。
缺点:
- 天花板明显:它只能让模型”用好已有能力”,不能创造新能力。
- 策略与任务强相关,一套参数不能通用。
- 压缩与缓存天然冲突,需要持续调参。
- 过度压缩会造成”看起来在正常工作,实际上丢了关键约束”的隐性失败,比直接报错更危险。
适用判断:只要你的 Agent 跑超过 20 步,或者单次上下文超过 5 万 token,上下文工程就是必修课。反之,短任务上做重度压缩是负收益。
3.12 ACI 的含义:给模型设计”界面”
SWE-agent 的摘要用了一个很准的比喻:语言模型是一类新的终端用户。人类开发者有 IDE、有语法高亮、有跳转定义;模型没有眼睛,它看到的只有你返回的那段文本。所以工具返回什么、报错怎么写、一次返回多少行,就是它的全部”界面”。
Anthropic 那篇文章把同一个意思说成:”像对待人机界面一样投入智能体—计算机接口。” 它列出的具体做法有四条,我按工程上的先后顺序重排一下:
文档像写给初级开发者的 docstring。 包括示例、边界情况、输入要求,以及和其他工具的区别。很多工具失败不是模型笨,是两个工具描述相近,模型选错了。
格式贴近互联网上常见的文本。 避免让模型做行号计数、字符串转义这类它不擅长的事。文章举过的做法是:让模型在提交动作前有”思考”的空间。
大量试例、迭代错误。 把工具跑几百个样例输入,看模型怎么用错,再改接口,而不是只改提示。
防呆设计(poka-yoke)。 把参数设计成”很难用错”。文章里最有名的例子是:在 SWE-bench 智能体里要求使用绝对路径,之后与相对路径相关的错误消失了。
3.13 一份工具设计检查表
下面这张表是我综合上述材料与第 3 章(延迟加载、输出落文件)整理的,凡是出处明确的我都标了来源,其余是工程判断。
| 检查项 | 做法 | 依据 |
|---|---|---|
| 名称与描述 | 动词开头,一句话说清”什么时候用”和”什么时候不要用” | Anthropic 文章(A) |
| 参数 | 能用枚举就不用自由文本;路径一律绝对路径 | Anthropic 文章(A) |
| 返回 | 默认返回摘要,附”如何取详情”的提示;大结果落文件,只返回路径与前若干行 | 第 3 章(B) |
| 报错 | 说明哪里错、怎么改,而不是抛堆栈 | SWE-agent 的接口分析(A,方向) |
| 数量 | 工具越多越容易选错且越占上下文,按需延迟加载 | 第 3 章(C,厂商自报) |
| 幂等 | 同一调用重复执行结果一致,或明确返回”已执行” | 第 2.11 节(B) |
| 权限 | 读写分离,写操作要二次确认或预算 | 第 8 章(B) |
3.14 工具数量问题与协议层
工具一多,两个问题同时出现:定义本身占上下文,选择也变难。第 3 章讲过 Anthropic 的延迟加载和程序化调用,都是在应对这件事。
MCP(Model Context Protocol)是这个问题在协议层的回答。官方文档把它比作”AI 应用的 USB-C 接口”:它是连接 AI 应用与外部系统的开放标准,外部系统包括数据源、工具和工作流。它的价值是**把”每个应用 × 每个工具”的集成成本,降为”每个应用一次 + 每个工具一次”**,这是协议的经济学,不是技术魔法。
但协议只解决”能连上”,不解决”该不该用”。我的判断是:接入 MCP 后最常见的问题是工具爆炸——连了十几个服务,几百个工具定义全塞进上下文。所以接入协议之后,仍然需要第 3 章那套治理手段:按任务选择暴露哪些工具、延迟加载、结果落文件。
3.15 动作空间的两种路线
CodeAct 的论文把问题推到了更根本的位置:动作空间应该是”一组工具”,还是”一门语言”?
| 维度 | 工具调用(JSON) | 代码作为动作(CodeAct) |
|---|---|---|
| 表达力 | 受预定义工具限制 | 可组合、循环、条件 |
| 可审计性 | 强:每次调用结构化 | 弱:要读代码才知道做了什么 |
| 安全面 | 小:只能做工具允许的事 | 大:沙箱必须真隔离 |
| 成本 | 中间结果都进上下文 | 可在代码里处理,只返回结果 |
| 失败形态 | 选错工具、参数错误 | 代码有 bug,需要调试循环 |
| 适合 | 动作明确、需要强审计 | 数据处理、多步组合 |
没有哪一边全面更好。一个务实的折中是:高风险、需要审计的动作走结构化工具,数据处理与组合走沙箱里的代码。 许多生产系统事实上就是这样混用的。
3.16 一个常见的错误:把工具当成函数库
很多团队的第一版工具集,是把现有的内部 API 一对一包装成工具。这样做省事,但几乎总是糟糕的,原因有三。
粒度错。 内部 API 是为程序员设计的,一个业务动作可能要调五个接口;模型要么调错顺序,要么中途丢状态。好的工具对应”一个完整的意图”,而不是”一个底层操作”。
返回错。 内部 API 返回的是完整对象,几百个字段;模型需要的是三四个。返回不裁剪,既贵又增加干扰(第 3.5 节讲过干扰会降低准确率)。
错误信息错。 内部 API 的错误码是给日志系统看的。给模型看的错误,应该包含”你传的参数哪一个不对,合法值有哪些”。
怎么改。 取一周的真实轨迹,统计哪些工具调用失败最多、失败后模型的下一步是什么。失败最多的那几个工具,先改描述,再改参数,最后才考虑改实现。这和第 7 章”从真实轨迹造评测”是同一个方法。
3.17 《Effective context engineering》:几个值得记住的定义
这篇是第 3 章的主要来源。精读后我想强调它的四个”可操作”论点。
论点一:上下文工程比提示工程更大。 原文把提示工程限定为”编写和组织 LLM 指令,尤其是系统提示”,而上下文工程是在推理时”策划并维护最优的 token 集合”,涵盖工具、MCP、外部数据和消息历史,并且是迭代的——每次决定给模型什么,都是一次策划。
论点二:注意力预算。 原文解释:模型像人一样只有有限的”注意力预算”,每多一个 token 就消耗一点。原因在于 transformer 里每个 token 都和其他所有 token 建立关联,产生 n² 个成对关系;训练数据又偏向较短序列。结果是性能梯度,而不是断崖——这与第 3.5 节”腐化是渐变的”一致,也与 RULER 的”陡峭下降”在措辞上有细微差别:一个强调渐变,一个强调随长度明显下降,两者并不矛盾,只是看的尺度不同。
论点三:系统提示的”高度”。 要落在”金发姑娘区”:一头是脆弱的硬编码 if-else,另一头是假设共同背景的含糊指导。原文给了一个很实用的起点:先用最好的模型写一个最小提示,再根据观察到的失败添加指令和示例。 并且特别说明”最小”不等于”短”。
论点四:即时检索。 智能体只保存轻量标识符(文件路径、存好的查询、链接),在运行时通过工具加载数据,而不是预先全部塞进去。文件夹层级、命名、时间戳本身就是行为信号,支持”渐进式披露”。代价是比预计算检索慢,且需要好的引导避免走进死胡同。原文说混合方案很常见:Claude Code 先加载 CLAUDE.md,再用 glob 和 grep 做即时探索。
原文对长程任务列了三种技术,各自带适用场景:
| 技术 | 做法 | 适用 |
|---|---|---|
| 压缩 | 对接近上限的对话做摘要并重启;先追求召回、再提精度;最轻的一档是清理工具结果 | 需要大量来回的任务 |
| 结构化笔记 | 在上下文外写持久笔记(如 NOTES.md、待办清单),之后读回 | 有清晰里程碑的迭代开发 |
| 子智能体 | 子智能体在干净上下文里工作,只返回浓缩摘要(常见 1000–2000 token) | 可并行探索的复杂研究 |
可迁移性判断。 这是三篇里最容易直接用的:工具设计的几条(自包含、容错、少重叠、”如果人都说不清用哪个工具,智能体也不会更好”)可以直接当检查项。
3.18 把实证放在一张表里
| 证据 | 来源 | 证明了什么 | 没证明什么 |
|---|---|---|---|
| 声称长度 ≠ 有效长度 | RULER 2404.06654 | 约一半模型在 32K 时不再令人满意 | 真实 Agent 轨迹里的衰减曲线 |
| 记忆能力可拆五类,跨会话约掉 30% | LongMemEval 2410.10813 | 知识更新与时间推理是独立难点 | 哪种记忆架构在你的场景最优 |
| 分离推理与观察省 token | ReWOO 2305.18323 | 先规划后执行有真实成本杠杆 | 动态环境下的鲁棒性 |
| 技能库可跨世界复用 | Voyager 2305.16291 | 可执行技能比自然语言经验更可组合 | 技能库长期不腐化 |
| 自评平均提升约 20% | Self-Refine 2303.17651 | 开放式生成任务自评有收益 | 有客观对错的任务上自评是否可靠 |
3.18.1 还缺什么
这几份证据拼起来,能支撑”上下文会腐化、记忆难、成本可以优化”,但仍有三个空白,写方案时要有意识地避开夸大:
空白一:缺少真实长程轨迹上的衰减曲线。 RULER 和 LongMemEval 都是构造的测试;真实 Agent 里上下文是工具结果、报错和计划混在一起的,衰减形态未必一样。
空白二:缺少记忆系统在真实业务里的长期评测。 LongMemEval 的聊天历史再长也是合成的,业务里的记忆还要面对权限、过期、冲突。
空白三:缺少跨 harness 的成本对比。 很多文章报了”省 X%”,但基线不同、任务集不同,不能直接比。
如果你的项目依赖这些点,最稳妥的做法是自己做一个小实验——第 7 章的评测骨架可以直接复用。
4 长程任务
长程任务的难点不是单步能力,而是几十上百步之后的退化。本章先拆退化机制与度量,再给五类解法,最后用一篇一手博客的具体配方和一条完整时间线收尾。
4.1 什么叫”长程”
“长”有三个维度,混在一起说会失焦。
步数长:几十到几百次工具调用。典型是代码修复、数据分析。
时长久:几小时到几天,中间可能中断、重启、跨会话。典型是大型重构、长期监控。
状态量大:需要记住的东西超过上下文容量。典型是跨多个系统的迁移。
还有一个容易被忽略的维度:不可逆性。一个 100 步但每步都可回滚的任务,和一个 10 步但有三次外部写操作的任务,后者更难。因为错误不可撤销。
工程上真正难的是后两个维度,不是步数。
4.2 四种退化机制
机制一:自我条件化。 模型看到自己前面的输出(包括错误),会把它当作既定前提继续推理。一篇 2026 年的论文把这称为”The Illusion of Diminishing Returns”——模型变大不能解决,因为问题不在能力,在条件化方式(B 级)。
机制二:压缩悬崖。 上下文压缩不是线性的。在某一点之前,压缩几乎无损;过了某一点,关键约束突然消失,性能断崖式下跌。有研究把这种现象命名为 Compaction Cliff(B 级)。
机制三:过早宣布完成。 模型倾向于在”看起来差不多了”的时候停下,而不是在”验证通过”的时候停下。这是训练目标导致的:人类标注的完成点通常早于严格验收点。
机制四:目标漂移。 跑了几十步之后,模型开始优化”当前这一步看起来合理”,而不是”原始目标”。表现为不断处理细枝末节,忘了主线。
这四种机制的共同点是:它们都不需要模型变笨就会发生。 换更强的模型只能延缓,不能消除。
4.3 怎么度量
时间视野(time horizon):METR 提出的指标,指 Agent 在 50% 成功率下能完成的任务对应的人类时长。它的价值是把”能力”换算成一个直观的量。注意这个指标是拟合出来的,样本少,外推误差大(C 级)。
成功率衰减曲线:固定任务类型,画”步数 vs 成功率”。如果曲线在某个步数附近断崖,说明那里有结构性问题(比如压缩触发点)。
pass^k:同一任务跑 k 次全部成功的概率。它衡量可靠性,比 pass@k 更接近生产要求。k 通常取 4–8。
单位成功成本:总成本除以成功任务数。这个指标会把”重试很多次才成功”和”一次成功”区分开。
4.4 解法 A:用任务结构对抗退化
这是目前性价比最高的一组手段,核心是 Anthropic 在长程 Agent 工程博客里描述的模式(A 级,读过博客)。
第一步:初始化会话。 在正式干活之前,先用一个独立会话做三件事:
- 建立环境(依赖、目录、初始 git 提交);
- 写一份
init.sh,保证环境可以从零重建; - 生成一份 JSON 格式的功能清单,每一项包含描述、验收标准、
passes: false。
第二步:单特性会话。 每个后续会话只做一个特性:
- 开头先读进度文件和
git log; - 先跑一遍端到端基线测试,确认起点是绿的;
- 实现一个特性;
- 跑验收;
- 更新
passes; - 提交。
第三步:会话之间不共享上下文。 只共享文件和 git 历史。
为什么有效:它把”一个很长的任务”变成了”很多个短任务 + 一个外部状态”。短任务不会触发上下文腐化;外部状态不会因为压缩而丢失;passes 字段是默认失败的,模型没法靠”我觉得做完了”蒙混过关。
代价:需要预先设计功能清单,而设计清单本身需要人参与。清单粒度太粗会退化成一个大任务,太细会碎片化。
图 10:长程任务的运行闭环
flowchart TD
I["初始化会话
建环境 · init.sh · feature list"] --> S["单特性会话
读 PROGRESS.md + git log"]
S --> B["先跑基线
确认起点是绿的"]
B --> W["实现一个特性"]
W --> V{"独立评估者
证据门禁"}
V -- 不通过 --> W
V -- 通过 --> P["更新 passes:true
git 提交"]
P --> K{"还有未完成特性?"}
K -- 是 --> S
K -- 否 --> H["人工验收 / 发布"]
S -.-> WD["看门狗
步数 · 重复动作 · 无进展 · 预算"]
WD -.-> S
读图要点:这个闭环的关键是”会话之间不共享上下文,只共享文件与 git”。 每一轮都从一个干净窗口开始,所以不会触发起始的上下文腐化;状态存在 feature list 和 git log 里,所以不会被压缩丢掉;passes 默认是 false,所以模型没法靠”我觉得做完了”过关。三个设计分别对应三种退化机制。
4.5 解法 B:独立验证
默认失败:所有检查项初始为未通过,只有证据能让它变成通过。
评估者只读:评估 Agent 用全新上下文,只有读权限,看不到实现者的推理过程,只看产物和验收标准。这一条很关键——如果评估者能看到”实现者说他已经修好了”,它会被锚定。
证据门禁:不是”跑一下测试”,而是”必须留下测试输出的原文、退出码、时间戳”。没有证据的通过不算通过。
反作弊:测试文件不可写;断言不可修改;关键测试用隐藏版本;检查是否删除了失败的用例。
anthropics/cwc-long-running-agents 这个仓库把上述做法做成了一个最小示例:契约文件默认失败、证据门禁钩子、无写权限的新上下文评估者、PROGRESS.md、停止时自动提交、kill-switch、STEER.md(B 级,仓库可访问,未逐行读)。
4.6 解法 C:状态与恢复
git 作为状态平面:每个有意义的步骤一个提交。好处是可回滚、可 diff、可审计,而且模型自己就会用。
检查点:在工具调用之间保存状态。注意不是保存”消息历史”,而是保存”结构化状态”——当前目标、已完成项、待办、关键产物路径。
幂等:所有写操作带幂等键。重放时先查是否已执行。
恢复后重验:恢复不是简单接着跑。外部世界可能变了,文件可能被改过,服务可能重启了。恢复的第一步应该是重新检查前提条件。
4.7 解法 D:监督与熔断
看门狗:监控四类信号——步数、重复动作、无进展轮数、资源消耗。任一超阈值就介入。
kill switch:一个外部文件或信号,harness 每轮检查一次。人发现不对时可以立刻停。
steering 文件:人可以在不打断 Agent 的情况下,往一个文件里写”改做 X”。Agent 每轮读这个文件。这比”停止再重启”温和得多。
预算:token、时间、金钱三个维度都要有上限,而且要按子任务分配,不能只有一个全局上限。
4.8 解法 E:训练侧
如果有训练资源,可以改变模型本身的长程行为。
- 可验证终态奖励:只奖励终态正确的轨迹,不奖励”看起来合理”。
- 分组无 critic 的 RL:同一任务采样多条轨迹,组内比较,省掉价值网络。
- 步级信用分配:长轨迹里稀疏奖励没法用,需要把奖励分摊到关键步骤。
- 视野课程:从短任务开始,逐步加长。AgentGym-RL 这类工作就是这个思路。
- 训练与推理一致:训练时用的上下文管理方式要和推理时一致,否则学到的策略在部署时失效。
训练侧的优点是能改变模型的下限,缺点是成本高、周期长、容易 reward hacking。
4.9 五种解法的优缺点
| 解法 | 优点 | 缺点 | 何时用 |
|---|---|---|---|
| 任务结构(initializer + feature list) | 见效快、可解释、不依赖模型 | 需要人工设计清单;不适合探索型任务 | 有明确交付物的工程任务 |
| 独立验证 | 直接解决”过早完成”;可自动化 | 需要可执行的验收标准;评估本身可能错 | 所有有 oracle 的任务 |
| 状态与恢复 | 抗崩溃;可回滚 | 幂等难保证;恢复要重验 | 长时、可中断的任务 |
| 监督与熔断 | 成本可控;可人工介入 | 阈值难调;误杀 | 所有生产环境 |
| 训练侧 | 提升模型下限 | 贵、慢、易过拟合 | 有数据和算力的团队 |
4.10 组合建议
一个可用的最小组合是:feature list + 独立评估者 + git 检查点 + 三档预算 + kill switch。这五件事加起来大约两周工作量,能覆盖 80% 的长程失败。
再往上加的是:周期性重规划、steering 文件、子任务上下文隔离、训练侧优化。
4.11 一个长程任务的完整时间线
抽象原则放在时间线上更容易理解。假设任务是”给一个已有服务加多租户支持”,预计三天。
第 0 天,初始化会话。 不写业务代码,只做四件事:建工作目录、装依赖、跑通一次端到端基线、生成功能清单。清单大约 12 项,每项带验收标准,passes 全为 false。最后做一次初始提交,并写 PROGRESS.md,记录”环境如何重建””基线命令是什么”。这一天的产出不是代码,是”后面所有会话的起点”。
第 1 天,第 1–3 个会话。 每个会话开头读 PROGRESS.md 和 git log,跑一次基线确认是绿的,然后只做一个特性。做完更新 passes,提交。三个会话结束,清单通过 3/12。
第 2 天上午,第 4 个会话。 出问题了:实现第 4 项时发现它依赖第 2 项的接口,而第 2 项的接口设计得不合适。这时候有两种做法——改第 2 项,或者给第 4 项加一层适配。Agent 倾向于加适配层,因为它不想动已经”通过”的东西。但这会留下技术债。
解法是:在功能清单里显式允许”重构项”,并规定”如果为了完成新特性需要改已通过的接口,必须新开一个会话专门做重构,且重构后要重跑所有已通过项的验收”。这条规则把”偷偷加适配层”变成了”显式重构”。
第 2 天下午,第 5–6 个会话。 单个会话跑到 40 多步时,出现了典型的压缩悬崖:Agent 忘了”公共接口不许改”这条约束,直接把一个方法签名改了。独立评估者发现回归测试挂了,打回。
解法是两条:把”不许改公共接口”放进每次压缩后重注入的约束块;在评估者的检查项里加一条”公共 API 的签名 diff 必须为空”。
第 3 天上午,第 7–9 个会话。 剩下的小项推进顺利。这里出现另一个问题:Agent 开始”顺手优化”——看到一段旧代码不优雅就改了。这类改动没有验收标准,评估者也不检查,属于隐性风险。
解法是加一条规则:任何不在功能清单里的改动,必须单独提交并在 PROGRESS.md 里说明理由,由人决定是否保留。
第 3 天下午,人工验收。 发现 2 个标记 passes: true 的项其实不满足需求。原因是验收脚本写得太宽松,只检查了”接口存在”,没检查”行为正确”。
这条最值得记住:**passes 的可信度等于验收脚本的严格度。** 脚本松,清单就是自欺欺人。所以初始化阶段最该花时间的不是拆功能,是写验收。
三天下来,真正起作用的不是模型能力,是六条机制:初始化会话、单特性会话、显式重构规则、约束重注入、独立评估者、人工验收。这六条加起来,工作量不到两周,但能把长程任务从”碰运气”变成”可管理”。
4.12 《Effective harnesses for long-running agents》:长程任务的具体配方
这是第 4 章的主要来源,但原文的操作细节比我当时概括的更具体,值得单独列出。
两部分方案。 一个初始化智能体只在第一个会话运行,用专门的提示;之后每个会话由编码智能体接手,每次只推进一点,并留下结构化更新。原文的脚注强调,这两个”智能体”之所以分开,只是因为第一条用户提示不同——系统提示、工具、harness 完全一样。这点很重要:不要把它理解成两套系统。
初始化阶段产出三样东西: 一个 init.sh(让后续会话不必每次重新摸索怎么启动应用)、一个 claude-progress.txt(每个会话做了什么的日志)、一个初始 git 提交(列出添加的文件)。
功能清单是核心。 原文把用户的一句话需求展开成详细的功能清单,在 claude.ai 克隆这个例子里超过 200 个条目。每个条目有类别、描述、测试步骤,并且全部以 "passes": false 开头。格式选了 JSON,理由写得很直接:模型”不太会不恰当地修改或覆盖 JSON 文件”,比 Markdown 稳。规则是智能体只能改 passes 字段,提示措辞很重:”删除或编辑测试是不可接受的”。
每个会话只做一个功能。 这是为了对抗”一次想做太多”的倾向。会话结束时,环境应处于”干净状态”,即代码可以合入主分支。
每个会话的开场流程有四步:先 pwd 确认位置;读 git 日志和进度文件;读功能清单,挑最高优先级的未完成项;运行 init.sh 启动开发服务器,并做一次基本的端到端检查,再开始新工作。
测试的教训。 不加提示时,模型会跑单元测试或 curl,但仍会在功能并未端到端可用时就把它标为完成。修法是提示它用浏览器自动化(Puppeteer MCP)像真人用户那样测试,明显提升了发现 bug 的能力。局限也写了:Puppeteer 看不到浏览器原生的弹窗,依赖弹窗的功能 bug 更多。
原文还给了一张四行的失败—修复表,我转述如下:
| 问题 | 初始化阶段的对策 | 后续会话的对策 |
|---|---|---|
| 过早宣布完成 | 建 JSON 功能清单 | 开场读清单,只选一个功能做 |
| 留下 bug 或未记录的进展 | 建 git 仓库与进度笔记 | 读笔记和日志,先跑基本测试,结束时提交并更新进度 |
| 过早把功能标成通过 | 建功能清单 | 自测,仔细测过才标通过 |
| 浪费时间弄清怎么运行应用 | 写 init.sh |
开场读 init.sh |
可迁移性判断。 这套配方的内核是”把状态外置到文件,把完成标准写成机器可检查的字段“,这与领域无关,可以迁移。但文章末尾自己列了两个开放问题:单个通用智能体和多智能体(测试、QA、清理)哪个更好;这套做法能否推广到 Web 开发以外,比如科研或金融建模。也就是说,作者自己没有声称它普适。 你迁移时,要自己确认两点:任务能否被拆成可独立验证的功能项;验证手段是否在你的领域里存在。
5 多智能体与 Workflow 选型
先回答“该不该用 Agent”,再回答“该不该用多个 Agent”。前半章是 Workflow 与 Agent 的选型框架,后半章是多智能体的拓扑、失败模式、协议与代价。
5.1 两个词的区分
文章把二者统称为”智能体系统(agentic systems)”,然后划出架构上的区别:
Workflow(工作流):LLM 和工具由预先写好的代码路径编排。流程是人定的,模型只在节点里干活。
Agent(智能体):LLM 动态地指挥自己的流程和工具使用。流程是模型决定的。
基础构件都是”增强型 LLM”:带检索、工具和记忆的模型。
这个区分的实用价值在于,它把”要不要自主性”变成了一个可以讨论的设计选择,而不是默认选项。
5.2 五种工作流模式
文章列出五种常见模式,它们按”自主性从低到高”排列:
| 模式 | 做法 | 典型场景 | 代价 |
|---|---|---|---|
| 提示链 | 把任务拆成顺序步骤,步骤间可加程序化检查 | 先写文案再翻译 | 牺牲速度换准确 |
| 路由 | 先分类,再交给专门的下游处理 | 简单问题给小模型,难题给强模型 | 分类错了全盘错 |
| 并行化 | 分段(独立子任务同时跑)或投票(同一任务多次) | 一路回答、一路审核;多提示审代码漏洞 | 成本线性增加 |
| 编排者—工作者 | 中央模型拆解、委派、汇总,子任务不预先确定 | 多文件代码修改 | 编排者成为瓶颈 |
| 评估者—优化者 | 一个生成,一个批评,循环 | 需要反复打磨的翻译 | 需要清晰的评判标准 |
这五种里,前三种的流程基本固定,第四种开始出现动态拆解,第五种引入循环。注意第五种对应的就是 Self-Refine 与独立验证的组合:评估者最好不是生成者本人。
5.3 什么时候才用 Agent
文章对智能体的描述是:”通常只是 LLM 基于环境反馈在循环里使用工具。” 它给出的适用条件很克制:开放式问题、步骤无法预测或写死、环境可信。代价明确写出来了:更高成本和”复合错误”,所以建议先在沙箱里测试并加护栏。
更关键的一句是原则性的:找到”最简单的可行方案”,只有在复杂度确实改善结果时才增加复杂度。 对很多应用,把单次 LLM 调用配上检索和示例就足够了。
文章还有一条常被忽略的建议:框架能帮你起步,但会遮蔽提示和响应;先用直接的 API 调用,理解框架底层再用。这和第 8.17 节”循环自建,工具和评测用现成的”同方向。
5.4 一个决策流程
综合文章、Agentless 的结果和第 5.9 节的四个判据,我整理了下面的流程。它不是文章里的原图,是我的归纳。
图 11:Workflow 与 Agent 的选型流程
flowchart TD
S["新任务"] --> Q1{"步骤能提前写死吗?"}
Q1 -- 能 --> W1["用 Workflow
提示链 / 路由 / 并行"]
Q1 -- 不能 --> Q2{"环境能给出可靠反馈吗?
测试、状态检查、类型系统"}
Q2 -- 不能 --> W2["先补反馈
否则 Agent 只会放大错误"]
Q2 -- 能 --> Q3{"错误代价可控吗?
沙箱、可回滚、有预算"}
Q3 -- 不能 --> W3["保留人工确认点
或降级为 Workflow"]
Q3 -- 能 --> A1["用单 Agent 循环"]
A1 --> Q4{"单 Agent 在评测集上
已到瓶颈?"}
Q4 -- 否 --> A1
Q4 -- 是 --> M1["再评估多 Agent
见第 5.9 节四判据"]
读图要点:第二个菱形最容易被跳过。 很多团队的 Agent 项目失败,不是因为模型不够强,而是环境给不出可靠反馈——没有测试、没有状态检查,Agent 就只能靠自评,而第 1.6 节已经说过自评的局限。
5.5 Agentless 给出的反问
用这套框架再看 Agentless,结论很清楚。SWE-bench Lite 的任务是”修一个有明确描述的 bug”,定位—修复—验证的流程可以事先写死,环境(测试)又能给出可靠反馈。这恰好是 Workflow 的舒适区。32.00% 的解决率和 0.70 美元的成本,说明在这种条件下,把自主性收回来,既便宜又不差。
反过来,当任务是”调研一个开放问题”或”在不熟悉的代码库里实现一个新功能”,步骤无法预先写死,这时才轮到 Agent 登场。所以不是 Agent 比 Workflow 高级,而是它们对应不同的任务结构。
5.6 混合形态才是常态
真实系统很少纯粹。常见的混合有三种:
外层 Workflow,内层 Agent。 例如客服:外层路由决定问题类别,类别内部由 Agent 自由调用工具。这样自主性被限制在可控范围里。
外层 Agent,内层 Workflow。 例如研究助手:Agent 决定查什么,但”查一篇论文并提取指标”这一步被固化成流水线,保证输出格式稳定。
Agent 带检查点。 在关键动作前(付款、删除、发送)强制人工确认,其余自由运行。这是第 8 章权限矩阵的落地形式。
5.7 对评测的含义
选型不同,评测重点也不同。Workflow 可以逐节点评测,每个节点是一个小任务,失败定位容易。Agent 只能评测轨迹和结果,需要第 7 章的五层评测加上 pass^k。如果你的评测体系只能做端到端,那它天然偏向 Workflow——不是 Agent 不好,而是你看不见它在哪一步坏了。
5.8 先分清纵向和横向
这是最容易被混淆的地方,值得单独说清楚。
纵向(父子 / 编排者—worker):一个任务被拆解,父 Agent 派生若干子 Agent,共享同一个目标和验证器。它解决的是”一个任务怎么拆给多个执行者干完”。
横向(同层 / 跨团队):地位对等的 Agent 之间通信。可以是同一个 harness 里的 peer(比如评审团),也可以是不同团队、不同 harness 的 Agent 互调(比如 A2A 协议)。
这两类问题的证据强度差别很大。纵向有大量可比较的数字:MAST 的 1600+ 条失败轨迹、Google 的错误放大倍数、Anthropic 的 C 编译器项目、Cursor 的分层扩展。横向基本只有协议规范和产品机制,没有公开的对照评测。
结论:讨论”多智能体”时,先问是哪一种。绝大多数工程问题在纵向,绝大多数标准化工作在横向。
5.9 什么时候值得用多 Agent
四个判据,全部满足才考虑:
- 可分解:任务能切成若干个几乎独立的子任务,子任务之间不需要频繁交换状态。
- 读多写少:子任务主要是检索、分析、生成,而不是修改同一份共享状态。
- 可独立验证:每个子任务有自己的验收标准,不需要全局判断。
- 上下文确实放不下:单 Agent 的上下文装不下所有材料。如果装得下,压缩就够了。
反过来的信号:任务有强顺序依赖、需要全局一致性、子任务之间要反复协商、共享同一份可写文件。这些情况下,多 Agent 的协调成本会超过收益。
图 12:要不要上多 Agent
flowchart TD
Q["任务"] --> A{"能拆成
近似独立的子任务?"}
A -- 否 --> S["单 Agent + 压缩"]
A -- 是 --> B{"子任务读多写少?"}
B -- 否 --> S
B -- 是 --> C{"每个子任务
可独立验证?"}
C -- 否 --> S
C -- 是 --> D{"单窗口确实
装不下?"}
D -- 否 --> S
D -- 是 --> M["多 Agent"]
M --> T1["编排者 + 并行只读子 Agent"]
M --> T2["分层 planner / worker"]
M --> T3["git 状态平面 + 任务锁"]
读图要点:四道门,任何一道答”否”都退回单 Agent。 这个顺序不是随便排的——可分解性决定上限,读写比决定冲突,可验证性决定能不能自动纠错,容量决定必要性。跳过前三道直接问”装不装得下”,就会做出那种”拆了但合不回来”的系统。
5.10 拓扑谱系
| 拓扑 | 结构 | 证据 | 适用 |
|---|---|---|---|
| 单 Agent + 压缩 | 一个循环 | 最成熟 | 顺序、强耦合 |
| 编排者 + 并行只读子 Agent | 一个 lead 派发,回收结论 | Anthropic 研究系统:比单 Agent 高 90.2%,token 约 15 倍(C 级) | 广度检索、调研 |
| 递归 planner / worker | 多层分解 | Cursor:扁平锁下 20 个 Agent 只等效 1–3 个,分层后扩到数百(C 级) | 大规模代码库 |
| git 状态平面 + 任务锁 | 共享仓库,原子认领 | Anthropic C 编译器:约 2000 会话、约 2 万美元(C 级) | 文件级独立任务 |
| 对等消息 | Agent 之间直接通信 | Claude Code agent teams | 评审、竞争式排查 |
| 独立并行投票 | 无通信,取多数 | 错误放大约 17 倍(B 级) | 几乎不适用 |
| 单 Agent 多角色 | 同一上下文里切换角色 | MetaGPT / ChatDev 类 | 轻量流程模拟 |
一个反直觉的结论:并行度不是越高越好。 扁平锁在 20 个 Agent 时吞吐就崩了,因为锁竞争。分层之后才扩得上去。这说明多 Agent 的真正瓶颈往往在协调机制,不在 Agent 数量。
5.11 失败模式
MAST 把多 Agent 系统的失败归纳为 14 种,可以压成五组:
规格与目标:任务描述不清、验收标准不一致、子任务目标冲突。
协调:信息没有传递、传递了错误信息、重复劳动、互相等待。
验证:没人检查、检查者被实现者影响、局部正确但全局错误。
状态:共享状态被并发修改、状态过期、回滚不彻底。
资源:成本失控、超时、上下文爆炸。
这五组里,协调和验证占了大多数。这意味着多 Agent 的工程重点不是”怎么让 Agent 更聪明”,而是”怎么让交接可靠”。
5.12 协调原语
git:最好的状态平面。天然支持分支隔离、diff、回滚、审计。缺点是合并冲突需要人处理。
任务锁:在仓库里放一个 tasks/xxx.lock 文件,原子创建表示认领。简单有效,但要注意锁的过期与清理。
worktree:每个 Agent 一个独立工作目录,共享同一个 git 历史。CAID 用的就是这个,报告 PaperBench +25.6%、Commit0 +14.7%(B 级)。
邮箱:每个 Agent 一个收件箱,消息放在上下文之外,按需拉取。好处是不占上下文,坏处是延迟。
黑板:共享的只追加日志,所有 Agent 都能读。适合广播状态,不适合细粒度协调。
消息总线:Temporal、Ray 这类。提供重试、持久化、顺序保证,但引入运维复杂度。
5.13 成本模型
多 Agent 的成本不是线性的,有三个放大器:
- 上下文复制:每个子 Agent 都要一份任务说明和工具定义。n 个子 Agent 就是 n 份。
- 协调往返:每次交接都要一次模型调用,交接越多越贵。
- 失败重试:子 Agent 失败要重跑,而重跑会重复前两步。
Anthropic 的研究系统报告 token 约为普通对话的 15 倍(C 级),这个量级可以作为预算起点。如果你的任务不能承受 10 倍以上的成本,就不要上多 Agent。
5.14 优缺点矩阵
| 方案 | 质量 | 成本 | 延迟 | 可调试性 | 适用规模 |
|---|---|---|---|---|---|
| 单 Agent | 中 | 低 | 低 | 高 | 任意 |
| 编排者 + 并行 | 高(可分解任务) | 高 | 中 | 中 | 中等 |
| 分层 planner/worker | 高 | 很高 | 高 | 低 | 大规模 |
| 对等消息 | 中 | 中 | 中 | 低 | 小团队 |
| 独立并行投票 | 低 | 高 | 低 | 高 | 不推荐 |
5.15 不该用多 Agent 的信号
- 单 Agent 加压缩已经能完成任务。
- 任务的主要难点是”想清楚”,不是”做得多”。分解不会让思考变清楚。
- 子任务之间需要频繁交换中间状态。
- 团队还没有可靠的单 Agent 评测。多 Agent 会让评测更难,而不是更容易。
- 预算敏感。
最后一条尤其重要:多 Agent 是放大器,不是修复器。 单 Agent 的评测做不好,多 Agent 只会让你更不知道自己错在哪。
5.16 早期框架:AutoGen 与 MetaGPT
5.16.1 AutoGen:把”对话”当作编排原语
AutoGen(arXiv 2308.08155,Wu 等,2023 年 8 月)的摘要说它是一个开源框架,开发者可以用多个相互对话的智能体构建 LLM 应用;智能体”可定制、可对话”,能混合 LLM、人类输入和工具;交互模式可以用自然语言或代码来编程。覆盖的领域包括数学、编程、问答、运筹、在线决策和娱乐。摘要没有给定量结果。
这里的设计选择是:让”对话”成为一切协作的底层抽象。 优点是灵活、容易上手;缺点是对话是非结构化的,状态、预算、终止条件都得靠约定。第 5.11 节 MAST 里很多失败模式(任务偏离、重复、终止条件缺失)都与此相关。
5.16.2 MetaGPT:把人类的 SOP 搬进提示
MetaGPT(arXiv 2308.00352,Hong 等,2023 年 8 月)盯的是另一个问题:简单地把 LLM 串起来会产生”级联幻觉”,导致逻辑不一致。它的做法是把标准作业程序(SOP)编码进提示序列,用”装配线”范式给不同智能体分配不同角色,每个角色检查中间产物,从而减少错误。摘要称在协作式软件工程基准上,它比此前基于聊天的多智能体系统产出更连贯的方案,同样没有给定量结果。
MetaGPT 的价值是方法论:用结构化的中间产物(需求文档、设计、接口说明)代替自由对话。 这与第 5.12 节”协调原语”里”共享产物优于消息”的结论一致,也与第 8 章的”任务接口三段分离”思路相通。
5.16.3 两个早期框架的共同局限
我的判断是,这两个框架在当时的意义是证明多智能体可以做,而不是证明应该做。它们的摘要都以”效果”为主,没有成本对比,也没有和强力单智能体基线的对比。这正是后来 MAST 和 agent-scaling 两项研究要补的课。
5.17 协议层:MCP 与 A2A 各管什么
协议是第 5.8 节”横向”那一层的主体。官方资料给出的定位是:
MCP:连接 AI 应用与外部系统(数据、工具、工作流)的开放标准。关系是”应用 ↔ 外部能力”。
A2A(Agent2Agent):让不同框架、不同公司、部署在不同服务器上的”不透明”智能体应用互操作的开放协议。能力发现靠 Agent Card,传输基于 HTTP 上的 JSON-RPC 2.0,支持同步请求、SSE 流式和异步推送通知,并且设计时考虑了安全、认证与可观测。项目在 Linux Foundation 下,Apache 2.0 许可,官方页面明确说它是对 MCP 的补充,关系是”智能体 ↔ 智能体”。
| 维度 | MCP | A2A |
|---|---|---|
| 连接对象 | 应用与工具/数据 | 智能体与智能体 |
| 对方是否透明 | 是,工具的 schema 公开 | 否,对方内部状态、记忆、工具不暴露 |
| 典型交互 | 调用、读取 | 委托长任务、协商、回传产物 |
| 解决的问题 | 集成成本 | 跨组织、跨框架的互通 |
一个必须说清楚的现实:这两份协议文档说的是”怎么连”,不是”连了之后协作得好不好”。第 5.8 节说过,横向互通的证据很弱——协议能保证消息送达,不能保证对方做对。所以在你的方案里,A2A 这类协议属于”基础设施选型”,不应该被当成”多智能体能力”的证明。
5.18 代价的量化证据
下面的图只画我这一轮在摘要里亲自核到的数字。
图 13:多智能体相对单智能体的表现变化
读图要点:Towards a Science of Scaling Agent Systems(2512.08296)摘要报告,在 260 种配置、6 个基准、5 种架构、3 个模型家族上,**多智能体相对单智能体的变化从可分解金融推理的 +80.8% 到顺序规划的 −70.0%**,基线是单智能体。同一摘要还说,没有集中式验证的架构比有集中协调的更容易传播错误;论文用一个框架预测最优架构,在 87% 的留出配置上选对。
必须交代一处核对结果: 第零章第 5 条和第 5.10 节的表格引用了”独立并行约放大 17 倍、集中式约 4.4 倍”,并标为 B 级。这一轮我重新读了该论文摘要,摘要里没有这两个倍数,只有上面的 +80.8% 到 −70.0% 的范围和”无集中验证更易传播错误”的定性结论。倍数可能出自论文正文,也可能是转述有出入,我没有读到正文,无法确认。所以请把这两个倍数当作”方向正确、数值待回查正文”使用,写进方案前先回查;上图只画摘要里确实写出的数字。
这组数字比倍数更有用,因为它说的是任务结构决定输赢:同一套多智能体,在能分解的任务上大赚,在必须按顺序一步步推理的任务上大亏。这和第 5.9 节”可并行、读多写少”的判据完全同向。再叠加第 5.13 节的成本(多智能体系统的 token 量约为单对话的 15 倍,来自 Anthropic 的工程报告),可以得出一个朴素的账:多 Agent 的收益必须大于成本放大,且任务得是可分解的。
5.19 两个案例的拆解
案例一:用 16 个并行 Agent 写一个 C 编译器。 Anthropic 的公开实验,约 2000 次会话、约 2 万美元成本(C 级)。做法是:把编译器拆成前端、后端、优化器等独立模块;每个 Agent 在自己的 worktree 里工作;用 git 分支和任务锁协调;用 GCC 作为对照 oracle 做差分测试。
这个案例能成立,有三个前提缺一不可。第一,有 oracle:编译器对不对,跑测试就知道,不需要人判断。第二,可分解:模块之间的接口可以先定死,之后各自实现。第三,成本可承受:2 万美元换一个编译器,账算得过来。
如果换成一个”写一份市场分析报告”的任务,这三个前提全部不成立——没有 oracle,模块之间强耦合,而且没人愿意花 2 万美元。所以这个案例不能直接复制,只能借鉴结构。
案例二:Cursor 从扁平锁到分层。 他们最初让多个 Agent 共享一个任务队列,用文件锁做原子认领。结果是:20 个 Agent 的吞吐只相当于 1–3 个(C 级)。原因不是模型慢,是锁竞争——Agent 大部分时间在等锁。改成 planner → sub-planner → worker 三层之后,每个 worker 的任务由上层预先划分,几乎不需要竞争,才扩展到数百个。
这个案例的教训是:多 Agent 的瓶颈经常在协调机制,不在 Agent 本身。 增加 Agent 数量之前,先问”它们会不会抢同一个资源”。如果会,先改协调结构,而不是加机器。
两个案例放在一起看,能得出一张判断表:
| 条件 | 适合并行 | 不适合并行 |
|---|---|---|
| 验证 | 有确定性 oracle | 靠人判断 |
| 耦合 | 接口可预先定死 | 需要频繁协商 |
| 写入 | 各写各的文件 | 共享同一份状态 |
| 成本 | 收益能覆盖 n 倍成本 | 预算敏感 |
四条里有一条不满足,就应该退回单 Agent 加压缩。
5.20 《How we built our multi-agent research system》:数字与教训
这是第 5 章的主要来源。精读后值得保留的信息有四组。
架构。 编排者—工作者模式:LeadResearcher 先规划,把计划存进记忆(因为上下文超过 20 万 token 会被截断),再派生子智能体并行搜索;子智能体用交错思考判断工具结果后回报;最后由 CitationAgent 处理文档和报告,确定引用应放在哪里。原文强调它不同于静态 RAG:它是随发现而调整的多步搜索。
成绩。 以 Opus 4 作主导、Sonnet 4 作子智能体的组合,在内部研究评测上比单智能体 Opus 4 高 90.2%。在 BrowseComp 上,三个因素解释了 95% 的方差,其中 token 用量单独解释 80%,另两个是工具调用数和模型选择。并行化把复杂查询的研究时间最多缩短 90%。
成本。 智能体比聊天多用约 4 倍 token,多智能体系统约 15 倍。所以文章明确说只在高价值任务上才经济,并把”带共享上下文或大量依赖的编码类任务”列为不合适的场景。
八条提示原则里我认为最有迁移价值的是三条:一是教编排者怎么委派(目标、输出格式、工具指引、任务边界);二是按复杂度配置投入(简单事实一个智能体 3 到 10 次调用,比较类 2 到 4 个子智能体,复杂研究 10 个以上);三是”像你的智能体一样思考”,也就是自己一步步模拟它的行为来发现问题。早期失败也很典型:对简单查询派生 50 个子智能体,偏爱 SEO 内容农场的来源。
评测方法。 原文建议立刻用小样本开始,约 20 条查询就够,因为早期提示改动可以把成功率从 30% 拉到 80%。评分用单次 LLM 调用、一个提示,输出 0.0 到 1.0 的分数加通过/不通过,细则覆盖事实准确、引用准确、完整性、来源质量、工具效率。人工测试仍能抓到边缘情况,例如来源选择偏差。对会改状态的智能体,评终态而不是每一轮。
生产挑战。 智能体有状态,错误会累积,所以他们从失败点恢复而不是重头来,并把重试、检查点与模型自身的适应能力结合;调试需要完整的生产追踪,但只监控决策模式、不读对话内容;部署用”彩虹部署”逐步切换流量,不打断正在运行的智能体;同步执行是瓶颈,异步能增加并行但会带来协调与一致性问题。
可迁移性判断。 90.2% 是 Anthropic 内部评测上的自报数字(C 级),而且它比较的是”强模型主导的多智能体”对”单个强模型”,不是对”一个做了充分上下文工程的单智能体”。把它当作”在可并行的读多写少任务上有上限提升”的存在性证据,而不是你的预期收益。
6 长期记忆
记忆不是“存了就有”。本章按四种记忆、存储介质、代表系统、经验与技能、写入策略、评测与失败模式的顺序展开,并把 LongMemEval 等实证放在对应位置。
6.1 四种记忆,用途完全不同
借认知科学的分类,但按工程含义重新定义:
工作记忆:当前任务的状态。等价于上下文窗口加结构化状态对象。生命周期是一个任务。
情景记忆:具体发生过什么。”上周处理过一起类似的退款纠纷,当时的处理方式是 X。”按事件索引。
语义记忆:抽象出的事实和规则。”这个系统的时区是 UTC+8””这个客户不接受部分退款。”按实体或主题索引。
程序性记忆:怎么做一件事。技能、脚本、操作流程。这是最能改变行为的一类,也是最危险的一类。
绝大多数”记忆系统”只做了情景和语义,程序性记忆往往被忽略。但从改进行为的角度,程序性记忆价值最高——它把”知道”变成”会做”。
6.2 存储介质谱系
| 介质 | 例子 | 优点 | 缺点 |
|---|---|---|---|
| 上下文内 | CLAUDE.md、core memory | 零延迟、模型一定能看到 | 占窗口、容量小 |
| 纯文本文件 | notes.md、技能目录 | 可读可编辑、可版本控制 | 需要模型主动检索 |
| 向量库 | Mem0 一类 | 模糊检索强 | 召回不准、不可解释 |
| 知识图谱 | Zep / Graphiti | 关系推理、时间有效性 | 构建贵、schema 难设计 |
| 参数 | 微调、LoRA、测试时训练 | 零推理开销、内化 | 不可检查、会遗忘、更新贵 |
选择介质的原则:能放文件就不要放向量,能放向量就不要放参数。 因为可检查性依次递减,而可检查性是调试记忆问题的唯一抓手。
6.3 系统对比
| 系统 | 核心机制 | 适合 | 注意 |
|---|---|---|---|
| MemGPT / Letta | 分层内存,模型自己管理换入换出 | 长对话、有状态助手 | 依赖模型正确调用内存工具 |
| Mem0 | 抽取事实存向量库,自动去重 | 个性化、用户画像 | 抽取会丢上下文;榜单成绩来自托管版 |
| Zep / Graphiti | 时间知识图谱,事实带有效期 | 事实会变化的关系型场景 | 构图成本高 |
| A-MEM | 记忆之间自动建链 | 需要关联回忆 | 链路质量难评估 |
| MemoryOS | 分层加热度淘汰 | 长周期助手 | 淘汰策略需调参 |
| MIRIX | 多类型记忆分模块 | 复杂助手 | 组件多、调试难 |
| LangMem | 与 LangGraph 集成 | 已在 LangChain 栈上 | 能力偏基础 |
一个重要的方法论提醒:这些系统的公开成绩高度不可比。Mem0 和 Zep 曾互相质疑对方在 LoCoMo 上的数字,双方都是竞争方,结论都要打折(B 级)。更可靠的做法是自己构造留出任务,和两个基线比:全上下文(把所有历史都塞进去)和 文件 + grep。如果记忆系统赢不了这两个基线,它就没有存在价值。
Letta 的报告里,”文件 + grep”在 LoCoMo 上能到 74.0%(C 级)。这个数字说明:很多记忆系统的收益,其实来自”把信息存到外部然后检索”这个朴素做法,而不是复杂的图结构。
6.4 经验与技能:记忆里最有价值的部分
Voyager:在 Minecraft 里把成功的行为固化成可执行技能,带描述和代码。技能库可以复用、组合。
ExpeL:从成功和失败轨迹里抽取自然语言经验,存成规则库,推理时检索。
Agent Workflow Memory:把重复出现的操作序列抽象成工作流,Mind2Web 相对提升 24.6%,WebArena 提升 51.1%(C 级)。
ReasoningBank:从成功和失败中都提炼策略,带适用条件。
Memento / Memento-Skills:技能写入有测试门禁,可回滚。这是把”记忆”和”验证”结合得最好的做法。
ACE:维护一个 playbook,用 Generator / Reflector / Curator 三个角色增量更新,避免整体重写导致的上下文塌缩。
这些工作的共同模式是:经历 → 反思 → 规则 → 技能。每一步都比上一步更抽象、更可复用,也更需要验证。
图 14:记忆的沉淀流水线
flowchart LR
E["原始经历
轨迹 / 日志"] --> R["反思
成功与失败都读"]
R --> I["洞察
带证据"]
I --> RU["规则
适用条件 + 反例"]
RU --> G{"验证门禁
后续任务表现"}
G -- 通过 --> SK["技能
可执行 · 带版本"]
G -- 不通过 --> X["丢弃 / 回滚"]
SK --> LIB["记忆库
文件 + 索引"]
LIB --> E
读图要点:每一层都比上一层更抽象,也更需要验证。 直接写”技能”是最危险的,因为它会被无条件执行;先落到”规则”并绑定反例,再经过门禁,才允许升级为技能。中间那道”不通过就丢弃”的边最重要——没有它,记忆库会变成错误经验的垃圾场。
6.5 参数化记忆
把记忆写进权重,是一条更激进的路。
- Titans:把记忆模块作为网络的一部分,在推理时更新。
- Nested Learning:多层嵌套的学习结构,不同时间尺度更新。
- SEAL:让模型自己生成微调数据并更新自己。
优点是推理时零额外开销,记忆真正”内化”。缺点很致命:不可检查、不可编辑、会灾难性遗忘、更新成本高。目前这条线还在研究阶段,不建议用于生产。
6.6 写入策略:写时抽取 vs 读时检索
写时抽取:发生时就总结成一条事实存起来。优点是存储小、检索快。缺点是在信息不全的时候做判断,容易丢关键上下文。
读时检索:存原始记录,需要时检索原文。优点是不丢信息。缺点是存储大、检索慢、需要模型自己判断相关性。
折中方案是两层:原始日志全量存(便宜介质,比如文件),抽取后的索引存一份(便于检索)。检索时先查索引,命中后回到原文。
6.7 评测与争议
基准:LoCoMo(长对话记忆)、LongMemEval(多类型记忆任务)、MemoryAgentBench、MemBench。
争议一:题目质量。 一份 2026 年的审计称 LoCoMo 有 99/1540 题有错(约 6.4%),且 LLM 评委放过了大量主题相关但事实错误的答案(B 级)。
争议二:评测设置不可比。 有的系统用检索增强,有的用全上下文,有的用不同模型做评委。分数放在一张表里没有意义。
争议三:记忆的价值被高估。 在很多任务上,”更长的上下文”比”更复杂的记忆系统”效果更好,只是更贵。所以记忆系统的真正卖点应该是成本,不是效果。
6.8 长期记忆为什么难:LongMemEval 的拆法
LongMemEval(arXiv 2410.10813,Wu 等,ICLR 2025)把”记忆能力”拆成五种:信息抽取、多会话推理、时间推理、知识更新、拒答。基准含 500 道精心设计的题,嵌在可以任意拉长的聊天历史里。摘要报告:商业聊天助手和长上下文 LLM 在需要跨持续交互记住信息时,准确率下降约 30%。
它还提出了一个统一框架——索引、检索、阅读三阶段,以及三项优化:把会话分解(决定存储颗粒度)、用事实增强键扩展(改进索引)、做时间感知的查询扩展(缩小检索范围)。摘要称这些改动显著提升了记忆召回和下游问答。
这给了第 6 章的几个判断一份直接证据。第一,”知识更新”和”时间推理”被单独列为能力,说明记忆系统的难点不只是”存”,而是”存了之后事实变了怎么办”。 第 6.11 节的”过期”失败模式就是这一条。第二,三项优化都是工程手段(粒度、索引、查询改写),说明记忆质量很大程度取决于检索流水线的设计,而不是单纯”换更大的向量库”。
6.9 优缺点
优点:跨会话连续;经验可复用;可以把长尾知识从上下文里移出去,降低单次成本。
缺点:写入错误会长期污染;检索错误会误导;不可解释;评测不可靠;增加系统复杂度。
6.10 最小可行记忆系统
如果要从零做一个,我建议这个结构,两周能跑起来:
- 文件层:
memory/目录,按主题分文件,纯 Markdown,git 管理。 - 索引层:每个文件一行摘要,放在
memory/INDEX.md,启动时注入上下文。 - 写入:任务结束时,后台一个反思 Agent 读轨迹,提出增量修改(不是重写整个文件)。
- 门禁:修改必须附带”这条经验来自哪个任务、预期改善什么”,下一轮验证不通过就回滚。
- 检索:先读索引,需要时读全文。不上向量库,除非文件超过几百个。
- 评测:留出 20 个跨会话任务,对比”有记忆”和”无记忆”的成功率与成本。
这个结构不先进,但它可检查、可回滚、可解释,而且能赢过大多数复杂方案。
6.11 记忆的四种失败
记忆系统的 bug 比普通 bug 难查,因为它是”慢性”的。四种典型形态:
失败一:写入固化。 Agent 在某次任务里用了一个非常规做法(比如 sed 直接改配置),恰好成功了,反思器把”遇到配置问题就用 sed”写成规则。之后它在需要结构化校验的场景也这么干,留下了坏数据。
检测方法:给每条记忆加”适用条件”和”反例”,写入时必须填。如果填不出来,说明这条经验还不成熟,不该写。
失败二:检索误导。 检索到一条相似但不同的历史案例,模型照抄了处理方式。比如客户 A 的退款特例被套用到客户 B。
检测方法:检索结果必须带”为什么相似”和”哪里不同”,让模型自己判断,而不是只给一段文本。
失败三:过期。 政策变了,记忆里还是旧规则。这在业务系统里非常常见,而且不会报错。
检测方法:每条记忆带有效期和来源版本;关键规则在启动时从权威系统重新拉取,记忆只做补充,不做唯一来源。
失败四:作用域污染。 A 用户的信息出现在 B 用户的上下文里。这在多租户系统里是严重事故。
检测方法:记忆的读写都带作用域键,检索时强制过滤;写测试用例验证跨租户不可见。
四种失败的共同修法是:记忆条目要有元数据——来源、时间、适用范围、置信度、反例。没有元数据的记忆,本质上就是谣言。
6.12 规划与记忆的朴素分类
Lilian Weng 2023 年 6 月那篇《LLM Powered Autonomous Agents》,是很多人入门时读的第一篇综述。它把 Agent 拆成三个部件:规划(任务分解:思维链、思维树,以及 LLM+P 借助外部规划器;自我反思:ReAct、Reflexion 等)、记忆(把人类的感觉记忆、短期记忆、长期记忆映射到嵌入、上下文学习和外部向量库;检索用近似最近邻如 HNSW、FAISS)、工具使用(MRKL、Toolformer、函数调用、HuggingGPT 等)。它列出的三项挑战是:有限的上下文长度、长程规划与任务分解的困难、自然语言接口的可靠性。
这篇文章今天读起来仍有价值,但要注意它的时代背景:写于 2023 年中,没有涉及长程任务的 harness 设计、独立验证、评测体系。它的三项挑战里,”上下文有限”和”规划困难”至今仍是主问题,”接口可靠性”则被函数调用和结构化输出大幅缓解。拿它做入门没问题,拿它做 2026 年的设计依据就不够了。
7 评测、自进化与训练
评测是整份报告的地基:自进化依赖它,训练也依赖它。本章先讲评测怎么建,再讲自进化(含 DSPy 这个前史),最后讲训练侧与 harness 的分工。
7.1 五个层次
评测不是一个东西,是五个层次,各有各的用途。
| 层次 | 测什么 | 典型方法 | 什么时候用 |
|---|---|---|---|
| L1 组件级 | 单个工具、单段提示、单次检索 | 断言、单元测试、held-out 任务 | 改动局部时 |
| L2 轨迹级 | 过程是否合理 | 步骤有效性、首个上游失败、rubric | 定位失败原因 |
| L3 结果级 | 终态是否正确 | 状态检查、单测、数据库 diff | 判断能不能用 |
| L4 可靠性 | 多次是否一致 | pass^k、方差、失败分布 | 上线前 |
| L5 业务级 | 是否产生价值 | 采纳率、节省时间、成本 | 上线后 |
大多数团队只做 L3,然后困惑于”为什么测试都过了但用户不满意”。因为 L3 不告诉你过程哪里有问题,也不告诉你稳定性。
图 15:评测的五个层次
flowchart BT
L1["L1 组件级
单工具 / 单提示 / 单检索
最便宜 · 最频繁"] --> L2["L2 轨迹级
步骤有效性 · 首个上游失败"]
L2 --> L3["L3 结果级
终态 / 单测 / 数据库 diff"]
L3 --> L4["L4 可靠性
pass^k · 方差 · 失败分布"]
L4 --> L5["L5 业务级
采纳率 · 节省时间 · 成本"]
读图要点:越往上越贵、越慢、越接近真实价值;越往下越快、越能定位原因。 日常迭代靠 L1/L2 快速反馈,上线决策看 L3/L4,真正判断值不值得做看 L5。只做 L3 的团队,通常会在”测试都过了但用户不用”上卡住。
7.2 从真实业务轨迹造评测集
这是我认为最值得投入的一件事。八个步骤:
第一步:取数。 200–500 条真实轨迹或工单,覆盖主要意图和长尾。必须包含失败样本、升级样本、用户点踩的样本,以及”差点成功”的样本。脱敏。
第二步:先做错误分析。 自己读 30–50 条,用开放编码给失败模式命名。不要先想指标,先看数据。这一步的产出是一张失败模式表,以及每条轨迹的”首个上游失败”。
第三步:轨迹转任务。 还原交互前的环境状态(文件、数据库、工具),写成任务描述。评分标准要写成领域专家会一致认同的形式。最好让人工解一遍,证明可解。
第四步:选评分器。 优先级:确定性检查(终态、数据库 diff、单测、工具调用断言)> 逐条标准的二元评委 > agentic 评委 > 人工。能用第一个就不要用第二个。
第五步:校准。 75/25 切分开发集和留出集。评委与人工的一致性目标在 0.7 以上。评委用与被测 Agent 不同家族的模型,随机顺序,避免位置偏差。
第六步:效度检查。 用 ABC 检查清单过一遍:任务是否真的测了它声称测的能力?评分器是否可被绕过?环境是否可复现?
第七步:运行。 每题跑 k 次(k=4–8),报告 pass@k(能力上限)、pass^k(可靠性)、成本、延迟、置信区间。固定数据集版本和 harness 版本,写 changelog。
第八步:飞轮。 新系统每周、成熟后每月抽样线上轨迹,标注,把新失败模式加成任务。定期刷新防污染。自进化时,只有在留出集上提升才接受修改。
图 16:从真实轨迹到评测集的八步
flowchart LR
A["1 取数
200–500 条轨迹"] --> B["2 错误分析
开放编码"]
B --> C["3 轨迹转任务
还原环境状态"]
C --> D["4 选评分器
确定性优先"]
D --> E["5 校准
评委对齐人工"]
E --> F["6 效度检查
ABC 清单"]
F --> G["7 运行
pass@k + pass^k"]
G --> H["8 飞轮
新失败加入"]
H --> A
读图要点:第 2 步不能跳。 大多数团队从”取数”直接跳到”写评分器”,结果造出来的题测的是自己想象的能力,不是真实的失败。先读 30–50 条轨迹、用开放编码命名失败模式,再决定造什么题、用什么评分器——这个顺序决定了评测集有没有用。
7.3 评分器选择树
1 | 终态可以用代码判定吗? |
这条树的核心思想是:尽可能把主观判断压缩成客观断言。 每压缩一层,评测的可靠性和可复现性就提升一档。
7.4 指标设计
成功率:最基础,但要知道分母。失败的任务算不算?超时算不算?被人工接管算不算?
pass^k:k 次全对的概率。它比平均成功率更接近生产要求,因为它惩罚不稳定。
单位成功成本:总成本 / 成功数。这个指标能揭示”靠重试堆出来的成功率”。
失败分类分布:按失败模式统计占比。这是优化的路标——先修占比最高的那一类。
首次通过率:不重试的情况下一次成功。衡量 harness 的”顺手程度”。
7.5 评测自身的效度
评测也会错,而且错了很难发现。四个检查点:
任务效度:任务是否真的需要它声称的能力?比如一个”代码修复”任务,如果答案在 issue 描述里就有,它测的是阅读理解,不是修复。
评分效度:评分器是否可被绕过?有没有 reward hacking 的空间?用对抗样本测一遍。
环境效度:环境是否可复现?依赖版本、网络、随机种子是否固定?
统计效度:样本量够不够?置信区间多宽?两个系统差 2 个点,是真实差异还是噪声?
一个实用做法:每次评测都保留 10% 的”已知答案”样本,用来检测评分器是否漂移。
7.6 回归门禁与飞轮
回归集:已经稳定的能力,接近 100% 通过率。任何一条失败都阻断合入。
能力集:还有提升空间的,用于衡量进步。
私有集:只在最终决策时用,防止过拟合。
三者分开,是因为它们的目标冲突:回归集要稳,能力集要难,私有集要保密。混在一起会导致”为了提升能力集而牺牲回归集”。
7.7 优缺点
优点:让优化有方向;让回归可发现;让自进化有信号。
缺点:建一次很贵;会过时;会被优化;容易测了容易测的,漏了难的。
7.8 一个评测集的骨架
抽象讲完,给一个可以直接抄的目录结构。
1 | evals/ |
task.yaml 至少包含这些字段:
1 | id: "0001" |
评分器要遵守四条规则:
- 幂等:同样的产物跑两次,结果一样。
- 隔离:评分时不依赖网络和外部服务。
- 防篡改:先校验测试文件和断言没被修改,再跑测试。
- 部分分:多步任务给中间分,否则全是 0 分,学不到信号。
评分器的骨架大致是:
1 | def grade(workdir): |
最后一个容易漏的点:每个任务都要记录 provenance,也就是它来自哪条真实轨迹、经过谁改写、原始失败模式是什么。没有 provenance 的任务,半年后就没人知道它为什么存在,也不敢删。
7.9 把问题形式化
自进化可以拆成五个要素。任何一篇论文、任何一个系统,都可以用这五个要素描述:
搜索空间:能改什么。提示词、工具描述、工具实现、中间件、控制流、拓扑、记忆策略。
表示:怎么表示一个候选。自然语言、代码文件、配置文件、图结构。
评价信号:怎么判断好坏。基准分数、完整轨迹、自然语言反思、可证伪的预测。
选择策略:怎么决定下一轮试什么。贪心、档案、Pareto、树搜索、Thompson 采样。
预算:花多少。编辑次数、评测次数、token、时间。
五个要素里,评价信号是最容易做错的一环。因为如果信号不可靠,搜索越强,过拟合越严重。
7.10 DSPy:自进化的前史
7.10.1 DSPy 的主张
DSPy(arXiv 2310.03714,Khattab 等,2023 年 10 月)的出发点是:当时的语言模型流水线靠手写的”提示模板”,这些模板是反复试错得来的,脆弱而且难迁移。它提出一种编程模型:把流水线看成”文本变换图”,语言模型通过声明式模块被调用;这些模块是参数化的,能通过生成和收集演示来学习,并能组合运用提示、微调、增强和推理技术。再配一个编译器,按给定的指标优化任何 DSPy 流水线。
摘要给的数字是:编译几分钟后,GPT-3.5 和 llama2-13b-chat 自举出的流水线,通常比标准少样本提示分别高出 25% 和 65% 以上;对比专家手写演示的流水线,提升分别是 GPT-3.5 的 5% 到 46% 和 llama2-13b-chat 的 16% 到 40%;为小开源模型(如 7.7 亿参数的 T5 和 llama2-13b-chat)编译出来的程序,可以与专家为 GPT-3.5 手写的提示链相当。案例涉及数学应用题、多跳检索、复杂问答和智能体循环控制。
7.10.2 它给自进化留下的三个概念
概念一:把”提示”当成可优化的参数。 这直接对应第 7.9 节”五要素”里的”表示”——提示、工具描述、代码,都是被搜索的对象。
概念二:优化需要一个指标。 DSPy 的编译器优化的是”你给定的指标”。这句话看起来平常,却是整个自进化领域的命门:指标是什么,系统就会往哪里优化,包括往你不想要的方向。 第 7.13 节的反证和第 7.14 节的六种防过拟合手段,都是在补这个洞。
概念三:小模型加好编译,可以追平大模型加手写。 这条结论在成本上很诱人,但需要谨慎:摘要里的比较对象是”专家手写的提示链”,不是”针对任务精调的大模型”;而且这些结果是在 2023 年的模型上取得的,今天的模型基线已大幅提高,不能直接外推。
7.10.3 DSPy 与后文各种自进化方法如何对应
| 方向 | DSPy 的做法 | 后来的做法 | 差别 |
|---|---|---|---|
| 搜索对象 | 提示、示例、模块组合 | 代码、工具、整个 harness | 搜索空间变大 |
| 评价信号 | 开发者给定的指标 | 基准分数、轨迹分析 | 信号更丰富也更易被钻空子 |
| 提案者 | 编译器里的启发式与采样 | LLM 读轨迹后提出修改(如 Meta-Harness) | 提案本身用模型 |
| 风险 | 对小开发集过拟合 | 对基准过拟合、改坏安全边界 | 风险从”效果差”升级到”不可控” |
我的判断是:**DSPy 代表了”自进化的低风险版本”**——只动提示和示例,不动代码和权限,结果可复现、可回滚。这正是第 8.17 节”自进化先做到提示和工具描述自动优化”的依据。
7.10.4 把它用起来的一个小流程
如果你想在自己的项目里先用提示优化,我建议这个顺序(是工程建议,不是论文流程):
第一步:确定指标,并保证它是确定性的。 能用测试、字符串匹配、状态检查就不要用评委模型。评委偏差本身会被优化放大。
第二步:把数据切三份。 训练集(用来生成和筛选演示)、选择集(用来比较候选)、留出集(最后只看一次)。第 7.14 节的三方切分在这里直接适用。
第三步:只开放有限的编辑空间。 例如只允许改指令措辞和示例选择,不允许改工具列表。编辑空间越大,越需要更强的评测。
第四步:对比人工基线。 一个有经验的工程师花一天写的提示,是最现实的基线。优化器如果追不上它,说明指标或数据有问题。
第五步:把胜出的提示当作代码提交。 版本化、写变更说明、能回滚。
7.10.5 局限
局限一:对指标的依赖。 指标设计不好,优化只会更快地把你带偏。
局限二:样本量。 开发集太小,容易对它过拟合,留出集上的表现会掉。
局限三:迁移性。 为某个模型编译出的提示,换模型后可能需要重编译。这既是缺点,也说明提示与模型是耦合的,需要把”重编译”纳入模型升级的流程。
7.11 五代方法
第一代:提示词优化。 GEPA、DSPy/MIPRO、TextGrad。改的是提示词文本,评价用任务分数或反思。优点是便宜、快;缺点是天花板低。
第二代:工作流搜索。 ADAS、AFlow、MaAS。改的是”用哪些模块、怎么连”。搜索空间是图结构。优点是能发现人想不到的组合;缺点是搜索成本高,且容易过拟合任务分布。
第三代:代码级自修改。 Gödel Agent、SICA、DGM、HGM。Agent 直接改自己的代码。优点是表达力最强;缺点是风险最高,需要沙箱和锚点。
第四代:Harness 专项优化。 Meta-Harness、AHE、RRSI。不追求通用自修改,而是针对”编码 Agent 的 harness”做结构化演化。优点是组件文件化、可回滚、可归因;缺点是仍绑定特定任务族。
第五代:元进化。 HSI 一类,进化”怎么进化”。目前证据很少,属于探索阶段。
图 17:自进化闭环
flowchart TD
T["任务集"] --> RUN["执行当前 harness
产生轨迹"]
RUN --> EV["评测
分数 + 失败分类"]
EV --> PR["提案者
读原始轨迹与源码"]
PR --> CA["候选 harness
一次可回滚的 diff"]
CA --> SB["沙箱 + 验证集"]
SB --> NO{"提升 > 评测噪声?"}
NO -- 否 --> AR["档案
记录失败原因"]
NO -- 是 --> RG{"防过拟合
预测绑定 · 批评者 · 编辑预算"}
RG -- 否 --> AR
RG -- 是 --> SEL["选择
档案 / Pareto / 子树统计"]
SEL --> HU["人工审批合入"]
HU --> RUN
AR --> PR
读图要点:两个出口决定这套系统是”研究玩具”还是”生产工具”。 第一个是”提升 > 噪声”——没有同预算对照,微小的提升大概率是噪声;第二个是”防过拟合”三道闸——它们拦掉的正是那些”专为基准而改”的改动。AHE 的消融显示增益来自工具、中间件和记忆而非提示词,这说明提案者必须能改到代码层,否则搜索空间太小,收益很快饱和。
7.12 代表工作解剖
DGM(Darwin Gödel Machine)。维护一个 Agent 档案,每代从档案里选父代,让 Agent 修改自己的代码,跑基准,把结果存回档案。论文报告的 SWE-bench 从 20% 到 50%,Polyglot 从 14.2% 到 30.7%(C 级,作者自报)。它的关键设计是档案——不淘汰早期看起来差的变种,因为有些变种需要再演化几步才能显现价值。
HGM(Huxley-Gödel Machine)。改进选择策略:不只看到当前节点的分数,而是用子树的整体表现估计”这个节点的后代可能有多好”(clade metaproductivity),再用 Thompson 采样平衡探索与利用。这解决了 DGM 的一个问题:早期高分节点会吸走所有预算。
SICA。单个 Agent 自改代码,配一个 LLM 评审委员会和一个 overseer 监督。它更像”带代码审查的自动重构”,而不是开放式搜索。
Meta-Harness。核心论点是:提案者要读原始轨迹和源码,不要读摘要。 摘要有损,会丢掉”为什么失败”的关键细节。论文报告:在线文本分类比最好的上下文管理系统高 7.7 分,同时上下文 token 少 4 倍;检索增强数学推理上,发现的 harness 在 200 道 IMO 级题目上对五个留出模型平均提升 4.7 分(A 级,读的是摘要)。
AHE(Agentic Harness Engineering)。三个支柱:组件文件化可回滚;轨迹蒸馏成可读的证据库;每次修改附带可验证的预测。论文报告:十轮迭代把 Terminal-Bench 2 的 pass@1 从 69.7% 提到 77.0%,超过人工设计的 Codex-CLI(71.9%);在 SWE-bench Verified 上,冻结后的 harness 用少 12% 的 token 达到更高成功率;对三个不同模型家族有 +5.1 到 +10.1 个百分点的迁移增益(A 级)。最有价值的是消融结论:增益主要来自工具、中间件和长期记忆,不是系统提示词。
RRSI(Regularized Recursive Self-Improvement)。专门解决过拟合。三个手段:退火的编辑预算(越到后面允许改的越少)、过滤”专为基准而改”的批评者、剪除无用改动的修剪器。论文报告:在八个基准上,进化集最多提升 6.0 分,五个分布外基准最多提升 4.3 分,最终 harness 比无正则化的版本少用 30% 的策略 token(A 级)。
这里要纠正一个常见的误传:网上流传的”RRSI 进化集提升 14.1 点、未见基准提升 4.7 点”与摘要不符。摘要给的是 6.0 和 4.3。引用时以原文为准。
7.13 反证:什么时候自进化不划算
这是这一章最重要的一节。
一篇 2026 年的论文(arXiv 2607.12227)在同等预算下做了对照:自动 harness 进化在 Terminal-Bench 这类任务上没有赢过简单的 test-time scaling,无论给不给测试用例;而且泛化能力有限。
但是,在长程游戏任务上,任务特定的进化比搜索基线高 80%(ARC-AGI-3)和 11%(EdgeBench)。
这个反差说明什么?
第一,自进化的收益取决于任务有没有结构性提升空间。 如果瓶颈是”模型不够聪明”,那么让模型多想一会儿(test-time scaling)比改 harness 更直接。如果瓶颈是”harness 的结构不适合这类任务”,进化才有价值。
第二,短任务的评测噪声大,进化容易学到噪声。 长程任务信号更稳定,进化的收益更容易显现。
第三,必须做同预算对照。 很多”自进化有效”的结论,其实是”多花了十倍算力”。
这条反证应该写进任何自进化项目的立项文档。它不否定这个方向,但它规定了前提条件。
7.14 防过拟合的六种手段
- 三层数据分离:进化集、验证集、私有测试集。私有集只在最后用一次。
- 编辑预算退火:早期允许大改,后期只允许小改。防止后期针对评测做特化。
- 批评者过滤:让一个独立模型判断”这个修改是不是在利用基准的特征”,是就拒绝。
- 预测绑定:每次修改必须写明”预期哪类任务提升、哪类不变”,验证不符就回滚。
- 修剪:定期删掉没有贡献的改动,防止复杂度累积。
- 多任务族验证:至少在两个不相关的任务族上都有提升,才算真提升。
7.15 安全边界
自进化系统是一个能修改自己的系统,安全要求比普通 Agent 高一个量级。
- 沙箱:进化过程必须在隔离环境里跑。
- 锚点:评测脚本、评分器、权限配置不能被被进化对象修改。
- 审批:合入主线要人确认。
- 回滚:每次修改是一个 commit,可一键回退。
- 审计:记录每次修改的动机、预测、结果。
有论文标题提到”被污染的基准会让 DGM / SICA 写出不安全代码”(B 级,仅见标题)。这个方向值得警惕:如果评测信号可以被利用,进化就会学会利用它,包括绕过安全检查。
7.16 优缺点
优点:能发现人想不到的结构;在长程、结构化任务上有真实增益;一旦跑通,迭代成本低于人工调优。
缺点:成本高;评测依赖强;容易过拟合;调试困难(改了哪里、为什么有效,往往说不清);安全风险。
7.17 最小可行实现
八周计划:
- 第 1–2 周:把 harness 组件文件化。系统提示、工具描述、工具实现、中间件、记忆策略,各自独立文件,git 管理。
- 第 3 周:建评测。50–100 题,确定性评分器优先,分进化集和留出集。
- 第 4 周:写提案者。输入是完整轨迹加源码,输出是一个 diff。先用最强模型。
- 第 5 周:加档案和选择。先用贪心,跑通再换子树统计。
- 第 6 周:加防过拟合。预测绑定 + 编辑预算 + 批评者。
- 第 7 周:跑对照。同预算的 test-time scaling 基线必须有。
- 第 8 周:评估是否值得继续。如果增益小于噪声,停。
这个计划的关键不是技术,是第 8 周的停车判断。大多数自进化项目失败不是因为做不出来,是因为做出来了但收益抵不过成本,却没人敢停。
7.18 提示优化的三件套
在走到”改代码”之前,先把提示词和工作流优化做透,性价比最高。三条主流路线:
GEPA(反思式提示进化)。 它不只看分数,而是读完整轨迹,用自然语言反思”为什么失败”,据此生成候选提示;用 Pareto 前沿保留多个在不同任务上表现好的候选,避免单一最优导致的过拟合。优点是演化过程可读、可解释,人能看懂每一步为什么改;论文自称相对 GRPO 平均提升 6%,rollout 少 35 倍(C 级)。缺点是每个候选都要跑完整评测,成本不低。
DSPy / MIPRO。 把提示拆成”指令 + 示例”两类参数,定义明确的 metric,用贝叶斯优化搜索组合。优点是工程化程度高、可复现、和代码解耦;缺点是需要一份像样的标注集,而且搜索空间被限制在它支持的模板里,发现不了结构性创新。
TextGrad。 把 LLM 的自然语言反馈当成”梯度”,反向传播到提示、代码或参数上。优点是通用,什么都能优化;缺点是方差大、调用次数多,而且”文本梯度”没有真正的方向保证,容易震荡。
三条路线的对比如下:
| 方法 | 改什么 | 信号 | 成本 | 何时用 |
|---|---|---|---|---|
| GEPA | 提示文本 | 分数 + 轨迹反思 | 中 | 有轨迹、要可解释 |
| DSPy/MIPRO | 指令 + 示例 | metric | 中 | 有标注集、要可复现 |
| TextGrad | 任意文本变量 | LLM 反馈 | 高 | 探索性、结构未定 |
一个常被忽略的点:这三者优化出来的提示,在训练任务上的提升通常远大于在新任务上的提升。所以无论用哪个,都必须留一份没参与优化的任务集,并且和”人工写的提示”做对照。如果自动优化的提示赢不了人工提示,说明你的评测噪声大于信号,先修评测。
7.19 训练侧:SWE-Gym 与 harness 的分工
7.19.1 SWE-Gym 做了什么
SWE-Gym(arXiv 2412.21139,Pan 等,ICML 2025)自称是首个用于训练真实软件工程智能体的环境。它包含 2438 个来自真实项目的 Python 任务实例,每个都配有带可执行运行时的代码库、单元测试和自然语言任务描述。
摘要的结果有三层:
第一层:用它训练的智能体,在 SWE-Bench Verified 和 Lite 上的解决率最多绝对提升 19%。
第二层:作者还用 SWE-Gym 里采样的轨迹训练验证器,用于推理时扩展。
第三层:验证器与微调后的智能体结合,在 Verified 上达到 32.0%,在 Lite 上达到 26.0%,作者称这是开放权重 SWE 智能体当时的新最好成绩。 环境、模型和轨迹都开源。
7.19.2 这对 harness 工程意味着什么
第一,”可验证的环境”是训练与评测共用的资产。 SWE-Gym 的每个实例都有可执行测试,这既能当训练信号,也能当评测。第 7 章强调的”确定性评分器”,在训练侧就是奖励函数。你为评测建好的环境和评分器,很可能将来也是训练数据的来源。
第二,验证器是推理时扩展的前提。 摘要里验证器的作用是从多个候选里挑好的。这对应第 4.5 节的独立验证:有了可靠的验证器,就可以多采样、再挑选,用算力换准确率。没有验证器,多采样只是多花钱。
第三,训练与 harness 不是替代关系。 训练把能力”烧”进模型,harness 把能力”约束与放大”在模型外。前者改动慢、成本高、跨任务;后者改动快、成本低、贴任务。
图 18:训练侧与 harness 侧的分工
flowchart LR
ENV["可验证环境
代码库 + 测试 + 任务描述"] --> EVAL["评测
确定性评分器"]
ENV --> TRAIN["训练
轨迹 → 微调 / 强化学习"]
TRAIN --> MODEL["模型能力"]
EVAL --> HARNESS["Harness 迭代
提示 / 工具 / 上下文策略"]
MODEL --> HARNESS
HARNESS --> TRACE["新轨迹"]
TRACE --> TRAIN
TRACE --> EVAL
读图要点:环境是中枢。 评测和训练共用同一批可验证环境,轨迹既用于评测,也回流成训练数据。第 7 章的自进化在这张图里对应”Harness 迭代”这一格,它依赖评测,却不改模型。
7.19.3 什么时候该考虑训练
我的建议是三个条件同时满足再考虑:
一是你有足够多的可验证任务。 没有环境和评分器,训练就没有信号。
二是 harness 优化已进入平台期。 提示、工具、上下文策略都调过,边际收益很低。
三是你的任务分布相对稳定。 训练烧进去的能力,在任务分布变化时会过时;harness 则可以跟着改。
三个条件缺一,先做 harness。这也是为什么本报告的主体放在 harness 上。
7.19.4 一个容易被忽略的风险:评测污染
用同一批题目既训练又评测,会让分数失去意义。SWE-Gym 的做法是训练实例与评测基准分开(评测在 SWE-Bench Verified 和 Lite 上)。第 2.11 节讲的”评测污染与过拟合”,在训练场景下更严重:留出集必须真正从未被训练、调参或提示设计接触过。
第三部分 落地
8 安全治理、开源实现与参考架构
这一章把前面的原则落到工程上:安全与权限怎么设计,开源仓库怎么读、怎么比,参考架构长什么样,二十二周怎么推进。
8.1 威胁模型
提示注入:外部内容(网页、文件、工具返回)里藏着指令,模型把它当成用户指令执行。这是最基础也最难防的一类。
越权操作:Agent 做了超出授权范围的事,比如删除、外发、修改配置。
数据外泄:敏感信息被写进日志、被发到外部、被放进上下文传给第三方模型。
自我修改失控:自进化系统改掉了自己的限制。
供应链:工具、MCP server、技能包本身带恶意代码。
8.2 权限设计
三条原则:
最小权限:默认只读;默认只能访问工作目录;默认无网络。需要什么显式授予。
分级审批:读文件、写文件、执行命令、访问网络、对外发送,风险递增,审批策略应该不同。低风险自动,高风险人工。
能力令牌:不是给 Agent 一个”万能身份”,而是给它一个只能做特定事情的令牌,带有效期和范围。
8.3 沙箱层级
| 层级 | 隔离强度 | 成本 | 适用 |
|---|---|---|---|
| 进程内限制 | 弱 | 低 | 只读任务 |
| 容器 | 中 | 中 | 一般任务 |
| microVM | 强 | 高 | 不可信代码 |
| 独立机器 | 最强 | 最高 | 高风险任务 |
选择标准是”最坏情况下损失多大”,不是”能不能跑起来”。
8.4 自进化的特殊风险
普通 Agent 的错误是一次性的;自进化系统的错误会被写进代码,之后每次运行都重复。
所以自进化必须额外满足:
- 进化过程在独立沙箱;
- 评测脚本和评分器不可被修改;
- 每次修改可回滚;
- 合入主线要人审批;
- 有”毒性检测”——检查新版本是否绕过了安全检查。
8.5 审计
要能回答三个问题:谁在什么时候让 Agent 做了什么?它当时看到了什么?结果是什么?
这要求轨迹完整(包括上下文快照)、事件不可篡改、成本可归因。
8.6 优缺点
严格治理的代价是效率和灵活性。一个每步都要审批的系统没人用。所以治理设计的目标不是”最安全”,是”在可接受的风险下最顺手”。这需要按场景分级,而不是一刀切。
8.7 一张权限矩阵
治理设计最实用的产物是一张矩阵。横轴是动作类型,纵轴是策略。
| 动作 | 风险 | 默认策略 | 审批 |
|---|---|---|---|
| 读工作区文件 | 低 | 允许 | 无 |
| 读工作区外文件 | 中 | 拒绝 | 单次审批 |
| 写工作区文件 | 中 | 允许并记录 | 无 |
| 执行 shell 命令 | 高 | 白名单 | 白名单外审批 |
| 安装依赖 | 高 | 拒绝 | 每次审批 |
| 访问网络 | 高 | 域名白名单 | 白名单外审批 |
| 对外发送消息 | 很高 | 拒绝 | 每次审批 + 预览内容 |
| 修改配置/权限 | 很高 | 禁止 | 只能由人操作 |
| 删除数据 | 很高 | 拒绝 | 备份后审批 |
三条使用经验:
第一,默认拒绝,显式放开。 默认允许的系统,出一次事故就够受的。默认拒绝会让前期接入变慢,但省掉后期所有的救火。
第二,审批要带上下文。 只问”是否允许执行 rm -rf”没有意义。要展示”在哪个目录、影响哪些文件、有没有备份”。人才能做出判断。
第三,审计日志 Agent 不可写。 日志写在 Agent 有写权限的地方,等于没有日志。要写到独立介质,或者用只追加的方式。
8.8 主流仓库对比
| 仓库 | 语言 | 特点 | 适合学什么 |
|---|---|---|---|
| openai/codex | Rust | 生产级 CLI,沙箱、压缩、续跑完整 | 工业级循环、上下文管理、权限 |
| block/goose(aaif-goose) | Rust | 状态机式 Agent,MCP 原生 | 状态机设计、工具审批 |
| charmbracelet/crush | Go | 终端 Agent,有循环检测 | Go 实现、循环检测 |
| sst/opencode(anomalyco) | TypeScript | 客户端服务端分离,快照回滚 | 架构分层、快照 |
| google-gemini/gemini-cli | TypeScript | 工具调度、上下文压缩 | 调度器、压缩服务 |
| OpenHands/software-agent-sdk | Python | 事件溯源、卡死检测 | 轨迹挖掘、condenser |
| SWE-agent / mini-swe-agent | Python | 最小可运行循环 | 循环的最小形态 |
| langchain-ai/deepagents | Python | 中间件组合式 harness | 可组合设计 |
| Aider | Python | repo map、编辑格式 | 代码上下文构造 |
| anthropics/cwc-long-running-agents | Python | 长程 harness 最小示例 | 契约、门禁、评估者 |
| harbor-framework/harbor | Python | 评测编排 | 评测基础设施 |
| stanford-iris-lab/meta-harness | Python | 自进化 harness | 提案者与档案 |
8.9 按目标推荐
想理解最小循环:mini-swe-agent → SWE-agent 的 history processors。
想做生产级 CLI:Codex(Rust)、Goose(Rust)、Crush(Go)。这三个正好覆盖了三种设计取向:Codex 偏工程完备,Goose 偏状态机与 MCP,Crush 偏轻量与循环保护。
想做上下文管理:Codex 的 compact、OpenHands 的 condenser、gemini-cli 的压缩服务,三份实现对照着看。
想做长程:cwc-long-running-agents,一晚上能读完。
想做自进化:meta-harness 加 dgm,再看 RRSI 的正则化。
想做评测:Harbor 加 tau2-bench,再看 Trace2Eval 的方法论。
8.10 读源码的方法
不要从 main 开始读。建议按这个顺序:
- 找到”一次模型调用”发生的地方,理解输入输出。
- 往外一层,看循环怎么写的,终止条件是什么。
- 看上下文是怎么组装的,压缩在哪里触发。
- 看工具是怎么注册和执行的,权限在哪里检查。
- 看状态存在哪里,崩溃后怎么恢复。
这五步走完,一个 harness 的骨架就清楚了。剩下的都是细节。
8.11 三个仓库的读码路线
Codex(Rust)。 从 codex-rs/cli 进入,找到 exec 子命令,再进 core。核心循环在 core/src/session/;上下文管理在 context_manager/ 和 compact*.rs;工具定义与分发在 tools crate;沙箱在 linux-sandbox,命令策略在 execpolicy。读它主要学三件事:生产级的错误处理(每个失败都有分类和恢复路径)、审批流怎么嵌进循环、压缩怎么做到不破坏缓存。
OpenHands SDK(Python)。 先读 conversation/event_store.py,理解事件溯源是怎么做的——每个动作是一条不可变事件,状态由事件重放得到。再读 context/condenser/,看压缩器怎么按 token 预算逐级裁剪。最后读 conversation/stuck_detector.py,看它怎么用”重复动作 + 无进展”判断卡死。读它主要学轨迹设计,这是做评测和自进化的基础。
deepagents(Python)。 先读 libs/deepagents/deepagents/graph.py,看整个 harness 怎么用图把中间件串起来;再读 middleware/,每个中间件是一个横切能力(文件系统、子 Agent、记忆、审批)。读它主要学”可组合”——如果你想把 harness 做成可配置的,这是最清晰的范本。
三个仓库的读法一样:先找”一次模型调用”发生在哪里,再往外一层看循环,再看上下文怎么组装,再看工具怎么执行,最后看状态存在哪里。这五步走完,剩下的都是细节。不要从 main 开始逐行读,那样会在参数解析和配置加载里耗掉耐心。
8.12 三个仓库的设计取舍
8.12.1 mini-swe-agent:极简主义
来自 SWE-bench 与 SWE-agent 的同一团队(普林斯顿与斯坦福)。README 描述的设计哲学相当鲜明:
体量。 智能体类大约 100 行 Python,加上环境、模型与运行脚本稍多一些,没有花哨的依赖。
工具。 只有 bash,甚至不需要模型的工具调用接口,所以任何模型都能跑。
执行。 每个动作用独立的 subprocess.run 执行,而不是持久 shell 会话。这让沙箱化很容易,比如换成 docker exec。
历史。 完全线性,所以轨迹就是发给模型的消息本身。
目标。 一个可改的工具和研究基线,而不是黑盒。
成绩。 README 称在 SWE-bench Verified 上超过 74%。另一个仓库(SWE-agent)的新闻条目里提到的是 100 行 Python 达到 65%——两个数字对应不同时间点和不同模型,不要拿它们互相比较,也不要拿去和其他系统比,除非你核对了各自的配置。
这个选择意味着什么。 它几乎是 Agentless 的”智能体版回应”:把 harness 压到最薄,让模型自己处理一切。它证明了一个很强的事实:在 SWE-bench Verified 这类任务上,一个极薄的 harness 加强模型就能走很远,而这反过来意味着,你在这个基准上看到的差距,有相当一部分来自模型而不是 harness。第 2.6 节”一个分数包含什么”的分解,在这里得到了又一个例证。
8.12.2 SWE-agent:配置驱动
README 的描述:让你选的语言模型(如 GPT-4o、Claude Sonnet 4)自主使用工具解决真实 GitHub 仓库里的问题,也支持攻防类 CTF 任务和自定义任务;在 NeurIPS 2024 上发表;MIT 许可。特点是给模型”最大自由度”,文档完整、可配置,行为由一个 yaml 文件管理。仓库按 sweagent、tools、config、trajectories、docs、tests 划分。
这个选择意味着什么。 配置驱动的好处是:改行为不用改代码,做实验方便,轨迹可复现(仓库里专门有 trajectories 目录)。这和第 8.15 节”一个 harness 就是一个可执行文件加一份配置”的接口设想完全一致。 代价是配置越来越复杂后,配置本身就成了需要测试的代码。
README 还有一条很有信息量的提示:项目的大部分开发精力已转向 mini-swe-agent,后者据称在性能上追平 SWE-agent 却简单得多,维护者建议今后使用它。 换句话说,原作者团队自己用实践验证了”更薄的 harness 不输”。
8.12.3 OpenHands Software Agent SDK:平台化
README 描述它是一套模块化工具包,提供 Python、TypeScript 和 REST 接口,用来”构建与代码协作的智能体”,驱动 OpenHands CLI 和 OpenHands Cloud,MIT 许可。核心概念:
Agent: 一个 LLM 加一组 Tool(终端、文件编辑器、任务跟踪器等)。
Conversation: 由智能体加工作空间创建,用 send_message(...) 发消息,再 run() 执行。
Workspace/sandbox: 可直接在本机运行,也可通过 Agent Server 在 Docker 或 Kubernetes 的临时环境里运行。
仓库拆成几个包:核心 SDK、内置工具、工作空间实现、远程执行服务器、浏览器可用的 TypeScript 客户端。README 报告 SWE-Bench 77.6,并配有 arXiv 技术报告。事件日志这一项,页面上只在”仓库拥有的对象”里提到,没有展开,所以我不对它的设计作判断。
这个选择意味着什么。 它选的是”可扩展的基础设施”:类型化的流程(SDK 与 Agent Server → OpenAPI 契约 → TypeScript 客户端),支持本地与远程执行,支持多智能体和公共技能。如果你要自己做平台,它给的是分包方式的参考:把 SDK、工具、工作空间、服务器分开,每个都能单独替换。
8.12.4 三个仓库的对比
| 维度 | mini-swe-agent | SWE-agent | OpenHands SDK |
|---|---|---|---|
| 设计目标 | 极简、可改、研究基线 | 可配置的研究平台 | 可扩展的生产基础设施 |
| 工具 | 仅 bash | 一组自定义命令(ACI) | 终端、文件编辑、任务跟踪等 |
| 行为定义 | 代码本身 | 单个 yaml | 代码加类型化接口 |
| 历史/状态 | 线性,等于消息 | 轨迹目录 | 对话与工作空间对象 |
| 执行环境 | 每次独立子进程,易换沙箱 | 容器 | 本机、Docker、Kubernetes |
| 适合谁 | 想搞懂循环的人、做基线的人 | 做受控实验的人 | 做平台与产品的人 |
规律:越靠右,越工程化,也越重。 没有哪个”更好”,它们对应不同阶段:先读 mini-swe-agent 理解最小循环,再读 SWE-agent 看 ACI 与配置,最后读 OpenHands 看怎么分包。第 8.11 节的读码路线与此一致。
8.12.5 读码时该问的五个问题
不管读哪个仓库,我建议按下面五个问题带着目的读:
一,主循环在哪? 找到”调模型—执行动作—写回结果”的那几十行。
二,历史怎么组装? 是线性追加,还是有裁剪、摘要、重排?
三,工具怎么注册与校验? 参数不合法时返回什么?
四,执行环境怎么隔离? 子进程、容器还是远程?超时和资源限制在哪设置?
五,轨迹怎么落盘? 格式是否稳定,能否重放?
回答完这五个问题,你就能把任何一个 harness 放进第 1 章的九层模型里对号入座。
8.13 五层架构
第一层:可编辑的 Harness 层。 提示、工具描述、工具实现、中间件、记忆策略、上下文策略、长程策略、协作策略,全部文件化、git 管理。
第二层:执行与观测层。 沙箱、统一轨迹格式、事件日志、成本归因、工具错误分类。
第三层:评测层。 分层评测集、确定性评分器、回归门禁、pass^k、私有留出集。
第四层:进化层。 提案者、候选、评测、档案、选择、防过拟合、审批合入。
第五层:记忆层。 反思器、规则、技能、验证晋升、回滚。
这五层的依赖关系是:进化层依赖评测层,评测层依赖观测层,观测层依赖执行层,所有层都依赖可编辑的 harness 层。记忆层横跨,因为它既是进化的产物,也是进化的输入。
图 19:五层参考架构与依赖方向
flowchart BT
subgraph L5["第五层 记忆层(横跨)"]
MEM1["反思器
把轨迹变成规则"]
MEM2["技能库
验证后晋升"]
MEM3["回滚"]
end
subgraph L4["第四层 进化层"]
E1["提案者
读轨迹与源码"]
E2["候选与档案"]
E3["防过拟合
留出集 + 编辑预算"]
E4["人工审批合入"]
end
subgraph L3["第三层 评测层"]
V1["分层评测集
L1–L5"]
V2["确定性评分器"]
V3["回归门禁
pass@k + pass^k"]
end
subgraph L2["第二层 执行与观测层"]
O1["沙箱执行"]
O2["统一轨迹格式"]
O3["成本归因 / 错误分类"]
end
subgraph L1["第一层 可编辑 Harness 层(全部文件化、git 管理)"]
H1["提示与工具描述"]
H2["工具实现与中间件"]
H3["上下文 / 长程 / 协作策略"]
end
L2 --> L3
L3 --> L4
L4 --> L1
L1 --> L2
MEM1 -.-> L4
L4 -.-> MEM2
MEM2 -.-> MEM3
读图要点:箭头方向就是”谁给谁提供证据”。 执行层给观测层原始事件,观测层给评测层结构化轨迹,评测层给进化层可信分数,进化层回头改第一层的文件。这是一个闭环,不是瀑布——任何一环不可信,整圈就退化成”用噪声优化噪声”。
记忆层用虚线横跨,因为它的位置特殊:它既是进化的产物(成功经验沉淀成规则和技能),又是进化的输入(规则进入上下文,改变下一轮的表现)。这也是为什么记忆最容易失控——它在环上,任何错误都会被闭环放大。
8.14 数据流
一次进化循环:
- 执行层跑一批任务,产生轨迹。
- 观测层把轨迹结构化,标注失败模式。
- 评测层给出分数和失败分类。
- 进化层的提案者读轨迹和源码,提出修改。
- 修改在沙箱里跑验证集。
- 通过则进档案,不通过则记录原因。
- 定期从档案里选最优版本,人工审批后合入。
- 记忆层从成功和失败中提炼规则,供下一轮使用。
8.15 关键接口
几个值得提前定好的接口:
- 轨迹格式:每条事件包含时间、类型、输入、输出、上下文快照、成本。格式要稳定,因为所有下游都依赖它。
- 任务接口:任务定义、环境构建、评分器三段分离。这样换评分器不用重跑环境。
- harness 接口:一个 harness 就是一个可执行文件加一份配置。评测框架只认这个接口,不认内部实现。
- 记忆接口:读、写、检索、回滚四个操作。不要暴露内部存储细节。
8.16 分阶段路线
第 0–4 周:先有尺子。 选一类真实业务任务,建 50–100 题评测集,接入 Harbor 或自建 runner,跑基线,加 test-time scaling 对照。
第 4–8 周:低风险收益。 上下文工程配方:稳定前缀、工具延迟加载、大输出落文件、压缩加规则置顶。用缓存命中率和成本验证。
第 8–14 周:长程稳定性。 feature list、独立评估者、看门狗、检查点。用长程失败模式做压力测试。
第 14–22 周:自进化。 先做提示和工具描述的优化,再做代码级进化,带防过拟合和留出集。记忆流水线同步建设。
并行或之后:多 Agent。 只在可并行、读多写少的任务上引入,先用拓扑评估决定是否值得。
图 20:22 周落地节奏
gantt
title Harness 工程落地路线(第 0–22 周)
dateFormat YYYY-MM-DD
axisFormat %m-%d
section 阶段一 先有尺子
选任务族与建 50–100 题评测集 :a1, 2026-01-05, 21d
接入 runner 与跑基线 :a2, after a1, 7d
test-time scaling 对照 :a3, after a2, 7d
section 阶段二 低风险收益
稳定前缀与缓存顺序 :b1, 2026-02-02, 14d
工具延迟加载与大输出落文件 :b2, after b1, 14d
压缩策略与规则置顶 :b3, after b2, 14d
section 阶段三 长程稳定性
feature list 与单特性会话 :c1, 2026-03-16, 21d
独立评估者与证据门禁 :c2, after c1, 14d
看门狗与检查点 :c3, after c2, 14d
section 阶段四 自进化
提示与工具描述自动优化 :d1, 2026-04-27, 21d
代码级进化与防过拟合 :d2, after d1, 21d
记忆流水线 :d3, after d1, 28d
人工审批与合入流程 :d4, after d2, 7d
section 并行
多 Agent 拓扑评估与试点 :e1, 2026-03-16, 42d
读图要点:四个阶段是串行的,只有多 Agent 是并行的。 顺序不能换——没有评测集就做上下文优化,你不知道有没有变好;没有长程稳定性就做自进化,进化会把不稳定的行为固化下来。
第 0–4 周看起来”没产出功能”,但这 4 周决定后面 18 周是不是在赌。第 14 周之后的自进化,收益最大也最容易翻车,所以它的前置条件是前三阶段的全部产物:可信的评测、稳定的长程、可回滚的 harness。
多 Agent 放在并行轨道,是因为它和主线正交,且**默认结论是”不上”**。只有四个判据全满足时才启动,否则这条轨道直接取消。
8.17 取舍清单
- 先做评测还是先做功能? 先做评测。没有评测的功能是在赌。
- 自建还是用框架? 循环自建,工具和评测用现成的。循环是核心竞争力,不值得外包。
- 单 Agent 还是多 Agent? 默认单 Agent,除非四个判据全满足。
- 记忆用向量还是文件? 先用文件,超过几百个再考虑向量。
- 自进化做到什么程度? 先做到”提示和工具描述自动优化”,这一步的收益/风险比最好。
8.18 团队配置与节奏
一个能跑起来的 harness 团队,最小配置大概是这样:
- 2 名平台工程师:循环、工具、沙箱、上下文。这是核心,不要外包。
- 1 名评测工程师:建任务集、写评分器、维护回归。这个角色最容易被省掉,也最不该省。
- 1 名数据/标注:从真实轨迹里提炼任务,维护 provenance。
- 0.5 名领域专家:定义验收标准,判断”这样算不算做对了”。
- 1 名应用工程师:负责接入业务、处理长尾。
五个人,六个月,能到”一类任务可用”的状态。想同时覆盖三类任务,人力和时间都要翻倍。
一个常见错误是只招模型工程师。模型工程师擅长调提示和模型,但 harness 的主要工作量在工程和评测。缺评测工程师的直接后果是:系统一直在改,但没人知道有没有变好。
节奏上,我建议双周一个循环:第一周做改动,第二周跑评测、读失败样本、决定保留还是回滚。这个节奏比”随时合并”慢,但能避免系统在不知不觉中退化。
9 场景推演、争议与学习路径
最后一章把方法用在五个场景上,列出尚未解决的争议,并给出自检清单、学习路径和汇报模板。
9.1 五个场景的推演
说明: 这五个场景是我构造的推演,用来演示方法,不是真实项目的复盘,所以不含任何实测数字。
9.1.1 场景一:客服改订单
任务结构。 对话式,用户意图多变,但可执行的动作有限(查订单、改地址、取消、退款)。有明确的业务规则。
反馈来源。 数据库状态。改完地址后,订单的地址字段是否等于用户要的值,是确定性的。这正是 τ-bench 的评分思路。
风险。 写操作不可逆(退款、取消)。用户可能诱导模型违反政策。
形态。 外层路由加内层单 Agent(第 5.6 节第一种混合)。路由决定问题类别,类别内由 Agent 调用工具;写操作带确认点。
评测重点。 pass^k,k 取实际重复率。同一个问题用不同说法问 8 次,看是不是每次都按政策处理。
典型坑。 只看单次成功率;用评委模型判断”回复是否礼貌”来代替状态检查。
9.1.2 场景二:存量代码库里修 bug
任务结构。 目标明确,需要定位、修改、验证。
反馈来源。 测试。有测试就是强反馈,没测试就要先补。
风险。 改了不该改的文件;为了过测试而改测试。
形态。 这是 Agentless 的舒适区,也是 SWE-agent 的原生领域。可以用固定流程(定位—修复—验证)作为基线,在评测集上确认单 Agent 循环确实更好再换。
评测重点。 终态检查加防篡改检查(测试文件不能被改,第 7.8 节的评分器示例)。
典型坑。 题目里泄漏了答案;环境没有固定依赖版本,同一任务今天过明天不过。
9.1.3 场景三:开放式调研
任务结构。 问题宽泛、来源分散、可并行读取。
反馈来源。 弱。没有标准答案,只能靠引用核查与抽样人工审阅。
风险。 编造引用;信息过时;把低质量来源当事实。
形态。 编排者加并行只读子 Agent(第 5.10 节),因为读多写少、可分解,最符合多 Agent 的适用条件。子 Agent 只负责检索和摘要,结论由编排者综合。
评测重点。 引用核查:每个断言能否在引用来源里找到。抽样人工评审,建立最小的评分细则。
典型坑。 没有独立验证,子 Agent 的错误被编排者原样采纳;成本失控。
9.1.4 场景四:运维变更执行
任务结构。 步骤多,每步都有副作用,错误代价高。
反馈来源。 健康检查、监控指标、变更前后状态对比。
风险。 最高。误操作可能影响线上。
形态。 不要全自主。 用 Workflow 加人工确认点:Agent 负责生成变更计划和预检,执行由人确认,或在严格白名单和预算内自动执行低风险步骤。第 8.7 节权限矩阵是核心设计。
评测重点。 在沙箱里重放历史变更,评估计划的正确性;对”不该执行时是否拒绝”单独设题。
典型坑。 为了演示效果放开权限;没有回滚路径。
9.1.5 场景五:数据分析报表
任务结构。 取数、清洗、计算、可视化、写结论。
反馈来源。 中等。数字可以与已知基准对账,结论是否合理要人看。
风险。 数字算错;口径不一致;过度解读。
形态。 CodeAct 路线(第 3.15 节):让 Agent 在沙箱里写代码处理数据,只把摘要送回上下文。把”数据处理”固化为可复现脚本,把”解读”留给人审。
评测重点。 给定数据集与标准答案的数值题;口径一致性检查;对解读部分用评分细则抽样人工评审。
典型坑。 把几十万行数据读进上下文;把图表当事实。
9.2 五个场景对照
| 场景 | 反馈强度 | 风险 | 推荐形态 | 评测核心 |
|---|---|---|---|---|
| 客服改订单 | 强(数据库状态) | 中高(写操作) | 路由 + 单 Agent + 确认点 | pass^k |
| 修 bug | 强(测试) | 中 | 先 Workflow 基线,再比 Agent | 终态 + 防篡改 |
| 开放调研 | 弱 | 中(信息质量) | 编排者 + 并行只读子 Agent | 引用核查 |
| 运维变更 | 中(健康检查) | 高 | Workflow + 人工确认 | 沙箱重放 + 拒绝能力 |
| 数据分析 | 中 | 中 | CodeAct + 人审解读 | 数值题 + 口径检查 |
规律:反馈越强,自主性可以越高;风险越高,自主性必须越低。 两条轴决定了形态,而不是任务”看起来有多智能”。
9.3 从场景里归纳出的通用顺序
第一,先确认反馈从哪来。 没有反馈的任务,先补反馈,或者承认它需要人审。
第二,再确认写操作的边界。 哪些动作可逆、哪些不可逆、哪些需要确认。
第三,再选形态。 能用 Workflow 就先用,Agent 要靠评测赢得位置。
第四,最后才考虑多 Agent、记忆、自进化。 它们是放大器,前三步没做好,放大的是噪声。
9.4 十个争议与未决问题
1. Harness 的边界到底在哪? 有人认为记忆系统、评测框架都算 harness,有人认为它们在外围。边界不清会导致责任不清。
2. 自进化是不是一个真问题? 反方认为,模型能力提升会自然解决大部分 harness 问题,投入自进化是浪费。正方认为,harness 的结构性问题是模型解决不了的。目前的证据支持”分任务看”。
3. 多 Agent 是不是过度设计? Cognition 明确反对,Anthropic 的研究系统证明有效。分歧的根源是任务类型不同,不是谁对谁错。
4. 记忆系统有没有必要? “文件 + grep” 在很多基准上能打平复杂系统。记忆的价值可能主要在成本,不在效果。
5. 长上下文模型会不会让压缩过时? 短期内不会。窗口变大不解决注意力不均匀和信息密度下降。
6. 评测能不能自动化? 能自动化的部分在扩大,但”什么是好”这个判断仍然需要人。
7. 开源 harness 能不能追上闭源? 在循环和工具层可以,在模型协同优化上很难。
8. Agent 的可靠性什么时候能到生产级? 取决于任务有没有 oracle。有 oracle 的已经在生产,没有的还很远。
9. 自进化的安全边界怎么定? 目前没有共识。比较务实的做法是”进化可以提方案,合入必须人批”。
10. 成本会不会成为主要瓶颈? 在很多场景已经是了。一个任务的成本可以到几万美元,这限制了试验次数。
9.5 三篇文章放在一起:它们共同的假设
我读完这几篇,注意到它们有三个没明说但一致的前提,迁移时要逐条检验:
前提一:任务价值足够高。 15 倍 token 的成本,只有在每个任务价值很高时才划算。大批量低价值任务不适用。
前提二:团队有评测。 三篇文章都在讲怎么评:功能清单就是评测,20 条小样本是评测,评终态是评测。没有评测,它们给的配方你都无法验证。
前提三:模型本身足够强。 这些做法在强模型上表现好,在弱模型上未必成立。例如”只改 passes 字段”这种约束,需要模型能遵守约束。换模型时,这些配方要重测。
9.6 自检清单
可以拿它给自己的 Agent 项目打分。每项回答”是 / 否 / 不适用”,**”否”最多的那一组,就是你下一步该投入的方向。**
A. 定义与边界(第 1 章)
- 你能说清楚你的系统里哪些属于模型,哪些属于 harness 吗?
- 每一层的输入输出契约有文档吗?
- 治理规则(权限、预算)是写在代码里,还是只写在提示里?
B. 上下文(第 3 章)
- 前缀是否稳定,缓存命中率是否被监控?
- 工具定义是否按需加载?
- 大的工具输出是否落文件,只回传摘要?
- 有明确的压缩触发线吗?
C. 工具接口(第 3 章)
- 工具描述是否写清”何时用、何时不用”?
- 参数是否做了防呆(枚举、绝对路径)?
- 报错信息是否告诉模型怎么改?
D. 长程与验证(第 4 章)
- 有任务清单文件和单特性会话吗?
- 验证者是否独立于执行者?
- 有看门狗和检查点吗?
E. 多智能体(第 3 章)
- 单 Agent 在评测集上是否已到瓶颈?
- 任务是否可分解、读多写少?
- 有集中的验证点吗?
F. 记忆与自进化(第 8–9、23 章)
- 记忆写入有门禁吗?
- 有过期与回滚机制吗?
- 自进化的编辑空间是否受限?
- 有真正从未被接触过的留出集吗?
G. 评测与安全(第 10–11、19 章)
- 评测集来自真实轨迹吗?
- 用确定性评分器优先吗?
- 报告了 pass^k、成本和版本吗?
- 写操作有确认或预算吗?
- 沙箱隔离是真隔离吗?
9.6.1 打分的读法
不要把”是”的数量当成成绩。 25 项里每项的重要性随场景不同:客服场景里 24 比 14 重要得多,调研场景里 15 比 11 重要得多。这份清单的作用是发现盲区,不是排名。
建议做法:团队每人独立打一遍,再对照分歧。分歧大的项,往往就是团队内部对系统理解不一致的地方。
9.7 学习路径
9.7.1 四周速成(工程师)
第一周:概念与最小循环。
读 Anthropic 的 harness 博客、LangChain 的上下文工程文章;跑通 mini-swe-agent;读一遍 SWE-agent 的 history processor。
第二周:上下文与评测。
读 Codex 的压缩实现、OpenHands 的 condenser;用 Harbor 跑一个基准;自己写 20 道题和评分器。
第三周:长程。
读 cwc-long-running-agents 全部代码;给自己的一类任务加上 feature list 和独立评估者;压力测试。
第四周:自进化。
读 meta-harness 和 AHE;跑一个最小的提示优化循环;做同预算对照。
9.7.2 十二周系统(研究者)
前四周同上。之后:
第五到六周:精读 DGM、HGM、SICA,理解档案与选择策略。
第七到八周:精读 Meta-Harness、AHE、RRSI,理解组件文件化与防过拟合。
第九到十周:精读 MAST、agent-scaling、C 编译器案例,理解多 Agent 的失败与协调。
第十一到十二周:精读记忆系统与长程训练侧工作,形成一个自己的研究问题。
9.7.3 一份最小书单
如果只读五篇,读这五篇:
- Anthropic,Effective harnesses for long-running agents(工程实践最完整)。
- AHE(组件文件化 + 自动演化,有消融)。
- MAST(失败模式分类,做多 Agent 必读)。
- 2607.12227(自进化的反证,防止过度乐观)。
- LangChain 的上下文工程四分类(最好用的思维框架)。
9.7.4 三个不要
不要在没有评测的情况下改 harness。 你的直觉在短期是对的,长期一定是错的。改动越多,越需要一把稳定的尺子。
不要用多 Agent 解决单 Agent 的问题。 单 Agent 失败的原因通常是上下文、工具或验证,这三样在多 Agent 里一样存在,而且更难排查。
不要相信任何没有说明版本、预算和评分器的分数。 包括这份报告里引用的数字。带着这三个问题去读每一条结论,你会避开大部分误导。
9.8 二次阅读地图
按目的给出下一步读什么,全部材料在附录 B 有链接。
如果你想理解”为什么这样设计”: 按第 1 章谱系,顺序读 ReAct、SWE-agent、Agentless、OpenHands。四篇读完,你对”Agent 循环为什么长成这样”就有了骨架。
如果你想做评测: Anthropic 的《Demystifying evals for AI agents》、τ-bench、ABC 检查清单、Harbor 的文档。先读方法,再读基准。
如果你想做上下文工程: Anthropic 与 LangChain 的上下文工程文章、RULER、LongMemEval。前者讲做法,后者讲边界。
如果你想做多 Agent: Anthropic 的多智能体研究系统、Cognition 的《Don’t Build Multi-Agents》、MAST、agent-scaling。先读反对意见,再读赞成意见。
如果你想做长程任务: Anthropic 的长程 harness 文章、METR 时间视野、cwc-long-running-agents 仓库。
如果你想做自进化: DSPy、GEPA、Meta-Harness、DGM,以及 2607.12227 的反证。一定读反证。
如果你想读代码: Codex、Goose、Crush、opencode、OpenHands SDK、mini-swe-agent。第 8.11 节给了三个仓库的读码路线。
9.9 一页纸汇报模板:怎样向团队讲清楚你的 Agent 项目
读完这么多材料,最后一个实际问题往往是:怎么把它讲给同事或上级听?我的经验是,汇报失败多半不是因为内容不够,而是顺序不对——先讲架构、再讲功能、最后才提到效果,听的人一路都在猜”所以到底好不好”。下面这个模板把顺序倒过来,一页纸讲完,每项都对应本报告的某一章。
第一栏:任务与价值。 一句话说明任务,一句话说明每完成一次值多少钱或省多少时间。这一栏决定了你能花多少成本(第 5.18 节说过,多智能体约 15 倍 token 的账只有在高价值任务上才算得过来)。
第二栏:反馈来源。 这个任务里,”做对了”由谁判定?是测试、数据库状态,还是人?第 5.4 节的决策图把它放在第二个菱形,因为它决定了你能不能放心让 Agent 自主运行。写不出这一栏,说明项目还没准备好。
第三栏:当前基线。 给出三个数字:单次成功率、重复 k 次全对的比例(pass^k)、单个成功任务的平均成本。一定要同时给出这三个,而且要写明评测集大小与版本。 只给一个最高分是最常见的汇报陷阱(第 2.8 节第六问)。
第四栏:失败分类。 把最近一批失败按原因归类,给出前三类各占多少。这是全页最有价值的一栏,因为它直接决定下一步投入哪里:若最多的是”工具选错或参数错”,就去改接口(第 3 章);若最多的是”做到一半丢状态”,就去做进度外置(第 4.12 节);若最多的是”自称完成其实没完成”,就去做独立验证。
第五栏:下一步一件事。 只写一件,并写清楚怎么验证它有效:用哪份评测集、预期哪个数字变化、变化多少算成功。不要写”优化上下文”这种无法证伪的目标,要写”把前缀改为稳定顺序,缓存命中率从 X 提升到 Y”。
第六栏:风险与边界。 哪些动作不可逆,哪些需要人工确认,沙箱隔离到什么程度(第 8 章)。这一栏是留给最担心出事的那个人看的,写得越具体,他越放心。
第七栏:明确不做什么。 例如”本阶段不引入多智能体””不做自动改代码的自进化”。说清楚不做什么,和说清楚做什么同样重要,它能挡住最常见的范围蔓延。
这个模板还有一个副作用:写不出某一栏,就说明你对系统的理解在那里有缺口。 第 9.6 节的自检清单与它是同一件事的两种形式——清单用来自查,模板用来对外讲。建议每两周更新一次,把基线数字和失败分类的变化画成趋势,团队很快就会形成”用数字讨论 Agent”的习惯,而不是靠印象争论”这次好像变好了”。
9.10 最后一条建议
这份报告读完,不要急着做大系统。挑一个真实任务,造 50 道评测题,跑一个最简单的 harness,看第一份失败分类。 那份失败分类会告诉你,本报告 25 章里哪几章真正适用于你。
10 什么是不变的
这个领域的变化速度让人焦虑。每隔几周就有新框架、新基准、新论文,上个月的最佳实践这个月就可能过时。
但把这份报告从头读到尾,你会发现真正稳定的东西只有三条:
第一,注意力是有限的。 不管窗口多大,模型能同时关注的东西都有上限。所以上下文工程不会过时,只会换形式。今天的压缩策略,明天可能变成检索策略,但”把决策需要的最小信息放进去”这个原则不变。
第二,验证是不可靠的。 没有 oracle 的任务,永远需要人参与判断。有 oracle 的任务,oracle 本身也可能有 bug。所以”默认失败 + 独立验证 + 证据门禁”这套做法不会过时。
第三,动作是有代价的。 每一次写操作、每一次外部调用、每一次重试,都有副作用和成本。所以幂等、审批、预算、回滚这些工程约束不会过时。
反过来,那些容易过时的东西——具体的提示模板、具体的框架 API、具体的榜单排名——恰恰是最容易被写进文章、最容易被当成”知识”的部分。读的时候要有意识地把它们和上面三条分开。
最后一个提醒:不要用新名词掩盖没解决的问题。 “自进化””多智能体””长期记忆”这些词听起来很高级,但如果你的系统连一个稳定的评测都没有,这些词只会让问题更难被发现。先把尺子做出来,再谈进化。
附录 A 术语表
Harness:模型之外的运行时与执行逻辑。
Scaffold:harness 的同义词,偏”支撑结构”。
Context engineering:设计和管理模型输入的全部工作。
Compaction:把长上下文压缩成短表示。
Prefix cache:基于相同前缀的缓存,能显著降低成本。
pass^k:k 次运行全部成功的概率。
Time horizon:50% 成功率对应的任务时长。
Oracle:判断任务是否完成的可靠标准。
Reward hacking:系统利用评分器的漏洞而非真正完成任务。
Anchor:自进化中不可被修改的组件(评测脚本、权限配置)。
Compaction cliff:压缩越过某个点后性能断崖式下降的现象。
Clade metaproductivity:用整个子树的表现估计节点潜力,HGM 用它做选择。
Verifier:独立判断任务是否完成的组件,可以是测试、检查脚本或评委。
MCP:Model Context Protocol,工具接入的传输与调用标准。
A2A:Agent-to-Agent,面向 Agent 间任务的协议,隶属 Linux Foundation。
Cost per success:总成本除以成功任务数,比单纯报 token 更接近真实经济性。
Self-conditioning:模型把自己前面的输出当作既定前提继续推理,导致错误放大。
附录 B 完整材料索引
本附录保留前一轮调研用到的全部论文、源码、博客与基准,按方向分类,不因改写而丢失;B.9 是后补的、逐条核对过原文页的材料。
标记说明:† 只核到标题或摘要,未读全文;‡ 厂商或作者自报,未见独立复现;★ 本轮读过摘要或仓库页面。原始调研报告同时保留在 agent_harness_research_report.md,其中的仓库目录结构与阅读路径可对照使用。
B.1 概念与架构
博客
- Anthropic,Effective context engineering for AI agents:https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
- Anthropic,Effective harnesses for long-running agents:https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents
- Anthropic,Advanced tool use(tool search、程序化工具调用)★:https://www.anthropic.com/engineering/advanced-tool-use
- Anthropic,Writing effective tools for agents:https://www.anthropic.com/engineering/writing-tools-for-agents
- LangChain,Context Engineering for Agents(Write / Select / Compress / Isolate):https://www.langchain.com/blog/context-engineering-for-agents
- LangChain,The Anatomy of an Agent Harness:https://www.langchain.com/blog/the-anatomy-of-an-agent-harness
- Manus,Context Engineering Lessons:https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus
- Cognition,Don’t Build Multi-Agents:https://cognition.com/blog/dont-build-multi-agents
- Cursor,Dynamic Context Discovery:https://cursor.com/blog/dynamic-context-discovery
论文
- 编码 Agent Harness 的源码研究(11 个系统、7 子系统、29 模式)†:https://arxiv.org/abs/2609.00006
- Context Engineering 综述(1400+ 篇)†:https://arxiv.org/abs/2507.13334
B.2 Harness 自进化
| 工作 | 编号 | 源码 |
|---|---|---|
| Darwin Gödel Machine(DGM)★ | 2505.22954 | https://github.com/jennyzzt/dgm |
| Huxley-Gödel Machine(HGM) | 2510.21614 | https://github.com/metauto-ai/HGM |
| SICA | 2504.15228 | https://github.com/MaximeRobeyns/self_improving_coding_agent |
| Gödel Agent | 2410.04444 | — |
| ADAS | 2408.08435 | — |
| AFlow | 2410.10762 | — |
| MaAS | 2502.04180 | — |
| Meta-Harness ★ | 2603.28052 | https://github.com/stanford-iris-lab/meta-harness |
| Agentic Harness Engineering(AHE)★ | 2604.25850 | — |
| RRSI ★ | 2609.24972 | https://github.com/google-research/rrsi |
| Harness 进化评估的反证 ★ | 2607.12227 | — |
| GEPA ‡ | 2507.19457 | https://github.com/gepa-ai/gepa |
| ACE | 2510.04618 | https://github.com/ace-agent/ace |
| Live-SWE-agent | 2511.13646 | — |
| JIT-Agent † | 2608.25593 | — |
| HSI(元进化)† | 2608.08466 | — |
| AutoHarness † | 2603.03329 | — |
| HARBOR(贝叶斯调 harness 开关)† | 2604.20938 | — |
| 技能误进化 † | 2608.12851 | — |
| 污染基准导致不安全代码 † | 2609.17817 | — |
平台与引擎
- EvoAgentX:https://github.com/EvoAgentX/EvoAgentX
- ShinkaEvolve:https://github.com/SakanaAI/ShinkaEvolve
- OpenEvolve、AlphaEvolve(后者闭源)
- Meta-Harness 的 Terminal-Bench 产物:https://github.com/stanford-iris-lab/meta-harness-tbench2-artifact
B.3 上下文工程
论文
- Lost in the Middle:https://arxiv.org/abs/2307.03172
- ACON(上下文压缩):https://arxiv.org/abs/2510.00615
- AgentFold:https://arxiv.org/abs/2510.24699
- Context-Folding:https://arxiv.org/abs/2510.11967
- MEM1:https://arxiv.org/abs/2506.15841
- ReSum:https://arxiv.org/abs/2509.13313
- WebResearcher:https://arxiv.org/abs/2509.13309
- IterResearch:https://arxiv.org/abs/2511.07327
- TokenPilot(缓存感知驱逐)★:https://arxiv.org/abs/2606.17016
- Context Rot(Chroma 报告,非论文)
源码与基准
- LLMLingua:https://github.com/microsoft/LLMLingua
- ACON 实现:https://github.com/microsoft/acon
- FoldAgent:https://github.com/sunnweiwei/FoldAgent
- LOCA-bench:https://github.com/hkust-nlp/LOCA-bench
B.4 多智能体
博客与工程报告
- Anthropic 多智能体研究系统:https://www.anthropic.com/engineering/multi-agent-research-system
- Anthropic,16 个并行 Agent 写 C 编译器:https://www.anthropic.com/engineering/building-c-compiler
- Cursor,大规模长程编码:https://cursor.com/blog/scaling-agents
- Claude Code agent teams 文档:https://code.claude.com/docs/en/agent-teams
论文
- MAST,多智能体系统为何失败(14 类失败模式):https://arxiv.org/abs/2503.13657
- Towards a Science of Scaling Agent Systems:https://arxiv.org/abs/2512.08296
- Kimi K2.5 Agent Swarm / PARL ‡:https://arxiv.org/abs/2602.02276
- CAID(git worktree + 依赖感知计划):https://arxiv.org/abs/2603.21489
- The Inbox as a Coordination Primitive †:https://arxiv.org/abs/2610.36264
- MegaFlow †:https://arxiv.org/abs/2601.07526
源码
- agent-scaling(五种拓扑):https://github.com/ybkim95/agent-scaling
- OpenHands SDK:https://github.com/OpenHands/software-agent-sdk
- AutoGen / Magentic-One:https://github.com/microsoft/autogen
- OpenAI Agents SDK:https://github.com/openai/openai-agents-python
- OWL:https://github.com/camel-ai/OWL
- OASIS:https://github.com/camel-ai/oasis
B.5 长期记忆
系统与论文
- MemGPT:https://arxiv.org/abs/2310.08560 ;源码 https://github.com/letta-ai/letta
- Mem0:https://arxiv.org/abs/2504.19413 ;源码 https://github.com/mem0ai/mem0
- Zep / Graphiti:https://arxiv.org/abs/2501.13956 ;源码 https://github.com/getzep/graphiti
- A-MEM:https://arxiv.org/abs/2502.12110
- MemoryOS:https://arxiv.org/abs/2506.06326
- MemOS:https://arxiv.org/abs/2507.03724
- MIRIX:https://arxiv.org/abs/2507.07957
- Memory-R1:https://arxiv.org/abs/2508.19828
- Hindsight:https://arxiv.org/abs/2512.12818
- Generative Agents:https://arxiv.org/abs/2304.03442
- Reflexion:https://arxiv.org/abs/2303.11366
经验与技能
- ExpeL:https://arxiv.org/abs/2308.10144
- Agent Workflow Memory(AWM):https://arxiv.org/abs/2409.07429
- ReasoningBank:https://arxiv.org/abs/2509.25140
- Memento:https://arxiv.org/abs/2508.16153
- Memento-Skills †:https://arxiv.org/abs/2603.18743
- SkillRL †:https://arxiv.org/abs/2602.08234
- Learning on the Job †:https://arxiv.org/abs/2607.22157
参数化记忆
- Titans:https://arxiv.org/abs/2501.00663
- Nested Learning:https://arxiv.org/abs/2512.24695
- SEAL:https://arxiv.org/abs/2506.10943
- 记忆管理风险(检索相似历史导致照抄错误):https://arxiv.org/abs/2505.16067
B.6 长程任务
度量与诊断
- METR 时间视野:https://arxiv.org/abs/2503.14499
- The Illusion of Diminishing Returns(自我条件化):https://arxiv.org/abs/2509.09677
- SWE-Marathon:https://arxiv.org/abs/2606.07682
- HORIZON 失败归因 ★:https://arxiv.org/abs/2604.11978
- LongCLI-Bench:https://arxiv.org/abs/2602.14337
- Compaction Cliff †:https://arxiv.org/abs/2608.22752
- Context Rot in Long-horizon Search †:https://arxiv.org/abs/2606.29718
- LEAD †:https://arxiv.org/abs/2603.06870
Harness 实践
- LongHorizon-Harness ‡:https://arxiv.org/abs/2608.01964
- anthropics/cwc-long-running-agents ★:https://github.com/anthropics/cwc-long-running-agents
训练侧
- GiGPO / verl-agent:https://arxiv.org/abs/2505.10978 ;源码 https://github.com/langfengQ/verl-agent
- RAGEN:https://arxiv.org/abs/2504.20073
- AgentGym-RL:https://arxiv.org/abs/2509.08755 ;源码 https://github.com/WooooDyy/AgentGym-RL
- ARPO:https://arxiv.org/abs/2507.19849
- Tree-GRPO:https://arxiv.org/abs/2509.21240
- rLLM:https://github.com/rllm-org/rllm
- DeepResearch(Tongyi):https://github.com/Alibaba-NLP/DeepResearch
B.7 评测与基准
方法论
- Anthropic,Demystifying evals for AI agents:https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents
- Hamel Husain / Shreya Shankar,AI Evals FAQ:https://hamel.dev/blog/posts/evals-faq/
- ABC 检查清单(10 个基准中 7 个有有效性问题):https://arxiv.org/abs/2507.02825
- HAL(成本受控的多维榜单):https://arxiv.org/abs/2510.11977
- Agent-as-a-Judge:https://arxiv.org/abs/2410.10934
- Trace2Eval(从真实轨迹建评测)★:https://arxiv.org/abs/2611.06506
- AD-Bench †:https://arxiv.org/abs/2602.14257
- GDPval(44 个职业的真实交付物):https://arxiv.org/abs/2510.04374
基准
- Terminal-Bench ★:https://arxiv.org/abs/2601.11868 ;官网 https://www.tbench.ai
- SWE-Bench Pro V2 ★:https://arxiv.org/abs/2610.24206
- 用户模拟器不可靠(换模拟器最多差约 9 点):https://arxiv.org/abs/2601.17087
- tau-bench / tau2-bench、Toolathlon、MCP-Universe、TheAgentCompany、OSWorld、WebArena、BrowseComp
框架与任务合成
- Harbor ★:https://github.com/harbor-framework/harbor
- Inspect AI(英国 AI Security Institute)
- mini-swe-agent / SWE-agent:https://github.com/SWE-agent/SWE-agent
- SWE-smith:https://github.com/SWE-bench/SWE-smith
- WorkBuddy-Bench ★:https://github.com/Tencent/workbuddy-bench
B.8 开源 Harness 源码
- OpenAI Codex(Rust):https://github.com/openai/codex
- Goose(Rust):https://github.com/block/goose
- Crush(Go):https://github.com/charmbracelet/crush
- opencode(TypeScript):https://github.com/sst/opencode
- gemini-cli(TypeScript):https://github.com/google-gemini/gemini-cli
- OpenHands SDK(Python):https://github.com/OpenHands/software-agent-sdk
- deepagents(Python):https://github.com/langchain-ai/deepagents
- Aider(Python):https://github.com/Aider-AI/aider
- Claude Agent SDK(Python / TypeScript,循环内部不开放)
B.9 后补材料(逐条核过原文页)
论文(均核对过 arXiv 摘要页)
- ReAct:https://arxiv.org/abs/2210.03629
- Toolformer:https://arxiv.org/abs/2302.04761
- Self-Refine:https://arxiv.org/abs/2303.17651
- ReWOO:https://arxiv.org/abs/2305.18323
- Voyager:https://arxiv.org/abs/2305.16291
- AutoGen:https://arxiv.org/abs/2308.08155
- MetaGPT:https://arxiv.org/abs/2308.00352
- SWE-bench:https://arxiv.org/abs/2310.06770
- DSPy:https://arxiv.org/abs/2310.03714
- CodeAct:https://arxiv.org/abs/2402.01030
- SWE-agent:https://arxiv.org/abs/2405.15793
- τ-bench:https://arxiv.org/abs/2406.12045
- Agentless:https://arxiv.org/abs/2407.01489
- OpenHands:https://arxiv.org/abs/2407.16741
- SWE-Gym:https://arxiv.org/abs/2412.21139
- WebArena:https://arxiv.org/abs/2307.13854
- GAIA:https://arxiv.org/abs/2311.12983
- OSWorld:https://arxiv.org/abs/2404.07972
- RULER:https://arxiv.org/abs/2404.06654
- LongMemEval:https://arxiv.org/abs/2410.10813
博客与文档
- Anthropic,Building Effective Agents:https://www.anthropic.com/engineering/building-effective-agents
- Lilian Weng,LLM Powered Autonomous Agents:https://lilianweng.github.io/posts/2023-06-23-agent/
- Model Context Protocol 介绍:https://modelcontextprotocol.io/docs/getting-started/intro
- Claude Code 最佳实践:https://code.claude.com/docs/en/best-practices
- Anthropic 长程 harness、上下文工程、多智能体研究系统三篇已列于 B.1 与 B.4,第三、四、五章分别精读了它们。
源码
- mini-swe-agent:https://github.com/SWE-agent/mini-swe-agent
- SWE-agent:https://github.com/SWE-agent/SWE-agent
- OpenHands Software Agent SDK:https://github.com/OpenHands/software-agent-sdk
- A2A 协议:https://github.com/a2aproject/A2A
核对时发现的两处需要注意
- 2512.08296 的摘要里没有出现 17.2 倍与 4.4 倍这两个错误放大倍数,只有 +80.8% 到 −70.0% 的范围;详见第 5.18 节。
- mini-swe-agent 自己的页面写”超过 74%(SWE-bench Verified)”,SWE-agent 页面的新闻条目写”65%”,对应不同时间与配置,不可互比。
B.10 使用建议
三条:
第一,按”证据等级”使用,不按”看起来权威”使用。 带 ★ 的可以直接引用,带 † 的先读原文,带 ‡ 的只当方向。
第二,同一结论至少找两个独立来源。 尤其是数字。这份索引里多个厂商数字互相矛盾,不是谁撒谎,是任务集和预算不同。
第三,仓库优先于博客,博客优先于二手总结。 博客会简化,二手会失真。读代码最慢,但最不容易被骗。
附录 C 证据等级与未核实清单
后补材料核对时发现的两处需要降级的内容:第零章第 5 条与 5.10 节表格引用的”独立并行约放大 17 倍、集中式约 4.4 倍”,在 arXiv 2512.08296 的摘要页里找不到,只有 +80.8% 到 −70.0% 的范围,应视为”方向正确、数值待回查正文”(C 级);mini-swe-agent 的 74% 与 65% 两个数字对应不同时间与配置,不可互比。详见第 5.18 节与 B.9。
A 级(本轮读过摘要或仓库):AHE、Meta-Harness、RRSI、2607.12227 的摘要与数字;Terminal-Bench 4.0 的发布时间与规格。
B 级(核对过标题或仓库可访问):多数 arXiv 编号、开源仓库、基准论文。
C 级(厂商或作者自报,未独立复现):Anthropic 的 token 降幅、Cursor 的 token 降幅、Manus 的缓存价格、Anthropic 的 15 倍 token、C 编译器的 2 万美元成本。
D 级(仅见转述,本轮未能核实):
- Databricks 关于”中等模型 + 好 harness 胜过强模型 + 弱 harness”的具体数字(GPT-5.5 vs GPT-5.4 高 16.5 个百分点)。
- “ETCLOVG 七层框架”这一提法,本轮未能找到原始出处。
- “AWS Infinity”运行时,本轮未能核实其存在与能力描述。
- “LLM Scorebook”这一评估方法论名称,本轮未能核实。
- DeepSeek 的长程 Agent 实践细节。
- 各类榜单聚合站给出的具体模型排名(不同来源互相矛盾,建议只信官方仓库)。
写作原则:以上 D 级内容只作为线索保留,不作为结论支撑。任何要写进方案的数字,都应回到一手来源核对版本、任务集、预算和评分器。
附录 D 工程速查
D.1 二十个反模式:一份”别这样做”的清单
这些是我从前面各章与一手材料里归纳的,不是某一篇论文的结论。每条给出症状、原因和替代做法。
D.1.1 评测类
反模式 1:只看单次成功率。 症状:演示漂亮,上线后”时好时坏”。原因:可靠性是乘出来的(图 5)。替代:同时报 pass@k 与 pass^k。
反模式 2:用评委模型当唯一评分器。 症状:分数高,但人看结果觉得不对。原因:评委有偏差,优化会放大偏差。替代:确定性评分器优先,评委只处理无法规则化的部分,并用人工抽样校准。
反模式 3:评测集从想象里来。 症状:题目整齐,真实失败却不在其中。原因:想象不出真实的混乱。替代:从真实轨迹抽样造题(第 7.2 节)。
反模式 4:改了 harness 不重跑基线。 症状:不知道这次改动到底有没有用。原因:缺回归门禁。替代:每次改动前后跑同一份评测集。
反模式 5:把榜单分数当预期收益。 症状:照着榜单选方案,结果不如预期。原因:任务集、预算、版本都不同。替代:在自己的任务上做小实验。
D.1.2 上下文与工具类
反模式 6:把所有历史原样塞进上下文。 症状:越跑越慢、越跑越贵、越跑越糊涂。替代:压缩加外置加即时检索。
反模式 7:前缀里放时间戳或随机内容。 症状:缓存命中率奇低。原因:前缀只要变一个字符,之后的缓存全部失效。替代:把易变内容放在末尾。
反模式 8:工具一对一包装内部 API。 症状:模型总是调错顺序或参数。替代:按”完整意图”设计工具,返回裁剪后的结果。
反模式 9:工具太多且描述相近。 症状:模型选错工具。替代:减少重叠,延迟加载,写明”何时不要用”。
反模式 10:报错只抛堆栈。 症状:模型重复同一个错误。替代:告诉它哪里错、怎么改。
D.1.3 长程与多智能体类
反模式 11:让执行者自己宣布完成。 症状:功能”通过”了但不能用。原因:自评有盲区。替代:独立验证,完成标准写成机器可检查的字段。
反模式 12:一个会话做太多事。 症状:做到一半上下文耗尽,留下半成品。替代:单特性会话加干净状态。
反模式 13:没有进度外置。 症状:新会话不知道上一会话做了什么。替代:进度文件加 git 提交。
反模式 14:默认上多智能体。 症状:成本翻倍、效果不升反降。原因:多智能体在顺序任务上可能变差(摘要里最差 −70.0%)。替代:先过四个判据(第 5.9 节)。
反模式 15:多智能体没有集中验证点。 症状:错误被层层传递。替代:编排者加独立验证。
D.1.4 记忆与自进化类
反模式 16:什么都往记忆里写。 症状:检索被无关内容污染。替代:写入门禁,只存经验证的规则与技能。
反模式 17:记忆没有过期与回滚。 症状:旧知识压过新事实(LongMemEval 把”知识更新”单列为一项)。替代:为每条记忆记录来源与时间,支持失效。
反模式 18:自进化没有留出集。 症状:开发集分数涨,真实表现不涨甚至下降。替代:三方切分,留出集只看最后一次。
反模式 19:让自进化改权限与安全规则。 症状:系统为了提分绕开约束。替代:治理层只读,修改必须人工审批(第 8.4 节)。
D.1.5 工程与组织类
反模式 20:治理只写在提示里。 症状:模型”忘了”规则,或被用户说服违反规则。原因:提示是建议,不是强制。替代:权限、预算、确认点写进代码,在 L8 层强制执行。
D.1.6 小结
二十条反模式里,相当一部分的根源是”缺了尺子”:评测类五条不必说,长程、记忆、自进化里的好几条,也都因为没有评测而无法发现问题。这再次回到全文的主线:先有评测,再谈其他一切。
D.2 常见问题
1. 该不该自己做 harness? 如果你的核心业务就是 Agent 本身,自己做。如果 Agent 只是功能的一部分,用开源实现加定制,把精力放在工具和评测上。
2. 用 LangChain 还是自建循环? 循环自建。几百行就能写清楚,而且你能完全控制上下文和错误处理。框架适合做工具适配和评测集成,不适合当黑盒循环。
3. 上下文多大算太大? 不看窗口,看任务。经验值:超过 5 万 token 就该开始压缩;超过 15 万 token 还没压缩,基本一定会腐化。
4. 要不要上向量库? 文件少于几百个时不要。先做 INDEX.md 加 grep,够用且可解释。向量库解决的是”文件太多找不到”,不是”记忆不好”。
5. 多 Agent 从几个开始? 3–5 个。先验证编排逻辑和合并规则,再扩。一上来就上几十个,你分不清是协调问题还是任务分解问题。
6. 自进化第一步做什么? 把组件文件化,并建一份能防过拟合的评测。没有这两样,自进化只会放大噪声。
7. 评测集最少多少题? 50 题能看出方向,200 题能做出统计判断。低于 30 题,别用来做决策。
8. 怎么判断是模型问题还是 harness 问题? 同一个 harness 换一个更强的模型;同一个模型换一套 harness。哪个变化大,问题就在哪边。
9. 长任务要不要每个任务一个容器? 要。容器启动的几秒钟,比环境污染导致的不可复现便宜得多。
10. 压缩多久触发一次? 按用量触发,不按轮数。到 60%–70% 先清工具结果,到 80% 再做摘要。不要每轮都压。
11. 工具描述怎么写? 写清楚”什么时候用””什么时候不用””返回什么””失败长什么样”。四句话比一段说明有效。
12. 记忆写什么、不写什么? 写”下次还会用到的判断规则”,不写”这次做了什么”。前者能改行为,后者只是日志。
13. 怎么防提示注入? 把外部内容标记为不可信数据;最小权限;危险动作人工审批;治理规则写在代码里。做不到归零,只能降低概率。
14. 成本怎么控? 预算按子任务分配,不要只有一个全局上限;用前缀缓存;强模型规划、弱模型执行;把大输出落文件。
15. 怎么选模型? 在你的评测集上选,不在公开榜单上选。同一梯队内,harness 的差异往往大于模型的差异。
16. 开源 harness 能直接用吗? 能用作参考和起点,但生产环境要重写治理层和观测层——这两块开源实现通常最弱。
17. 回归测试怎么写? 每修一个 bug,加一条任务。每条任务都要能独立复现,且评分器不依赖外部服务。
18. 失败了怎么归因? 按第一章的九层顺序排查:先评测,再环境,再工具,再上下文,最后才是模型。顺序反了会浪费很多时间。
19. 什么时候该停掉一个自进化项目? 当同预算对照显示增益小于评测噪声,且连续两轮没有改善时。停下来不是失败,是止损。
20. 一年后这个领域会怎么变? 三个判断:上下文工程会变成标配而不是优势;自进化会收敛到”结构化组件演化”而不是”任意自修改”;评测会从公开榜单转向私有业务集。这三条都会让”把基础做扎实”比”追新方法”更划算。
(全文完)




