harness-实例
·
AGENTS.md
根指令文件。agent 每次开工会先读这个文件。它定义了工作规则:写代码前要做什么、工作过程中怎么守规矩、收尾时要检查什么。
怎么用:
- 复制到项目根目录
- 把开工流程里的步骤换成你自己项目的路径和命令
- 工作规则按你们团队的约定调整
- 完成定义那一段别改——那是整个 harness 最关键的部分
它帮 agent 做什么:
- 让它在开始工作前先读进度和功能状态
- 逼它一次只做一个功能
- 要求它拿出证据才能标记完成
- 定义了什么叫"干净收尾"
用 AGENTS.md 给 Codex 或其他 agent。用 CLAUDE.md 给 Claude Code——内容一样,格式按 Claude 的指令风格来的。
# AGENTS.md ## 开工流程 写代码前先做这些事: 1. 用 `pwd` 确认当前目录。 2. 读取 `claude-progress.md`,了解最新已验证状态和下一步。 3. 读取 `feature_list.json`,选择优先级最高的未完成功能。 4. 用 `git log --oneline -5` 看最近提交。 5. 运行 `./init.sh`。 6. 在开始新功能前,先跑必需的 smoke test 或端到端验证。 如果基础验证一开始就失败,先修基础状态,不要在坏的起点上继续叠新功能。 ## 工作规则 - 一次只做一个功能。 - 不要因为“代码已经写了”就把功能标记为完成。 - 除非为了消除当前 blocker 的窄范围修复,否则不要扩大到其他功能。 - 实现过程中不要悄悄改弱验证规则。 - 优先依赖仓库里的持久化文件,而不是聊天记录。 ## 必需文件 - `feature_list.json`:功能状态的唯一事实来源 - `claude-progress.md`:会话进度和当前已验证状态 - `init.sh`:统一的启动与验证入口 - `session-handoff.md`:较长会话可选的交接摘要 ## 完成定义 一个功能只有在以下条件都满足时才算完成: - 目标行为已经实现 - 要求的验证真的跑过 - 证据记录在 `feature_list.json` 或 `claude-progress.md` - 仓库仍然能按标准启动路径重新开始工作 ## 收尾 结束会话前: 1. 更新 `claude-progress.md` 2. 更新 `feature_list.json` 3. 记录仍未解决的风险或 blocker 4. 在工作处于安全状态后,用清晰的提交信息提交 5. 保证下一轮会话可以直接运行 `./init.sh`
init.sh
启动脚本。一条命令完成依赖安装、验证和打印启动命令。
怎么用:
- 复制到项目根目录
- 改顶部这三个变量:
INSTALL_CMD— 你的依赖安装命令(比如npm install、pip install -r requirements.txt)VERIFY_CMD— 你的基础验证命令(比如npm test、pytest)START_CMD— 你的开发服务器启动命令(比如npm run dev)
- 加执行权限:
chmod +x init.sh
它做什么:
- 打印当前目录(确认跑在正确的地方)
- 安装依赖
- 跑验证命令
- 打印启动命令(如果设了
RUN_START_COMMAND=1就直接启动)
如果验证失败了,agent 应该停下来先修基础状态,不要在坏的基础上继续叠新功能。
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$ROOT_DIR"
# 按你的项目实际情况替换这些命令。
INSTALL_CMD=(npm install)
VERIFY_CMD=(npm test)
START_CMD=(npm run dev)
echo "==> 当前目录: $PWD"
echo "==> 同步依赖"
"${INSTALL_CMD[@]}"
echo "==> 运行基础验证"
"${VERIFY_CMD[@]}"
echo "==> 启动命令"
printf ' %q' "${START_CMD[@]}"
printf '\n'
if [ "${RUN_START_COMMAND:-0}" = "1" ]; then
echo "==> 启动应用"
exec "${START_CMD[@]}"
fi
echo "如果希望 init.sh 直接启动应用,请设置 RUN_START_COMMAND=1。"
feature_list.json
功能清单。机器可读的功能列表,每个功能有状态、验证步骤和证据。
怎么用:
- 复制到项目根目录
- 把示例功能换成你自己的
- 每个功能需要填:
id— 短的唯一标识priority— 整数,越小越优先area— 属于应用的哪块(比如 "chat"、"import"、"search")title— 简短描述user_visible_behavior— 功能正常时用户能看到什么status— 四种状态之一:not_started、in_progress、blocked、passingverification— 逐步验证步骤evidence— 验证通过的记录(agent 填)notes— 额外说明
状态规则:
not_started— 还没碰in_progress— 当前正在做的那个(同一时间只能有一个)blocked— 有记录的阻塞问题,推不动passing— 验证通过,证据已记录
agent 任何时候只能有一个功能处于 in_progress。
{ "project": "替换成你的项目名", "last_updated": "YYYY-MM-DD", "rules": { "single_active_feature": true, "passing_requires_evidence": true, "do_not_skip_verification": true }, "status_legend": { "not_started": "功能还没开始做。", "in_progress": "这个功能是当前唯一正在进行的任务。", "blocked": "因为已记录的阻塞问题,当前无法继续推进。", "passing": "要求的验证已经通过,并且证据已经记录。" }, "features": [ { "id": "chat-001", "priority": 1, "area": "chat", "title": "创建新会话", "user_visible_behavior": "用户点击 New Chat 后,可以看到一个新的空白对话。", "status": "not_started", "verification": [ "打开应用。", "点击 New Chat。", "确认侧边栏出现一个新会话。", "确认主面板显示空白对话状态。" ], "evidence": [], "notes": "" }, { "id": "chat-002", "priority": 2, "area": "chat", "title": "在当前会话里发送消息", "user_visible_behavior": "用户提交一条消息后,可以在当前线程中看到它。", "status": "not_started", "verification": [ "打开一个已有会话。", "在输入框中输入消息。", "提交消息。", "确认线程中出现这条新消息。" ], "evidence": [], "notes": "" }, { "id": "chat-003", "priority": 3, "area": "chat", "title": "持久化保存会话列表", "user_visible_behavior": "应用重启后,用户仍能看到之前创建的会话。", "status": "not_started", "verification": [ "创建两个会话。", "重启应用。", "确认两个会话仍显示在侧边栏中。" ], "evidence": [], "notes": "" } ] }
claude-progress.md
进度日志。每轮会话往里写,每轮新会话先读它。
怎么用:
- 复制到项目根目录
- 把"当前已验证状态"那段填上你的项目信息
- 每轮会话结束后更新会话记录
每个字段的意思:
- 当前已验证状态 — 项目当前进展的唯一真相
仓库根目录— 项目在哪标准启动路径— 把项目跑起来的命令标准验证路径— 跑测试的命令当前最高优先级未完成功能— 下一轮该做什么当前 blocker— 哪里卡住了
- 会话记录 — 每轮一条
本轮目标— 打算做什么已完成— 实际做了什么运行过的验证— 跑了什么测试已记录证据— 留下了什么证明提交记录— 提了什么 commit已知风险或未解决问题— 哪里可能有问题下一步最佳动作— 下一轮从哪开始
# 进度日志
这是一个通用的仓库内会话进度日志。`claude-progress.md` 只是课程沿用的历史
文件名,并不要求使用 Claude Code。只要仓库里的指令明确要求,Codex 或其他
coding agent 都可以在开工时读取、交接前更新;agent 不会自动维护这个文件。
## 当前已验证状态
- 仓库根目录:
- 标准启动路径:
- 标准验证路径:
- 当前最高优先级未完成功能:
- 当前 blocker:
## 会话记录
### Session 001
- 日期:
- 本轮目标:
- 已完成:
- 运行过的验证:
- 已记录证据:
- 提交记录:
- 更新过的文件或工件:
- 已知风险或未解决问题:
- 下一步最佳动作:
### Session 002
- 日期:
- 本轮目标:
- 已完成:
- 运行过的验证:
- 已记录证据:
- 提交记录:
- 更新过的文件或工件:
- 已知风险或未解决问题:
- 下一步最佳动作:
session-handoff.md
会话交接摘要。一轮会话结束时写,下一轮开始时读。让接手的人(或 agent)快速了解现状。
怎么用:
- 复制到项目根目录
- 每轮会话结束时填写(也可以让 agent 自己填)
每段写什么:
- 当前已验证 — 哪些是确认能用的,跑过什么验证
- 本轮改动 — 改了什么代码或基础设施
- 仍损坏或未验证 — 已知问题和风险区
- 下一步最佳动作 — 下一轮该做什么,哪些东西不要动
- 命令 — 启动、验证、调试命令,方便快速参考
短会话可以不写这个文件。会话长了或者项目有多个并行区域时,它就很关键了。
# 会话交接
## 当前已验证
- 现在明确可用的部分:
- 这轮实际跑过的验证:
## 本轮改动
- 新增了哪些代码或行为:
- 基础设施或 harness 发生了哪些变化:
## 仍损坏或未验证
- 已知缺陷:
- 未验证路径:
- 下一轮会话需要注意的风险:
## 下一步最佳动作
- 最高优先级未完成功能:
- 为什么它是下一步:
- 什么结果才算 passing:
- 这一步中哪些东西不要动:
## 命令
- 启动命令:
- 验证命令:
- 定向调试命令:
clean-state-checklist.md
收尾检查清单。每次会话结束前过一遍,确保仓库处于下一轮可以直接开工的状态。
怎么用:
- 复制到项目根目录
- 关掉会话前逐项检查
- agent 的收尾流程里也应该包含这些检查
检查什么:
- 标准启动路径还能用
- 标准验证还能跑
- 进度日志已更新
- 功能清单真实反映了 passing 和未验证的边界(没有假 passing)
- 没有半成品处于未记录状态
- 下一轮会话不需要人工修复就能继续
# 干净状态检查清单
- [ ] 标准启动路径仍然可用
- [ ] 标准验证路径仍然可运行
- [ ] 当前进度已经记录到进度日志
- [ ] 功能状态真实反映了 passing 和未验证的边界
- [ ] 没有任何半成品步骤处于未记录状态
- [ ] 下一轮会话无需人工修复即可继续
evaluator-rubric.md
评审评分表。会话结束后或到里程碑时,用它评估 agent 做的东西够不够格。
怎么用:
- 复制到项目根目录
- 一轮(或几轮)会话后,按六个维度打分
- 每个维度 0-2 分
六个维度:
- 正确性 — 实现出来的行为是否符合目标功能
- 验证 — 要求的检查是否真的跑过,并留下证据
- 范围纪律 — 是否基本保持在选定功能范围内
- 可靠性 — 结果是否能在重启或重跑后继续工作
- 可维护性 — 代码和文档是否清楚到足以交给下一轮会话
- 交接准备度 — 新会话是否能只靠仓库内文件继续推进
结论选项:
- Accept — 达标
- Revise — 需要修补才能接受
- Block — 有根本性问题,需要先解决
Evaluator 需要校准。 开箱即用的 agent 做评审很弱——它会发现问题,然后把自己说服到通过。你需要反复校准:
- 用 evaluator 给一个已完成的 sprint 打分。
- 把它的分数和你自己的人工判断对比。
- 有分歧的地方,把 rubric 里的通过/失败标准写得更具体。
- 对同一个输出重新跑 evaluator,看对齐了没有。
- 重复直到 evaluator 的判断和人工评审基本一致。
预计需要 3-5 轮校准。每轮记录改了什么、为什么改。
# 评审评分表
在实现完成后、正式验收前,用这张表做一次评审。
| 维度 | 问题 | 分数 (0-2) | 备注 |
| --- | --- | --- | --- |
| 正确性 | 实现出来的行为是否符合目标功能? | | |
| 验证 | 要求的检查是否真的跑过,并留下证据? | | |
| 范围纪律 | 这一轮是否基本保持在选定功能范围内? | | |
| 可靠性 | 结果是否能在重启或重跑后继续工作? | | |
| 可维护性 | 代码和文档是否清楚到足以交给下一轮会话? | | |
| 交接准备度 | 新会话是否能只靠仓库内工件继续推进? | | |
## 结论
- Accept
- Revise
- Block
## 后续动作
- 缺失的证据:
- 必须补的修复:
- 下次复审触发条件:
更多推荐



所有评论(0)