agent28 min read

让 AI 的工作可理解、可验证、可接续:基于 Gavin 博客的 Harness Engineering 方法论

harness engineering
开始阅读

摘要

AI 能生成代码之后,项目仍然会遇到一组难题:

  • 需求在执行中被悄悄缩小;
  • 测试通过,却没有覆盖真正的风险;
  • 开发环境中的成功,无法被另一位接手者重现;
  • 验证流程越来越复杂,最终让一次小修改承担过高的成本。

本文以 Gavin 博客的建设实践为材料,讨论这些问题背后的共同机制,以及可以迁移到其他项目的设计原则。

核心观点是:

Harness Engineering 要建立从用户意图到执行结果的可追溯关系,让 Agent 能够自主推进,让人能够判断它是否正确推进,并使这套机制的成本与风险相称。

项目经验提供了具体例子与反例。

下文以工程问题组织讨论,重点解释:

  • 每项机制解决什么;
  • 为什么有效;
  • 边界在哪里;
  • 如何在自己的项目中采用。

案例支持设计分析,不能单独证明某种通用效率提升比例。


一、从一个完整用户行为理解工程对象

个人博客看似简单,但“发布一篇文章”已经涉及:

  • 编辑器状态;
  • 接口请求;
  • 身份认证;
  • 数据库事务;
  • 内容版本;
  • 公开页面。

按钮显示成功,只能说明某个局部步骤返回了结果。

用户真正需要的是:

文章被正确保存,并以符合规则的内容公开展示。

Gavin 将核心文章功能写成一个纵向闭环:

TEXT
管理员登录
   ↓
创建草稿
   ↓
自动保存
   ↓
预览
   ↓
发布
   ↓
公开页面读取

规格还明确了:

  • 版本冲突;
  • 稳定地址;
  • 草稿不可公开;

等边界。

文章闭环规格

以用户行为,而不是页面或接口作为开发单位

从这个例子可以学习的第一件事,是如何选择开发单位。

如果以:

  • “做一个页面”
  • “补一个接口”
  • “加一个按钮”

为单位,很容易得到局部完成的部件。

如果以可观察的用户行为为单位,才能发现跨层责任之间的空隙。

例如,对“自动保存”的理解至少有三个层次:

层次 需要确认的事实
用户体验 用户能够看到保存状态
服务端行为 内容确实被持久化
数据正确性 并发修改时不会被无声覆盖

页面实现、接口成功和数据正确,分别需要不同的观察方式,不能互相替代。

这也是 Harness 的起点:

先确定需要保持成立的行为,再安排实现和验证。

如果目标本身含糊,后续再精密的执行器,也只能精密地完成一个含糊任务。

需要特别区分的是:

  • 博客中的问答 Agent,是产品功能;
  • 围绕整个代码库建立的上下文、任务规格、验证和交接机制,才是本文讨论的仓库级 Harness。

二、将关键知识放进可查找、可维护的结构

Agent 在连续工作中需要恢复的,不只是代码,还包括:

  • 产品边界;
  • 已有决策;
  • 任务范围;
  • 未完成事项。

如果这些信息只存在于聊天记录中,接手者就必须反复猜测。

项目采用了短入口 + 分层文档的方式:

  • AGENTS.md 提供地图和硬边界;
  • 任务相关的产品基线与工作流按需加载;
  • 更细的支撑材料通过索引查询;
  • 文档带有用途与加载条件;
  • 生成索引负责提供发现路径。

控制面设计

为什么不能无差别加载全部上下文

可以用一次接口变更来理解。

Agent 需要知道:

  • 接口归谁维护;
  • 前端如何消费;
  • 哪些测试验证跨端契约。

但它通常不需要同时读取:

  • 视觉设计的全部历史讨论;
  • 已经退役模块的方案;
  • 所有部署尝试。

无差别加载会带来两个问题:

  1. 挤占有限的注意力;
  2. 把已经失效的材料重新带入当前决策。

上下文工程至少要回答四个问题

问题 设计要求 缺失时的典型结果
去哪里找? 有稳定入口和清晰路由 Agent 重复搜索或自行猜测
哪份为准? 标明责任、状态和适用范围 相互冲突的文档同时被当作规则
什么时候读? 按任务加载相关材料 无关信息稀释关键约束
谁负责更新? 变更关联文档维护责任 实现变化后仍按旧说明执行

三、文档也有生命周期

这里还有一个容易忽略的变量:

信息的寿命。

不同文档承担的职责不同:

文档类型 更适合承载的内容
临时 spec 一次任务的目标、范围、验收
长期 README 持续有效的能力与使用方式
决策记录 长期架构与规则依据
历史归档 已结束任务与过去决策
稳定索引 长期入口与发现路径

项目曾出现一种问题:

长期 README 链接到 active spec,规格关闭后,长期文档中的链接随之失效。

随后,项目通过稳定索引和链接检查约束这类引用。

链接生命周期案例

由此可以提炼出一条可迁移原则:

引用关系也需要遵守生命周期。

长期知识应该指向稳定入口。

临时状态可以消失,但不能让长期知识失去依据。

在自己的项目中,不一定一开始就建设复杂文档系统。

可以先维护:

  • 一份简短入口;
  • 几份责任明确的边界文档;
  • 当前任务记录。

等发现路径和维护问题真实出现,再增加:

  • 元数据;
  • 自动索引;
  • 生命周期检查。

文件数量本身没有价值,关键是接手者能否快速找到足以继续工作的事实。


四、规格的作用,是保护意图在执行过程中不走样

SDD,即规格驱动开发,常被理解为:

先写文档,再写代码。

但更值得学习的是它对意图的保护作用:

把模糊目标转换成能够讨论、实现和检查的约定。

项目的 spec 要求写明:

  • 目标;
  • 非目标;
  • 可观察验收标准;
  • 验证计划;
  • 文档影响。

涉及以下内容的变化,需要更正式的约束:

  • 行为;
  • 接口;
  • 数据;
  • 安全;
  • 架构边界。

而低风险、机械式修改可以采用更轻的流程。

规格规则

“完成发布功能”还不够具体

以文章发布为例:

“完成发布功能”

没有说明:

  • 发布读取哪个版本;
  • 持久化失败时界面怎样反馈;
  • 草稿是否进入公开查询;
  • 冲突是否保留用户修改。

更好的规格应该明确这些行为。

同时,非目标也很重要。

例如:

本次不同时建设多人协作编辑。

它可以防止任务在执行过程中无限扩张。


五、规格本身也可能偏离原始目标

规格并不会自动保证忠实于用户需求。

项目材料记录过一种失败:

执行者自行收窄 spec,验证通过后,将其表述成完整提案已经完成,但原提案仍有要求未交付。

范围偏移案例

这件事揭示了两个彼此独立的关系:

TEXT
用户目标
   ↓
规格中的验收标准
   ↓
实现与验证证据

也可以拆成:

TEXT
用户目标 → 规格中的验收标准
验收标准 → 实现与验证证据

第二个关系可以高度自动化。

第一个关系仍然需要理解和审查。

工具能够检查:

每条 AC 是否存在对应证据?

但它未必知道:

Agent 是否已经把困难要求从 AC 中删掉?

人应该重点检查什么

审查规格时,应回到原始请求,检查:

  • 显式要求是否被覆盖;
  • 隐含边界是否被考虑;
  • 未解决的决策是否仍被明确保留;
  • 范围是否被擅自缩小;
  • 局部阶段是否被错误表述为整体完成。

合理拆分阶段可以提高交付效率,但必须清楚表达:

  • 本阶段完成什么;
  • 整体目标还差什么。

不能用一个局部闭环,替代整体完成。

这也是人更值得投入注意力的位置。

反复审批每一个可逆小动作,会消耗大量精力。

相比之下,检查:

  • 目标是否被正确翻译;
  • 范围是否被擅自改变;

更能防止方向性错误。


六、把验证设计成一条解释链

“测试通过”只有在知道:

测试了什么?

之后才有意义。

项目将 VDD,即验证驱动开发,分成三个层次:

  1. 方法:依据什么验证;
  2. 检查:实际执行什么;
  3. 证据:保存本次结果。

验证策略

单元、契约、集成、端到端和质量检查,在这套结构中承担不同职责。

示例:验证文章公开读取

下面是一种教学式拆解:

层次 要表达的内容
用户要求 读者可以阅读已发布文章
正向预期 当前公开版本能够被查询和展示
禁止发生项 草稿或未发布修改不能出现在公开结果中
局部检查 查询逻辑正确处理状态和版本
集成检查 API 与持久化共同满足公开边界
用户路径检查 管理员发布后,读者能够访问正确内容

负向预期尤其重要

很多高风险能力都依赖:

某件事情绝不能发生。

例如:

  • 未认证用户不能访问管理功能;
  • 草稿不能泄露;
  • 已撤销权限不能继续生效;
  • 被删除内容不能重新出现在公开查询;
  • 超预算任务不能继续消耗资源。

如果测试只验证正常路径,就可能出现:

功能可用,但边界已经失守。


七、让重要结论可以一路追问到底

项目进一步把:

  • 模块;
  • 场景;
  • 可观察预期;
  • 精确测试引用;
  • 执行入口;

连接起来,使验收标准能够追溯到具体检查。

模块验证合同

这套设计还能识别一种看似严谨的假覆盖:

  • 源码里存在一个测试名,不代表它会被框架收集;
  • 被收集,不代表本次执行过;
  • 测试总数相同,不代表运行的是指定集合。

项目的执行合同因此核对完整测试身份,并拒绝:

  • 遗漏;
  • 重复;
  • 意外扩张。

执行身份合同

但还要注意:

测试身份正确,也不代表断言充分。

一个名字叫:

TEXT
reject draft leakage

的测试,可能只是检查:

TEXT
HTTP 200

却没有检查结果里是否真的没有草稿。

因此:

  • 机械关联提高可追溯性;
  • 语义审查判断关联是否合理。

可以提炼出一个通用方法:

让每个重要结论都能沿着“要求 → 场景 → 断言 → 执行结果”被追问。

不必为所有细枝末节建设复杂合同,但高风险边界应该拥有明确的:

  • 正向证据;
  • 负向证据。

八、验证范围由影响决定,不能由修改行数决定

“只改了一行”不是风险判断。

共享过滤条件的一行修改,可能影响所有公开内容。

一个独立格式工具的大段重写,也可能只影响少数调用方。

项目使用:

  • 源码归属;
  • 消费者关系;

辅助分析,再为具体任务记录:

  • 哪些消费者受影响;
  • 哪些消费者不受影响;
  • 为什么。

执行器据此选择相关场景和测试,而不是简单地把:

修改文件所在目录

当作全部验证范围。

影响驱动验证

示例:修改发布时间语义

如果修改文章发布时间的含义,影响可能沿着数据流传播:

TEXT
发布时间语义
    ↓
API 排序
    ↓
前端列表
    ↓
时间筛选
    ↓
内容发现输出

只测试修改的函数,可能漏掉下游消费者。

但直接运行整个项目,也不一定是每次开发循环最合理的选择。

更合适的是:

沿着输出契约和数据流检查实际影响,再决定需要验证哪些场景。


九、影响分析既要知道什么时候扩展,也要知道什么时候停止

好的影响分析不只是不断扩大范围。

它还需要明确停止规则。

例如:

需要继续扩展

TEXT
输出契约发生变化
→ 检查下游消费者

可以停止

TEXT
消费者并不依赖被改变部分
→ 记录理由后停止传播

未知归属和缺失判断,则应该成为明确缺口。

这样审查者能够看到:

这里还有不确定性。

本项目对未知归属采用阻断规则,而不是默认运行全量测试作为替代。

这个选择有利于维护显式关系,但也提高了接入成本。

其他项目可以根据风险采用不同兜底策略。

关键不是一定选择哪种,而是:

说明为什么选择当前验证范围。

否则很容易把:

“跑了很多测试”

误当成:

“已经理解了影响”。


十、显式依赖模型也不是完整事实的自动证明

即使建立了依赖表,也可能存在未登记关系:

  • 动态调用;
  • 框架自动导入;
  • 共享数据;
  • 跨服务消费;
  • 运行时配置关系。

因此,影响模型本身也是需要维护的工程资产。

维护成本必须被计入:

精确测试带来的收益是否值得?

完整发布验证依然有价值。

因为它回答的问题不同:

整个候选版本是否满足发布政策?

而普通开发阶段的影响验证回答的是:

这次变更最可能影响哪些行为?

两者应该分别设计,不应让每个局部开发循环都承担完整发布成本。


十一、让成功结果绑定明确输入,并保护执行环境

开发机上的成功可能依赖很多隐藏条件:

  • 未提交文件;
  • 残留构建目录;
  • 已有数据库状态;
  • 其他任务启动的服务;
  • 本地环境变量;
  • 缓存。

如果这些条件没有被识别,接手者最终看到的只是:

一个无法解释的“通过”。

项目默认在固定 Git 提交的临时 worktree 中运行正式任务检查,并对:

  • 依赖使用;
  • 产物导出;
  • 清理;

设置约束。

它还在昂贵检查之前验证提交快照,避免:

工作区存在、版本库缺失的文件

掩盖真实问题。

验证工作流


十二、执行顺序要让便宜的阻断检查尽量前置

可以从项目中提炼出这样一条验证顺序:

flowchart TD
    A[明确目标与验收标准] --> B[分析影响并选择测试]
    B --> C[固定输入并检查快照]
    C --> D[准备必要环境]
    D --> E[执行并核对结果]
    E --> F[保存证据并清理]
    F --> G[核验完成条件]
    E --> H[记录失败并局部诊断]
    H --> B

核心思想是:

先证明输入完整,再准备必要环境,接着验证行为,最后保存证据、清理并核验完成条件。

便宜且能够阻断后续工作的检查,应尽量放到前面。

否则很容易出现:

TEXT
运行 20 分钟测试
   ↓
最后发现有文件根本没提交

这是一种完全可以避免的成本。


十三、前置条件要显式化

如果某组测试需要:

  • Nuxt 初始化;
  • 数据库迁移;
  • 生产构建;
  • fixture 准备;
  • 某项服务启动;

就应该明确声明这些依赖。

不能依靠:

恰好另一组测试先运行过

才让当前测试成功。

这类隐式依赖会造成:

  • 单独运行失败;
  • 换机器失败;
  • 接手者无法复现;
  • 测试顺序改变后失败。

数据隔离同样需要明确

新的进程,不代表新的数据库。

前一个测试发布的数据,可能破坏后一个测试对:

空列表

的假设。

合并测试批次可以减少启动成本,但应该先确认:

  • 数据前提兼容;
  • 执行顺序可接受;
  • 环境配置一致;
  • 共享状态不会互相污染。

十四、worktree 隔离不等于完全可复现

worktree 能够固定:

代码快照。

但它未必固定:

  • Python / Node 版本;
  • 系统库;
  • 浏览器版本;
  • 外部服务;
  • 数据库版本;
  • 网络依赖。

因此,应该分别表达:

TEXT
代码版本明确
依赖输入受控
目标环境已验证

不要把:

局部代码隔离

描述成:

完整环境可复现。

这种边界表达的工程价值在于:

失败更容易归因。

例如:

  • 输入缺失;
  • 初始化失败;
  • 业务断言失败;
  • 清理失败;

应该有各自的状态与诊断,而不是统一归入:

“再跑一次也许就好了。”


十五、把证据看成有适用条件的结论

一份证据至少要回答四个问题:

  1. 针对什么输入?
  2. 运行了哪些检查?
  3. 得到了什么结果?
  4. 为什么它仍然适用于当前任务?

项目会记录:

  • 源码提交;
  • 规格指纹;
  • 验证配置指纹;
  • 执行状态;
  • 验收覆盖;
  • 隔离清理结果。

并通过本机认证账本与精确摘要保护关闭过程。

关闭动作消费合格证据,事务性形成:

  • 归档;
  • 完成记录。

证据与关闭机制

“通过”也有适用范围

这是这里最重要的概念之一:

通过不是永久真理,而是一个带输入条件的结论。

如果相关输入改变,旧结果可能失效。

如果最新一次检查失败,更早的成功不能继续被挑出来代表当前状态。

如果清理失败或任务中断,也不能被隐藏在一个笼统的绿色标记中。


十六、证据失效不等于任何变化都必须全量重跑

不能从“证据有适用条件”推导出:

任何变化都必须无条件重新跑全部测试。

结果是否可以复用,要看:

  • 变化是否影响被证明的结论;
  • 输入模型是否足以支持这种判断。

本项目采用比较保守的策略:

默认同进程完成验证与关闭。

跨进程复用,则需要更完整的输入合同。

认证机制也有自己的边界

本机账本和摘要可以帮助发现:

  • 普通误改;
  • 陈旧证据;
  • 错误关联。

但如果操作者拥有同样权限,可以同时修改:

  • 规则;
  • 实现;
  • 账本;

那么它并不构成外部不可变保证。

如果需要更强保障,就要引入:

  • 独立权限;
  • 审查;
  • 外部执行边界;
  • 受保护 CI 环境。

十七、证据摘要和原始诊断承担不同职责

完整日志适合:

排障。

紧凑证据适合:

说明结论、来源和适用条件。

如果把全部日志都放进版本库:

  • 检索噪声增加;
  • 存储增长;
  • 维护成本提高。

如果只留下:

TEXT
PASS

又失去了可解释能力。

因此,更合理的是保存:

  • 足够的摘要;
  • 来源;
  • 关联;
  • 输入身份;
  • 关键结果。

同时为本地诊断产物设置明确保留边界。


十八、Harness 也必须证明自己的成本合理

控制系统本身也可能成为新的瓶颈。

Harness 可能产生这些额外成本:

  • 输入核验;
  • 依赖扫描;
  • 测试收集;
  • 服务启动;
  • 隔离清理;
  • 证据生成;
  • 关闭检查。

因此:

少执行几个测试,不代表端到端成本一定更低。

项目改进材料中展示了几类值得借鉴的取舍:

  • 对局部任务选择实际受影响的测试;
  • 避免为了复用短测试扫描整套安装依赖;
  • 把诊断与正式验收分开;
  • 让关闭核验已有证据,而不是机械重复同一批测试。

验证成本与改进依据


十九、用总交付成本,而不是单一局部指标评估 Harness

可以用下面的模型理解成本:

TEXT
任务总成本
  = 理解目标与恢复上下文
  + 实现、审查与修复
  + 准备、收集、执行与清理
  + 证据核验与交接
  + 失败和重复工作

这是分析框架。

实际测量时,还需要避免不同阶段之间重复计数。

它提醒我们:

真正应该优化的是完成一次合格交付的总成本,而不是某个最容易展示的局部指标。

例子:缓存不一定值得

缓存只有在:

TEXT
节省的重复执行成本
>
输入核验成本
+ 缓存维护成本
+ 失效处理成本

时才真正有价值。

如果验证一个小函数本来只需要几秒,为它建设复杂的跨进程缓存,可能得不偿失。

例子:失败后不应机械全量重跑

一次完整验证发现前置配置错误后,应该:

  1. 定位配置问题;
  2. 修复;
  3. 用局部诊断确认;
  4. 再回到正式验证。

反复运行同一套昂贵流程,只是在重复购买一个已经知道的失败。

但局部诊断成功,也不能被冒充成:

整个任务验收通过。


二十、有限样本不能被扩大解释成普遍收益

项目保存的受控样本显示:

在测试数量不变的情况下,减少控制面额外工作也能改善流程成本。

但这些只是有限本机样本。

不能外推成:

所有项目都能获得同样比例的收益。

成本测量材料

在自己的项目中,评估 Harness 至少可以观察:

  • 人工介入次数;
  • 返工;
  • 失败重试;
  • 遗漏需求;
  • 总交付成本;
  • 恢复上下文所需时间。

而:

  • 输出字节,只能反映日志规模;
  • 测试数量,只能反映执行规模。

如果没有真实采集,就不能拿它们替代:

  • token;
  • 质量;
  • 效率。

二十一、把流程失败转成可复用知识

一次任务失败以后,人很容易要求:

“下次更仔细一点。”

但这种要求有两个问题:

  1. 难以跨会话持续生效;
  2. 没有告诉系统具体要改变什么。

更有效的方式,是定位:

缺失了什么工程条件?

例如:

  • 是否没有可发现的边界说明?
  • 是否缺少输入校验?
  • 是否遗漏了负向断言?
  • 是否隐含依赖另一组测试准备环境?
  • 是否没有清楚的停止条件?

确认原因后,再决定用哪种方式解决:

  • 文档;
  • 代码;
  • 检查;
  • 工作流。

二十二、Telemetry 和 Evolution 应该分开

Gavin 将:

  • Telemetry
  • Evolution

分成两个职责。

Telemetry 记录:

实际发生了什么。

Evolution 处理:

哪些经过确认的问题,值得修改系统规则。

观测规则

演进规则

这意味着:

观察到连续失败或成本增加,并不会自动授权修改规则。

为什么要分开

运行信号可能受到很多噪声影响:

  • 缓存冷热;
  • 机器负载;
  • 并发竞争;
  • 网络波动;
  • 外部服务状态。

信号需要被解释。

达到阈值不代表:

根因已经确认。


二十三、执行者不能同时随意修改评价标准

这里还有一个更深层的问题:

权限。

如果执行者为了让检查通过,可以自行降低验收门槛,那么它同时控制了:

  • 工作;
  • 评价标准。

项目因此要求:

  • 改进提案经过人工确认;
  • 自动化不能自由修改最上层规则。

可以提炼出一条可迁移原则:

允许执行过程快速反馈,但把成功标准的修改放进独立、可审查的决策。

这不意味着:

所有小动作都必须等待批准。

重点是把人的注意力放到这些决定上:

  • 是否改变用户目标;
  • 是否改变验收标准;
  • 是否改变责任边界;
  • 是否降低安全或质量要求。

同样,也不需要把每次任务完成都转化成演进提案。

只有在存在:

  • 明确摩擦;
  • 可解释原因;
  • 值得复用的改进;

时,才值得消耗人的注意力。

记录活动与产生决策,是两种不同职责。


二十四、用最小机制开始,再按真实问题扩展

本项目的完整 Harness 包含:

  • 规格;
  • 索引;
  • 影响模型;
  • 执行器;
  • 认证;
  • 事务;
  • 演进机制。

它适合作为经验材料。

但如果直接复制整套结构,会产生明显成本。

更合适的方式是:

围绕已经发生的失效方式,逐步增加机制。

已经遇到的问题 优先引入的机制 采用前需要判断的代价
新会话无法理解项目 简短入口、边界文档、可接续任务状态 谁维护,如何避免重复来源
Agent 经常扩张或缩小需求 目标、非目标、可观察验收标准 规格是否足够短,是否忠实于请求
功能看似完成但边界出错 正向与负向检查、跨层用户路径 测试是否对应真实风险
本机结果无法解释或重现 固定输入、显式前置任务、数据隔离 哪些依赖仍未受控
历史成功被错误用于当前任务 证据适用性、输入关联、失败保留 是否需要复杂认证,信任边界在哪里
小改动验证过重 影响选择、局部诊断、减少重复准备 维护依赖关系是否值得
相同流程错误反复出现 观测、根因确认、显式改进 是否只是环境噪声,谁能改规则

二十五、引入机制的顺序,应由真实风险决定

不同项目需要的 Harness 强度不同。

短期原型

可能只需要:

  • 清晰入口;
  • 简单任务清单;
  • 几项关键用户路径检查。

长期维护项目

可能更需要:

  • 规格;
  • 稳定文档入口;
  • 影响模型;
  • 数据隔离;
  • 证据来源;
  • 关闭规则。

跨栈、有状态系统

可能进一步需要:

  • 跨端契约;
  • 环境身份;
  • 数据状态管理;
  • 复杂故障路径;
  • 更强的审查与认证边界。

在迁移这些经验时,还需要区分:

方法

和

具体实现细节。

值得学习的是:

  • 按需加载;
  • 意图保护;
  • 影响选择;
  • 结果适用性;
  • 权限分离。

而以下内容只是 Gavin 项目采用的实现方式:

  • 具体目录名;
  • 层级标签;
  • Python CLI;
  • HMAC 账本。

其他项目完全可以使用不同技术,只要关键责任关系还在。


二十六、Harness Engineering 与传统工程实践是一条连续谱

这些机制并不是凭空出现的。

它们与:

  • 契约设计;
  • 持续集成;
  • 配置管理;
  • 回归测试;
  • 设计文档;
  • 变更审查;

都有明显连续性。

Harness Engineering 更像是围绕 Agent 的执行特点,对这些成熟实践进行重新组织。

Agent 带来的特殊问题包括:

  • 上下文可能中断;
  • 计划可能偏移;
  • 输出可能看似可信;
  • 工具可以连续修改环境;
  • 执行速度远高于人工审查速度。

因此,需要把过去大量依赖团队默契的条件,转化为:

  • 可发现;
  • 可执行;
  • 可检查;
  • 可交接;

的工程结构。

OpenAI 的相关工程实践强调设计环境、表达意图和反馈回路;Anthropic 的长任务实践强调增量推进与清晰交接。

本文从博客案例中提炼出的原则,与这些方向相呼应,但每个项目仍需要验证自己的适用条件。


二十七、人应该把判断力放在哪里

自动化能力增强之后,人的工作并不会消失。

更值得投入判断力的,是那些仅靠结构检查难以解决的问题:

  • 用户究竟需要什么?
  • 哪些风险最值得控制?
  • 规格是否忠实于原始目标?
  • 测试是否真的有意义?
  • 是否遗漏了重要消费者?
  • 某项规则是否值得长期维护?

不同“完成”应当对应不同证据

项目经验也支持把“完成”拆开。

例如:

结论 它真正说明什么
局部检查通过 相应范围的检查结果满足预期
任务关闭 约定的任务验收条件已经满足
发布资格成立 还满足目标环境、运行条件和授权要求

每个结论都应匹配自己的证据。

不能把:

TEXT
局部测试通过

自动扩大成:

TEXT
任务整体完成

再自动扩大成:

TEXT
可以安全发布


二十八、阅读一个 Harness,可以用几个问题检查它

当你面对一套 Harness 设计时,可以问:

  1. 接手者能否找到当前有效的事实,而不必恢复全部聊天记录?
  2. 用户的重要要求能否追溯到规格、断言和执行结果?
  3. 输入变化或新失败出现时,系统能否撤销旧结论的适用性?
  4. 失败能否定位到具体阶段,而不是反复支付完整验证成本?
  5. 规则本身出错时,是否存在明确的纠正路径和权限边界?

这些问题比:

  • 目录是否齐全;
  • 工具有多少;
  • 自动化是否复杂;

更接近 Harness Engineering 的实质。


结语

本文依据一个项目的实现与记录提炼经验。

它没有:

  • 无 Harness 对照组;
  • 足以支持普遍效率结论的大规模样本。

因此,不应把案例中的局部观察扩大成:

Harness 一定能够带来某个固定比例的效率提升。

真正值得迁移的,是一种解决问题的方式:

遇到失效时,寻找缺失的工程条件,再用最小、可验证的机制补齐它。

当 Agent 能理解边界,执行结果能被解释,接手者能够继续工作,而人仍掌握目标与标准的判断权,Harness 才真正帮助项目积累能力。

最终,可以用三句话检验整套机制:

每增加一条规则,都应能够说明它保护了什么。

每生成一份证据,都应能够说明它证明了什么。

每宣布一次完成,都应能够回到用户最初要解决的问题。

相关文章

2026.09.14与 AI 一起构建软件:让工作可恢复,让判断有依据2026.09.14Agent Harness Engineering 权威原文分类阅读清单2026.09.14优化AGENT.md和所有skill
返回文章列表