Harness Engineering 落地指南:AGENTS.md、verify.sh、ExecPlan 一次配齐

内容管家 编程开发评论10字数 3230阅读10分46秒阅读模式
摘要这不是一篇只讲概念的 Harness Engineering 介绍,而是一份能直接照着搭的落地指南。文中给出仓库布局、AGENTS.md、ARCHITECTURE.md、verif...
Harness Engineering 主题横版封面图

如果你最近频繁刷到 Harness Engineering,这不是错觉。2026 年 2 月,OpenAI 先把它作为 agent-first 开发里的核心方法公开讲明白;3 月,Anthropic 又把长任务里的 reset、handoff 和生成/评估分离写成工程经验;到了 4 月,Martin Fowler 也专门跟进,把这套思路整理成更稳定的工程语言。

这个词突然变热,不是因为技术圈又发明了一个新名词,而是因为越来越多团队已经踩到同一个坑:模型现在当然会写代码,但它并不会天然稳定交付。项目一复杂,AI 很快就会暴露出老问题:同样的错误反复出现,任务一长就断片,换个会话就得重新解释背景,最后人花的大部分时间,不是在推进需求,而是在替模型补上下文、补规则、补验证。

Harness Engineering 要解决的,正是这层“会写”到“能交付”之间的落差。它关心的不是怎么把提示词再润色一轮,而是怎么把项目地图、计划、验证、交接、回滚真正放进仓库,变成可执行、可复检、可接力的工件。

所以这篇文章不准备再从抽象概念兜圈子,而是直接给你一套能落地的最小配置:仓库怎么摆、AGENTS.md 怎么写、ARCHITECTURE.md 写什么、verify.sh 怎么做、什么时候必须写计划、任务做到一半怎么交接。目标只有一个:让你今天就能把自己的 Harness Engineering 配起来。

先说结论:普通人最该先做的,不是上工具,而是把仓库变成系统记录

很多人一聊 Harness Engineering,就先去看多代理、工作流编排、会话恢复、权限系统。那些东西当然重要,但对大多数开发者来说,第一步其实没那么复杂。

最该先做的是一件更朴素的事:让仓库本身能承载任务状态。也就是把“项目怎么跑、怎么验、改到哪一步了、下一步做什么、哪些地方别乱动”这些信息,从聊天记录和脑子里,搬到版本库里。

只要这一步没做,再强的模型、再花的工作流层,最后也会变成新的混乱来源。

30 分钟先搭出最小骨架

别一上来就想把整套系统做满。先把下面这套骨架建出来,已经能解决大多数“AI 会写,但总写不稳”的问题。

repo-root/
  AGENTS.md
  ARCHITECTURE.md
  PLANS.md
  docs/
    index.md
    exec-plans/
      active/
      completed/
    runbooks/
      verify.md
  scripts/
    verify.sh
  .github/workflows/
    verify.yml

这一套结构最关键的不是“看起来专业”,而是职责清楚:

  • AGENTS.md 负责当地图,不负责当百科全书。
  • ARCHITECTURE.md 负责讲边界、分层和不变量。
  • PLANS.md / exec-plans 负责承接长任务状态。
  • docs/runbooks/verify.md 负责告诉人和模型:到底怎么启动、怎么验证、怎么回滚。
  • scripts/verify.sh 负责把所有验证收口成一个入口。

第一份 AGENTS.md,就该长这样

很多人写 AGENTS.md 最大的问题,是总想“一次写全”。结果文档越来越长,谁都不爱看,过几天还会过时。

AGENTS.md 最好的写法,就是只写地图、入口和硬规则。下面这份可以直接拿去改:

# AGENTS.md

## 目标
本仓库采用 harness engineering 方式工作:把约束、计划、验证与交接写进仓库工件,让 Codex 在没有外部上下文的情况下也能稳定推进任务。

## 先读什么
- 架构总览:./ARCHITECTURE.md
- 计划规范:./PLANS.md
- 文档索引:./docs/index.md
- 执行计划:./docs/exec-plans/active/
- Runbook:./docs/runbooks/

## 工作流约定(PBV)
- Planner:先产出或更新 ExecPlan,把验收标准写清楚
- Builder:严格按已批准的 Plan 修改代码
- Verifier:独立运行 verify 流水线并记录结果

## 什么情况下必须写 ExecPlan
- 需要跨多个文件或模块修改
- 需要迁移、重构、引入新依赖
- 影响安全、权限、支付、发布、数据模型
- 预计超过 30 分钟,或会跨多次会话完成

## 一键验证
- 本地:./scripts/verify.sh
- CI:同样调用 verify.sh
- verify 不绿,不允许标记完成

## 受保护路径
- vendor/**, third_party/**, generated/**
- infra/prod/**, .github/workflows/**
- secrets/**, *.key, *.pem, .env*

## 输出与交接
- 每次停下前都要更新 Progress / Decision Log
- 每个长任务都要留下 Handoff
- 记录:已做、未做、如何复现、如何验证、风险与下一步

这份模板的重点,不是写得多漂亮,而是它能让模型一进仓库就知道:该先读哪里、按什么流程做、什么叫完成、哪些地方别乱碰。

ARCHITECTURE.md 不要讲理想状态,只写真实边界

很多项目的架构文档之所以没用,不是因为没人写,而是因为写得太虚。真正有用的架构文档,应该是模型和新同事都能拿来判断“这次改动有没有越界”的。

下面这份同样可以直接改:

# ARCHITECTURE.md

## 总览
- 核心业务域:
  - domain-a: 负责...
  - domain-b: 负责...
- 关键入口:
  - API: <path>
  - Web/UI: <path>
  - CLI/Jobs: <path>

## 分层与依赖方向
建议层次:
- types/ → config/ → repo/ → service/ → runtime/ → ui/

规则:
- 依赖只能向前
- 横切关注点必须走统一入口
- 任何跨域调用都必须经过显式边界

## 关键不变量
- 禁止裸 console.log / print
- 类型与 schema 命名必须统一
- 单文件默认不超过 500 行
- 敏感数据不得写日志
- 外部 IO 必须做校验与限流

## 如何验证架构没有被破坏
- 结构测试命令:make structural-test
- 失败修复指引:见 docs/runbooks/verify.md

## 变更策略
- 小改动:轻量 plan + verify
- 大改动:ExecPlan + milestone + 回滚路径

这里最重要的是两句话:边界要能被验证,不变量要能被执行。 如果它只是写在文档里,最后还是会失效。真正稳定的做法,是后面再把这些规则升级成结构测试、lint 或 CI。

verify.sh 必须只有一个入口

很多团队明明有 lint、有单测、有构建命令,最后还是经常“看起来改好了,实际一跑全崩”。原因往往不是没验证,而是验证太分散。

最省事的办法,就是收口到一个命令。下面这份多栈版 verify.sh 可以直接当起点:

#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"

echo "==> verify: repo=$(basename "$ROOT")  pwd=$ROOT"

run_if() {
  local desc="$1"; shift
  local cmd="$*"
  echo "---- $desc"
  bash -lc "$cmd"
}

if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  echo "==> git status (short)"
  git status --porcelain || true
fi

if [[ -f package.json ]]; then
  PM=""
  if command -v pnpm >/dev/null 2>&1; then PM="pnpm";
  elif command -v yarn >/dev/null 2>&1; then PM="yarn";
  else PM="npm"; fi

  run_if "node: install (best-effort)" "$PM -s install || true"
  run_if "node: lint" "$PM -s run lint"
  run_if "node: typecheck" "$PM -s run typecheck || $PM -s run tsc -- --noEmit"
  run_if "node: unit" "$PM -s run test || true"
  run_if "node: build" "$PM -s run build"
  run_if "node: e2e (optional)" "$PM -s run test:e2e || true"
fi

if [[ -f pyproject.toml || -f requirements.txt ]]; then
  if command -v uv >/dev/null 2>&1 && [[ -f pyproject.toml ]]; then
    run_if "python: uv sync (best-effort)" "uv sync --extra dev || true"
    run_if "python: ruff" "uv run ruff check . || true"
    run_if "python: pytest" "uv run pytest -q || true"
  else
    run_if "python: ruff (if installed)" "ruff check . || true"
    run_if "python: pytest (if installed)" "pytest -q || true"
  fi
fi

if [[ -f go.mod ]]; then
  run_if "go: test" "go test ./..."
fi

if [[ -f composer.json ]]; then
  run_if "php: composer install (best-effort)" "composer install --no-interaction || true"
  run_if "php: lint (optional)" "composer lint || true"
  run_if "php: unit (optional)" "composer test || true"
fi

echo "==> verify: done"

这份脚本不追求一步到位,它的意义是先把“完成”定义成同一个动作。之后你再慢慢把 flaky 项、结构测试、手测 runbook、预发布检查一点点加进去。

什么时候必须写计划,不要靠感觉

Harness Engineering 最容易被忽略的一点,是“计划必须工件化”。任务一复杂,如果还靠聊天记录和临场发挥,后面一定会乱。

最简单的规则就是:满足下面任意一条,就必须写 ExecPlan。

  • 需要跨多个文件或模块改动
  • 涉及迁移、重构、引入新依赖
  • 影响安全、权限、支付、发布、数据模型
  • 预计会超过 30 分钟,或者会跨多次会话完成

ExecPlan 不需要写成论文,但必须保证一件事:换一个全新的上下文,甚至换一个人,只靠这份文件也能继续做下去。

一份能接力的 Handoff,至少要包含这些字段

很多任务之所以做着做着断掉,不是因为不会写代码,而是因为没人把“当前状态”整理成能接手的东西。下面这份 Handoff 模板,已经足够实用:

# Handoff: <任务名>

## 当前状态概览
- 目标:一句话说明要解决什么
- 当前进度:完成到哪个 milestone / 哪个 commit
- 是否可安全合并:是 / 否(原因)

## 已完成(带证据)
- 改动点:
- 关键 commit / branch:
- 通过的验证:
  - lint:
  - typecheck:
  - unit:
  - e2e:
  - manual:

## 未完成与下一步
- 命令:
- 文件路径:
- 预期结果 / 验收点:

## 复现与验证 runbook
- 如何启动:
- 如何复现问题:
- 如何验证修复:

## 风险与注意事项
- 可能的回归面:
- 兼容性 / 迁移风险:
- 回滚策略:

## 需要人类判断的问题
- 可选方案:
- 推荐方案与理由:

只要这个东西写到位,你就会明显感觉到:长任务不再那么依赖“这次对话还记不记得前情提要”。

给普通人的 PBV 用法:先强制角色切换,再谈多代理

很多人一看到 Planner、Builder、Verifier,就以为非得上多代理编排。其实完全不用。单代理也能先跑起来,关键是强制角色切换

  1. Planner 阶段:只允许写计划、补验收、标边界,不许直接开改。
  2. Builder 阶段:只按计划改代码,尽量保持改动最小、可验证、可回滚。
  3. Verifier 阶段:独立跑 verify,按 runbook 手测,把失败证据写回计划或 handoff。

这一步做熟之后,你再考虑把不同角色拆到不同 worktree、不同 agent,收益才会真正出来。

存量项目,照着这 7 天清单接管就够了

如果你面对的是老项目,先别急着让模型写大功能。先用一周时间,把最关键的承载层补起来。

  1. 第 1 天:建 AGENTS.md、ARCHITECTURE.md、docs/index.md、docs/runbooks/verify.md,顺手把最可靠的一套本地命令封进 ./scripts/verify.sh
  2. 第 2 天:把真实模块边界、关键入口、依赖方向补进 ARCHITECTURE.md,只写当前真实情况,不写理想蓝图。
  3. 第 3 天:挑一个低风险任务,第一次完整跑 PBV:计划 → 实现 → 验证 → handoff。
  4. 第 4 天:回头看前三天最常见的一个错误,把它升级成脚本、lint 或 CI 规则,别再只写在文档里。
  5. 第 5 天:让 docs/index.md 真正成为索引,至少能列出 runbooks、active ExecPlans 和关键设计文档。
  6. 第 6 天:试一次 git worktree,把一个小任务放到独立 worktree 里跑验证,感受并行隔离的价值。
  7. 第 7 天:做一次盘点,记录 verify 通过率、返工次数、任务重启是否还能继续、哪些规则最该机械化。

这一周做完,你的项目就已经不是“全靠聊天推进”的状态了。

什么时候再上 oh-my-codex 或 OpenHarness?

顺序别反。先把 repo-native harness 配起来,再考虑更重的外部能力。

  • 如果你现在最大的问题还是“任务离开聊天历史就接不上”,先补 ExecPlan 和 Handoff。
  • 如果你最大的问题还是“总有人没跑验证就说做完了”,先把 verify 和 runbook 收口。
  • 如果你已经把这些都做稳了,瓶颈开始变成并行开发、长程恢复、权限治理、会话状态管理,这时候再看 oh-my-codex 或 OpenHarness,才是真收益。

最后给你一个最小执行清单

如果你今天只打算做 5 件事,就做这 5 件:

  1. 在仓库根目录建 AGENTS.md
  2. 补一份只写真实边界的 ARCHITECTURE.md
  3. 把本地验证收口成 ./scripts/verify.sh
  4. 给长任务建立 docs/exec-plans/active/
  5. 每次停下前都写一份 Handoff

你会很快发现,Harness Engineering 真正有价值的地方,不是“又学了一个新概念”,而是从这一刻开始,你的 AI 编程终于不再只靠上下文运气,而是开始靠系统推进。

参考资料

 
内容管家

发表评论