Agent Harness 学习报告:从概念边界到工程落地

从概念边界到工程落地,梳理当前 Agent 系统的组成、主要难点与解决思路。报告区分论文和实验中的证据、厂商或作者自报数据,以及需要进一步核实的判断,便于读者结合自己的任务与预算使用这些结论。

阅读指南

这份报告不是论文综述,也不是产品选型指南。它想回答三个问题:

  1. 现在的 Agent 到底是由什么构成的? 模型之外那一大坨东西,有没有一个稳定的分类方式。
  2. 它在哪里坏掉? 不是笼统地说”幻觉””不稳定”,而是具体到某一层、某一类失败、某一个可以观测的信号。
  3. 别人怎么修的?每种修法付出了什么代价? 这一条最重要。工程上几乎没有”更好的方案”,只有”在某个约束下更划算的方案”。

阅读顺序建议:如果你时间很少,读第零章和第二章;如果你要动手做,读第一章、第三章、第八章;如果你要做研究,读第四到第七章。

报告里的观点有强弱之分。带数字的多数是别人的实验结论,写”建议””我倾向于”的是我的工程判断。两者要分开用:前者可以引用,但要核对版本与预算;后者只能作为你在自己场景里验证的起点。

报告分为三部分、九章,配有 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 的谱系

图 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 一次请求的完整数据流

把九层串起来,一次典型请求是这样的:

  1. 治理层检查任务是否被允许、预算多少、需要哪些审批。
  2. 持久化层创建检查点,记录初始状态。
  3. 编排层判断是否需要分解;如果不需要,进入单 Agent 路径。
  4. 上下文层组装初始提示:系统提示、工具定义、任务描述、相关记忆。
  5. 控制层调用模型。
  6. 模型返回工具调用。控制层解析,交给工具接口层。
  7. 工具接口层校验参数、检查权限,交给执行环境层。
  8. 执行环境层在沙箱里执行,返回结果。
  9. 工具接口层格式化结果(截断、落文件、错误分类)。
  10. 上下文层决定这个结果怎么进上下文(全文、摘要、还是只留路径)。
  11. 观测层记录一条完整事件。
  12. 控制层判断终止条件;未终止则回到第 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
state = {
"goal": goal,
"constraints": constraints,
"todo": [...],
"done": [],
"artifacts": {},
"step": 0,
"budget": {"tokens": 200_000, "seconds": 1800},
}

while not done(state):
ctx = assemble(state) # L3:组装上下文
msg = call_model(ctx, tools) # L4:一次模型调用
if msg.is_tool_call:
result = dispatch(msg, state) # L2+L1:校验、执行
result = truncate(result) # L3:结果裁剪
state = record(state, msg, result) # L7+L9:记录、持久化
else:
state = record(state, msg)
state["step"] += 1

这二十行里已经包含了五个关键决策:

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:基准发布时人类与最好模型的成功率

图 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 衰减

图 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 匹配,遇到第一个不同就失效。

这带来几条硬性设计约束:

  1. 顺序固定:工具定义 → 系统提示 → 历史 → 当前输入。不要把易变内容放在前面。
  2. 不要放时间戳。当前时间:2026-11-14 15:03:27 会让每一秒的缓存都失效。需要时间就放在最后一条消息里。
  3. 不要中途增删工具。工具列表变了,整个前缀就变了。需要动态工具时,用工具检索的结果放在历史之后,而不是改工具定义区。
  4. JSON 键序固定。序列化不稳定会导致缓存 miss。
  5. 批量驱逐。压缩时一次删够,不要每轮删一点,否则每轮都 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 十条工程配方

以下每一条都可以直接落地,数字来自来源方自报,当作起点而不是定律。

  1. 固定前缀顺序,工具 → 系统 → 历史 → 输入。任何动态内容都往后放。
  2. 工具超过 10 个或定义超过 1 万 token 时启用延迟加载,常驻 3–5 个高频工具。Anthropic 报告工具定义 token 约降 85%(C 级)。
  3. 数据密集链路用程序化工具调用:让模型写代码在沙箱里聚合,只返回结果。Anthropic 报告平均省约 37% token(C 级)。
  4. 大输出一律落文件,返回路径加头尾各若干行,让模型自己 grep。Cursor 报告 MCP 场景总 token 降约 47%(C 级)。
  5. 先清工具结果,再摘要。触发线可以设在上下文用量的 60%–70%,清理时保留最近 3 次工具调用。
  6. 压缩后重注入约束:把”不许做什么”和”验收标准”贴在压缩摘要的末尾。
  7. 每 N 步复述目标。在上下文末尾重写一遍当前目标和待办,对抗中间位置丢失。
  8. 保留错误信息。失败的工具调用和报错要留在上下文里,否则模型会重复同样的错误。
  9. 压缩用固定 schema:目标、约束、已完成、待办、关键产物、未决问题。六个字段比自由摘要稳定得多。
  10. 把缓存命中率当成一等指标。和成功率、成本一起看,否则优化会悄悄破坏缓存。

3.8 怎么评测上下文策略

上下文策略很难评,因为它影响的是”多步之后的表现”。三个方法:

探针问答:在长上下文里埋几个必须记住的事实(比如”第三步用的端口是多少”),压缩后提问。答对率直接反映保真度。

同预算对比:固定总 token 预算,比较不同策略的完成率。不限预算的对比没有意义,因为谁都可以把所有东西留着。

长程基准:用 LOCA-bench 这类专门测长上下文的基准,或者自己构造需要跨几十步保持约束的任务。

3.9 五类任务的上下文策略

抽象原则要落到具体任务上才有用。下面五类是最常见的形态,各自的策略重心不同。

代码修复。 上下文的主体不是对话,是代码。策略是:用 repo map 或符号索引给出仓库概览,按需读取具体文件;保留最近的 diff;测试输出只留失败用例和关键堆栈。不要做的:把整个文件塞进上下文、把完整测试日志保留超过两轮。代码任务的一个特殊点是,文件内容会随时变化,所以”读到的东西可能已过时”要显式提示模型重新读。

检索研究。 上下文的主体是证据。策略是:用只读子 Agent 并行检索,每个子 Agent 只回一份结构化证据卡(结论、原文引用、来源、可信度);主 Agent 只持有证据卡,不持有原始网页。这样主上下文可以很小,而覆盖面很大。代价是子 Agent 可能漏掉关键证据,所以需要一轮”覆盖度检查”。

数据分析。 上下文的主体是 schema 和中间结果。策略是:只把表结构和样本行放进上下文,聚合计算全部在沙箱里用代码完成,只回结果和形状。不要做的:把原始数据行塞进上下文让它”看着算”,那既贵又容易算错。

客服对话。 上下文的主体是结构化状态。策略是:维护一个槽位对象(用户身份、订单号、诉求、已尝试方案、当前情绪),每轮更新;对话原文只留最近 3–5 轮;政策和禁止事项置顶并在压缩后重注入。客服场景的一个关键是”不许做什么”比”要做什么”更重要,所以约束必须放在压缩器碰不到的位置。

长文档生成。 上下文的主体是大纲和已完成部分。策略是:先固定大纲和术语表,每写完一章就生成一份”本章摘要 + 用到的术语 + 与前文的衔接点”,后续章节只读摘要不读全文。这样能保持一致性,又不会爆上下文。不要在最后统一检查一致性,那时已经改不动了。

这五类的共同点是:上下文里应该放”决策需要的最小信息”,而不是”所有相关信息”。 判断标准很简单——如果这条信息不影响下一步做什么,它就不该在上下文里。

3.10 成本这一面:把账算清楚

前面几章讲的都是”能力”,这里补”成本”。下面这张图复现了第 2.10 节的演算。

图 9:一个 50 步任务的 token 成本

图 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

四个判据,全部满足才考虑:

  1. 可分解:任务能切成若干个几乎独立的子任务,子任务之间不需要频繁交换状态。
  2. 读多写少:子任务主要是检索、分析、生成,而不是修改同一份共享状态。
  3. 可独立验证:每个子任务有自己的验收标准,不需要全局判断。
  4. 上下文确实放不下:单 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 的成本不是线性的,有三个放大器:

  1. 上下文复制:每个子 Agent 都要一份任务说明和工具定义。n 个子 Agent 就是 n 份。
  2. 协调往返:每次交接都要一次模型调用,交接越多越贵。
  3. 失败重试:子 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:多智能体相对单智能体的变化

图 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 最小可行记忆系统

如果要从零做一个,我建议这个结构,两周能跑起来:

  1. 文件层:memory/ 目录,按主题分文件,纯 Markdown,git 管理。
  2. 索引层:每个文件一行摘要,放在 memory/INDEX.md,启动时注入上下文。
  3. 写入:任务结束时,后台一个反思 Agent 读轨迹,提出增量修改(不是重写整个文件)。
  4. 门禁:修改必须附带”这条经验来自哪个任务、预期改善什么”,下一轮验证不通过就回滚。
  5. 检索:先读索引,需要时读全文。不上向量库,除非文件超过几百个。
  6. 评测:留出 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
2
3
4
5
6
7
终态可以用代码判定吗?
├─ 是 → 写断言/单测/状态检查
└─ 否 → 能拆成若干可判定的子断言吗?
├─ 能 → 拆开,每个子断言用代码判定
└─ 不能 → 有明确的评分标准吗?
├─ 有 → 逐条二元评委 + 人工校准
└─ 没有 → 先定义标准,或者用人工

这条树的核心思想是:尽可能把主观判断压缩成客观断言。 每压缩一层,评测的可靠性和可复现性就提升一档。

7.4 指标设计

成功率:最基础,但要知道分母。失败的任务算不算?超时算不算?被人工接管算不算?

pass^k:k 次全对的概率。它比平均成功率更接近生产要求,因为它惩罚不稳定。

单位成功成本:总成本 / 成功数。这个指标能揭示”靠重试堆出来的成功率”。

失败分类分布:按失败模式统计占比。这是优化的路标——先修占比最高的那一类。

首次通过率:不重试的情况下一次成功。衡量 harness 的”顺手程度”。

7.5 评测自身的效度

评测也会错,而且错了很难发现。四个检查点:

任务效度:任务是否真的需要它声称的能力?比如一个”代码修复”任务,如果答案在 issue 描述里就有,它测的是阅读理解,不是修复。

评分效度:评分器是否可被绕过?有没有 reward hacking 的空间?用对抗样本测一遍。

环境效度:环境是否可复现?依赖版本、网络、随机种子是否固定?

统计效度:样本量够不够?置信区间多宽?两个系统差 2 个点,是真实差异还是噪声?

一个实用做法:每次评测都保留 10% 的”已知答案”样本,用来检测评分器是否漂移。

7.6 回归门禁与飞轮

回归集:已经稳定的能力,接近 100% 通过率。任何一条失败都阻断合入。

能力集:还有提升空间的,用于衡量进步。

私有集:只在最终决策时用,防止过拟合。

三者分开,是因为它们的目标冲突:回归集要稳,能力集要难,私有集要保密。混在一起会导致”为了提升能力集而牺牲回归集”。

7.7 优缺点

优点:让优化有方向;让回归可发现;让自进化有信号。

缺点:建一次很贵;会过时;会被优化;容易测了容易测的,漏了难的。

7.8 一个评测集的骨架

抽象讲完,给一个可以直接抄的目录结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
evals/
tasks/
0001_fix_circular_import/
task.yaml # 任务定义
setup.sh # 构建环境(幂等)
grader.py # 评分器
fixtures/ # 初始文件、数据库快照
runners/
run.py # 批量运行、并发、重试
results/
2026-11-14T10-00/ # 每次运行一个目录
traces/ # 原始轨迹
summary.json # 汇总指标

task.yaml 至少包含这些字段:

1
2
3
4
5
6
7
8
9
id: "0001"
title: "修复循环导入"
tags: ["python", "multi-file"]
source: "trace_2026_09_14_001" # 来自哪条真实轨迹
setup: "setup.sh"
timeout_s: 900
max_steps: 60
grader: "grader.py"
weight: 1.0

评分器要遵守四条规则:

  1. 幂等:同样的产物跑两次,结果一样。
  2. 隔离:评分时不依赖网络和外部服务。
  3. 防篡改:先校验测试文件和断言没被修改,再跑测试。
  4. 部分分:多步任务给中间分,否则全是 0 分,学不到信号。

评分器的骨架大致是:

1
2
3
4
5
6
7
8
def grade(workdir):
if tests_modified(workdir): # 防篡改
return 0.0, "tests modified"
r = run_pytest(workdir, timeout=300)
score = pass_ratio(r) # 部分分
if not final_state_ok(workdir): # 终态检查
score *= 0.5
return score, r.summary

最后一个容易漏的点:每个任务都要记录 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 防过拟合的六种手段

  1. 三层数据分离:进化集、验证集、私有测试集。私有集只在最后用一次。
  2. 编辑预算退火:早期允许大改,后期只允许小改。防止后期针对评测做特化。
  3. 批评者过滤:让一个独立模型判断”这个修改是不是在利用基准的特征”,是就拒绝。
  4. 预测绑定:每次修改必须写明”预期哪类任务提升、哪类不变”,验证不符就回滚。
  5. 修剪:定期删掉没有贡献的改动,防止复杂度累积。
  6. 多任务族验证:至少在两个不相关的任务族上都有提升,才算真提升。

7.15 安全边界

自进化系统是一个能修改自己的系统,安全要求比普通 Agent 高一个量级。

  • 沙箱:进化过程必须在隔离环境里跑。
  • 锚点:评测脚本、评分器、权限配置不能被被进化对象修改。
  • 审批:合入主线要人确认。
  • 回滚:每次修改是一个 commit,可一键回退。
  • 审计:记录每次修改的动机、预测、结果。

有论文标题提到”被污染的基准会让 DGM / SICA 写出不安全代码”(B 级,仅见标题)。这个方向值得警惕:如果评测信号可以被利用,进化就会学会利用它,包括绕过安全检查。

7.16 优缺点

优点:能发现人想不到的结构;在长程、结构化任务上有真实增益;一旦跑通,迭代成本低于人工调优。

缺点:成本高;评测依赖强;容易过拟合;调试困难(改了哪里、为什么有效,往往说不清);安全风险。

7.17 最小可行实现

八周计划:

  1. 第 1–2 周:把 harness 组件文件化。系统提示、工具描述、工具实现、中间件、记忆策略,各自独立文件,git 管理。
  2. 第 3 周:建评测。50–100 题,确定性评分器优先,分进化集和留出集。
  3. 第 4 周:写提案者。输入是完整轨迹加源码,输出是一个 diff。先用最强模型。
  4. 第 5 周:加档案和选择。先用贪心,跑通再换子树统计。
  5. 第 6 周:加防过拟合。预测绑定 + 编辑预算 + 批评者。
  6. 第 7 周:跑对照。同预算的 test-time scaling 基线必须有。
  7. 第 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 开始读。建议按这个顺序:

  1. 找到”一次模型调用”发生的地方,理解输入输出。
  2. 往外一层,看循环怎么写的,终止条件是什么。
  3. 看上下文是怎么组装的,压缩在哪里触发。
  4. 看工具是怎么注册和执行的,权限在哪里检查。
  5. 看状态存在哪里,崩溃后怎么恢复。

这五步走完,一个 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 数据流

一次进化循环:

  1. 执行层跑一批任务,产生轨迹。
  2. 观测层把轨迹结构化,标注失败模式。
  3. 评测层给出分数和失败分类。
  4. 进化层的提案者读轨迹和源码,提出修改。
  5. 修改在沙箱里跑验证集。
  6. 通过则进档案,不通过则记录原因。
  7. 定期从档案里选最优版本,人工审批后合入。
  8. 记忆层从成功和失败中提炼规则,供下一轮使用。

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 章)

  1. 你能说清楚你的系统里哪些属于模型,哪些属于 harness 吗?
  2. 每一层的输入输出契约有文档吗?
  3. 治理规则(权限、预算)是写在代码里,还是只写在提示里?

B. 上下文(第 3 章)

  1. 前缀是否稳定,缓存命中率是否被监控?
  2. 工具定义是否按需加载?
  3. 大的工具输出是否落文件,只回传摘要?
  4. 有明确的压缩触发线吗?

C. 工具接口(第 3 章)

  1. 工具描述是否写清”何时用、何时不用”?
  2. 参数是否做了防呆(枚举、绝对路径)?
  3. 报错信息是否告诉模型怎么改?

D. 长程与验证(第 4 章)

  1. 有任务清单文件和单特性会话吗?
  2. 验证者是否独立于执行者?
  3. 有看门狗和检查点吗?

E. 多智能体(第 3 章)

  1. 单 Agent 在评测集上是否已到瓶颈?
  2. 任务是否可分解、读多写少?
  3. 有集中的验证点吗?

F. 记忆与自进化(第 8–9、23 章)

  1. 记忆写入有门禁吗?
  2. 有过期与回滚机制吗?
  3. 自进化的编辑空间是否受限?
  4. 有真正从未被接触过的留出集吗?

G. 评测与安全(第 10–11、19 章)

  1. 评测集来自真实轨迹吗?
  2. 用确定性评分器优先吗?
  3. 报告了 pass^k、成本和版本吗?
  4. 写操作有确认或预算吗?
  5. 沙箱隔离是真隔离吗?

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 一份最小书单

如果只读五篇,读这五篇:

  1. Anthropic,Effective harnesses for long-running agents(工程实践最完整)。
  2. AHE(组件文件化 + 自动演化,有消融)。
  3. MAST(失败模式分类,做多 Agent 必读)。
  4. 2607.12227(自进化的反证,防止过度乐观)。
  5. 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 概念与架构

博客

论文

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 —

平台与引擎

B.3 上下文工程

论文

源码与基准

B.4 多智能体

博客与工程报告

论文

源码

B.5 长期记忆

系统与论文

经验与技能

参数化记忆

B.6 长程任务

度量与诊断

Harness 实践

训练侧

B.7 评测与基准

方法论

基准

框架与任务合成

B.8 开源 Harness 源码

B.9 后补材料(逐条核过原文页)

论文(均核对过 arXiv 摘要页)

博客与文档

源码

核对时发现的两处需要注意

  • 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. 一年后这个领域会怎么变? 三个判断:上下文工程会变成标配而不是优势;自进化会收敛到”结构化组件演化”而不是”任意自修改”;评测会从公开榜单转向私有业务集。这三条都会让”把基础做扎实”比”追新方法”更划算。


(全文完)