摘要
AI 能生成代码之后,项目仍然会遇到一组难题:
- 需求在执行中被悄悄缩小;
- 测试通过,却没有覆盖真正的风险;
- 开发环境中的成功,无法被另一位接手者重现;
- 验证流程越来越复杂,最终让一次小修改承担过高的成本。
本文以 Gavin 博客的建设实践为材料,讨论这些问题背后的共同机制,以及可以迁移到其他项目的设计原则。
核心观点是:
Harness Engineering 要建立从用户意图到执行结果的可追溯关系,让 Agent 能够自主推进,让人能够判断它是否正确推进,并使这套机制的成本与风险相称。
项目经验提供了具体例子与反例。
下文以工程问题组织讨论,重点解释:
- 每项机制解决什么;
- 为什么有效;
- 边界在哪里;
- 如何在自己的项目中采用。
案例支持设计分析,不能单独证明某种通用效率提升比例。
一、从一个完整用户行为理解工程对象
个人博客看似简单,但“发布一篇文章”已经涉及:
- 编辑器状态;
- 接口请求;
- 身份认证;
- 数据库事务;
- 内容版本;
- 公开页面。
按钮显示成功,只能说明某个局部步骤返回了结果。
用户真正需要的是:
文章被正确保存,并以符合规则的内容公开展示。
Gavin 将核心文章功能写成一个纵向闭环:
管理员登录
↓
创建草稿
↓
自动保存
↓
预览
↓
发布
↓
公开页面读取
规格还明确了:
- 版本冲突;
- 稳定地址;
- 草稿不可公开;
等边界。
以用户行为,而不是页面或接口作为开发单位
从这个例子可以学习的第一件事,是如何选择开发单位。
如果以:
- “做一个页面”
- “补一个接口”
- “加一个按钮”
为单位,很容易得到局部完成的部件。
如果以可观察的用户行为为单位,才能发现跨层责任之间的空隙。
例如,对“自动保存”的理解至少有三个层次:
| 层次 | 需要确认的事实 |
|---|---|
| 用户体验 | 用户能够看到保存状态 |
| 服务端行为 | 内容确实被持久化 |
| 数据正确性 | 并发修改时不会被无声覆盖 |
页面实现、接口成功和数据正确,分别需要不同的观察方式,不能互相替代。
这也是 Harness 的起点:
先确定需要保持成立的行为,再安排实现和验证。
如果目标本身含糊,后续再精密的执行器,也只能精密地完成一个含糊任务。
需要特别区分的是:
- 博客中的问答 Agent,是产品功能;
- 围绕整个代码库建立的上下文、任务规格、验证和交接机制,才是本文讨论的仓库级 Harness。
二、将关键知识放进可查找、可维护的结构
Agent 在连续工作中需要恢复的,不只是代码,还包括:
- 产品边界;
- 已有决策;
- 任务范围;
- 未完成事项。
如果这些信息只存在于聊天记录中,接手者就必须反复猜测。
项目采用了短入口 + 分层文档的方式:
AGENTS.md提供地图和硬边界;- 任务相关的产品基线与工作流按需加载;
- 更细的支撑材料通过索引查询;
- 文档带有用途与加载条件;
- 生成索引负责提供发现路径。
为什么不能无差别加载全部上下文
可以用一次接口变更来理解。
Agent 需要知道:
- 接口归谁维护;
- 前端如何消费;
- 哪些测试验证跨端契约。
但它通常不需要同时读取:
- 视觉设计的全部历史讨论;
- 已经退役模块的方案;
- 所有部署尝试。
无差别加载会带来两个问题:
- 挤占有限的注意力;
- 把已经失效的材料重新带入当前决策。
上下文工程至少要回答四个问题
| 问题 | 设计要求 | 缺失时的典型结果 |
|---|---|---|
| 去哪里找? | 有稳定入口和清晰路由 | Agent 重复搜索或自行猜测 |
| 哪份为准? | 标明责任、状态和适用范围 | 相互冲突的文档同时被当作规则 |
| 什么时候读? | 按任务加载相关材料 | 无关信息稀释关键约束 |
| 谁负责更新? | 变更关联文档维护责任 | 实现变化后仍按旧说明执行 |
三、文档也有生命周期
这里还有一个容易忽略的变量:
信息的寿命。
不同文档承担的职责不同:
| 文档类型 | 更适合承载的内容 |
|---|---|
| 临时 spec | 一次任务的目标、范围、验收 |
| 长期 README | 持续有效的能力与使用方式 |
| 决策记录 | 长期架构与规则依据 |
| 历史归档 | 已结束任务与过去决策 |
| 稳定索引 | 长期入口与发现路径 |
项目曾出现一种问题:
长期 README 链接到 active spec,规格关闭后,长期文档中的链接随之失效。
随后,项目通过稳定索引和链接检查约束这类引用。
由此可以提炼出一条可迁移原则:
引用关系也需要遵守生命周期。
长期知识应该指向稳定入口。
临时状态可以消失,但不能让长期知识失去依据。
在自己的项目中,不一定一开始就建设复杂文档系统。
可以先维护:
- 一份简短入口;
- 几份责任明确的边界文档;
- 当前任务记录。
等发现路径和维护问题真实出现,再增加:
- 元数据;
- 自动索引;
- 生命周期检查。
文件数量本身没有价值,关键是接手者能否快速找到足以继续工作的事实。
四、规格的作用,是保护意图在执行过程中不走样
SDD,即规格驱动开发,常被理解为:
先写文档,再写代码。
但更值得学习的是它对意图的保护作用:
把模糊目标转换成能够讨论、实现和检查的约定。
项目的 spec 要求写明:
- 目标;
- 非目标;
- 可观察验收标准;
- 验证计划;
- 文档影响。
涉及以下内容的变化,需要更正式的约束:
- 行为;
- 接口;
- 数据;
- 安全;
- 架构边界。
而低风险、机械式修改可以采用更轻的流程。
“完成发布功能”还不够具体
以文章发布为例:
“完成发布功能”
没有说明:
- 发布读取哪个版本;
- 持久化失败时界面怎样反馈;
- 草稿是否进入公开查询;
- 冲突是否保留用户修改。
更好的规格应该明确这些行为。
同时,非目标也很重要。
例如:
本次不同时建设多人协作编辑。
它可以防止任务在执行过程中无限扩张。
五、规格本身也可能偏离原始目标
规格并不会自动保证忠实于用户需求。
项目材料记录过一种失败:
执行者自行收窄 spec,验证通过后,将其表述成完整提案已经完成,但原提案仍有要求未交付。
这件事揭示了两个彼此独立的关系:
用户目标
↓
规格中的验收标准
↓
实现与验证证据
也可以拆成:
用户目标 → 规格中的验收标准
验收标准 → 实现与验证证据
第二个关系可以高度自动化。
第一个关系仍然需要理解和审查。
工具能够检查:
每条 AC 是否存在对应证据?
但它未必知道:
Agent 是否已经把困难要求从 AC 中删掉?
人应该重点检查什么
审查规格时,应回到原始请求,检查:
- 显式要求是否被覆盖;
- 隐含边界是否被考虑;
- 未解决的决策是否仍被明确保留;
- 范围是否被擅自缩小;
- 局部阶段是否被错误表述为整体完成。
合理拆分阶段可以提高交付效率,但必须清楚表达:
- 本阶段完成什么;
- 整体目标还差什么。
不能用一个局部闭环,替代整体完成。
这也是人更值得投入注意力的位置。
反复审批每一个可逆小动作,会消耗大量精力。
相比之下,检查:
- 目标是否被正确翻译;
- 范围是否被擅自改变;
更能防止方向性错误。
六、把验证设计成一条解释链
“测试通过”只有在知道:
测试了什么?
之后才有意义。
项目将 VDD,即验证驱动开发,分成三个层次:
- 方法:依据什么验证;
- 检查:实际执行什么;
- 证据:保存本次结果。
单元、契约、集成、端到端和质量检查,在这套结构中承担不同职责。
示例:验证文章公开读取
下面是一种教学式拆解:
| 层次 | 要表达的内容 |
|---|---|
| 用户要求 | 读者可以阅读已发布文章 |
| 正向预期 | 当前公开版本能够被查询和展示 |
| 禁止发生项 | 草稿或未发布修改不能出现在公开结果中 |
| 局部检查 | 查询逻辑正确处理状态和版本 |
| 集成检查 | API 与持久化共同满足公开边界 |
| 用户路径检查 | 管理员发布后,读者能够访问正确内容 |
负向预期尤其重要
很多高风险能力都依赖:
某件事情绝不能发生。
例如:
- 未认证用户不能访问管理功能;
- 草稿不能泄露;
- 已撤销权限不能继续生效;
- 被删除内容不能重新出现在公开查询;
- 超预算任务不能继续消耗资源。
如果测试只验证正常路径,就可能出现:
功能可用,但边界已经失守。
七、让重要结论可以一路追问到底
项目进一步把:
- 模块;
- 场景;
- 可观察预期;
- 精确测试引用;
- 执行入口;
连接起来,使验收标准能够追溯到具体检查。
这套设计还能识别一种看似严谨的假覆盖:
- 源码里存在一个测试名,不代表它会被框架收集;
- 被收集,不代表本次执行过;
- 测试总数相同,不代表运行的是指定集合。
项目的执行合同因此核对完整测试身份,并拒绝:
- 遗漏;
- 重复;
- 意外扩张。
但还要注意:
测试身份正确,也不代表断言充分。
一个名字叫:
reject draft leakage
的测试,可能只是检查:
HTTP 200
却没有检查结果里是否真的没有草稿。
因此:
- 机械关联提高可追溯性;
- 语义审查判断关联是否合理。
可以提炼出一个通用方法:
让每个重要结论都能沿着“要求 → 场景 → 断言 → 执行结果”被追问。
不必为所有细枝末节建设复杂合同,但高风险边界应该拥有明确的:
- 正向证据;
- 负向证据。
八、验证范围由影响决定,不能由修改行数决定
“只改了一行”不是风险判断。
共享过滤条件的一行修改,可能影响所有公开内容。
一个独立格式工具的大段重写,也可能只影响少数调用方。
项目使用:
- 源码归属;
- 消费者关系;
辅助分析,再为具体任务记录:
- 哪些消费者受影响;
- 哪些消费者不受影响;
- 为什么。
执行器据此选择相关场景和测试,而不是简单地把:
修改文件所在目录
当作全部验证范围。
示例:修改发布时间语义
如果修改文章发布时间的含义,影响可能沿着数据流传播:
发布时间语义
↓
API 排序
↓
前端列表
↓
时间筛选
↓
内容发现输出
只测试修改的函数,可能漏掉下游消费者。
但直接运行整个项目,也不一定是每次开发循环最合理的选择。
更合适的是:
沿着输出契约和数据流检查实际影响,再决定需要验证哪些场景。
九、影响分析既要知道什么时候扩展,也要知道什么时候停止
好的影响分析不只是不断扩大范围。
它还需要明确停止规则。
例如:
需要继续扩展
输出契约发生变化
→ 检查下游消费者
可以停止
消费者并不依赖被改变部分
→ 记录理由后停止传播
未知归属和缺失判断,则应该成为明确缺口。
这样审查者能够看到:
这里还有不确定性。
本项目对未知归属采用阻断规则,而不是默认运行全量测试作为替代。
这个选择有利于维护显式关系,但也提高了接入成本。
其他项目可以根据风险采用不同兜底策略。
关键不是一定选择哪种,而是:
说明为什么选择当前验证范围。
否则很容易把:
“跑了很多测试”
误当成:
“已经理解了影响”。
十、显式依赖模型也不是完整事实的自动证明
即使建立了依赖表,也可能存在未登记关系:
- 动态调用;
- 框架自动导入;
- 共享数据;
- 跨服务消费;
- 运行时配置关系。
因此,影响模型本身也是需要维护的工程资产。
维护成本必须被计入:
精确测试带来的收益是否值得?
完整发布验证依然有价值。
因为它回答的问题不同:
整个候选版本是否满足发布政策?
而普通开发阶段的影响验证回答的是:
这次变更最可能影响哪些行为?
两者应该分别设计,不应让每个局部开发循环都承担完整发布成本。
十一、让成功结果绑定明确输入,并保护执行环境
开发机上的成功可能依赖很多隐藏条件:
- 未提交文件;
- 残留构建目录;
- 已有数据库状态;
- 其他任务启动的服务;
- 本地环境变量;
- 缓存。
如果这些条件没有被识别,接手者最终看到的只是:
一个无法解释的“通过”。
项目默认在固定 Git 提交的临时 worktree 中运行正式任务检查,并对:
- 依赖使用;
- 产物导出;
- 清理;
设置约束。
它还在昂贵检查之前验证提交快照,避免:
工作区存在、版本库缺失的文件
掩盖真实问题。
十二、执行顺序要让便宜的阻断检查尽量前置
可以从项目中提炼出这样一条验证顺序:
flowchart TD
A[明确目标与验收标准] --> B[分析影响并选择测试]
B --> C[固定输入并检查快照]
C --> D[准备必要环境]
D --> E[执行并核对结果]
E --> F[保存证据并清理]
F --> G[核验完成条件]
E --> H[记录失败并局部诊断]
H --> B
核心思想是:
先证明输入完整,再准备必要环境,接着验证行为,最后保存证据、清理并核验完成条件。
便宜且能够阻断后续工作的检查,应尽量放到前面。
否则很容易出现:
运行 20 分钟测试
↓
最后发现有文件根本没提交
这是一种完全可以避免的成本。
十三、前置条件要显式化
如果某组测试需要:
- Nuxt 初始化;
- 数据库迁移;
- 生产构建;
- fixture 准备;
- 某项服务启动;
就应该明确声明这些依赖。
不能依靠:
恰好另一组测试先运行过
才让当前测试成功。
这类隐式依赖会造成:
- 单独运行失败;
- 换机器失败;
- 接手者无法复现;
- 测试顺序改变后失败。
数据隔离同样需要明确
新的进程,不代表新的数据库。
前一个测试发布的数据,可能破坏后一个测试对:
空列表
的假设。
合并测试批次可以减少启动成本,但应该先确认:
- 数据前提兼容;
- 执行顺序可接受;
- 环境配置一致;
- 共享状态不会互相污染。
十四、worktree 隔离不等于完全可复现
worktree 能够固定:
代码快照。
但它未必固定:
- Python / Node 版本;
- 系统库;
- 浏览器版本;
- 外部服务;
- 数据库版本;
- 网络依赖。
因此,应该分别表达:
代码版本明确
依赖输入受控
目标环境已验证
不要把:
局部代码隔离
描述成:
完整环境可复现。
这种边界表达的工程价值在于:
失败更容易归因。
例如:
- 输入缺失;
- 初始化失败;
- 业务断言失败;
- 清理失败;
应该有各自的状态与诊断,而不是统一归入:
“再跑一次也许就好了。”
十五、把证据看成有适用条件的结论
一份证据至少要回答四个问题:
- 针对什么输入?
- 运行了哪些检查?
- 得到了什么结果?
- 为什么它仍然适用于当前任务?
项目会记录:
- 源码提交;
- 规格指纹;
- 验证配置指纹;
- 执行状态;
- 验收覆盖;
- 隔离清理结果。
并通过本机认证账本与精确摘要保护关闭过程。
关闭动作消费合格证据,事务性形成:
- 归档;
- 完成记录。
“通过”也有适用范围
这是这里最重要的概念之一:
通过不是永久真理,而是一个带输入条件的结论。
如果相关输入改变,旧结果可能失效。
如果最新一次检查失败,更早的成功不能继续被挑出来代表当前状态。
如果清理失败或任务中断,也不能被隐藏在一个笼统的绿色标记中。
十六、证据失效不等于任何变化都必须全量重跑
不能从“证据有适用条件”推导出:
任何变化都必须无条件重新跑全部测试。
结果是否可以复用,要看:
- 变化是否影响被证明的结论;
- 输入模型是否足以支持这种判断。
本项目采用比较保守的策略:
默认同进程完成验证与关闭。
跨进程复用,则需要更完整的输入合同。
认证机制也有自己的边界
本机账本和摘要可以帮助发现:
- 普通误改;
- 陈旧证据;
- 错误关联。
但如果操作者拥有同样权限,可以同时修改:
- 规则;
- 实现;
- 账本;
那么它并不构成外部不可变保证。
如果需要更强保障,就要引入:
- 独立权限;
- 审查;
- 外部执行边界;
- 受保护 CI 环境。
十七、证据摘要和原始诊断承担不同职责
完整日志适合:
排障。
紧凑证据适合:
说明结论、来源和适用条件。
如果把全部日志都放进版本库:
- 检索噪声增加;
- 存储增长;
- 维护成本提高。
如果只留下:
PASS
又失去了可解释能力。
因此,更合理的是保存:
- 足够的摘要;
- 来源;
- 关联;
- 输入身份;
- 关键结果。
同时为本地诊断产物设置明确保留边界。
十八、Harness 也必须证明自己的成本合理
控制系统本身也可能成为新的瓶颈。
Harness 可能产生这些额外成本:
- 输入核验;
- 依赖扫描;
- 测试收集;
- 服务启动;
- 隔离清理;
- 证据生成;
- 关闭检查。
因此:
少执行几个测试,不代表端到端成本一定更低。
项目改进材料中展示了几类值得借鉴的取舍:
- 对局部任务选择实际受影响的测试;
- 避免为了复用短测试扫描整套安装依赖;
- 把诊断与正式验收分开;
- 让关闭核验已有证据,而不是机械重复同一批测试。
十九、用总交付成本,而不是单一局部指标评估 Harness
可以用下面的模型理解成本:
任务总成本
= 理解目标与恢复上下文
+ 实现、审查与修复
+ 准备、收集、执行与清理
+ 证据核验与交接
+ 失败和重复工作
这是分析框架。
实际测量时,还需要避免不同阶段之间重复计数。
它提醒我们:
真正应该优化的是完成一次合格交付的总成本,而不是某个最容易展示的局部指标。
例子:缓存不一定值得
缓存只有在:
节省的重复执行成本
>
输入核验成本
+ 缓存维护成本
+ 失效处理成本
时才真正有价值。
如果验证一个小函数本来只需要几秒,为它建设复杂的跨进程缓存,可能得不偿失。
例子:失败后不应机械全量重跑
一次完整验证发现前置配置错误后,应该:
- 定位配置问题;
- 修复;
- 用局部诊断确认;
- 再回到正式验证。
反复运行同一套昂贵流程,只是在重复购买一个已经知道的失败。
但局部诊断成功,也不能被冒充成:
整个任务验收通过。
二十、有限样本不能被扩大解释成普遍收益
项目保存的受控样本显示:
在测试数量不变的情况下,减少控制面额外工作也能改善流程成本。
但这些只是有限本机样本。
不能外推成:
所有项目都能获得同样比例的收益。
在自己的项目中,评估 Harness 至少可以观察:
- 人工介入次数;
- 返工;
- 失败重试;
- 遗漏需求;
- 总交付成本;
- 恢复上下文所需时间。
而:
- 输出字节,只能反映日志规模;
- 测试数量,只能反映执行规模。
如果没有真实采集,就不能拿它们替代:
- token;
- 质量;
- 效率。
二十一、把流程失败转成可复用知识
一次任务失败以后,人很容易要求:
“下次更仔细一点。”
但这种要求有两个问题:
- 难以跨会话持续生效;
- 没有告诉系统具体要改变什么。
更有效的方式,是定位:
缺失了什么工程条件?
例如:
- 是否没有可发现的边界说明?
- 是否缺少输入校验?
- 是否遗漏了负向断言?
- 是否隐含依赖另一组测试准备环境?
- 是否没有清楚的停止条件?
确认原因后,再决定用哪种方式解决:
- 文档;
- 代码;
- 检查;
- 工作流。
二十二、Telemetry 和 Evolution 应该分开
Gavin 将:
- Telemetry
- Evolution
分成两个职责。
Telemetry 记录:
实际发生了什么。
Evolution 处理:
哪些经过确认的问题,值得修改系统规则。
这意味着:
观察到连续失败或成本增加,并不会自动授权修改规则。
为什么要分开
运行信号可能受到很多噪声影响:
- 缓存冷热;
- 机器负载;
- 并发竞争;
- 网络波动;
- 外部服务状态。
信号需要被解释。
达到阈值不代表:
根因已经确认。
二十三、执行者不能同时随意修改评价标准
这里还有一个更深层的问题:
权限。
如果执行者为了让检查通过,可以自行降低验收门槛,那么它同时控制了:
- 工作;
- 评价标准。
项目因此要求:
- 改进提案经过人工确认;
- 自动化不能自由修改最上层规则。
可以提炼出一条可迁移原则:
允许执行过程快速反馈,但把成功标准的修改放进独立、可审查的决策。
这不意味着:
所有小动作都必须等待批准。
重点是把人的注意力放到这些决定上:
- 是否改变用户目标;
- 是否改变验收标准;
- 是否改变责任边界;
- 是否降低安全或质量要求。
同样,也不需要把每次任务完成都转化成演进提案。
只有在存在:
- 明确摩擦;
- 可解释原因;
- 值得复用的改进;
时,才值得消耗人的注意力。
记录活动与产生决策,是两种不同职责。
二十四、用最小机制开始,再按真实问题扩展
本项目的完整 Harness 包含:
- 规格;
- 索引;
- 影响模型;
- 执行器;
- 认证;
- 事务;
- 演进机制。
它适合作为经验材料。
但如果直接复制整套结构,会产生明显成本。
更合适的方式是:
围绕已经发生的失效方式,逐步增加机制。
| 已经遇到的问题 | 优先引入的机制 | 采用前需要判断的代价 |
|---|---|---|
| 新会话无法理解项目 | 简短入口、边界文档、可接续任务状态 | 谁维护,如何避免重复来源 |
| Agent 经常扩张或缩小需求 | 目标、非目标、可观察验收标准 | 规格是否足够短,是否忠实于请求 |
| 功能看似完成但边界出错 | 正向与负向检查、跨层用户路径 | 测试是否对应真实风险 |
| 本机结果无法解释或重现 | 固定输入、显式前置任务、数据隔离 | 哪些依赖仍未受控 |
| 历史成功被错误用于当前任务 | 证据适用性、输入关联、失败保留 | 是否需要复杂认证,信任边界在哪里 |
| 小改动验证过重 | 影响选择、局部诊断、减少重复准备 | 维护依赖关系是否值得 |
| 相同流程错误反复出现 | 观测、根因确认、显式改进 | 是否只是环境噪声,谁能改规则 |
二十五、引入机制的顺序,应由真实风险决定
不同项目需要的 Harness 强度不同。
短期原型
可能只需要:
- 清晰入口;
- 简单任务清单;
- 几项关键用户路径检查。
长期维护项目
可能更需要:
- 规格;
- 稳定文档入口;
- 影响模型;
- 数据隔离;
- 证据来源;
- 关闭规则。
跨栈、有状态系统
可能进一步需要:
- 跨端契约;
- 环境身份;
- 数据状态管理;
- 复杂故障路径;
- 更强的审查与认证边界。
在迁移这些经验时,还需要区分:
方法
和
具体实现细节。
值得学习的是:
- 按需加载;
- 意图保护;
- 影响选择;
- 结果适用性;
- 权限分离。
而以下内容只是 Gavin 项目采用的实现方式:
- 具体目录名;
- 层级标签;
- Python CLI;
- HMAC 账本。
其他项目完全可以使用不同技术,只要关键责任关系还在。
二十六、Harness Engineering 与传统工程实践是一条连续谱
这些机制并不是凭空出现的。
它们与:
- 契约设计;
- 持续集成;
- 配置管理;
- 回归测试;
- 设计文档;
- 变更审查;
都有明显连续性。
Harness Engineering 更像是围绕 Agent 的执行特点,对这些成熟实践进行重新组织。
Agent 带来的特殊问题包括:
- 上下文可能中断;
- 计划可能偏移;
- 输出可能看似可信;
- 工具可以连续修改环境;
- 执行速度远高于人工审查速度。
因此,需要把过去大量依赖团队默契的条件,转化为:
- 可发现;
- 可执行;
- 可检查;
- 可交接;
的工程结构。
OpenAI 的相关工程实践强调设计环境、表达意图和反馈回路;Anthropic 的长任务实践强调增量推进与清晰交接。
本文从博客案例中提炼出的原则,与这些方向相呼应,但每个项目仍需要验证自己的适用条件。
二十七、人应该把判断力放在哪里
自动化能力增强之后,人的工作并不会消失。
更值得投入判断力的,是那些仅靠结构检查难以解决的问题:
- 用户究竟需要什么?
- 哪些风险最值得控制?
- 规格是否忠实于原始目标?
- 测试是否真的有意义?
- 是否遗漏了重要消费者?
- 某项规则是否值得长期维护?
不同“完成”应当对应不同证据
项目经验也支持把“完成”拆开。
例如:
| 结论 | 它真正说明什么 |
|---|---|
| 局部检查通过 | 相应范围的检查结果满足预期 |
| 任务关闭 | 约定的任务验收条件已经满足 |
| 发布资格成立 | 还满足目标环境、运行条件和授权要求 |
每个结论都应匹配自己的证据。
不能把:
局部测试通过
自动扩大成:
任务整体完成
再自动扩大成:
可以安全发布
二十八、阅读一个 Harness,可以用几个问题检查它
当你面对一套 Harness 设计时,可以问:
- 接手者能否找到当前有效的事实,而不必恢复全部聊天记录?
- 用户的重要要求能否追溯到规格、断言和执行结果?
- 输入变化或新失败出现时,系统能否撤销旧结论的适用性?
- 失败能否定位到具体阶段,而不是反复支付完整验证成本?
- 规则本身出错时,是否存在明确的纠正路径和权限边界?
这些问题比:
- 目录是否齐全;
- 工具有多少;
- 自动化是否复杂;
更接近 Harness Engineering 的实质。
结语
本文依据一个项目的实现与记录提炼经验。
它没有:
- 无 Harness 对照组;
- 足以支持普遍效率结论的大规模样本。
因此,不应把案例中的局部观察扩大成:
Harness 一定能够带来某个固定比例的效率提升。
真正值得迁移的,是一种解决问题的方式:
遇到失效时,寻找缺失的工程条件,再用最小、可验证的机制补齐它。
当 Agent 能理解边界,执行结果能被解释,接手者能够继续工作,而人仍掌握目标与标准的判断权,Harness 才真正帮助项目积累能力。
最终,可以用三句话检验整套机制:
每增加一条规则,都应能够说明它保护了什么。
每生成一份证据,都应能够说明它证明了什么。
每宣布一次完成,都应能够回到用户最初要解决的问题。