目录

轻一点的 harness,强一点的 runtime:Agent 训练轨迹里的信号问题

讨论 Agent 的时候,我们很容易把注意力放在模型本身:参数更多了、上下文更长了、工具调用更稳了。但真正把一个模型变成可工作的 Agent 的,往往是模型外面那层 harness

这里的 harness 可以理解成 Agent 的脚手架或外骨骼:Planner、状态机、工具路由、反思模块、子 Agent 调度、上下文压缩、权限规则、重试策略、执行环境、日志系统等等。它的初衷很合理:模型不够稳定时,用工程系统把它扶住,让任务能跑完。

问题在于,如果 harness 太重,它也会反过来污染训练信号。很多看起来成功的轨迹,未必说明模型真的学会了工作,也可能只是框架把模型一路扶到了终点。

重 harness 最大的问题:成功不再好解释

设想一个 coding agent 修好了一个测试。表面轨迹可能长这样:

读测试文件 -> 读源码 -> 修改代码 -> 运行测试 -> 修复失败 -> 最终通过

这条轨迹看上去很漂亮。但它背后可能有两种完全不同的因果解释。

第一种是模型真的会工作:

模型判断应该先读测试;
模型选择运行最小测试;
模型根据错误日志定位原因;
模型决定做小范围修改;
模型主动验证结果。

第二种是 harness 很强:

框架规定 bug fix 任务必须先读测试;
框架自动注入相关文件;
框架自动运行测试;
框架发现失败后自动重试;
框架用规则选择了修复策略。

两种轨迹表面相似,训练价值却完全不同。前者能训练出更强的通用 Agent;后者更像是在训练模型适应某一套流程。也就是说,harness 越重,越难判断成功到底来自模型能力,还是来自框架托举。

模型学到的可能不是原则,而是环境习惯

重 harness 还有一个更隐蔽的问题:它会让模型学习到某个框架的局部习惯,而不是可迁移的工作原则。

比如一个框架里的工具叫:

ReadFile
SearchCode
RunShell
ApplyPatch

另一个框架里工具变成:

read
grep
bash
edit

如果训练轨迹强依赖前一个框架,模型可能学到的是:

看到测试失败 -> 调用 SearchCode -> 调用 ApplyPatch

而不是更抽象的原则:

看到测试失败 -> 找失败证据 -> 找相关代码 -> 做最小修改 -> 运行验证

后者可以迁移到任何工具环境,前者只能适配某个 harness。这就像学生不是学会了数学,而是背熟了某本练习册的答案格式。一换题型,就开始不稳。

所以,高质量 Agent 训练数据不能只保存某个框架的内部流程,而要尽量抽象出底层语义:

当前目标是什么;
可见证据是什么;
模型选择了什么动作;
动作产生了什么结果;
结果是否支持继续;
任务是否真的完成。

这也是为什么轨迹数据需要标准化。不要只记录:

framework_state = RETRY_STEP_3

更有价值的是转换成语义事件:

{
  "event": "tool_call_failed",
  "tool": "Bash",
  "reason": "test_command_not_found",
  "model_next_action": "inspect_package_scripts",
  "outcome": "recovered"
}

前者是框架状态,后者才是可以跨框架复用的经验。

重 harness 会制造虚假的 Agent 能力

更危险的是,重 harness 会让我们高估模型本体。

如果框架自动压缩上下文,模型看起来就像长程记忆很好;如果框架自动选择工具,模型看起来就像工具使用很好;如果框架自动重试失败命令,模型看起来就像错误恢复很好;如果框架自动生成计划,模型看起来就像规划能力很好。

这些都可能是真能力,也可能只是外部系统给出的错觉。

一旦换到新的执行环境,问题就会暴露:

模型不会自己找上下文;
不会判断风险;
不会决定验证方式;
不会从失败日志里恢复;
不会在工具变化时迁移策略。

所以,重 harness 的最大风险不是效率低,而是掩盖了模型真实的能力边界。它让我们以为自己在训练一个更会工作的模型,实际却可能只是在训练一个更会配合某个工作台的模型。

训练时最难的是 credit assignment

Agent 训练里最难的问题之一,是功劳归因。一次任务成功,背后可能有很多参与者:

模型;
工具;
权限系统;
上下文检索器;
Planner;
Verifier;
重试器;
子 Agent;
人类用户;
测试环境。

任务成功以后,到底应该奖励谁?

如果模型选择了危险命令,但 harness 拦截并改写成安全命令,最后任务成功了,那么这条轨迹能不能直接当正样本?不能。因为模型原始动作是错的。如果只看最终成功,就会错误奖励:

危险动作 -> 被框架救回来 -> 最终成功

模型可能学到“危险动作也没关系”。

再比如,模型没有主动运行测试,但 harness 在最后自动跑了测试并发现通过。如果我们把这条轨迹当成“模型完成前会验证”的正样本,也是不准确的。

真正有价值的轨迹数据,必须拆开记录:

模型原始意图是什么;
harness 改写了什么;
工具真实执行了什么;
权限系统拦截了什么;
最终结果是谁导致的;
模型有没有从反馈中主动修正。

否则,训练闭环会吸收很多错误信号。最终模型学到的不是“怎么把事情做好”,而是“怎么在框架保护下看起来做得不错”。

训练期的 harness 应该像观察仪器,而不是代驾司机

更适合训练的 Agent harness,应该薄而透明。它不应该过度替模型做认知决策,而应该把真实反馈暴露出来,让模型从反馈中学习。

例如,不要直接替模型决定:

这个任务应该读哪些文件。

更好的方式是让模型自己选择文件,并记录:

模型读了哪些文件;
哪些文件后来证明有用;
哪些文件是无效读取;
缺少哪个文件导致失败;
成功轨迹通常先读哪些文件。

这样训练出来的是上下文选择能力。

再比如,不要直接替模型决定:

测试失败后应该怎么修。

而是记录:

模型看到的错误日志;
模型提出的修复假设;
模型修改的 diff;
测试是否通过;
失败后模型是否换策略。

这样训练出来的是错误恢复能力。

训练期的 harness 更像一台观察仪器:它记录、约束、回放、验收,但尽量不替模型思考。模型承担认知责任,框架承担工程责任。

不是 harness 越轻越好,而是认知层要轻,执行层要强

这里很容易走到另一个极端:既然重 harness 会污染训练信号,那是不是 harness 越轻越好?

我觉得不是。更准确的说法是:

认知层要轻,执行层要强。

也就是:

少替模型思考;
多约束模型行动。

框架应该尽量少做这些事:

替模型规划;
替模型选工具;
替模型决定下一步;
替模型总结自己做得好不好;
替模型自动修正策略。

但必须强力保留这些能力:

权限控制;
沙箱隔离;
日志记录;
超时中断;
回滚恢复;
工具参数校验;
数据脱敏;
离线回放;
结果验证;
安全边界。

未来好的 Agent 框架不应该是重编排器,而应该是强 runtime。

哪些能力应该蒸馏进模型,哪些必须留在框架

可以把 harness 能力分成两类:可蒸馏能力和不可蒸馏边界。

可蒸馏能力,是那些长期应该被模型学会的工作能力:

Harness 能力未来是否应内化到模型原因
任务分解模型应学会自己规划
工具选择Agent 的核心能力
上下文选择决定效率和质量
错误恢复策略泛化能力关键
何时验证体现真实工作流
避免重复无效动作需要从失败轨迹学习
小范围修改偏好coding agent 的基本习惯

不可蒸馏边界,是不能完全交给模型自觉的系统能力:

Harness 能力是否应保留在框架原因
权限执行必须保留模型不能自己批准自己
沙箱隔离必须保留防止真实副作用
审计日志必须保留用于追责、调试和回放
密钥保护必须保留安全边界不能靠模型自觉
工具参数校验必须保留防止非法调用
版本回滚必须保留真实文件修改需要恢复能力
离线评估必须保留新模型不能直接线上试错

一句话:可以让模型学会怎么工作,但不能让模型成为唯一的安全边界。

一个好的训练 harness 应该长什么样

我会把它概括成六个部分:

薄认知编排
+ 强执行护栏
+ 完整轨迹记录
+ 可插拔评估器
+ 标准化事件格式
+ 离线回放环境

具体到设计原则,大概是这些:

1. 不强制固定 Planner,让模型自己决定是否规划。
2. 不硬编码工具顺序,让模型自己选择工具。
3. 不自动替模型完成验证,但可以标注“未验证”。
4. 不隐藏工具失败,要把失败原样反馈给模型。
5. 不把权限拒绝静默改写,要让模型看到拒绝原因。
6. 不只保存最终结果,要保存完整行为链。
7. 不把最终成功当作唯一奖励,要标注每一步动作质量。
8. 不让生产安全依赖模型自觉,要由框架强制执行。

这套设计的核心,就是让模型承担尽可能多的认知责任,让框架承担不可替代的工程责任。

判断一个 harness 模块该不该退场

可以问三个问题:

1. 这个模块是在替模型做判断,还是在约束真实世界风险?
2. 这个模块产生的能力,能不能通过轨迹训练内化到模型?
3. 去掉它以后,只是模型表现下降,还是会造成安全、数据、资产风险?

如果答案是:

替模型做判断;
可以训练内化;
去掉后主要影响效果,不直接造成不可接受风险;

那它就应该逐步简化。

如果答案是:

约束真实世界风险;
不能完全依赖模型内化;
去掉后可能造成安全、隐私、资产或合规问题;

那它必须保留在框架里。

最终形态:轻 harness 不是少系统,而是少认知干预

所以,我会把这件事总结成一句话:

不是 harness 越轻越好;
而是认知 harness 越轻越好,执行 harness 越强越好。

未来 Agent 框架的方向应该是:

少编排,多运行时;
少流程,多约束;
少替模型想,多让模型做;
少看最终回答,多看完整轨迹;
少线上试错,多离线回放;
少自我反思,多外部验证。

Agent 训练真正宝贵的不是一段看起来顺滑的完成过程,而是轨迹里可解释、可归因、可迁移的因果信号。harness 可以保护模型与真实世界之间的边界,但它最好不要把模型该学会的工作能力全都代劳掉。