ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AI编程助手持久化治理框架:AGENTS.md与状态机实战

AI编程助手持久化治理框架:AGENTS.md与状态机实战 1. 为什么“聊完就忘”是 AI 编程助手的头号顽疾用 AI 编程助手写过稍大一点项目的人大概都经历过这种崩溃昨天刚跟助手把数据库表结构、接口命名规范、错误码分段规则全部对齐今天新开一个会话它又像失忆一样把user_id写成userId把统一返回体拆成三种风格甚至把已经废弃的旧模块又给你“优化”回来。单文件小脚本无所谓可一旦项目跨了几十个文件、迭代了几周这种“每次从零开始”的协作方式就会把效率优势全部吃掉。问题的根子不在模型能力而在于项目治理状态没有被持久化。人类团队靠什么保证一致性靠规范文档、靠代码评审清单、靠架构决策记录ADR、靠 CI 卡口。AI 助手缺的正是这一层——它每次只看到你当前粘贴的上下文看不到“这个项目过去做过哪些决定、哪些是禁区、当前处于哪个阶段”。所谓持久化项目治理框架本质就是给 AI 编程助手补上一套它每次开工前必读、干完活必更新的“项目宪法 状态账本”。这里有两个关键词值得先拆开。AGENTS.md是社区里逐渐形成的一种约定在仓库根目录放一个 Markdown 文件专门写给 AI 助手看声明项目结构、编码规范、命令、禁区。它解决的是“静态规则”的持久化。而状态机解决的是“动态阶段”的持久化——项目现在是在搭骨架、填功能、还是收尾重构不同阶段 AI 该被允许做什么、禁止做什么是完全不同的。把这两者合起来再配上一套更新机制才构成一个能长期运转的治理框架而不是又一个写完就烂尾的文档。这篇内容适合三类人一是已经在日常用 AI 编程助手、但被一致性问题反复折磨的开发者二是团队里想推动 AI 协作规范落地的技术负责人三是对AI Agent、多 AI 协作感兴趣、想搞清楚“治理层”到底该怎么设计的人。下面我会从目录结构、AGENTS.md 的写法、状态机的设计、多助手协作、以及实际踩过的坑几个角度把整套框架讲透尽量给到能直接抄的模板和判断依据。2. 治理框架的目录骨架把“规则”和“状态”分开放很多人一上来就把所有东西塞进一个巨大的 AGENTS.md写到三千行结果 AI 读不完、人也不想维护。我的经验是规则要分层状态要独立历史要可追溯。一个能长期跑下去的治理框架目录结构大致长这样project-root/ ├── AGENTS.md # 入口索引短小精悍指向其他文件 ├── .ai/ │ ├── conventions.md # 编码规范、命名、目录约定 │ ├── architecture.md # 架构决策记录ADR │ ├── commands.md # 构建/测试/lint 命令清单 │ ├── forbidden.md # 禁区清单绝对不能碰的东西 │ ├── state.json # 当前项目阶段状态机 │ └── changelog-ai.md # AI 每次改动的治理日志 └── src/ ...为什么入口文件必须短因为 AI 助手的上下文窗口是有限资源。你把所有规则堆在入口等于每次对话都先烧掉一大块预算真正干活的空间被压缩。正确做法是让AGENTS.md只做“目录 最高优先级铁律”细节按需加载。这跟人类新员工入职一个道理先给他一页纸的“必读须知”而不是把员工手册全文拍他脸上。2.1 入口文件只放三类信息AGENTS.md里我通常只放三类内容。第一类是项目一句话定位让 AI 立刻知道这是什么系统、技术栈是什么。第二类是最高优先级铁律通常是三到五条比如“所有对外接口必须走统一响应包装”“禁止直接操作生产数据库”“新增依赖必须记录到 architecture.md”。第三类是文件索引告诉 AI 遇到什么任务该去读哪个文件。# AGENTS.md ## 项目定位 电商后台服务Node.js TypeScript PostgreSQL单体仓库。 ## 铁律违反即视为任务失败 1. 所有 HTTP 响应必须使用 src/utils/response.ts 的 wrap() 包装。 2. 禁止在业务代码中直接拼接 SQL一律走 query builder。 3. 新增任何第三方依赖前先读 .ai/architecture.md 的依赖决策章节。 4. 每次完成任务后必须更新 .ai/changelog-ai.md。 ## 按需加载索引 - 写业务代码前 → 读 .ai/conventions.md - 改架构/加依赖 → 读 .ai/architecture.md - 不确定能不能做 → 读 .ai/forbidden.md - 想知道当前阶段 → 读 .ai/state.json这个入口文件我实测下来控制在 60 行以内最舒服。超过 100 行AI 就开始“选择性忽略”后面的内容了——这不是玄学是注意力机制在长上下文里的自然衰减。2.2 为什么状态要单独用 JSON 而不是 Markdown有人会问状态机为什么不用 Markdown 写非要搞个 JSON原因是状态需要被程序读取和校验。Markdown 是给人看的JSON 是给机器看的。当你想在 CI 里加一道检查——“如果当前阶段是freeze则禁止合并新增功能文件”——你就需要一个结构化、可解析的状态文件。Markdown 做不到这点你得写正则去抠脆弱得很。{ phase: feature-development, since: 2025-01-10, allowed_actions: [add_feature, write_test, refactor_local], forbidden_actions: [change_schema, add_dependency, rename_public_api], next_phase_condition: 所有 P0 功能完成且测试覆盖率 80%, owner: team-backend }这个文件是整套框架的“心脏”。AI 每次开工前读它就知道自己现在能干什么、不能干什么。人也能一眼看出项目卡在哪个阶段。下一节我会详细讲状态机怎么设计这里先记住一个原则状态文件要能被机器校验规则文件要能被人快速扫读两者职责不同别混。3. AGENTS.md 到底该写什么从“说明书”升级为“契约”我见过太多 AGENTS.md 写成了一份“项目介绍”通篇在讲这个项目多牛、用了什么炫酷技术但对 AI 干活毫无帮助。真正有用的 AGENTS.md应该是一份契约它明确告诉 AI“你被期望做什么、你被禁止做什么、你做完要交付什么”。判断标准很简单——如果一条内容删掉之后AI 的行为不会有任何变化那这条就是废话删。3.1 规范条款要写成“可判定”的句子“代码要写得优雅”这种话对 AI 毫无意义因为它无法判定自己是否达标。要写成可判定的“函数超过 40 行必须拆分”“所有异步函数必须有 try/catch 或显式错误传播”“公共函数必须有 JSDoc 注释包含 param 和 returns”。可判定意味着 AI 能自查你也能在评审时快速验证。## 编码规范节选自 conventions.md ### 命名 - 文件名kebab-case如 user-service.ts - 类名PascalCase - 常量UPPER_SNAKE_CASE - 布尔变量必须以 is/has/can/should 开头 ### 函数 - 单个函数不超过 40 行超过必须拆分 - 参数超过 3 个时改用对象参数 - 禁止使用 any未知类型用 unknown 类型守卫 ### 错误处理 - 业务错误统一抛 BusinessError携带 code 和 message - 禁止吞掉异常空 catch 块这些条款的价值在于它们既是给 AI 的指令也是给你自己的评审清单。当 AI 提交的代码违反其中任何一条你可以直接引用条款让它改而不是含糊地说“这里不太对”。3.2 禁区清单比正面规范更重要正面规范告诉 AI“该怎么做”禁区清单告诉 AI“绝对不能怎么做”。后者往往更关键因为 AI 闯祸通常不是因为它不会写而是因为它“太热心”——顺手帮你重构了不该动的模块或者为了图方便引入了一个新依赖。禁区清单要写得斩钉截铁不留解释空间。## 禁区forbidden.md 以下操作在任何阶段都禁止除非人类明确书面授权 1. 修改 src/core/ 下的任何文件核心引擎改动风险极高 2. 删除或重命名已有的数据库迁移文件 3. 在 package.json 中新增依赖 4. 修改 CI 配置文件 .github/workflows/ 5. 直接操作 .env 或任何密钥文件 6. 修改公共 API 的签名向后兼容性红线我特别想强调第 6 条。AI 助手有个通病它觉得某个函数签名“不够优雅”就顺手给你改了结果调用方全炸。把公共 API 列为禁区能省掉大量返工。如果确实需要改走“人类授权 更新 architecture.md”的流程而不是让 AI 自作主张。3.3 命令清单要精确到可复制粘贴AI 经常需要跑测试、跑 lint、跑构建来验证自己的改动。如果你不告诉它确切的命令它就会猜猜错就浪费时间甚至搞坏环境。命令清单要精确到可以直接复制粘贴包括工作目录、环境变量、常见参数。## 常用命令commands.md | 目的 | 命令 | 工作目录 | |------|------|----------| | 安装依赖 | npm ci | 根目录 | | 跑单元测试 | npm run test:unit | 根目录 | | 跑单个测试 | npm run test:unit -- file | 根目录 | | 类型检查 | npm run typecheck | 根目录 | | Lint | npm run lint -- --fix | 根目录 | | 本地启动 | npm run dev | 根目录 |注意npm ci而不是npm install——前者严格按 lock 文件安装不会偷偷升级依赖版本这在治理框架里很重要能避免“AI 跑完测试后依赖树变了”这种隐蔽问题。4. 用状态机管住 AI 的“手”阶段、门禁与转移条件规则管的是“怎么做”状态机管的是“现在能做什么”。这两者缺一不可。一个项目在搭骨架阶段AI 可以大胆创建新文件、新模块但到了发布冻结阶段AI 连改一个字符串都得谨慎。如果框架不区分阶段AI 就会用同一种激进度对待所有时期这在后期是灾难。4.1 四个核心阶段与各自的权限边界我把项目生命周期抽象成四个阶段每个阶段对应一组明确的允许/禁止动作。这不是唯一分法但覆盖了大多数中小型项目的实际需求。阶段目标允许禁止bootstrap搭骨架建目录、定接口、写脚手架写复杂业务逻辑feature-development填功能加功能、写测试、局部重构改 schema、加依赖、改公共 APIhardening加固补测试、修 bug、性能优化加新功能、改接口freeze冻结只修 P0 bug、改文档任何功能性改动这个表的价值在于它把“什么时候该保守”这件事从人的直觉变成了明文规则。AI 读到phase: freeze就知道自己只能修 P0不会手痒去“顺便优化一下”。4.2 状态转移必须有人类确认的卡口状态机最容易出问题的地方是自动转移。如果让 AI 自己判断“功能都做完了我进入 hardening 阶段吧”它往往会过早乐观。我的做法是转移条件由 AI 检查并提议但最终转移必须由人类确认。AI 可以更新state.json里的proposed_phase字段但phase字段的修改需要人类操作或人类明确授权。{ phase: feature-development, proposed_phase: hardening, proposal_reason: P0 功能 12/12 完成单元测试覆盖率 83%, proposal_at: 2025-01-15, awaiting_human_confirm: true }这个设计借鉴了状态机里“守卫条件guard condition”的思路转移不是无条件的必须满足守卫条件且通过外部事件触发。在这里外部事件就是人类的确认。实测下来这个卡口能拦住至少一半的“过早进入下一阶段”问题。4.3 状态机图怎么画才不流于形式很多人画状态机图就是画个流程图交差画完没人看。要让状态机图真正有用得让它和state.json一一对应并且标注清楚每个转移的守卫条件。我通常用简单的文本描述而不是复杂的图形工具因为文本更容易和代码一起维护。bootstrap --[骨架完成 人类确认]-- feature-development feature-development --[P0 功能全完成 覆盖率80% 人类确认]-- hardening hardening --[无 P0/P1 bug 性能达标 人类确认]-- freeze freeze --[发布完成]-- (归档) 任意阶段 --[发现严重设计缺陷]-- bootstrap回退需人类确认注意最后那条回退路径。项目不是单向前进的发现架构问题时需要回退到 bootstrap 重新设计。状态机必须允许回退否则 AI 会在错误的地基上越盖越高。回退同样需要人类确认因为回退意味着大量返工不能由 AI 单方面决定。5. 多 AI 协作下的治理让不同助手读同一本“账”现在很多人不止用一个 AI 助手可能用 A 写后端、B 写前端、C 做代码评审。多 AI 协作最大的风险是各自为政——A 改了接口没通知 BB 按旧接口写前端C 评审时又按自己的理解提意见。治理框架在这里的作用就是让所有助手读同一本“账”写同一本“账”。5.1 用 changelog-ai.md 做跨助手的交接日志每个 AI 完成任务后必须往.ai/changelog-ai.md追加一条记录。这条记录不是给你看的虽然你也能看主要是给下一个 AI看的。它要包含改了什么、为什么改、影响了哪些文件、有没有遗留问题。## 2025-01-15 14:30 | 助手A | feature-development - 任务实现订单查询接口 - 改动文件src/order/query.ts, src/order/query.test.ts - 接口变更新增 GET /api/orders响应走 wrap() 包装 - 遗留分页参数暂只支持 page/sizecursor 分页待定 - 影响下游前端助手需按新接口对接这条记录的关键是“影响下游”那一行。多 AI 协作时最贵的就是沟通成本。有了这条日志前端助手开工前读一遍就知道后端接口变了不用人去口头同步。5.2 冲突检测让治理框架当“裁判”两个 AI 同时改一个文件或者一个 AI 改了公共 API 而另一个 AI 还在按旧签名调用这类冲突靠人盯是盯不过来的。我的做法是在治理框架里加一道轻量检查每次 AI 提交前先跑一个脚本比对changelog-ai.md里最近几条记录涉及的文件如果和当前任务的文件有重叠就提示 AI“可能存在冲突请先阅读最近的改动记录”。# 伪代码示意检查文件冲突 recent_files$(grep -A5 改动文件 .ai/changelog-ai.md | tail -20) current_files$(git diff --name-only) overlap$(comm -12 (echo $recent_files | sort) (echo $current_files | sort)) if [ -n $overlap ]; then echo 警告以下文件近期被其他助手改动过请先阅读 changelog echo $overlap fi这个检查很粗糙但实测能拦住大部分“撞车”情况。它不需要多复杂的实现核心思路是把隐性的协作冲突显性化让 AI 在动手前先看一眼别人干了什么。5.3 不同助手的能力边界要写进治理文件不同 AI 助手擅长的东西不一样有的擅长写测试有的擅长重构有的擅长写文档。治理框架里可以加一节“助手分工”明确每个助手适合干什么、不适合干什么。这不是限制而是让任务分配更合理。## 助手分工建议 - 助手A擅长后端逻辑业务逻辑、数据库查询、API 实现 - 助手B擅长前端组件、样式、状态管理 - 助手C擅长评审代码评审、测试补充、文档整理 - 通用禁区任何助手都不得单独修改 .ai/state.json 的 phase 字段最后那条“通用禁区”很重要。状态机的 phase 字段是整个框架的“总开关”如果允许 AI 随便改那状态机就形同虚设。把它列为所有助手的共同禁区是保证框架不被绕过的底线。6. 落地时最容易踩的五个坑框架设计得再漂亮落地时该踩的坑一个都不会少。下面这五个是我和身边同行反复踩过的写出来帮你省点时间。6.1 坑一AGENTS.md 写成“一次性文档”最常见的失败模式是项目初期兴致勃勃写了一大篇 AGENTS.md然后三个月没更新里面的命令早就失效了规范也跟实际代码脱节。AI 读到过时的规范反而会按错误的方式干活。治理文件必须和代码一起进版本控制并且每次规范变更都要同步更新。我的做法是把“更新治理文件”写进 PR 检查清单改代码的人有责任同步改规范。6.2 坑二状态机阶段划分过细有人把状态机设计成十几个阶段每个阶段权限都不一样。结果就是维护成本爆炸AI 也记不住。阶段划分要粗权限边界要清晰。四个阶段bootstrap / feature-development / hardening / freeze对大多数项目足够了。阶段越少AI 越容易记住人也越容易维护。6.3 坑三禁区清单太模糊“不要做危险操作”这种禁区等于没写因为 AI 对“危险”的定义和你不一样。禁区必须具体到文件路径、具体操作、具体命令。比如“禁止修改 src/core/ 下任何文件”就比“禁止修改核心代码”有用得多。模糊的禁区等于没有禁区这是我在多个项目里验证过的铁律。6.4 坑四忘了给 AI 留“提问通道”治理框架不应该把 AI 管死。如果 AI 遇到规则没覆盖的情况它需要有个地方提问而不是硬猜。我在 AGENTS.md 里加了一条“遇到规则未覆盖的情况在 changelog-ai.md 中记录[待确认]标记并暂停该部分任务等待人类回复。” 这条通道能避免 AI 在灰色地带自作主张。6.5 坑五只治理 AI不治理人最后这个坑最隐蔽框架只管 AI 的行为人却可以随意绕过。比如人自己手动改了公共 API 却没更新 architecture.mdAI 下次读到旧记录就会困惑。治理框架要同时约束人和 AI规则对双方生效。人改了什么也要记进 changelog。只有人和 AI 都遵守同一套规则这套框架才真正持久。7. 从零搭一套的最小可行路径如果你现在就想动手不用一上来就搞全套。我给一条最小可行路径半天能搭起来之后按需扩展。第一步在仓库根目录建AGENTS.md只写项目定位、三到五条铁律、文件索引。第二步建.ai/目录先放conventions.md和forbidden.md两个文件把最关键的规范和禁区写进去。第三步建state.json初始阶段设为bootstrap把允许/禁止动作列清楚。第四步建changelog-ai.md空文件即可约定每次任务后追加记录。第五步在团队里同步这套约定明确“AI 干活前先读 AGENTS.md干完活更新 changelog”。这套最小版本跑一两周你会明显感觉到 AI 的一致性变好了——它不再每次从零猜你的项目规范而是有据可依。之后再根据实际痛点逐步补充 architecture.md、commands.md、冲突检测脚本这些进阶内容。治理框架是长出来的不是一次设计出来的先跑起来比设计完美更重要。我在实际项目里用这套框架管了半年多最大的体会是它真正省下的不是 AI 的 token而是人的返工时间。以前每次新会话都要花十分钟重新交代背景现在 AI 自己读文件就能进入状态以前 AI 时不时改坏公共接口现在禁区清单直接拦住。这套东西不复杂难的是坚持维护——而坚持维护的前提是它真的有用。
返回列表