BMAD-METHOD 项目上下文管理实战:用 bmad-project-context 打造精准的 AGENTS.md 指令块
【免费下载链接】BMAD-METHODBreakthrough Method for Agile Ai Driven Development项目地址: https://gitcode.com/gh_mirrors/bm/BMAD-METHOD
导读
本篇文章聚焦 BMAD-METHOD 仓库中的bmad-project-context技能(SKILL.md),讲解如何为任意代码仓库生成、采纳、刷新、审计并维护一份"小而准"的 AI Agent 指令块(即AGENTS.md中被<!-- bmad:context -->标记包围的区块)。读完本文,你将掌握该技能的五个操作意图(setup / adopt / refresh / record / audit)、六步对话式工作流、账本(ledger)机制,以及"什么该写入、什么必须排除"的证据化判定规则,并能直接复用它为你的仓库建立可持续的 Agent 运行上下文。
一、技能定位:产出"经过验证的小指令块"
bmad-project-context的职责一句话概括:通过一场对话,产出一个仓库的 Agent 指令——AGENTS.md内一块小而经过验证的区块。用户带来他们希望被遵守的规则(治理、安全、标准),仓库提供其余部分,且每一句都由技能验证过。整个过程始终是对话式的,每一次写入都必须经用户批准(No writes until step 5!),技能从不擅自提交(Never commit.)。
技能接收的参数(Args):
- intent:
setup|adopt|refresh|record|audit五选一; - target repo or path:目标仓库或路径;
- extra source paths or URLs:额外来源路径或 URL。
从源码结构看,该技能是一个"对话即工作流"的 Skill 定义:不依赖自有脚本,核心逻辑全部写在 SKILL.md 的提示词流程中,判定规则沉淀在 references/best-practices.md,输出模板则来自 references/template.md。技能模块元数据见 module-manifest.toml(版本6.13.0-next)。
二、五个意图:先检测,再确认
技能在激活时会先做意图检测,而不是盲目信任用户声明的 intent——如果用户声明与检测结果冲突(例如对一份有实际内容的文件声称setup),技能会亮出矛盾并请用户确认,绝不静默服从。五个意图的判定标准:
| 意图 | 触发条件 |
|---|---|
| setup | 目标中没有任何含实质内容的指令文件——只有脚手架、空标题、一行注释或孤立 import 行都不算"有意义";拿不准时按 adopt 处理(采纳一份近乎空白的文件只花一小笔账本开销,而 setup 一个有内容文件会丢失指令) |
| adopt | 指令文件有内容但没有受管理区块——无论文件状态如何、谁写的;这是 refresh 的迁移形态,该文件成为基线,其中每条指令都进入第 1 步的账本 |
| refresh | 已存在受管理区块 |
| record | 用户报告 Agent 犯下的错误 |
| audit | 重新验证并修剪 |
record是唯一只接收"观察到的一次真实 Agent 失误"的意图——它是 pitfall(陷阱记录)唯一合法的来源。
三、六步核心工作流
1. 评估并汇报(Assess and report)
读取AGENTS.md、harness 或 Agent 专属规则文件、docs 目录以及任何承载经验的笔记。已有指令是待改进的基线,绝不是可丢弃的原材料。此步要开立一份账本(ledger):
- 对每个既有小节、每条独立有意义的指令各开一个条目,初始状态为
retain或rewrite; - 每个条目携带"若缺失,Agent 会出什么错"的说明;
- 随着第 2–4 步的证据到来,条目结算为
retain | rewrite | relocate | automate | delete之一,并附上理由、证据、删除风险、迁移目的地与批准标记; - 删除必须满足 best-practices.md 中四个理由之一;迁移目的地本身必须可被加载或位于可观察的触发器之后——移到无人读取的文件等于删除,需要同等理由。
若目标包含可分离单元(工作区清单列出的成员、或带独立构建清单的子目录),技能会点名这些单元并询问本次运行是否只覆盖根目录、全部或其中哪些;若无此证据则不提问。兄弟仓库不是子单元,各自是独立目标,会依次提供。
2. 询问用户带来什么(Ask what they bring)
询问与仓库做什么无关、都必须遵守的规则:治理、安全与合规、编码标准、风格指南、冻结区域。同时索取外部文档——手册、wiki、架构文档、MCP 知识库。只记下路径,此刻不读取。对新项目(Greenfield),这段对话就是全部内容;对既有代码库(Brownfield),它是任何扫描都够不到的那一半。
3. 发现并验证(Discover and verify)
用并行子代理针对各小节所需进行扇出调查:
- 可执行配置与 CI:用于政策类内容,也用于核验其自身已声明的语句;
- 受版本控制的源码:用于约定与边界;
- 定向历史:用于"理由必须仍然成立"的约束。
package.json、Makefile、pyproject.toml、贡献指南、PR 模板、CI 配置都会被读取——目的是知道指令块"绝不能重复什么"。对每条命名文件的说法做路径核验;对指令块将声称"某命令做什么"的每条语句,都要读取运行它的目标或脚本并核验。
4. 访谈空白区(Interview the gaps)
只问扫描够不到的问题:Agent 在这里反复出错的是什么、什么被禁止、某个领域术语的含义、某条约束为何存在。规则明确:
- 绝不问扫描能回答的问题——让用户确认一条已路径核验的说法或配置文件已声明的事实,属于缺陷;
- 问回忆型问题,不给清单——绝不把扫描制造的"选择题"丢给用户;
- 本次会话犯过并已发现的错误是观察到的证据,可以主动提出;
- 本次会话中读到的任何可复现命令(日志、文档、其自身运行),若其正确形式并非显而易见的猜测,是候选行——例如
uv run pytest才是对的,而表面上看pytest也没错但实际运行在项目环境之外; - 每批最多八个问题,越少越好;一批问题毫无新收获就意味着该写了;
- 当仓库与用户矛盾时,展示证据并提问——既不按原样写入用户说法,也不静默丢弃。
5. 展示区块,然后写入(Show the block, then write it)
按 template.md 组装。对每个候选,先问"hook、lint 规则或 CI 检查是否比散文更能强制它"——若是,先提议检查,该行在用户拒绝时才作为后备(账本中标记automate的条目在其检查落地前保留指令,检查上线后后续运行按理由 2 删除该行)。
写入前必须展示完整区块,子区块一并展示——一次批准覆盖整组。已结算的账本必须一同呈现:仅给替换文本是不完整的提案,因为它只展示用户所得、隐藏用户所失。每条既有指令都带其决策与理由;保留且未弱化完整规则的retain/rewrite可以分组;若重写弱化、收窄或删除了规则的一部分,被删部分按删除单独列出。删除若不属于前三项理由(陈旧错误 / 机械强制 / 有害矛盾),必须逐行单独审批——批准整个区块绝不等于批准删除;被拒的删除、迁移或自动化回退为retain。
批准后,在<!-- bmad:context -->与<!-- /bmad:context -->标记之间拼接写入——拼接本身绝不触碰标记之外的任何内容。标记外的文本只能通过已结算的账本条目或用户已看到的修复提案改变。每条 provenance(溯源)行填入今天的日期与核验过的 commit SHA。
若别处指令与区块矛盾且会改变行为(过期的CLAUDE.md行、退役的命令),则向该文件提出修复——两条同时生效的矛盾指令是缺陷。永不提交。
6. 收尾(Close)
- 汇报:写了什么、没写什么及原因;adopt/refresh 后每条既有指令的去向;
- 用用户的语言解释为什么——为什么区块这么小、为什么仓库已声明的内容被排除在外、为什么 pitfall 在其根因消失前一直保留;
- 说明它如何被加载,以及其它 harness 文件如何指向它;
- 说明用户提交这些指令变更时适用的分支、ticket、commit、PR 规则;
- 维护建议:重大变更后重跑、Agent 一出错就
record、优先用检查而非新增一行; - 跨项目重复的规则、或个人而非团队层面的规则,应放进用户的全局 Agent 配置。
四、区块模板:六个板块与书写纪律
template.md 规定区块内按此顺序排列,任何没有内容能通过准入规则的板块一律省略,绝不写空板块:
- Orientation(方向)——三到四句话:这是什么、技术栈、规划与深入文档在哪;
- Policy(政策)——组织要求什么;
- Where things are(物在何处)——入口点,以及指向子文件与链接文件的指针;
- Running and verifying(运行与验证)——正确的运行命令与所需工具版本,外加
package.json、pyproject.toml、Makefile或 CI 配置尚未说明的内容; - Conventions that differ from defaults(与默认不同的约定);
- Known pitfalls(已知陷阱)。
书写纪律:
- 平级标题下用简洁的祈使句;除 Orientation 外无散文、无引言、无总结;
- 裸事实只能作为指令的"理由从句"出现——写"从搜索中排除
vendor/,它占跟踪文件的 60%",而不是"vendor/占跟踪文件的 60%"; - 禁令必须指名替代方案;
- 整个区块最多两处强调标记。
模板自带一个 worked example(acme-billing 支付服务示例),完整展示了从<!-- bmad:context -->注释(含核验日期与 SHA)到六个板块再到闭合标记的成品形态,可作为实际产出物的直接参照。模板同时提醒:provenance 行必须填真实日期和核验所对的 commit SHA,refresh 时从该 SHA 做差异对比。
五、判定规则:什么该写、什么该排除
best-practices.md 是整个技能的价值核心,它回答"仓库的 Agent 指令里到底该放什么"。
核心测试
不是"Agent 能否推导出来",而是**"推导不出来时代价多大"**:找到它需要多少探索、Agent 有多大可能按时搜对地方而非猜测、它在使用时是否可得还是只在犯错后出现、检索失败的成本是浪费一次搜索还是损坏数据、它是必须成立的规则还是代码已展示的细节。每行都要回答同一个问题:删掉它会不会改变 Agent 行为?不会就删。
能阻止每次会话重复同一昂贵探索的一行,哪怕可推导也值得留下;而把 Agent 一手的、更准确的读取结果复制一份则不值得——副本会腐烂,且每次会话都要付费。
准入清单(Admit)
- 代码无法表达的政策——分支规则、冻结与受保护路径、生成文件、机密、安全与合规;必须由人声明或从强制配置读出,绝不推断;
- 配置文件无法说明的运行事项——根测试脚本在此工作区什么都不做、集成测试需先起服务、全套件要十一分钟所以迭代时跑单文件、
Makefile才是真正入口而package.json形同虚设、CI 跑测试脚本不覆盖的 typecheck。显然的猜测就能得到正确调用的命令,已由package.json/Makefile/pyproject.toml/CI 声明,不值得占行;修正、注意事项和正确的命令才值得; - 与生态默认不同的约定——Agent 默认遵循惯例,只有偏差值得占行;命令调用也算:当显而易见的命令在此处是错的(裸仓库前缀、必需的包装器),精确的正确调用就值得一行,且无需先观察到失误;
- 有观察证据的陷阱——已记录的经验、维护者的回忆、历史中反复修复的同一错误、或本次会话犯下并已抓住的错误。仓库能产出数百个"看起来像陷阱"的事实,但只有观察到的行为能预测真实失误;令人惊讶的扫描发现是"要问的问题",不是"要写的行";
- 仓库中不可见的运行时行为——回放的 webhook、撒谎的健康检查端点、环境怪癖——一旦人工确认;
- 跨组件规则——在一个文件里改错会在别处破坏东西的规则:谁拥有什么、数据如何流动、流水线按什么顺序运行。例如"写入必须走 dispatcher;直接改 store 会跳过事务""importer 是两遍——先逐行校验再提交;绝不要在解析循环里写库";
- 必需的工具与运行时版本——从声明它们的项目文件读取,绝不从本次会话环境读取(会话环境回答更快,也错得更快);
- 入口点与指针——指向工作落点。
排除清单(Exclude)
| 排除内容 | 原因 |
|---|---|
| 仓库概述、目录树、技术栈清单 | 现场重新推导更准确;存储副本会腐烂 |
| 任何只因"有趣"而收录的内容 | 兴趣不是需求 |
| Agent 本可自我执行的风格规则 | 属于 formatter、linter、hook 或 CI——应提议检查 |
| 陈词滥调 | 本来就是默认 |
| 显而易见调用本就正确的命令清单转写 | 从package.json/Makefile/CI 读取即可;脚本一改名副本就漂移 |
| 粘贴的代码、变更日志内容、快速变化的事实 | 立即过时 |
| 理想状态 | 写"是什么";意图属于 spec |
| 历史与编辑叙述 | Git 存着历史;区块只陈述当下真相 |
退役规则(Retire)
政策或陷阱只在其所守护之物消失、或用户将其退役时才能删除。"最近没出事"绝不是证据——一条正常工作的规则会抹掉它自己的证据。任何其它既有指令,只能依据"评判既有文件"的四个理由之一删除。
规模纪律(Size)
**每一行都在每次会话中付费,且随加载集增大,指令遵循会退化。**预算超了就砍最弱的行或把它们移到触发器之后——绝不提高预算。十条证据就是十行。采纳的文件也必须适配预算,但缩减方式不同:先把最弱的指令移出去(子文件、链接文档、或强制它的 hook/检查),删除仍需四个理由。文件仍然过大且无理由再删时,展示给用户由其决定——用户选择的超预算文件,好过用户没有参与的"被掏空"的文件。"保持小"约束的是技能自己写什么,而不是维护者已写的。
检索原则(Retrieval)
**必须主动选择去取的索引会被跳过;已经在上下文中的索引不会。**一切承重内容留在区块内。指向外部的指针必须命名 Agent 可观察的触发器(路径、文件类型、具名任务),绝不能是它需要判断的东西("当任务复杂时")或需要追踪自身状态的东西("在首次编辑之前")。仅当触发器不是路径时才用链接文件。
维护(Maintain)
- 复查注意事项是否仍然成立(变快的慢套件、被修复的 bug 的变通方案);
- 对照核验 SHA 之后的删除与重命名,逐行 diff;
- 在区块内记录 provenance,让下次运行知道自己在对什么做 diff;
- 失误发生时当场记录,而不是评审时;一次出现是笔记,复发才占一行;
- 任何机械可防的问题路由到 hook/lint/CI——落地的检查会删除对应行。
评判既有文件(Judging an existing file)
人类写下的每条指令都被假定为有意为之:有人为它付过钱,通常是看着 Agent 失败。文件是被改进的基线,不是原材料。删除必须满足四个理由之一:
- 陈旧或错误——所指之物已消失,或指令从未为真,并点名证据;
- 机械强制——hook、linter、formatter 或 CI 检查已能让该指令指出的违规失败。只覆盖相同文件或主题的工具不算强制了这条指令;
- 有害或矛盾——把 Agent 指向错误的东西,或与另一条生效指令矛盾且无法调和;
- 用户批准本次删除——必须逐行单独询问,绝不因批准替换区块而暗示。
理由 1–3 由本次运行自证并随区块批准;理由 4 是其余一切情况都要走的"先问"路径。除此之外什么都不删。简洁不是理由、最近没出事不是理由、"Agent 能推导"不是理由、"仓库里某个地方找得到"单独永远不是理由——那正是掏空好文件的推理方式。被排除清单拒绝的内容(目录树、技术栈清单、粘贴代码)没有自己的理由,按理由 4 提议删除。
汇报顺序固定:先讲什么不可验证或过时,再讲对照各小节缺什么,然后讲什么已经很好,最后是账本——每条迁移、自动化、删除都逐条列明。已记录的经验是维护者的证词,默认保留,只有用"所指之物已消失或错误"的证据才能挑战。
六、扩展流程:refresh、adopt、greenfield 与迁移
- Refresh:步骤相同,但第 1 步是 diff。读取 provenance 行,重新核验每条路径与每条注意事项,并对照记录的 SHA 运行
git log --diff-filter=DR --name-only逐行检查——证据消失的行要更新或删除。每条拟删除都是第 5 步展示的账本条目,绝非静默编辑。绝不重问先前运行已解决的问题;访谈收缩为"团队工作方式发生了什么变化"。区块只在新证据上增长。 - Adoption:对技能从未触碰过的指令做 refresh。没有先前的结算,完整访谈适用;文件本身是维护者的证词,因此账本是本次运行的主要产出——用户应能读着它看到自己每条指令的去向。提案须说明从哪些文件中移出指令后各文件还剩下什么(常见形态:
CLAUDE.md瘦身为@AGENTS.md一行导入,前提是已验证每个在用 harness 都支持该导入)。同一条指令绝不出现在两个被加载的文件中(付两次费);重复的——无论逐字还是改写——只保留一次,区块保留幸存者,两个条目同时结算。 - Greenfield:从 spec 或规划文档播种,或仅靠访谈。尚不存在的命令写成显式 TODO 并点名既定技术栈,绝不把猜测的调用当事实陈述,待代码出现后的首次 refresh 再核验。真正有争议的设计决策(真实权衡、多个可行形态)交给
bmad-architecture。 - Migration:若目标中存在已退役技能(
bmad-generate-project-context/bmad-document-project)遗留的project-context.md(通常在{output_folder}下),第 1 步读取它并提供吸收其内容的选项。未经同意不删除,也不静默弃置。
七、record 与 audit:错误即入口,审计只减不增
Record:当场捕获一次观察到的 Agent 失误——这是 pitfall 唯一合法的来源。取走任务、失误、纠正及其证据;检查区块是否已有覆盖该行的一行;单次出现记为笔记,反复出现或代价高昂的失误才立即占一行——命令类错误写成Running and verifying下的精确调用,其它写成 pitfall;写完后展示 diff。若机械可防,则提议 hook、lint 或 CI 检查。
Audit:重新核验每条注意事项、路径核验每个文件、跟进每个指针,并问每一行"删掉它是否会改变 Agent 行为";对照运行它的目标或脚本核验每条命令声明;检查与其它指令文件的矛盾。失败的行被修复、移到可观察触发器之后、或变成账本条目——删除仍需 best-practices.md 的四个理由,按第 5 步展示并结算后才能移除。政策或陷阱只在其所守护之物消失或用户将其退役时离开;"最近没失败"不是理由。审计结束时区块更小或相等,绝不更大。
八、子文件(Children):何时拆分、何时留在根区块
当工作持续落在一个组件、嵌套仓库或抽取的规则文件上,且每个条件都成立时,才为它建立同构的子文件:规则是子树专属的、内容可观(寥寥几条规则撑不起一个文件)、拆分显著减小父区块、加载机制对每个在用 harness 都核验过(检查,绝不假设),且用户批准拆分。即使加载已核验,若规则必须在会话进入该目录前生效、或违反它会影响到子树外的工作,仍把它留在根区块。否则以路径限定行留在父区块("在src/importer/中:……"),比一个没人加载的文件便宜。**仅在触发器不是路径时才用链接文件。**被选中的子文件若最终没有父区块未说过的新内容,就不建文件,说明原因后继续。每个子文件都要在父区块的Where things are中用一行列出其路径——发现过程绝不依赖 harness 自己找到它。
九、定制面:workflow 配置与源码佐证
技能激活时会解析定制配置:执行uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow,失败时直接读 customize.toml 用默认值;若{project-root}/_bmad存在,再运行resolve_config.py读取中央配置。
customize.toml 定义了 [workflow] 表(该文件被更新时整体覆盖,团队覆盖放{project-root}/_bmad/custom/bmad-project-context.toml,个人覆盖放...user.toml;合并规则为标量后层覆盖、数组追加):
activation_steps_prepend/activation_steps_append:激活前后注入的步骤,默认空数组;persistent_facts:默认故意为空——技能自身的产出(AGENTS.md)由 harness 加载,不经过此数组;用户自行追加自己的常驻事实(file:为路径/glob,其它按原文处理);on_complete:完成钩子,默认空字符串;external_sources:每次 setup/refresh 默认提供的仓库外来源(未验证前不可信),支持file:{project-root}/...、file:/abs/path、skill:name、tool:name(MCP 知识库)及纯文本常驻事实,追加式。
源码层面,resolve_customization.py 实现了三层 TOML 合并与项目根解析:find_project_root以_bmad/优先于.git向上寻找(子模块携带.git却未必是 BMad 项目);candidate_project_roots按"工作目录 → 脚本安装路径 → 技能目录"的信任顺序候选;若所选根没有该技能定制而其它根有,会向 stderr 打印提示而非静默采用。--key支持点路径抽取(如workflow),输出 JSON 到 stdout。resolve_config.py 则对四层中央 TOML 配置做同样风格的合并与键抽取。这些脚本同时解释了 SKILL.md 中"失败时直接读 customize.toml 用默认值"这一降级路径的由来:resolve_customization.py在配置解析失败时返回非零退出码并打印错误。
十、与官方文档、仓库实践的对齐
本技能在 BMAD-METHOD 文档体系中对应 Set and Maintain Project Context(操作指南)与 The Theory of Project Context(原理论证)。后者的核心论据恰好解释了本技能为何如此克制:
- 实测表明,仓库级任务中代码访问优于文档访问;为 Agent 写的大多数文档反而让它们更糟——测量显示仓库指令文件"存在 vs 缺失"对成功率无提升,且推理成本 +20%;
- 但对模型训练数据中不存在的框架 API,一份压缩的文档索引放入
AGENTS.md能把通过率提到100%(无文档 53% → 压缩索引 100%,40KB 压到 8KB 性能无损); - Agent 常跳过需要主动选择的检索(709 页 wiki 测试中 Agent 跳过索引直接猜路径),因此"已在上下文中"的区块才能承重,指针必须命名可观察触发器;
- 结论即本技能的产出哲学:实现上下文(约束、命令、约定、陷阱)属于代码仓库,必须极小、可核验、每次会话加载;规划上下文(理由、被拒方案、归属、领域语义)属于项目/计划,是另一项能力——用同一文件服务两者正是被本技能取代的两个旧技能(
bmad-generate-project-context、bmad-document-project)失败的原因。
仓库自身就是本技能的活样本:AGENTS.md 展示了规则先行的仓库指令形态(Conventional Commits、推送前运行uv sync --frozen && (cd docs-site && npm ci) && uv run --frozen tools/quality.py等);它同时印证了 best-practices 中"命令正确调用值得一行"的原则——正是这类"明显猜测会出错"(未加--frozen、未在确切 checkout 上运行)的命令,才有资格进入指令块。
十一、实战快速上手
- 在目标仓库根目录运行
bmad-project-context,用平实语言说出意图——"set up AGENTS.md"、"adopt 我们已有的 AGENTS.md"、"refresh the context"、"audit our context"、"agent 总在用错的测试运行器"——技能会自动路由到对应意图; - 若不在目标仓库内,指明路径;该路径解析到多个工作树时先询问,树内不可提交时也先询问;
- 按第 2–4 步提供治理/安全/风格规则与外部文档,等待技能完成扫描验证与空白访谈;
- 审阅完整区块与已结算账本,逐项批准(删除、迁移、自动化需逐项确认);
- 批准后内容写入
AGENTS.md的<!-- bmad:context -->标记之间;对读取其它文件(如CLAUDE.md)的工具,技能会提议并核验一行@AGENTS.md导入;标记外内容一律不动,技能从不 commit; - 提交这份变更——区块随代码入库,团队共享、跨机器一致、与它所约束的代码同版本演进;
- 之后保持健康循环:重大变更后refresh、Agent 一出错当场record、定期audit(只减不增),能把规则交给 hook/lint/CI 的尽早移交。
bmad-project-context的最终交付物永远是:证据允许几行,就写几行——保持小、保持核验、保持每行都能改变 Agent 行为。
【免费下载链接】BMAD-METHODBreakthrough Method for Agile Ai Driven Development项目地址: https://gitcode.com/gh_mirrors/bm/BMAD-METHOD
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考