cd ..
2026-07-2215 min322 views

Harness Engineering:把 AI 编码从“能写代码”推进到“能交付系统”

#Harness Engineering#AI In Software Development#Agent Autonomy#Continuous Integration#Software Engineering Practices
AI Summary
每分钟最多 5 次
  • 明确任务定义:将自然语言需求转换为包含目标、范围、约束、验收条件和验证命令的具体契约,确保任务闭合且可执行。
  • 构建最小可闭环Harness:从简单任务开始,确保环境初始化、相关检查运行、必要文档获取及失败信息反馈的自动化,实现无人干预下的稳定复现与验证。
  • 优化仓库结构与知识管理:采用“短入口、深链接、就近说明”的策略组织文档,使关键规则最终进入可执行系统,并通过CI工具化代码审查中的常见反馈。
  • 增强Agent对系统的感知能力:提供脚本化启动服务、固定测试数据、浏览器自动化等功能,以支持端到端验证,生成统一证据目录,提高问题定位效率。
  • 逐步扩大自治权限并持续治理:根据任务风险和Harness成熟度分级授权给Agent,并定期维护Harness,包括更新文档、减少冗余工具、处理过期信息等,确保长期可持续性。

Harness Engineering:把 AI 编码从“能写代码”推进到“能交付系统”

本文受 OpenAI《Harness engineering: leveraging Codex in an agent-first world》启发,尝试回答一个更具体的问题:团队如何从零开始,把 Harness 一步步落到真实软件工程中?

过去一年,很多团队已经验证了 AI 能写代码。可一旦任务从“补一个函数”扩大到“完成一个需求”,成功率就会迅速下降:Agent 找不到真正入口,不知道哪些约束不能破坏,改完无法自证正确,遇到失败也得不到足够信息。

问题通常不只在模型,而在模型工作的环境。

这正是 Harness Engineering 要解决的事。这里的 Harness 不是某个框架,也不是一份超长提示词,而是包围编码 Agent 的整套工程控制面:上下文、工具、环境、约束、反馈、观测和权限。它的目标,是让 Agent 可以独立完成“理解—修改—验证—纠错—交付”的闭环。

可以把一次 Agent 交付的可靠性粗略理解为:

可靠交付 = 清晰任务 × 可发现上下文 × 可执行环境 × 快速反馈 × 安全边界

这是乘法,不是加法。任何一项接近零,单纯换更强模型或增加提示词都很难补救。

一、先定义目标:Harness 交付的不是代码,而是证据

传统研发中,工程师可以依靠长期记忆、组织默契和人工判断补足信息。Agent 没有这些默认背景。一个适合 Agent 的任务必须是“闭合”的:输入清楚、边界清楚、完成条件可以执行。

建议用以下任务契约取代一句自然语言需求:

## 目标
用户可以撤销尚未发货的订单。

## 范围
- 修改订单 API 和用户端订单详情页
- 不修改已发货订单的状态机

## 约束
- 复用现有鉴权与审计日志
- 不新增生产依赖
- 数据库变更必须向后兼容

## 验收条件
- 待支付、已支付订单可以撤销
- 已发货订单返回 409
- 重复请求保持幂等
- 单元、集成和端到端测试通过

## 验证命令
make check
make test-order
make e2e-order-cancel

这里最重要的变化是:完成不再等于“Agent 说已经完成”,而等于“仓库能够产出可检查的证据”。

二、第一阶段:建立最小可闭环 Harness

不要一开始追求全自治。先选一个边界清楚、风险低、10~30 分钟可验证的任务,例如新增校验规则、修复局部缺陷或补一个 API 字段。

最小 Harness 只需具备四个条件:

  1. 一条命令完成环境初始化;
  2. 一条命令运行与改动相关的检查;
  3. Agent 能在仓库内找到必要文档;
  4. 失败信息足以指导下一次修改。

仓库入口可以统一为:

.PHONY: setup check test-agent

setup:
	./scripts/bootstrap.sh

check:
	./scripts/lint.sh
	./scripts/typecheck.sh
	./scripts/test-changed.sh

test-agent:
	./scripts/test-agent-smoke.sh

脚本要满足三个要求:非交互、幂等、失败即非零退出。不要让 Agent 猜测先启动哪个服务、去哪里复制环境变量,或如何判断测试究竟有没有完成。

这一步的验收指标不是生成了多少代码,而是:同一个任务在全新工作区中能否稳定复现,Agent 是否能在无人补充命令的情况下完成一次修改和验证。

三、第二阶段:把仓库变成可导航的知识库

Agent 最容易获得、也最不容易过期的上下文,应该在代码仓库里。聊天记录、口头约定和散落在内部系统里的说明,都不适合作为唯一事实来源。

但这不意味着把所有知识塞进根目录的 AGENTS.md。超长总说明会稀释关键约束,也更容易过期。更好的做法是“短入口、深链接、就近说明”。

repo/
├── AGENTS.md                 # 全局地图、通用命令、硬约束
├── docs/
│   ├── architecture.md      # 模块边界与依赖方向
│   ├── domain/
│   │   └── orders.md        # 订单领域语义与状态机
│   ├── decisions/           # ADR:为什么这样设计
│   └── runbooks/            # 调试、回滚、故障处理
├── services/
│   └── order/
│       └── AGENTS.md         # 订单服务局部命令与陷阱
└── scripts/
    └── agent/               # 面向 Agent 的稳定工具入口

AGENTS.md 应像地图,而不是百科全书:

# Repository Guide

## 快速开始
- 安装:`make setup`
- 全量检查:`make check`
- 仅检查改动:`make check-changed`

## 架构硬约束
- domain 不得依赖 transport 或 persistence
- 跨服务调用必须通过公开 client
- 所有写接口必须包含鉴权、审计和幂等策略

## 按任务阅读
- 修改订单:`docs/domain/orders.md`
- 数据库迁移:`docs/runbooks/migrations.md`
- 新增服务:`docs/architecture.md`

文档中的每条关键规则最好最终进入可执行系统。比如“domain 不得依赖 web”不应只是一句话,还应由依赖检查器验证。文档负责解释意图,工具负责阻止违规。

四、第三阶段:把架构意图编译成机械约束

代码审查中的大量反馈其实是可机械化的:目录依赖、命名、接口兼容性、迁移规则、安全基线。这类判断应尽量从 Reviewer 的记忆迁入 CI。

可以按以下顺序推进:

  • 格式化、静态检查和类型检查;
  • 禁止依赖和模块边界;
  • API Schema 与数据库迁移兼容性;
  • 安全、隐私和许可证扫描;
  • 针对本仓库约定的自定义检查。

例如,用伪配置表达依赖方向:

layers:
  - domain
  - application
  - infrastructure
  - transport

rules:
  domain: []
  application: [domain]
  infrastructure: [domain, application]
  transport: [application]

CI 则提供由快到慢的反馈阶梯:

jobs:
  fast-checks:
    steps:
      - run: make format-check lint typecheck test-changed

  contract-checks:
    needs: fast-checks
    steps:
      - run: make dependency-check api-compat migration-check

  integration:
    needs: contract-checks
    steps:
      - run: make test-integration

  e2e:
    needs: integration
    steps:
      - run: make test-e2e

把最便宜、最确定的检查放在前面。Agent 若要等待 20 分钟才发现一个类型错误,自治循环必然昂贵且缓慢。

五、第四阶段:让 Agent 看见系统,而不只是源代码

真实功能经常跨越 UI、API、队列和数据库。只给代码与单元测试,Agent 无法判断实际行为是否正确。Harness 需要给它与人类工程师类似的感知能力。

对于 Web 系统,至少提供:

  • 可脚本化地启动整套本地服务;
  • 固定的测试账号和种子数据;
  • 浏览器自动化与截图;
  • 可检索的结构化日志;
  • Trace ID 串联前端请求、API、任务和数据库操作;
  • 必要时可查询本地指标或事件。

一个端到端验证脚本可以输出统一证据目录:

artifacts/run-20260722-103000/
├── summary.json
├── browser/
│   ├── before.png
│   ├── after.png
│   └── console.log
├── api/
│   └── responses.jsonl
└── traces/
    └── order-cancel.json

summary.json 不仅写成功或失败,还应包含失败阶段、关键日志位置、复现命令和 Trace ID。好的反馈不是信息越多越好,而是下一步行动越明确越好。

六、第五阶段:设计自校正循环

成熟 Harness 中,Agent 的主循环应当非常朴素:

读取任务契约
  → 定位相关代码与文档
  → 制定小步修改计划
  → 实施最小改动
  → 运行最快的相关检查
  → 根据失败信息修复
  → 运行更高层验证
  → 输出变更摘要、证据和剩余风险

关键是控制每次循环的范围。一次改几十个文件后再统一验证,会让错误归因变得困难。可以在 Harness 中明确限制:先搜索后修改;优先局部检查;连续两次同类失败后重新读取约束;涉及数据库、权限或外部接口时提高验证等级。

建议把最终交付格式也固定下来:

## 变更
- 实现了什么
- 修改了哪些边界

## 验证
- `make check`:通过
- `make test-order`:通过,38 tests
- `make e2e-order-cancel`:通过

## 证据
- 截图、日志或 Trace 路径

## 风险
- 尚未覆盖的情况
- 是否需要迁移、灰度或监控

七、第六阶段:分级扩大自治,而不是一次放权

权限应该随任务风险和 Harness 成熟度增长。

等级 Agent 能力 典型任务 必要门禁
L0 辅助 解释、建议,不写入 调研、代码问答 无写权限
L1 修改 在分支中改代码 测试、局部修复 人工逐项审查
L2 自证 修改并运行验证 常规功能 CI 全绿、证据齐全
L3 提交 创建提交或 PR 标准化需求 所有权规则、自动审查
L4 合并 低风险变更自动合并 依赖升级、机械重构 风险分类、自动回滚
L5 运行 处理受控生产操作 特定运维任务 最小权限、审批、审计、熔断

不要按“模型有多聪明”授权,而要按“系统多可验证、失败多可逆”授权。支付、权限、数据删除、不可逆迁移等高风险区域,即使 Agent 表现很好,也应保留明确的人类审批点。

八、持续治理:控制仓库熵增

Agent 提高吞吐后,新的瓶颈会从“代码写得慢”转为“仓库是否还能被理解”。重复工具、过期文档、例外架构和不一致测试会快速积累,并反过来降低后续 Agent 的成功率。

因此需要把维护 Harness 当作产品工作:

  • 记录 Agent 经常问错或找不到的内容,补导航而不是补聊天提示;
  • 统计最常见 CI 失败,将高频模糊错误变成明确诊断;
  • 删除重复脚本,为常用动作保留一个标准入口;
  • 定期验证文档中的命令、链接和所有者;
  • 把反复出现的代码审查意见升级为 lint、测试或生成器;
  • 为遗留代码设立“允许存在但不得新增”的基线。

这是一个很实用的治理原则:规则第一次出现时写进评审意见,第二次写进文档,第三次就应该考虑写成机器检查。

九、衡量 Harness 是否真的有效

不要用生成代码行数衡量成功。它鼓励更大的改动,却不能代表更高的交付质量。建议观察四类指标:

1. 自治能力

  • 无人工追问完成率;
  • 首次验证通过率;
  • 每个任务需要人工干预的次数;
  • Agent 可独立完成的任务等级分布。

2. 反馈效率

  • 首次有效反馈时间;
  • 局部检查与完整 CI 时长;
  • 失败信息可直接定位问题的比例;
  • 从失败到修复的平均循环次数。

3. 交付质量

  • 合并后缺陷率和回滚率;
  • 架构违规数量;
  • 测试逃逸率;
  • 安全与兼容性问题数量。

4. 人类负担

  • 每个 Agent 任务的审查时间;
  • Reviewer 重复反馈比例;
  • 环境与工具问题导致的阻塞时间;
  • 从需求提出到可验证 PR 的周期。

初期最值得优化的通常不是“完全无人干预率”,而是首次有效反馈时间和重复人工指导次数。它们能直接暴露 Harness 的断点。

十、一套可执行的 30 天落地路线

第 1 周:跑通一个最小闭环

  • 选择 10 个历史小任务作为基准集;
  • 统一 setupchecktest-changed 命令;
  • 建立短小的根 AGENTS.md
  • 记录每次人工介入的原因。

交付标准:全新工作区里,Agent 可以独立完成至少一类低风险任务。

第 2 周:消除知识与架构黑箱

  • 补模块地图、领域说明和关键 ADR;
  • 给高频目录增加就近指引;
  • 将三条最高频架构规则变成自动检查;
  • 为失败输出增加可操作提示。

交付标准:Agent 不依赖口头补充即可找到入口,并能在数分钟内获得首轮反馈。

第 3 周:补齐真实行为验证

  • 提供一键启动的本地集成环境;
  • 建立固定账号和种子数据;
  • 接入浏览器自动化、截图、日志和 Trace;
  • 统一保存验证证据。

交付标准:至少一个跨 UI/API/数据层的任务能由 Agent 自行观察并验证。

第 4 周:建立分级自治与度量

  • 按目录和变更类型定义风险等级;
  • 明确哪些步骤自动、哪些必须审批;
  • 建立任务成功率、人工介入和反馈耗时看板;
  • 每周从失败案例反推一个 Harness 改进项。

交付标准:低风险任务可稳定达到 L2;团队能用数据回答下一项 Harness 投资应该放在哪里。

结语

Harness Engineering 的核心,不是教 Agent 写出更多代码,而是重构软件工程,使正确行为更容易被发现、执行和验证。

当上下文只存在于人的脑中,Agent 就会反复追问;当架构只存在于文档中,它就会反复越界;当测试无法复现真实行为,它就只能宣称成功;当失败没有清晰证据,人类就必须接管调试。

真正可扩展的做法,是把隐性知识迁入仓库,把团队约定编译成约束,把运行状态转化为可观察证据,再用逐级授权扩大自治范围。最终得到的不只是一个更好用的 AI 编码工具,而是一套对人和 Agent 都更清晰、更可靠的软件生产系统。


参考:OpenAI,Harness engineering: leveraging Codex in an agent-first world。本文是基于其理念整理的独立工程实践方案,并非原文翻译。

/** Comments(0)*/

Loading comments...