昨天我翻了翻 Phodal 讲「AGENTS.md 五步法」的文章,越看越有同感。他整理 Better Harness 仓库时发现一个问题:实践越来越完整,可第一次上手 Coding Agent 工程化的人,反而更不知道先做什么。让 Coding Agent 改一个真实项目,你可能见过这个循环:它很快定位到代码、改完、跑通测试;可换一次对话,它又开始猜你用什么包管理器、哪份文档可信、哪个目录不能碰。你不断往 Prompt 里补规则,项目里的经验却一点没留下来。
Phodal 把「构建 Agent 友好项目」拆成了五步:写清项目入口 → 连起核心知识 → 沉淀重复流程 → 接入执行工具 → 回到真实任务。本文把这五步拆开,讲清楚每一步解决什么问题、具体怎么落地,最后给一份可以直接照抄的检查清单。
一、第一步:先用 AGENTS.md 给 Agent 一张项目地图
想象一个新人第一天入职。你不会直接甩给他全部架构文档,而是先告诉他:项目做什么、代码在哪里、怎样启动、修改后运行什么测试、哪些地方不要碰。
Coding Agent 进入仓库时,也需要这样一张地图。
2.1 AGENTS.md 该写什么
不同 Coding Agent 对文件名和加载范围的支持有所不同,但 AGENTS.md 承担的内容应该尽量稳定:
- 包管理器和运行时:仓库同时有 npm 和 pnpm 的痕迹时,写明当前用哪个
- 安装与测试命令:完整测试跑半小时的话,改单个模块该先跑哪条聚焦命令
- 无法从目录结构推断的约定:某个目录看起来像源码,实际是工具生成的
- 生成文件的位置:哪些目录不要直接改
- 安全边界:涉及凭据、数据库迁移、发布时的注意事项
原则很简单——Agent 能从代码中看出来的内容,没有必要再写一遍。真正值得写进去的,是它看不出来、却很容易猜错的事实。
2.2 一份最小示例
如果还不知道怎样起步,先在仓库根目录创建一份很短的 AGENTS.md:
# AGENTS.md
- 安装依赖:`pnpm install`
- 修改后先运行:`pnpm test -- <相关测试>`
- 不要直接修改:`dist/`、`generated/`
- 修改模块边界前:阅读 `docs/ARCHITECTURE.md`
- 涉及数据库迁移或发布:先请求人工确认
这只是最小示意,命令和路径必须换成你项目里真实能跑的,最好自己先跑一遍。
2.3 渐进式披露
一份实用的 AGENTS.md 应该简短、准确、可执行。关键原则是渐进式披露:根目录只保留多数任务都需要的说明,更细的架构、设计、流程,通过链接按需读取。
二、第二步:把核心文档接到任务路径上
有了项目地图,Agent 只是知道怎样开工,还不知道代码为什么这样组织。第二步要做的,是让散落在架构决策、设计规范、测试策略和运行手册里的知识,从「仓库里存在」变成「任务进行到这里时能够被找到」。
3.1 核心文档的职责划分
常见的核心文档包括 ARCHITECTURE.md、DESIGN.md、编码规范、测试指南、发布说明和 Runbook。名字不必统一,但职责应该清楚:
| 文档 | 职责 |
|---|---|
| ARCHITECTURE.md | 解释模块边界和依赖方向 |
| DESIGN.md | 保存界面与交互约束 |
| 编码规范 | 记录团队特有的技术选择 |
| 测试/运行手册 | 说明如何验证和诊断系统 |
3.2 知识路由:给链接加读取条件
只在 AGENTS.md 末尾放一串链接还不够。更有效的写法,是同时给出读取条件:
# AGENTS.md(导航版)
## 文档路由
- 修改模块边界前 → 读 `docs/ARCHITECTURE.md`
- 调整公共界面前 → 查 `docs/DESIGN.md`
- 改变发布流程前 → 看 `docs/RUNBOOK.md`
## 约定
- 禁止修改 `dist/`、`generated/`
- 涉及数据库迁移或生产发布 → 先请求人工确认
这一小句把文档接到了具体任务上,形成了一条最小的知识路由。
3.3 单一权威来源
同一个事实最好只有一个权威来源。架构约束属于架构文档,AGENTS.md 只负责把 Agent 带过去;测试命令如果已经由脚本提供,文档负责解释如何选择,而不是再复制一份可能过期的命令。走到这步,AGENTS.md 管导航,核心文档管解释,源码和测试提供最终事实。
三、第三步:从重复工作中提炼第一个 Skill
4.1 什么时候该建 Skill
每次发布都要检查版本、变更记录和产物;每次排查线上问题都要收集日志、缩小范围并验证修复;每次代码审查都要核对最终变更、测试证据和风险边界。如果这些步骤每次都要重新提醒 Agent,就值得沉淀了。
但重复出现,不等于立即创建 Skill。实用的门槛是:相似需求至少出现过两次;或者只发生过一次,但成本高、风险大、很可能再次发生。同时确认输入稳定、步骤能复用、结果可检查,且没有被现有文档、脚本或 Skill 覆盖。
4.2 Skill 文件长什么样
Skill 可以理解成一份由 Agent 按需加载的工作手册。它回答一种任务应该怎样完成:何时触发、需要哪些输入、按什么顺序执行、产出什么结果、如何验证、遇到什么情况应该停止并交给人。
name: review-final-diff
description: 审查最终代码变更,而非未暂存的修改
triggers:
- 用户要求"审查"或"Review"本次变更
steps:
1. 收集全部变更,而非只看一部分
2. 在最终提交的代码上运行测试,记录具体命令与结果
3. 检查 Review 与 CI 是否走完
stop_when:
- 涉及不可逆操作,交回人工确认
注:以上为示意结构,非 Better Harness 原文件。
4.3 第一个 Skill 从哪来
如果不知道第一个 Skill 应该从哪里来,翻看最近几次与 Agent 的对话:
- 哪些要求已经解释过两次?
- 哪些检查每次都要手工提醒?
- 哪些失败修复以后很可能再次出现?
四、第四步:把重复流程变成可执行的工程接口
写出 Skill,只是定义了方法。要让流程真正运行起来,Agent 还需要读取数据、执行检查或操作外部系统。这一步不必立刻增加一个 MCP Server——对于已经有脚本或命令行的项目,CLI 通常是成本最低、也最容易复现的起点。一个 Agent 友好的 CLI,你应该让它满足:
- 能从
--help中发现用法; - 支持非交互执行;
- 输出稳定,必要时提供 JSON 等结构化格式;
- 失败时返回明确的错误和退出状态;
- 为耗时操作提供超时;
- 修改外部状态前支持
plan或dry-run。
# 一个 Agent 友好 CLI 的示意接口
agentctl status --format json # 非交互、结构化输出
agentctl sync --dry-run # 预览改动,确认后再执行
5.2 CLI 与 MCP 的分工
CLI 优先并不意味着拒绝 MCP。当外部系统缺少合适的命令行入口,或需要结构化资源发现、持续交互时,MCP 依然合适。关键是让两者建立在同一套底层能力和权限规则上,而不是各写一套输入、输出、错误语义。
5.3 不是所有问题都该交给 Skill 提醒
能够被程序明确判断的规则(例如禁止修改生成文件),应该交给脚本、Hook 或 CI 自动检查;涉及生产环境、凭据和不可逆操作,则继续保留权限控制、沙箱或人工确认。职责清楚、过程可复现、结果能验证,才说明它真正进入了工程流程。
五、第五步:回到真实任务,让项目记住经验
Agent 完成修改、测试显示通过时,先别急着开始下一个需求:打开最终代码变更,确认测试覆盖的是这次修改后的版本,再检查它是否走完了该走的 Review 和 CI。
6.1 Agent Work Loop
Better Harness 把「理解需求 → 找到知识 → 执行修改 → 验证交付」这个过程叫 Agent Work Loop。循环里,AGENTS.md 帮 Agent 进来,核心文档给上下文,Skill 与工具推着任务执行,测试、Hook、权限守住结果与边界。
6.2 交付后的回顾
交付以后,你再回头看一眼这次任务:Agent 是否又重新寻找了一遍启动命令?是不是在同一个目录上再次犯错?是不是还需要你提醒某项检查?也要留意那些奏效的路径——比如某个排查步骤,是不是连续帮了几次任务。
一个顺手的交付检查清单:
# 一次任务的交付检查
- [ ] 最终代码变更完整,无未暂存遗漏
- [ ] 测试跑在最终提交的代码上,而非较早版本
- [ ] 记录具体测试命令与结果(不是写「测试通过」了事)
- [ ] Review 与 CI 均已走完
- [ ] 沉淀:本次经验该写回 AGENTS.md / 文档 / Skill / 脚本
6.3 经验该沉淀到哪里
这些反复出现的摩擦和有效经验,才是下一轮改进的起点。可以借助 Loop Discovery 判断它们应该沉淀在哪里:
| 经验类型 | 沉淀位置 |
|---|---|
| 稳定事实 | 写回 AGENTS.md 或核心文档 |
| 重复方法 | 整理成 Skill |
| 确定性操作和检查 | 交给 CLI、脚本、Hook 或 CI |
| 需要外部资源发现或持续交互 | 使用 MCP |
| 高风险、不可逆的操作 | 保留权限边界和人工确认 |
不过,写进仓库并不代表实践已经生效。等下一次类似任务到来,Agent 能否找到它、用上它、因此少一次返工,才决定这项实践值不值得留。
六、总结与建议
所谓持续改进,不是不断增加配置,而是让这一次任务留下的东西,真正帮助下一次。这套方法最反直觉的地方在于「克制」:不是看到什么新机制就往上加,而是让真实的摩擦来决定下一步加什么。工具地图铺得再大,Agent 找不到、用不上,都只是摆设。
项目不需要在第一天就拥有完整的 Agent 平台,它只需要开始记得自己如何工作。当这个循环转起来,AI Coding 才不再只是个人临时使用的聪明工具,而会逐渐成为项目自身拥有的工程能力。
如果你刚起步,就选择一个最近发生的真实任务:让 Agent 从理解需求走到验证与交付,结束时只沉淀一件最值得复用的经验。等这个闭环跑顺了,再考虑下一个。