Agent开发入门系列第 10 篇 · 读这一篇需要 6 分钟 · 系列收官篇
系列导读:这个系列不追热点,只把 Agent 架构里那些密度极高、一次读不透的概念,一个一个拆开。
某团队改 Prompt 的流程是这样的:改一版,跑几十个临时编的用例,"感觉好像变好了",上线。线上出问题,回滚。再改一版,跑更多用例,"感觉好像更好了",上线。又出问题。
三个月后他们发现:所有真正生效的改动都能在两周前的版本里找到差异;而所有线上事故,都来自那些"感觉变好了"的改动。 问题不在于测试不够多,而在于缺一套判断标准。
一、为什么需要"原则"
第 9 篇最后留了一个判断:范式划分会过时,设计原则不会。
模型每半年换一轮,今天要手写的 JSON 修复代码,后天模型自己就写错了。但下面这些原则有一个共同点------它们约束的不是模型能力,是系统的形状。

这八条原则是并列关系,不是包含关系。 它们不像第 9 篇那五个范式层层嵌套,每一条独立成立,而且几乎必然同时生效。
二、三个基本原则
1. 保持简单
从最简单的方案开始,只在必要时增加复杂度。 优先直接调 API,不要先造一层框架;优先用确定性代码解决确定性问题。
每增加一层抽象,都会增加调试和理解成本。
抽象的成本在写代码时不付,在出问题时一次性付------第 5 篇讲过,验证的前提是你能追踪一次失败经过了几层。
2. 保持透明
展示或记录:规划步骤、执行日志、决策轨迹、工具调用、验证结果。
第 3 篇讲 ReAct 轨迹时提过一句话:轨迹既是下一次决策的输入,也是事后排查的唯一证据。这两件事不冲突------透明性既服务于调试,也有助于建立用户信任。 用户不信任 Agent,往往不来自它做错了,而来自它说不清为什么这么做。
3. 设计好工具接口(ACI)
ACI(Agent-Computer Interface) 这个词是对标 HCI 造出来的:接口应该为使用者设计,而不是为调用者设计。
Agent 就是使用者。它一次可能调用几十次、参数说明可能比任务描述还长,它不会因为"这个字段不太清楚"停下来问你------人靠常识补上的一步,对它是致命的。
要素:名称直观、参数清晰、提供示例、明确边界。最关键的是:
尽量让误用在设计上不可发生。
这个思想和制造业的防呆(Poka-yote)一模一样:USB 插头做成那个奇怪形状,不是因为用户要小心,而是因为错误的形状根本插不进去 。放到 ACI 上就是------一个只接受 start_date 而拒绝 2025/13/45 的工具,一个把"删除"和"归档"分成两个名字的接口。
三、五个通用设计模式
4. 渐进式披露(Progressive Disclosure)
思路来自 UI 设计:不要一次性把所有信息摊开,只给目录,让使用者自己点进去。 用在 Agent 上就是三步------先给目录或元数据 → 允许检索 → 按需加载详细内容,同时优化两个目标:
| 目标 | 含义 |
|---|---|
| 上下文预算 | 别把所有东西塞进窗口,把预算留给真正需要的 |
| 选择精度 | 别让无关信息挤占注意力,模型选得更准 |
落地形态:Agent Skills 、分层检索 、主动工具发现 (不够用时主动去工具库检索,而不是启动时全挂上)、分页截断 (明确告诉 Agent "还有第 2 页"而不是静默截断)、多 Agent 发现。
5. 只增不改(Append-only)
状态以追加方式演进,已经写入的内容不回头修改。
三个收益------可缓存 (KV Cache 前缀稳定)、可重放 (状态能原样重建)、可审计(记录完整,不因覆盖丢线索)。对应场景:知识库更新写成新记录而非原地改旧;事件式记忆按时间追加;工具 schema 追加到轨迹末尾。
核心价值是一句:保证历史记录稳定、减少缓存失效、方便审计和重放 ------只要历史能完整保留,事后判断才有依据。
6. 边界集 + 保留集
这是八条里最朴素、也最容易被跳过的一条:每次修改都必须同时在两类样本上验证。
| 验证什么 | 缺了会怎样 | |
|---|---|---|
| 边界集 | 它应当改变的那批样本 | 不知道改动到底生效没有 |
| 保留集 | 它不应当影响的那批样本 | 不知道改动是否引入了回归 |
关键在于两类样本对应两种方向正好相反的失败方式:
只测边界集 → 把过拟合误认为进步。 你优化的是那一组样本,不是真实分布------反复用同一批边界集调 Prompt,调出来的就是过拟合。
只测保留集 → 把无效修改误认为安全。 保留集全绿,你得到的是虚假的安全感:它只能证明"什么都没变坏",不能证明"什么变好了"------一个没改动的系统也能拿满分。
适用:回归任务、训练与评估的数据隔离、更新提案的验证。
7. 最小 diff + 可回滚
每次修改应该:尽量小、带来源、可单独回滚、易于归因、避免整体重写。 适用:知识更新、代码补丁、Prompt 更新、规则更新。
最被低估的是**"带来源"------每条修改要能回答"它为什么存在、对应哪个被验证过的问题"。回到开头那个团队:Prompt 改一次崩一次,正是因为没有一次可独立回滚**。
这条原则正好对应第 6 篇的三层更新路径------上下文内适应、外部产物更新、参数更新。
从可解释性和可回滚角度看,外部产物更新通常更容易审计和控制。
这就是这八条原则里大多数原则真正的落点。 第 6 篇的判断标准是"能不能写成文字或规则",这里补上第二条:能不能被 diff、回滚、被独立审核。
8. 提议者---审核者(Proposer-Reviewer)
由两个不共享上下文的角色分别负责:一个生成产物,另一个独立审核。

审核者看到什么 是整个模式的关键:渲染结果、测试输出与断言结果、结构化调用参数、最终产物。看不到产出方的推理过程。这是立论基础:
同一个上下文中的模型难以发现自己的认知盲区,也可能无法识别自己已经被注入。
拆开看是两种失败。发现不了认知盲区 ------提议者把某个结论写进上下文,审核者读到时会当成既成事实,提议者的错误变成了审核者的前提。识别不了自己被注入 ------提示注入混在提议者的上下文里,审核者读同一份时同样会读到,它没有第二个干净的视角。
所以隔离不是流程洁癖,而是这个模式能不能成立的前提条件------不隔离的审核者,只是在复述提议者的判断。
适用:知识更新、工具调用审批与事后验证、PPT / 视频 / 日志生成、UI 评估、多 Agent 协作。Sidecar 是它的一种只读变体------只审核、不生成,天然不共享上下文。
四、这八条落在哪一层
把这八条对进第 6 篇的三层更新机制:
| 原则 | 上下文内适应 | 外部产物更新 | 参数更新 |
|---|---|---|---|
| 渐进式披露 | ✓ | ✓ | --- |
| 只增不改 | ✓ | ✓ | --- |
| 边界集 + 保留集 | --- | ✓ | ✓ |
| 最小 diff + 可回滚 | --- | ✓ | ✗ |
| 提议者---审核者 | --- | ✓ | ✗ |
这八条原则中大部分作用于"外部产物更新"这一层------因为这是唯一可审计、可修改、可回滚的一层。
上下文内适应的问题不是它不好,而是它改完就没了 ------没有任何产物可以 diff、回滚或交给另一个角色审核。 参数更新正好相反:它把经验固化进权重,但你看不见 diff,也退不回去 。外部产物更新两重困境都没有:它是文本 ,又独立于模型。
五、长时运行 Agent 的 Harness 设计
真要处理"一个任务跑几小时甚至跨天"的场景,还需要专门的 Harness 结构。Anthropic 的思路是拆成两个角色:初始化 Agent 设置环境、分解任务列表、建立初始状态;执行 Agent 在每个会话中增量推进、留下交接产物、避免过早声明完成。
| 问题 | 结构化手段 |
|---|---|
| 上下文耗尽 | 每轮只带必要状态进上下文 |
| 长任务中断 | 状态存在上下文之外的外部产物里 |
| 任务状态丢失 | 任务列表独立维护,可持久化 |
| 过早完成 | 显式的完成判据,不能由模型自行宣布 |
| 会话之间无法接续 | 交接产物作为下一轮的起点 |
这个结构本身就是前面原则的应用:任务列表是外部产物,所以可审计可回滚 ;执行 Agent 不共享初始化 Agent 的上下文,所以有提议者---审核者的味道 ;避免过早声明完成,是第 9 篇"何时算真正完成"的工程答案。
六、什么时候这个说法会失效
原则是最容易被当成教条的东西,所以这一节要写重一点。
第一,渐进式披露会增加一次往返,简单任务上得不偿失。 目录 → 检索 → 加载至少多一次模型往返。如果只需要读一个 200 字的文件,先给目录再取全文比直接塞进去更慢。 适用条件是"全量会挤爆预算"。
第二,只增不改会让上下文持续膨胀,这和第 2 篇的上下文预算直接冲突。 轨迹只增不减是优势也是代价:第 30 轮时窗口里有 29 轮的历史,而上下文工程里必须存在压缩、摘要、丢弃------这些动作全都是"改"。 只增不改真正适用的范围是可持久化的外部存储。
第三,提议者---审核者意味着成本翻倍,而且审核者可能只是另一种模型的偏见。 两个角色就是两次调用、两倍 token、两倍延迟。审核者也是模型,它同样可能犯错,它的偏见只是和提议者不同,不代表更少 ------你完全可能得到"提议者错了,审核者也错了,还错了另一个方向"的结果。独立不等于正确。
第四,最小 diff 在需要大范围重构时反而更难。 换掉整个检索策略、重构一层抽象、迁移一套数据格式------硬拆成十个小 diff,每一步都要保证系统可运行,成本远高于一次大改然后充分测试。它的前提是存在一个明显更小的等价改法;不存在时,这条原则会逼你写出更糟的代码。
第五,边界集和保留集需要人工精心构造,成本很高,而且一定会漏。 这两套样本集不是自动生成的。更麻烦的是保留集会被逐渐"吃掉"------每次失败都往里加一条,加到最后它变成了另一个训练集。
第六,"简单"和"透明"在某些场景下与安全和效率直接冲突。 透明意味着完整记录决策轨迹,而轨迹本身可能包含敏感数据 ------全部执行日志写进数据库,是审计资产,也是攻击面和合规风险。简单意味着不做多余抽象、不做重复校验,在需要权限隔离的场景里,"少一层"可能就是少一道防线。这两条原则都有隐含前提:默认你处在一个可信环境里。
第七,原则本身也会被模型内化。 如果哪天模型原生就能可靠维持长程状态、自己完成验证和纠错,"保持透明""避免过早声明完成"就不再必要------不是因为原则错了,而是因为它变成了模型的默认行为。 判断一份原则清单是否过期:看它是否还在解决真实问题。
小结
十篇走完是一条很克制的路线:拆开三件套、设计眼睛和手脚、处理模型变强带来的张力、加护栏、摆范式,最后收在不依赖模型能力的约束上。
ini
保持简单 = 每加一层抽象,就多付一层调试成本
保持透明 = 轨迹既是决策输入,也是唯一证据
设计好接口 = 让误用在设计上不可发生(防呆)
渐进式披露 = 先目录后内容,同时省预算和提精度
只增不改 = 可缓存、可重放、可审计
边界集+保留集 = 该变的和不该变的必须一起验
最小 diff = 小才好归因,好归因才好回滚
提议者---审核者 = 隔离上下文,才可能发现自己的盲区
回到第 1 篇那个公式,它到现在还是全部内容的锚:
Agent = 大脑(LLM)+ 眼睛(上下文)+ 手脚(工具)
没进上下文的信息 = 不存在。没被动作接口允许的操作 = 做不到。
这八条原则里,渐进式披露、只增不改、ACI、护栏是在加固这两条边界;边界集+保留集、最小 diff、提议者---审核者,是在模型之外加一层独立于模型的验证机制 。它们不指望模型更聪明,只指望系统更清楚。
最后是我自己的判断:
模型会越来越强,但决定一个 Agent 靠不靠谱的,永远是模型之外的那部分。
理由有三层。
第一,模型的能力提升会同时抬高所有人的基线。 当下一代模型把上一代 Harness 的脚手架内化进去,差距会被抹平------但被抹平的是所有用同一个模型的人之间的差距。 你要赢的不是"用了新模型",而是"模型更新后系统没退化"。
第二,能力的进步和可靠性不是一回事。 更强的推理会提升单步成功率,但 Agent 面对的是长链条------每一环 95% 的可靠性,20 环之后只剩 36%。 这个衰减不会因为模型变强而消失,只会被更强的底数抬高。要压住它,靠的是外部产物更新、最小 diff 这类不依赖模型判断力的机制。
第三,也是最重要的一点:模型输出的"看起来对"和"实际对"之间的差距,只能由外部来收。 这就是提议者---审核者的全部理由。同一个上下文里的模型,看不见自己的盲区。 这不是这一代模型的缺陷,而是自回归预测的性质------模型只能顺着已有内容往下生成,没法回头质疑前提。要给它一面镜子,就得从外面递一面进去。
所以这八条原则的真正寿命,不是"到下一代模型发布为止"。它们会因为模型变强而显得多余,但不会因为模型变强而失效。 模型再强,边界仍在:没进上下文的信息依然不存在,没被动作接口允许的操作依然做不到,而是否有人在这两条边界之外为它的每一次修改做过验证------这件事永远得有人管。
这就是这个系列的结尾。
十篇,一个公式。感谢你读到这里。如果这个系列帮你把"Agent 到底是什么"讲清楚了,那它就完成了它该做的事。