主题
Prompt 告诉 Agent "做什么",Harness 告诉 Agent "做对了没有" — 总结
来源:KM平台文章
作者:binghuiluo
发布时间:2026-03-13
标签:Agent、Coding、AI、Harness
一、引子:一句话与 1.2 亿 token
作者在一次 Agent 协作中,输入了一句 "e2e 测试验证检查",Agent 从上午9点跑到晚上9点,单个 session 消耗约 1.2 亿 token(约等于几百本书的文字量)。
Agent 并非在空转——它在与真实运行环境中的边缘问题搏斗:macOS 内核缓冲区限制导致数据静默丢失、不同版本 Shell 语法行为不一致、用户配置文件中第三方插件冲突、网络分片时序导致信号被拆散……每修好一个,下一个不同的问题又冒出来。
关键洞察:这 12 小时能持续迭代,恰恰是因为 Harness 给出的反馈足够精确、足够多样。产出的不只是功能代码,而是一整套 Harness——从此同类问题再也不需要 12 小时了。
二、核心观点:环境才是 Agent 的天花板
Agent 的效能天花板不在模型,在环境。准确说,在你愿不愿意为构建验证环境付出必要的成本。
大部分 AI Coding 讨论聚焦于 prompt 怎么写、模型怎么选、context window 够不够长,但真正拿 Agent 干过活的人会发现——瓶颈是项目的运行环境。
跑通闭环的四个条件
| 条件 | 说明 |
|---|---|
| 模型不蠢 | 当前大模型已能分辨测试失败是 feature 变了还是代码有 bug,这个门槛已过 |
| 验证环境接近幂等 | 同样的代码、同样的输入,跑出来的判定必须一致,不能今天绿明天红 |
| 验收条件够明确 | pass 就是 pass,fail 就是 fail,不能是"看起来像对的" |
| 问题够边缘 | 核心逻辑模型写得动,真正难的是运行环境带来的不确定性 |
四个条件中,后三个全是环境问题,而且互相依赖。
三、运行环境的三个层次
Harness 不是一个东西,是一组分层的环境,每一层消灭一类不确定性:
1️⃣ 隔离层:消灭"在我机器上能跑"
- 目的:幂等
- 做法:
- 测试运行在临时目录,不碰用户真实 HOME
- 环境变量受控(PATH 最小集合,HOME 指向临时目录)
- 外部依赖容器化(数据库、SSH、消息队列等,测试后销毁)
- 检验标准:项目 clone 到全新机器,装好运行时和包管理器,
npm test一次通过 - 对 Agent 的意义:隔离层是 Agent 的"世界观基准"
2️⃣ 进程层:覆盖操作系统的"意见"
- 目的:处理跨平台、跨版本的操作系统行为差异
- 典型问题:
- macOS PTY 行缓冲区仅 1024 字节(Linux 4096),超长数据被内核静默丢弃
- macOS 自带 bash 3.2(2007年)vs Linux bash 5.x,语法行为不同
- 用户 .bashrc / .zshrc 加载的插件引入不可预期副作用
- 做法:spawn 真实进程,用 stdin/stdout 通信,在隔离用户环境中验证,不 mock 任何东西
- 特点:暴露出来的问题往往最诡异,正因如此更需要自动化覆盖
3️⃣ 栈层:端到端才是验收基石
- 目的:验证完整链路,而非局部行为
- 典型环境:浏览器自动化 + 前端开发服务器 + 后端服务 + 容器化依赖 + 全局 setup/teardown
- 测试内容:网络传输丢数据?WebSocket 分片导致时序错乱?浏览器事件循环导致异步操作被饿死?
- 对 Agent 的意义:栈层测试是最终验收裁判,只有栈层说"过了",任务才算完成
三层对比
| 层次 | 消灭的不确定性 | 反馈速度 |
|---|---|---|
| 隔离层 | 逻辑错误、接口契约 | 秒级 |
| 进程层 | 操作系统行为差异、进程间交互 | 十秒级 |
| 栈层 | 完整链路集成、网络时序、并发竞态 | 分钟级 |
Agent 修一个栈层失败时,真正的 root cause 往往要回到隔离层或进程层定位。三层联动才构成完整的 Harness。
四、Harness 的设计原则
1. 幂等优先
- 怎么强调都不过分。环境不幂等是 Agent 效能的头号杀手
- 不幂等时 Agent 进入死循环:改代码 → 测试不稳定 → 无法判断 → 继续改 → 耗费大量推理资源做无效分析
- 对客户端项目的两层含义:
- 单元/集成测试环境要隔离干净(保证反馈确定性)
- 端到端测试要故意暴露在真实环境下(让边缘问题提前浮出来)
2. 信号明确
- 验收结果必须是机器可读的结构化信号(JSON、exit code、结构化协议消息)
- 不能是"看终端输出像不像对的"、"日志里没有 ERROR 字样"
- Agent 可以 grep、正则匹配、解析 JSON,但没法"看一眼终端觉得大概对了"
3. 分层捕获
- 不同类型的失败在不同层暴露(这是客观规律,不是美学追求)
- 字符串转义 bug → 隔离层就该挂掉
- 进程配置异常 → 只有进程层测试才暴露
- 系统缓冲区溢出 → 只有栈层测试才暴露
- 跳过任何一层 = 给那一类问题留了免检通道
4. 超时和降级
- 每个环节都应有独立超时,超时 ≠ 失败,超时是降级
- Agent 需要区分:超时(外部环境暂时不可用)vs 错误结果(代码 bug)
- 没有超时机制 → Agent 面对无限等待的黑洞
五、AI Coding 是放大器
工程基础好 + Agent = 效率爆炸
工程基础差 + Agent = 灾难加速
- 好的情况:Harness 到位,Agent 能在一个 session 里完成多文件修改、跑几百个测试、反复 debug 直到全绿
- 差的情况:没有 Harness,Agent 会"自信地"写出能编译、能通过 lint、但行为完全错误的代码
- 更糟的情况:只有单元测试没有端到端验收,Agent 会"过拟合"到单元测试层——把单元测试调绿,但真实环境跑不通
- 反面也是正面:Agent 不怕脏活,愿意在不确定环境里一个问题一个问题地啃。1.2 亿 token 是一次性的基建成本,不是持续的运行开销
六、Accept Automation 才是目的
Harness Engineering 的目标不是"写更多测试",而是 Accept Automation——自动化验收。
- TDD、CI/CD、契约测试,这些理念一个比一个正确,一个比一个难落地
- 难不在技术,在于组织上总有理由不做(进度压力、deadline、"差不多就行")
- Agent 是第一个真正无法"跳过测试"的开发者——没有偷懒动机,没有赶进度压力,只认环境反馈
- 为 Agent 构建的 Harness 人类开发者一样受益
七、结语
Prompt 告诉 Agent "做什么"。Harness 告诉 Agent "做对了没有"。
前者是需求,后者是工程。没有后者,前者只是一句愿望。
Harness Engineering 本质上就是软件工程本身——讲了几十年的工程化,终于不用再假装达成了。因为现在有了一个不会绕路的执行者(Agent),它才变成了必需品。
那 1.2 亿 token,就是认真做工程的代价。贵,但一次性。建好之后,每一次后续的 Agent 协作都在享受这笔投入的回报。
核心金句摘录
- "Agent 的效能天花板不在模型,在环境"
- "Harness 不是一个东西,是一组分层的环境,每一层消灭一类不确定性"
- "环境不幂等是 Agent 效能的头号杀手"
- "Agent 是第一个真正无法'跳过测试'的开发者"
- "AI Coding 是放大器:工程基础好效率爆炸,工程基础差灾难加速"
- "1.2 亿 token 是一次性的基建成本,不是持续的运行开销"