外观
第 4 章 · AGENTS.md 持久化规则
前 3 章解决「当下这一轮怎么做好」,本章解决「如何让好做法自动发生」。AGENTS.md 是 OpenCode V2 的规则中枢:写一次,每个会话自动遵守。
本章包含 5 个知识点:
- AGENTS.md 是什么:定位与加载层级
- 该写什么:长期有效规则的分类
- 不该写什么:易失信息与一次性内容
- 规则的写法:具体、可执行、带正反例
- 规则冲突、层级合并与长期维护
知识点 1:AGENTS.md 是什么:定位与加载层级
① 定位
这是规则系统的起点。要用好 AGENTS.md,先要准确回答:它放在哪、什么时候被读取、多个文件之间什么关系。 这些机制决定了你的规则会不会生效、在多大范围内生效。
② 是什么(What)
AGENTS.md 是一个纯文本(Markdown)规则文件,你在其中写下希望 AI 在本项目(或本机)长期遵守的约定。会话启动时,它被自动加载进上下文,无需每次口述。
V2 中规则文件分布在几个层级:
| 层级 | 典型位置 | 作用范围 |
|---|---|---|
| 全局(用户级) | ~/.config/opencode/AGENTS.md | 你在所有项目中的通用偏好 |
| 项目级 | 项目根目录 AGENTS.md | 整个项目,通常纳入版本控制供团队共享 |
| 目录级 | 子目录中的 AGENTS.md | 该子目录及其下层(就近规则) |
多个层级同时存在时,它们共同构成规则集,是「合并」关系而非「互相覆盖」:全局给通用底色,项目给团队约定,子目录给局部细则。嵌套文件按「就近优先」的顺序加载并自动去重;同一区域不会被重复注入。也就是说,不存在「子目录规则覆盖、抹掉根规则」——所有仍适用的规则同时在场。
两条必须记牢的事实:
- V2 只识别
AGENTS.md,不会回退读取CLAUDE.md。 把规则写进CLAUDE.md在 V2 中不生效。 - AGENTS.md 本质是每次都自动附上的上下文——它因此稳定,但也占用窗口,应保持精炼。
③ 怎么做(How)
- 想让某条偏好在所有项目生效 → 写进全局
~/.config/opencode/AGENTS.md; - 团队共享的项目规范 → 写进项目根
AGENTS.md并提交到版本库; - 仅某个子目录需要的特殊约定 → 在该目录放
AGENTS.md; - 迁移自其它工具时,把
CLAUDE.md中的有效内容并入AGENTS.md;
④ 为什么这么做(Why)
- 重复沟通必然出错且耗力。 「测试用 Vitest」「提交信息用规范格式」这类规则每次口述,十次里可能漏两三次,疲劳、新项目、新成员加入时尤其严重。文件不会疲劳,加载即生效。
- 分层加载匹配「通用 / 团队 / 局部」三类规则的天然差异。 个人偏好不该强加给团队,故放全局;团队约定需要共享,故放项目根并入库;局部细则只需在相关目录生效,避免污染全局语境。
- 自动加载把规则从「记忆责任」变成「系统责任」。 你不需要记得「该提醒什么」,系统保证规则在场——这是把人从易漏环节中解放出来的工程设计。
- 规则即上下文,因此稳定也占空间。 理解这一点,你才会认真对待 AGENTS.md 的长度和内容质量,而不是什么都往里塞。
⑤ 这样做的好处
- 规则零重复、零遗漏:一次书写,长期自动遵守。
- 团队一致:项目根文件入库后,每个人、每个会话看到同样的约定。
- 新人友好:新成员(人类或新会话)开局即掌握规范。
- 范围精准:通过层级选择规则影响面,不扩大也不缩小。
- 可沉淀、可演进:规则文件有版本历史,能随项目成长。
⑥ 不这么做的问题 / 坏处
- 只靠口头交代 → 规则时灵时不灵,质量全凭当天状态。
- 写错文件名 → 把规则写进
CLAUDE.md,V2 根本不读,还困惑「为什么不生效」。 - 所有规则都堆全局 → 个人偏好污染团队项目,或无关规则挤占每个会话窗口。
- 不用目录级规则 → 在项目根写大量只针对某模块的细则,全员被迫阅读无关内容。
⑦ 举一反三:三个例子
例 1(基础):建立个人通用偏好
📌 场景:你希望所有项目里 AI 回复都用中文、解释尽量带示例。
✅ 做法:创建 ~/.config/opencode/AGENTS.md:
markdown
# 个人通用偏好
- 默认使用中文回复
- 解释概念时优先给简短示例,再给结论🔍 讲解:这是与具体项目无关的偏好,放全局最合适——一次设置,处处生效,且不会影响团队仓库。
例 2(进阶):项目根写团队共享规范
📌 场景:团队约定测试用 Vitest、提交信息用 Conventional Commits、禁止随意改迁移文件。
✅ 做法:项目根 AGENTS.md 并提交 Git:
markdown
# 项目工程约定
- 单元测试使用 Vitest,测试文件与源码同级
- 提交信息使用 Conventional Commits(feat:/fix:/docs: ...)
- 未经明确授权,不要创建或修改数据库迁移文件🔍 讲解:这些是团队级、长期有效的规则,入库后所有成员的会话都自动遵守。比起在群里反复强调,文件是唯一不会被聊天记录淹没的载体。
例 3(挑战):用目录级规则隔离特殊模块
📌 场景:项目主体是普通业务代码,但 legacy/ 目录是一套不准随意改动的老系统,有独特禁忌。
✅ 做法:在 legacy/AGENTS.md 写局部规则(如「改动前必须先列出影响面,禁止升级该目录依赖」),不污染项目根规则。
🔍 讲解:当 AI 在 legacy/ 下工作时就近规则生效;在其它目录则不受这些细则干扰。目录级规则是「局部高压政策」的精准工具,避免为一个特殊模块让全项目背上冗余规则。
⑧ 练习题 ×2
练习 1(巩固型)
📝 题目:判断下列规则应放在哪个层级:(a)你个人偏好用中文回复;(b)团队统一的代码风格;(c)只针对某第三方 SDK 封装目录的特殊约定。
💡 思路提示:按「影响谁、在多大范围生效」归类。
✅ 参考答案:
text
(a) 全局:~/.config/opencode/AGENTS.md;
(b) 项目根:AGENTS.md(入库共享给团队);
(c) 目录级:该目录下的 AGENTS.md。🔍 讲解:层级选择的本质是让规则影响面与规则适用范围精确匹配。
练习 2(迁移型)
📝 题目:迁移到公司管理:「公司制度 / 部门规定 / 小组约定」这种分层,和 AGENTS.md 的层级有什么共性?分层有什么好处?
💡 思路提示:上位规则通用、下位规则具体;局部规定不干扰其它部门。
✅ 参考答案(示例):
text
- 公司制度 ≈ 全局 AGENTS.md:全员通用的底线与偏好;
- 部门规定 ≈ 项目根规则:本部门(项目)特有的协作约定;
- 小组约定 ≈ 目录级规则:仅小范围生效的细则。
共性:上位层给通用底色,下位层补具体细则,各层只影响自己的范围;
好处是通用规则不重复书写,局部规则不强加给无关人员,
体系既统一又灵活——AGENTS.md 复刻的正是这种成熟的分层治理结构。知识点 2:该写什么:长期有效规则的分类
① 定位
知道放哪之后,下一个问题是写什么。本知识点给出一份「值得写进 AGENTS.md」的内容地图,帮你系统地识别身边哪些隐性约定该被固化,而不是面对空白文件无从下笔。
② 是什么(What)
适合写进 AGENTS.md 的,是长期稳定、反复适用、不说就容易出错的规则。常见可分为六类:
| 类别 | 例子 |
|---|---|
| 技术栈与命令 | 用什么框架、安装 / 构建 / 测试命令 |
| 代码风格与结构 | 命名约定、目录组织、组件写法 |
| 测试要求 | 测试框架、覆盖率期望、何时必须补测试 |
| 提交与协作 | 提交信息格式、分支约定、PR 要求 |
| 禁区与风险 | 哪些文件 / 操作不能擅自触碰 |
| 业务与领域规则 | 关键业务概念、计量单位、特殊约束 |
判断一条内容值不值得写,用三个筛子:
- 长期有效吗? 下周就变的事不该写;
- 会反复用到吗? 只此一次的任务不该写;
- 不说会出错吗? 显而易见、永不会被违反的不必写。
③ 怎么做(How)
- 先在工作中捕捉:当你发现自己第二次对 AI(或新同事)说同一件事,就是该写进文件的信号;
- 按六类归类起草,每条一行、简明可执行;
- 优先写高价值、易出错项:禁区、业务规则、测试与提交要求;
- 写不出时,翻看最近几次返工——返工的根因往往就是缺失的规则;
④ 为什么这么做(Why)
- 「第二次重复」是最优的固化时机。 第一次可能是偶然,第二次说明它是模式;此时写下,既不过早抽象,也不会等到第十次重复才行动。
- 分类让隐性约定显性化。 很多规则你以为「大家都知道」,其实只存在于你的经验里。六类清单像探测器,帮你把本该共享却没说出口的知识挖出来。
- 三个筛子保证规则的「信噪比」。 只收长期、反复、易出错的内容,AGENTS.md 才能保持精炼——它每轮都被加载,低质量规则会持续浪费窗口和注意力。
- 返工根因是最宝贵的规则来源。 每一次 AI(或人)犯错,都暴露了一条没被写明的约定;把教训转成规则,错误就不会重演第二次。
- 规则可逐步生长,降低启动门槛。 不需要完美的初始版本,几条核心约定就能产生价值,随后持续迭代。
⑤ 这样做的好处
- 内容系统无遗漏:六类清单覆盖项目协作的主要方面。
- 规则高价值:每条都经得起「长期 / 反复 / 易出错」检验。
- 返工持续下降:教训被及时转化为防线。
- 文件精炼可读:不堆积短命、无用内容。
- 沉淀变轻松:日常工作中顺手捕捉,不依赖专门「大整理」。
⑥ 不这么做的问题 / 坏处
- 凭感觉写 → 要么写一堆显而易见的废话,要么漏掉真正关键的禁区。
- 把一次性任务写进去 → 文件很快过期、失真,后续规则的可信度也下降。
- 从不回看返工 → 同类错误反复发生,教训从未变成规则。
- 追求一次写全 → 面对空白文件压力大,迟迟不动手。
⑦ 举一反三:三个例子
例 1(基础):从一次返工提炼规则
📌 场景:AI 又一次把金额按「元」处理,而项目内部单位是「分」,导致数值错误。
✅ 做法:在 AGENTS.md 业务规则类写下:「所有金额内部以『分』(整数) 存储与计算,展示层才转换为元。」
🔍 讲解:这是典型的领域规则——不写就极易被通用假设(元)取代,且后果严重。一次真实返工就是规则立项的最佳证据。
例 2(进阶):系统补一组工程规则
📌 场景:新项目启动,你想把团队成熟做法一次性固化。
✅ AGENTS.md 节选:
markdown
# 工程约定
- 包管理器使用 pnpm,不要混用 npm/yarn
- 测试:Vitest;新增工具函数必须附带单元测试
- 提交:Conventional Commits
- 禁区:不要擅自修改 CI 配置与数据库迁移🔍 讲解:四条分别覆盖命令、测试、提交、禁区四类高价值项,都是长期反复适用的。项目开局就定规则,比运行中反复纠正便宜得多。
例 3(挑战):判断哪些「想写的内容」其实不该写
📌 场景:你考虑把下面这些写进 AGENTS.md:「本周五前完成登录页」「记得给这个临时文件改名」「函数不要太长」。
✅ 筛选结论:
text
- “本周五前完成登录页”:一次性、短期 → 不写(属任务,不属规则);
- “给这个临时文件改名”:单次动作 → 不写(直接做即可);
- “函数不要太长”:方向正确但太模糊 → 若写,改成可执行标准,
如“单函数尽量不超过 50 行,超出时考虑拆分”。🔍 讲解:高手不仅知道该写什么,还能剔除短命内容、把模糊口号改写成可执行规则。这保证 AGENTS.md 始终是稳定、可操作的规则集,而不是杂记本。
⑧ 练习题 ×2
练习 1(巩固型)
📝 题目:说出适合写入 AGENTS.md 的至少 4 类规则,以及判断一条内容是否值得写的三个筛子。
💡 思路提示:六类清单 + 长期 / 反复 / 易出错。
✅ 参考答案:
text
类别(任 4):技术栈与命令、代码风格、测试要求、提交协作、
禁区风险、业务领域规则。
三个筛子:是否长期有效、是否会反复用到、不说是否容易出错。🔍 讲解:能同时回忆「写什么」和「怎么筛」,说明你具备独立建设规则文件的能力。
练习 2(迁移型)
📝 题目:迁移到团队知识管理:为什么「员工手册 / Wiki」只应收录长期有效的内容,而不是本周待办?混入过期内容会怎样?
💡 思路提示:可信度、检索噪音、维护成本。
✅ 参考答案(示例):
text
- 手册的价值在于「随时可查且可信」,只收录稳定规则才能保持这一价值;
- 本周待办是短命信息,写完很快过期,混入手册后读者无法分辨
哪些仍然有效,逐渐不再信任整份文档;
- 过期内容还增加检索噪音和维护负担。
共性:任何「规则 / 知识库」都应与「任务 / 待办」分离,
保持内容长期有效——AGENTS.md 同理,所以不写一次性任务。知识点 3:不该写什么:易失信息与一次性内容
① 定位
上一知识点从正面讲「写什么」,本知识点从反面讲「绝不写什么」。往 AGENTS.md 里加内容很容易,删除却常被忽视——而文件质量往往不是被「缺内容」毁掉,而是被「多余、过期内容」稀释掉的。
② 是什么(What)
不应写进 AGENTS.md 的内容主要有五类:
| 不该写 | 原因 | 应放何处 |
|---|---|---|
| 一次性任务 / 待办 | 做完即过期 | 任务管理 / 当前会话 |
| 临时状态(如「某服务暂时挂了」) | 状态随时变化 | 会话中说明即可 |
| 具体实现细节 / 大段代码 | 易随重构过期,且占窗口 | 代码本身与文档 |
| 秘密与敏感凭证 | 入库即泄露 | 密钥管理 / 环境变量 |
| 模糊口号、矛盾规则 | 无法执行或互相打架 | 改写成具体可执行规则 |
核心理念:AGENTS.md 是「规则」容器,不是「信息」垃圾桶。 判断不准时,回到三个筛子(长期 / 反复 / 易出错),通不过的就不写。
还要警惕「规则膨胀」:每次出问题都加一条,却从不删除已失效规则。文件越长,每轮加载成本越高,真正重要的规则反而越不突出。
③ 怎么做(How)
- 写入前自问:「这条三个月后还成立吗?」——不成立就不写;
- 临时信息只在会话里给,必要时用
/btw或排队; - 大段说明放进专门文档,AGENTS.md 只保留稳定的规则条目;
- 敏感信息一律不入库,用环境变量 / 密钥工具;
④ 为什么这么做(Why)
- 过期规则比没有规则更危险。 一条已失效的规则若仍被加载,AI 会按它行动,产出与当前现实冲突;而你可能很久才意识到规则早就过期。错误的权威比无权威误导性更强。
- AGENTS.md 每轮都占窗口。 大段代码、临时细节塞进去,每个会话、每次请求都在为这些内容付费,信噪比持续下降。
- 敏感信息入库是不可逆泄露。 项目文件通常进 Git、可能推到远端;凭证一旦写入历史,即使之后删除也可能已被复制,必须从源头杜绝。
- 矛盾规则让 AI 无所适从。 「优先写简短函数」与「每个函数都要处理所有错误并打日志」若冲突,模型只能随机取舍,问题却被掩盖。
- 定期删除与新增同样重要。 规则集是活系统,项目演进时旧规则必须退场,才能始终准确反映现实。
⑤ 这样做的好处
- 规则始终可信:每条都长期有效,AI 与团队都能放心依赖。
- 文件精炼省窗口,加载和阅读成本低。
- 安全无泄露:凭证不进入版本历史。
- 重点突出:最重要的规则不会被噪音淹没。
- 维护成本低:定期小复审,避免积重难返的大清理。
⑥ 不这么做的问题 / 坏处
- 任务 / 状态混入 → 几周后文件半真半假,没人再当真。
- 粘贴大段代码 → 重构后规则与代码不一致,AI 引用过时示例。
- 写入密钥 → 凭据泄露,可能造成安全事故。
- 只增不删 → 文件膨胀、规则互相矛盾,执行结果漂移。
⑦ 举一反三:三个例子
例 1(基础):临时故障只在会话里说
📌 场景:测试环境数据库今天上午维护,你想让 AI 暂时别跑依赖数据库的测试。
✅ 做法:只在当前会话说明:「测试库今天上午维护,先不要跑集成测试。」不写进 AGENTS.md。
🔍 讲解:这是几小时后就失效的临时状态。写入规则文件,下午它仍会被加载,造成误导。短命信息走会话,长期规则才进文件。
例 2(进阶):敏感配置绝不入库
📌 场景:AI 需要调用第三方 API,你手头有 API Key。
✅ 做法:通过环境变量 / 密钥管理注入,AGENTS.md 只写「调用该服务需从环境变量读取 XXX_API_KEY」,绝不写密钥本身。
🔍 讲解:规则可以描述「怎么取用」秘密,但不能包含秘密内容。这样既让 AI 知道正确做法,又不造成泄露。
例 3(挑战):给膨胀的规则文件瘦身
📌 场景:项目迭代半年后,AGENTS.md 积累了大量条目,其中一些描述的模块已删除、几条互相重复。
✅ 做法:逐条过一遍——模块已删的规则删除;重复的合并;仍有效但模糊的改写;最后确认剩下的每条都「长期有效且可执行」。
🔍 讲解:定期瘦身让规则文件重新与项目现实对齐。高手把「删除」当作与「新增」同等重要的维护动作——规则系统的质量,取决于你是否舍得删掉过时的部分。
⑧ 练习题 ×2
练习 1(巩固型)
📝 题目:判断下列内容该不该写进 AGENTS.md,并说明理由:(a)「下周一切换到新域名」;(b)「金额以分为单位」;(c)第三方服务的 API Key;(d)「代码写好点」。
💡 思路提示:长期有效吗?敏感吗?可执行吗?
✅ 参考答案:
text
(a) 不写:短期、一次性,过期即误导;
(b) 写:长期业务规则,不说易出错;
(c) 不写:敏感凭证,应走环境变量 / 密钥管理;
(d) 不直接写:太模糊无法执行,需改写成具体标准。🔍 讲解:这四类覆盖了「短命 / 长期 / 敏感 / 模糊」四种典型判断,掌握后你对任何内容都能快速归类。
练习 2(迁移型)
📝 题目:迁移到个人生活管理:为什么「长期原则」适合写进日记 / 信条,而「今天买牛奶」只适合写进购物清单?混在一起会怎样?
💡 思路提示:信息稳定性不同,容器应与内容寿命匹配。
✅ 参考答案(示例):
text
- 长期原则反复适用、长期稳定,放在固定的信条 / 笔记里随时可回顾;
- “今天买牛奶”当天有效、做完即弃,放购物清单即可;
- 混在一起:信条里堆满过期琐事,真正的原则被淹没,
购物项又可能在几天后仍被当成待办。
共性:容器要与内容的「寿命」匹配——长期规则进规则文件,
临时事项进任务 / 清单,AGENTS.md 与生活管理遵循同一原则。知识点 4:规则的写法:具体、可执行、带正反例
① 定位
选对了内容,还要写得让 AI(和人)能准确执行。同一条规则,「写清楚」和「写个口号」效果天差地别。本知识点把第 1 章的 Prompt 表达原则,应用到规则撰写上。
② 是什么(What)
一条好规则通常包含三要素:
- 明确的行为:具体做什么 / 不做什么,而不是抽象形容词;
- 可判断的标准:怎样算做到(格式、位置、数量、触发条件);
- 必要时给正反例:一个符合、一个违反的简短示例。
对比:
| 模糊口号(弱) | 可执行规则(强) |
|---|---|
| 注意代码风格 | 使用 2 空格缩进,语句末尾不加省略号 |
| 多写注释 | 每个导出函数加一行 JSDoc 说明用途与参数 |
| 测试要全 | 新增工具函数必须覆盖正常、边界、非法输入三类 |
| 别乱改东西 | 只修改任务指定文件,改动无关文件需先说明 |
写作时同样遵循「肯定式为主、否定式守险」:用「要做成什么样」驱动,用「不要做 X」封堵特别危险的路径。
③ 怎么做(How)
把每条规则写成「行为 + 标准」,必要时附例:
markdown
# 规则写法示例
- 错误处理:捕获异常时必须记录原始错误信息与上下文,
不要只写 catch 后留空。
正例:catch (e) { logger.error("支付失败 orderId=%s", id, e) }
反例:catch (e) {}
- 文件命名:组件文件用 PascalCase,工具文件用 camelCase。- 写完读一遍:「一个不熟悉项目的人能照着做吗?」
- 把「尽量 / 最好 / 适当」换成具体条件或数值;
- 危险路径用否定句点名,同时给出正确做法;
- 规则之间保持单一焦点,一条只讲一件事;
④ 为什么这么做(Why)
- 规则最终也要被「解读」。 AI 和新成员都无法读取你脑中的标准;抽象词(「优雅」「健壮」)在每个人心中含义不同,具体行为 + 可判断标准才能统一执行。
- 可验证标准让规则能被检查。 「测试要全」无法验收,「覆盖正常 / 边界 / 非法三类」可以逐条核对——规则有了标准,遵守与否才说得清。
- 正反例提供最高带宽的说明。 一个边界情形用文字描述可能要几句,正反例一摆,正确与错误形态立刻分明,尤其适合格式与写法类规则。
- 肯定为主保证「知道该做什么」。 只写「别乱改」,模型知道禁区却不知正确路径;补上正确做法,规则才真正可执行。
- 一条一焦点减少误读。 一条规则塞多个要求,可能被部分遵守或互相混淆;拆成单焦点条目,执行和审查都更清晰。
⑤ 这样做的好处
- 执行一致:AI 与团队对规则的理解高度统一。
- 可检查、可验收:每条都有判断标准。
- 学习成本低:新人看正反例即懂,不必反复问。
- 规则真正落地:从口号变成可照做的动作。
- 便于维护:单焦点条目增删改都清晰。
⑥ 不这么做的问题 / 坏处
- 满篇形容词 → 各自解读,规则形同虚设。
- 没有判断标准 → 是否违规只能靠吵,执行随机。
- 只有否定没有做法 → 模型避开一项又犯等价的新问题。
- 一条混多事 → 部分遵守、遗漏,review 困难。
⑦ 举一反三:三个例子
例 1(基础):改写「函数别太长」
📌 场景:你想约束函数长度。
❌ 模糊写法:「函数不要写得太长。」
✅ 改写:「单函数尽量不超过 50 行;超过时优先按职责拆分成更小的函数,并保持函数名能说明其职责。」
🔍 讲解:给出可判断的数值(50 行)和正确出路(按职责拆分),规则既能检查又指明做法,而不是只给一个主观禁区。
例 2(进阶):给提交规则加正反例
📌 场景:规范提交信息格式。
✅ 规则:
markdown
- 提交信息使用 Conventional Commits:<类型>: <描述>。
正例:feat: 新增订单导出功能
正例:fix: 修复登录态过期未跳转
反例:更新代码
反例:修复了一些问题和其它东西🔍 讲解:两个正例示范不同类型,两个反例点名最常见的「无类型、描述空泛」问题。对照示例,AI 生成提交信息时形态稳定,团队 review 也轻松。
例 3(挑战):为微妙的领域规则写清楚
📌 场景:业务规定「退款金额不能超过原订单实付金额,且部分退款累计也受限」。
✅ 规则:
markdown
- 退款约束:单次退款金额必须 > 0,且不得超过该订单「可退余额」
(实付金额减去已成功退款总额);
- 发起退款前必须先读取并校验可退余额,不要信任前端传入的金额;
正例:refundable = paid - sum(成功退款),再校验 0 < amount <= refundable
反例:直接使用请求中的 amount 创建退款🔍 讲解:这类规则涉及计算口径 + 安全校验,最容易在实现中走样。规则同时写清「可退余额如何计算」(标准)、「不信任前端金额」(关键约束)和正反例,把微妙的业务逻辑钉死,防止资金类事故。
⑧ 练习题 ×2
练习 1(巩固型)
📝 题目:把「错误处理要规范」改写成一条具体、可执行、带正反例的规则。
💡 思路提示:规范在你心里具体指什么?记录哪些信息?空 catch 是不是反例?
✅ 参考答案:
markdown
- 错误处理:catch 异常时必须记录错误信息与关键上下文(如订单号、
操作名),并按需向上抛出或返回明确失败,不要吞掉异常。
正例:catch (e) { logger.error("下单失败 orderId=%s", id, e); throw e }
反例:catch (e) {}🔍 讲解:改写把「规范」落成「记录什么、怎么处理、禁止什么」+ 正反例,规则立即可照做、可检查。
练习 2(迁移型)
📝 题目:迁移到制定家庭 / 团队公约:为什么「十点后小声」比「晚上注意点」好?写公约时具体、可验证为什么重要?
💡 思路提示:可执行、可判断、减少争议。
✅ 参考答案(示例):
text
- “晚上注意点”没有标准,几点算晚上、怎样算注意都靠各自理解,
容易产生争议;
- “十点后保持安静:不外放、不大声通话”给出明确触发时间与具体行为,
可执行、可判断,违规与否一说即明。
共性:任何公约 / 规则要真正被遵守,都应具体到行为、附可判断标准,
最好再有示例——这与撰写 AGENTS.md 完全同理。知识点 5:规则冲突、层级合并与长期维护
① 定位
规则一旦多起来,必然遇到两类问题:规则之间打架、规则随时间过期。 本知识点讲如何预防和处理冲突、理解层级间的合并关系,并建立长期维护机制——这是让规则系统「活」得久的最后一块拼图。
② 是什么(What)
两种冲突要分清:
- 同级内容冲突:同一个 AGENTS.md 里两条规则互相矛盾(「一律加缓存」vs「禁止缓存」)。
- 层级之间差异:全局、项目、子目录规则不一致。
处理原则:
- 就近先加载、更具体的规则先出现:子目录细则在进入该目录区域时就近加载、排在项目通用规则之前,但两者是合并共存,而非互相替换;
- 更具体的描述补充更一般的描述:若不是矛盾而是细化,二者叠加理解;
- 真正矛盾必须人工消解:不能靠模型「猜以哪个为准」,应改写文件消除冲突。
维护机制的核心是让规则持续反映现实:定期复审、随变更更新、过期即删。规则文件应有版本历史(随项目入库),改动可追溯。
③ 怎么做(How)
- 起草新规则前先搜索是否已有相关条目,避免重复或冲突;
- 发现矛盾时,显式标注适用范围(如「除
legacy/外」),或合并成一条带例外的规则; - 利用目录级规则承载「局部例外」,而不是在项目根写自相矛盾的条目;
- 设定轻量复审节奏(如每个大版本 / 里程碑),过一遍:失效、重复、矛盾、模糊;
④ 为什么这么做(Why)
- 冲突规则会让产出随机化。 当两条规则指向相反方向,模型选择哪条无法预测,同一场景这次这样、下次那样——比没有规则更糟,因为你以为有规则约束。
- 就近先加载符合规则适用范围的本意。 子目录之所以单列规则,正是为了补充该局部的特殊情况;让具体细则在其范围内就近出现、与根规则合并,分层体系才真正有效。
- 能用「范围标注 / 目录规则」消解的,就不该留下裸矛盾。 显式说明「一般规则 + 例外条件」,模型无需猜测,执行结果稳定。
- 规则与代码一样会腐化。 技术栈升级、模块删除、业务变化都使旧规则失真;不同步更新,规则文件逐渐从资产变成负债。
- 轻量定期维护成本最低。 每次里程碑顺手复审,问题少量易处理;长期不维护则积重难返,最终只能整份推倒。
⑤ 这样做的好处
- 规则系统内部一致,执行结果可预期。
- 分层真正发挥作用:通用与局部各得其所。
- 长期保持准确,规则始终反映当前现实。
- 改动可追溯:版本历史让规则演进透明。
- 维护负担小:嵌入日常变更节奏,不搞大突击。
⑥ 不这么做的问题 / 坏处
- 冲突长期存在 → 产出漂移,出了问题无法归因。
- 层级关系混乱 → 子目录特殊约定被遗漏,或个人偏好意外与团队规则冲突。
- 规则只增不改 → 文件腐化、可信度下降,最终没人参考。
- 变更不联动规则 → 技术栈换了规则还写旧的,AI 持续产出过时方案。
⑦ 举一反三:三个例子
例 1(基础):用例外条款消除矛盾
📌 场景:项目根规则写「组件一律使用函数式写法」,但 legacy/class-*.tsx 仍是类组件,需要维护。
✅ 改写:「新组件一律使用函数组件 + Hooks;维护 legacy/ 下既有类组件时可沿用类写法,不强制改写,除非该组件正在整体重构。」
🔍 讲解:没有矛盾被删除,而是用适用范围 + 例外把两条需求统一起来。模型据此知道在不同位置该遵循哪条,无需猜测。
例 2(进阶):用目录级规则补充局部细则
📌 场景:全局 / 项目根约定「不要直接操作本地文件系统」,但 scripts/ 目录本来就是写文件脚本的。
✅ 做法:在 scripts/AGENTS.md 写明局部规则:「本目录脚本允许使用 Node fs 读写文件,但路径必须基于参数校验,禁止硬编码绝对路径。」
🔍 讲解:局部特殊情况交给就近规则承载,根规则保持简洁。这样既不否定一般安全约定,又把真正需要的细则在进入该区域时合并进来。
例 3(挑战):技术栈迁移后做规则同步
📌 场景:项目从 JavaScript 迁移到 TypeScript、测试从 Jest 切到 Vitest,AGENTS.md 还写着旧约定。
✅ 做法:把「测试用 Jest / 允许 .js」等条目更新为「Vitest / 新代码用 .ts 并补类型」,删除已失效条目,并在同一提交 / PR 中完成,确保规则与代码同时切换。
🔍 讲解:让规则更新伴随技术变更,而不是事后补——这样迁移期间和之后的会话都依据正确现实,避免 AI 一边写 TS、一边引用 Jest 旧规则的混乱。
⑧ 练习题 ×2
练习 1(巩固型)
📝 题目:你发现 AGENTS.md 中「所有接口必须缓存」与「实时数据接口禁止缓存」冲突。请给出至少两种消解方式。
💡 思路提示:范围标注、合并成带例外的规则、或目录级承载。
✅ 参考答案:
text
方式 1:合并为带例外的一条——“默认接口可加缓存;实时数据接口
(如库存、余额)禁止缓存,必须实时读取”;
方式 2:按模块用目录级规则分别约定,普通模块允许缓存,
实时模块目录写禁止缓存;
关键:显式标明适用范围,不让模型在矛盾中自行选择。🔍 讲解:冲突处理的目标是消除解释空间——只要范围清晰、规则一致,用哪种方式都可以。
练习 2(迁移型)
📝 题目:迁移到法律法规 / 公司制度更新:为什么新规出台时要同时明确「与旧规冲突时以谁为准」并清理旧条文?
💡 思路提示:冲突套利、执行混乱、信任成本。
✅ 参考答案(示例):
text
- 若不明确效力优先级,执行者可能在新旧规间挑选对自己有利的一条
(冲突套利),规则失去约束力;
- 旧条文不清理,执行口径混乱,同类事项处理结果不一致,
还增加解释和监督成本;
- 明确“新规优先 / 旧规废止”并更新文本,规则体系保持一致、可信。
共性:任何规则系统(法律、制度、AGENTS.md)在演进时都必须
处理冲突、标明层级关系、同步清理失效内容,才能长期有效。🔍 讲解:规则冲突与维护是治理问题的通用主题。理解这一层,你管理 AGENTS.md 的思路会和管理任何成熟规则体系一致。
本章小结
| 知识点 | 一句话核心 |
|---|---|
| 1. 定位与层级 | 全局 / 项目 / 目录分层加载;V2 只认 AGENTS.md |
| 2. 该写什么 | 长期、反复、易出错的六类规则;第二次重复即固化 |
| 3. 不该写什么 | 任务 / 状态 / 代码 / 秘密 / 口号一律不进文件 |
| 4. 规则写法 | 行为 + 可判断标准 + 正反例,肯定为主、否定守险 |
| 5. 冲突与维护 | 层级合并共存,显式消解矛盾,随变更同步更新 |
下一章进入可复用能力层:《Agents / Commands / Skills》——如何定制专属 Agent、把常用 Prompt 固化成斜杠命令、用 Skill 组织专门知识,让 OpenCode 从「通用助手」进化为「为你量身定制的工作台」。