AGENTS.md 模板深度解析:用 learn-harness-engineering 构建可验证、可续接的长期编码代理 Harness
AGENTS.md 模板深度解析:用 learn-harness-engineering 构建可验证、可续接的长期编码代理 Harness
本指南以 learn-harness-engineering 仓库中面向多语言分发的 AGENTS.md 模板(西班牙语版) 为核心骨架,系统讲解这份根指令文件的设计意图、五大结构(启动工作流、工作规则、必需产物、完成定义、会话收尾)及其背后的 Harness 工程理念,并逐一对照仓库内 project-01 至 project-06 的真实落地产物(feature_list.json、init.sh、claude-progress.md 等)验证每条规则的实际效果。读完本文,你将掌握如何为自己的编码代理项目编写、裁剪并维护一份真正可续接的 AGENTS.md。
一、这份模板解决什么问题:从"产出代码"到"留下状态"
仓库在模板配套指南 docs/es/resources/templates/index.md 中给出了明确的产品定位:
AGENTS.md 是"根指令文件(el archivo de instrucciones raíz)",是代理在每次会话启动时第一件读取的东西,它定义了操作性规则:写代码之前做什么、如何工作、如何收尾。
而 AGENTS.md 模板 开篇就用一句话点明了整份文件的哲学:
本仓库是为长期编码代理(long-running coding-agent)工作而设计的。目标不是最大化原始代码输出,而是让仓库在下一次会话开始时处于"无需猜测即可继续"(continue without guessing)的状态。
这与本仓库课程体系(如 lecture-05-why-long-running-tasks-lose-continuity)所讲的"长时任务连续性"一脉相承:跨会话的连续性不靠代理的记忆,而靠仓库里持久化的、可验证的工件(artifacts)。
因此,AGENTS.md 的真正职责有三层:
- 启动校准:让新会话在写第一行代码之前,先确认"我在哪、做到哪了、下一步做什么";
- 过程约束:限制代理一次只做一个特性、不擅自改验证规则、不把"写了代码"等同于"完成了特性";
- 收尾标准化:强制把状态、证据、风险写回仓库,让下一次会话能直接续接。
下文依次拆解模板的五个章节,并给出每个章节对应的仓库实例佐证。
二、启动工作流(Startup Workflow):写代码前的 6 步校准
模板明确要求"写代码之前"(Antes de escribir código)按顺序执行以下 6 步:
- 用
pwd确认当前工作目录; - 阅读
claude-progress.md,获取最新已验证状态与下一步; - 阅读
feature_list.json,选择优先级最高的未完成特性; - 用
git log --oneline -5检查最近提交; - 执行
./init.sh; - 在开始新工作前,运行要求的 smoke 或端到端验证。
随后模板给出了一条硬性纪律:
如果基线验证(baseline verification)已经在失败,先修复它。不要在已经损坏的初始状态之上堆叠新特性的工作。
这一条的用意是防止"错误累积":基线是后续一切验证的参照物,基线若坏,任何新验证结果都不可信。project-06 的 init.sh 正是把"基线验证"脚本化的例子,它做了 5 步检查:
#!/usr/bin/env bash
# init.sh -- Verify the project builds cleanly before starting work.
set -euo pipefail
echo "[1/5] Installing dependencies..."
npm install
echo "[2/5] Running type checks..."
npm run check
echo "[3/5] Building project..."
npm run build
echo "[4/5] Verifying harness files..."
for file in AGENTS.md CLAUDE.md feature_list.json clean-state-checklist.md session-handoff.md evaluator-rubric.md quality-document.md; do
if [ ! -f "$file" ]; then echo " MISSING: $file"; FILES_OK=false; else echo " OK: $file"; fi
done
echo "[5/5] Verifying sample data..."
# ...检查 docs/ 与 scripts/ 下的关键文件、data/sample-documents/ 下的样例数据
if [ "$FILES_OK" = true ]; then
echo "=== Init complete. All checks passed. ==="
else
echo "=== Init complete with warnings. Some harness files are missing. ==="
exit 1
fi
可以看到,实际项目中的 init.sh 除了安装依赖、类型检查、构建之外,还会验证 harness 文件本身是否齐全——把 AGENTS.md、feature_list.json 等工件也纳入基线,这正是"仓库即可重启"(restartable from the standard startup path)理念的落地。
仓库还提供了一个更精简的 init.sh 模板:它把可配置项收敛为三个命令变量和一个开关:
INSTALL_CMD=(npm install) # 依赖安装命令,如 pip install -r requirements.txt
VERIFY_CMD=(npm test) # 基线验证命令,如 pytest
START_CMD=(npm run dev) # 开发启动命令
"${INSTALL_CMD[@]}" # 1. 同步依赖
"${VERIFY_CMD[@]}" # 2. 运行基线验证
if [ "${RUN_START_COMMAND:-0}" = "1" ]; then
exec "${START_CMD[@]}" # 3. 设置 RUN_START_COMMAND=1 时直接启动应用
fi
从源码结构看,模板版与 project-06 实例版的差异恰好体现了"模板→实例"的演进路径:模板用 npm test 作通用验证命令,实例则针对 Electron 项目把验证拆成了 check(类型检查)、build(构建)与文件完整性检查三个层次。
三、工作规则(Working Rules):五条防失控纪律
模板的"工作规则"章节只有五条,但每一条都对应一类典型的代理失控场景:
- 一次只做一个特性(Work on one feature at a time)——防止上下文被多个半成品稀释;
- 不要因为加了代码就把特性标记为完成——代码存在 ≠ 行为达标;
- 将改动控制在所选特性范围内,除非被阻塞问题迫不得已做狭窄的支撑性修复——防止范围蔓延;
- 实现过程中不得悄悄更改验证规则——验证规则是"裁判",代理不能边比赛边改规则;
- 优先使用仓库中的持久化工件,而不是聊天摘要——聊天记录会丢,仓库不会。
这五条规则在 feature_list.json 的状态规则 中得到制度性支撑:状态机只有四种——not_started(未开始)、in_progress(进行中,且任意时刻只允许一个特性处于此状态)、blocked(因已记录的问题无法推进)、passing(验证通过且证据已登记)。"一次只做一个特性"由此从一句口号变成可被脚本校验的约束:如果 feature_list.json 里出现两个 in_progress,就说明代理违规了。
四、必需产物(Required Artifacts):Harness 的"最小文件集"
模板列出了四个必需的仓库工件,并注明各自职责:
| 工件 | 职责 |
|---|---|
feature_list.json |
特性状态的唯一事实来源(source of truth) |
claude-progress.md |
会话记录与当前已验证状态 |
init.sh |
标准启动与验证路径 |
session-handoff.md |
大型会话的可选紧凑交接单 |
四个工件恰好覆盖了一个长期代理会话的完整生命周期:启动时读 claude-progress.md 和 feature_list.json,验证时跑 init.sh,收尾时写回进度、可选地写 session-handoff.md。
以 project-06 的 feature_list.json 为例,每个特性条目记录 id、name、description、status、evidence、testedAt:
{
"project": "project-06",
"description": "Capstone: Runtime Observability and Debugging -- full product with import, index, Q&A, feedback, clean state, benchmarking",
"features": [
{
"id": "document-import",
"name": "Document Import",
"status": "pass",
"evidence": "DocumentService.importDocument() validates file existence, checks 10MB limit, copies file, stores content, creates metadata.",
"testedAt": "2026-03-30T10:15:00Z"
}
]
}
注意这里的 evidence 字段是"证据"而非"描述":它指明在哪个源文件的哪个行为上验证过(如 DocumentService.importDocument() 做了文件存在性校验、10MB 大小限制等),这正是"定义完成"要求中"证据已登记"的载体。而 模板指南 建议的字段更完整——id、priority(数值越小优先级越高)、area、title、user_visible_behavior、status、verification(逐步验证步骤)、evidence、notes——从源码结构看,实际项目普遍精简为 id/name/description/status/evidence/testedAt,说明该清单可以根据项目规模裁剪,但 id、status、evidence 三个字段是底线。
五、定义完成(Definition Of Done):四条不可缺一的标准
模板给出了一份可逐条勾选的完成定义:一个特性只有在以下全部成立时才算完成(hecho):
- 目标行为已实现(the target behavior is implemented);
- 要求的验证确实执行过(the required verification actually ran);
- 证据已登记到
feature_list.json或claude-progress.md; - 仓库仍然可以从标准启动路径重新启动(remains restartable from the standard startup path)。
"验证确实执行过"与"证据已登记"这两条,是防止代理"过早宣布胜利"(对应课程 lecture-09-why-agents-declare-victory-too-early)的机制设计。project-06 的 claude-progress.md 展示了"证据登记"的完整形态,其"基准测试结果"一节记录的是可复现的运行数据:
Benchmark Results (sample data):
- Import 3 documents: ~120ms
- Batch indexing: ~80ms (14 chunks)
- Query "What is the architecture?": ~250ms with 2 citations
- Clean state reset: ~15ms
而"仓库保持可重启"则由 clean-state-checklist.md 这样的配套清单来兜底——它把"可重启"拆成构建、架构、运行时、日志、数据完整性、性能、仓库卫生、脚本共八大类几十个勾选项,例如:
- 渲染层代码不得出现
fs/path导入,服务层不得出现 Electron IPC 调用(架构边界); - 所有日志条目必须是可解析的 JSON,且包含 timestamp、level、service、message(可观测性);
bash init.sh能通过全部验证步骤(重启路径)。
六、会话收尾(End Of Session):五步干净交接
模板要求会话结束前依次完成:
- 更新
claude-progress.md; - 更新
feature_list.json; - 记录任何未解决的风险或阻塞;
- 在工作处于安全状态后,用描述性的提交信息 commit;
- 让仓库干净到下一次会话能立即运行
./init.sh。
project-06 的 session-handoff.md 是这套收尾流程的成品示例,其章节结构与模板指南完全对应:本次完成(What Was Accomplished)、剩余事项(What Remains)、关键决策(Decisions Made)、修改的文件清单(Files Modified)、阻塞项(Blockers)、下一步(Next Steps)。其中"修改的文件清单"精确到 src/services/logger.ts、src/main/ipc-handlers.ts 等文件级粒度,使下一会话无需 diff 猜测改动范围。
七、AGENTS.md 在模板体系中的位置:一份文件的背后是一套系统
AGENTS.md 不是孤立文件,它只是仓库 templates 目录 中十份模板之一。完整模板清单如下:
| 模板 | 作用 | 调用时机 |
|---|---|---|
AGENTS.md / CLAUDE.md |
根指令文件,定义规则 | 每次会话启动首先读取 |
init.sh |
启动+验证脚本 | 每次会话启动执行 |
claude-progress.md |
进度日志 | 会话中/结束时读写 |
feature_list.json |
特性状态机 | 选任务时读、完成时写 |
session-handoff.md |
紧凑交接单 | 大会话结束时写 |
clean-state-checklist.md |
收尾自检清单 | 提交前/会话结束时 |
evaluator-rubric.md |
输出质量评分卡 | 会话后/里程碑时 |
quality-document.md |
代码库健康快照 | 会话前后对比 |
模板指南 index.md 建议的落地顺序是:先拷贝四件套(AGENTS.md 或 CLAUDE.md、init.sh、claude-progress.md、feature_list.json)到项目根目录,其余文件随项目增长逐步加入。它还特别指出:AGENTS.md 用于 Codex 等代理,CLAUDE.md 用于 Claude Code,结构相同、仅指令风格不同——这也是为何本仓库的 solution 目录中两个文件并存(见 project-06/solution/AGENTS.md 与 project-06/solution/CLAUDE.md)。
另外两件值得注意的配套机制:
- evaluator-rubric.md 需要人工校准:模板指南明确警告"开箱即用的代理是糟糕的自我裁判"——它们会发现问题后又说服自己通过。建议先在一个已完成的 sprint 上运行评分器,与人工评审对比,分歧处细化评分标准,计划 3–5 轮校准。
- quality-document.md 支撑 harness 减负实验:每个 harness 组件都编码了一个"模型做不到什么"的假设,模型变强后假设会过时。验证某个组件是否还有存在价值的方法是:快照质量文档 → 移除组件 → 跑基准任务集 → 再快照对比,评分未下降则该组件是纯负担。
八、在自己的项目中落地:一份可复制的行动清单
综合模板与仓库实例,为你的项目接入 AGENTS.md 的最小行动路径如下:
- 拷贝四件套到项目根目录:
AGENTS.md、init.sh、claude-progress.md、feature_list.json(可从 docs/es/resources/templates/ 取用对应语言的版本); - 改写 init.sh 的三个变量:
INSTALL_CMD(如npm install)、VERIFY_CMD(如npm test)、START_CMD(如npm run dev),并chmod +x init.sh;若需要直接拉起应用,设RUN_START_COMMAND=1; - 用真实命令替换 AGENTS.md 启动工作流中的占位步骤:确认
pwd、读进度文件、选特性、看最近 5 条提交、跑./init.sh、跑 smoke/e2e; - 把特性清单填进 feature_list.json:每个特性至少含
id、status(四态之一)、verification(逐步验证步骤)、evidence(验证通过后填写);严格保证任意时刻只有一个in_progress; - 在 claude-progress.md 中维护"当前已验证状态":至少包含仓库根目录、标准启动路径、标准验证路径、最高优先级未完成特性、当前阻塞项五个字段;
- 每次会话结束跑一遍收尾五步,大项目再补写
session-handoff.md,提交前过一遍clean-state-checklist.md。
结语
从模板到实例,learn-harness-engineering 给出的 AGENTS.md 始终围绕同一个核心命题:长期编码代理工作的连续性不靠模型记忆,而靠仓库内可验证、可重启、可追溯的持久化工件。启动六步校准方向,五条规则约束过程,四类工件承载状态,四条标准判定完成,五步收尾留下干净现场——这套协议的价值不在于文件本身,而在于它把"下一个会话无需猜测即可继续"从愿望变成了可检查的仓库事实。你可以在 docs/es/resources/templates/ 取用全部模板,并在 projects/project-06/solution/ 看到它们的完整落地形态。