1. 规则文件写了却像没写一个让人抓狂的下午如果你正在用 CodeBuddy 这类 AI 编程助手并且花了不少时间写了一份自认为很完善的CODEBUDDY.md结果发现它该遵守的规范一条没遵守、该走的流程一步没走那你不是一个人。我第一次遇到这个问题的时候反复检查了三遍文件内容确认路径没错、语法没错、关键词也没拼错但 CodeBuddy 就是像没看见一样该干嘛干嘛。这个问题的本质其实不是 CodeBuddy 坏了而是它的规则加载机制有一套自己的逻辑而大多数人在写规则文件的时候默认它跟普通的配置文件一样——放在那里就会被读取。实际上CODEBUDDY.md和rules目录的加载机制涉及文件位置、frontmatter 元数据、glob 匹配规则、优先级顺序等多个环节任何一个环节出问题规则都会静默失效。更麻烦的是它不会报错不会提示你规则未加载你只能通过行为反推。这篇文章就是把我踩过的坑一个个拆开从加载机制到 frontmatter 写法从 glob 匹配到优先级冲突把整个链路讲清楚。不管你是刚装好 CodeBuddy 的新手还是已经用了一段时间但总觉得规则时灵时不灵的老用户都能从这里找到对应的排查思路和修复方案。2. 先搞清楚 CodeBuddy 到底从哪里读规则2.1 规则文件的三个候选位置CodeBuddy 加载规则文件时并不是只认一个路径。根据我的实测和反复验证它至少会从以下三个位置尝试读取项目根目录下的CODEBUDDY.md这是最常用的位置适合放项目级别的通用规范比如代码风格、提交信息格式、目录结构约定等。项目根目录下的.codebuddy/rules/目录这个目录下可以放多个.md文件每个文件通过 frontmatter 声明自己的适用范围。适合把规则按模块拆分比如前端规则、后端规则、测试规则分开管理。用户主目录下的全局配置这个位置放的是跨项目的个人偏好比如你习惯用哪种命名风格、注释语言用中文还是英文等。很多人规则不生效的第一个原因就是文件放错了位置。比如把规则写在了.codebuddy/rules/下但文件名不是.md结尾或者目录名拼成了.codebuddy/rule/少了个 sCodeBuddy 直接忽略连日志都不打一条。注意目录名和文件名都是大小写敏感的。CODEBUDDY.md全大写没问题但如果你写成CodeBuddy.md或者codebuddy.md在某些系统上可能就读不到。建议统一用全大写。2.2 加载顺序与优先级当多个位置都存在规则文件时CodeBuddy 会按照一定的优先级进行合并。根据我的测试优先级从高到低大致是优先级位置说明1项目根目录CODEBUDDY.md项目级最高优先级覆盖其他所有2.codebuddy/rules/下的规则文件按 frontmatter 中的优先级字段排序3用户全局配置作为兜底默认值这里有一个容易踩的坑如果你在CODEBUDDY.md里写了一条规则又在.codebuddy/rules/里写了一条相反的规则最终生效的是CODEBUDDY.md里的那条。但如果你把CODEBUDDY.md删了.codebuddy/rules/里的规则才会接管。很多人误以为后加载的覆盖先加载的实际上 CodeBuddy 是按优先级合并不是按时间顺序覆盖。2.3 为什么你的规则文件被静默忽略了规则文件被忽略的情况我总结下来主要有这么几种第一种是文件编码问题。如果你在 Windows 上用记事本编辑保存成了 GBK 编码而 CodeBuddy 按 UTF-8 读取中文规则内容就会变成乱码解析失败后整份文件被跳过。这个坑我踩过两次后来统一用 VS Code 保存为 UTF-8 才解决。第二种是frontmatter 格式错误。.codebuddy/rules/下的规则文件需要在文件开头用---包裹一段 YAML 格式的元数据如果---写成了--或者———解析器直接报错跳过。更隐蔽的是 YAML 缩进问题比如glob:下面用了 Tab 而不是空格YAML 解析器会直接抛异常。第三种是文件权限问题。在 Linux 或 macOS 上如果规则文件的权限是000或者属于其他用户CodeBuddy 进程读不到自然也不会加载。这种情况在团队协作时偶尔会遇到比如从别人那里拷贝了一份配置权限没改。3. frontmatter 里的 glob 才是规则生效的开关3.1 frontmatter 的基本结构.codebuddy/rules/下的每个规则文件开头都需要一段 frontmatter。一个标准的写法长这样--- description: 前端组件开发规范 glob: src/components/**/*.tsx priority: 10 ---这三个字段里description是给人看的glob是给 CodeBuddy 看的priority决定多条规则冲突时谁说了算。很多人只写了description就以为完事了结果规则文件被加载了但因为glob为空CodeBuddy 不知道这条规则该应用到哪些文件上于是干脆不应用。3.2 glob 匹配的常见误区glob字段的写法直接决定了规则能不能命中目标文件。我见过最多的错误是把 glob 写成了正则表达式比如glob: .*\\.tsx$这是不对的。glob 有自己的一套语法*匹配任意字符但不跨目录**匹配任意字符可以跨目录?匹配单个字符{a,b}匹配 a 或 b[abc]匹配 a、b、c 中的任意一个举个例子如果你想匹配src下所有层级的.ts文件正确的写法是src/**/*.ts。如果你写成src/*.ts那只匹配src直接子目录下的.ts文件src/utils/foo.ts就匹配不到。还有一个隐蔽的坑glob 的基准路径。CodeBuddy 在匹配 glob 时基准路径是项目根目录不是规则文件所在目录。也就是说如果你的规则文件在.codebuddy/rules/frontend.md里面写glob: *.tsx它匹配的是项目根目录下的.tsx文件而不是.codebuddy/rules/下的。这个设计跟很多人直觉相反我第一次遇到的时候也困惑了很久。3.3 多条规则同时命中时的优先级计算当多个规则文件的 glob 都命中了同一个文件时CodeBuddy 会按priority字段排序数值大的先应用。如果priority相同则按文件名的字典序排列。这里有一个实测出来的细节CODEBUDDY.md里的规则没有priority概念它永远是最先应用的相当于优先级无穷大。我建议在团队协作中给每条规则都显式写上priority并且约定一个范围。比如全局通用规范priority: 1语言级别规范priority: 10框架级别规范priority: 20项目特定规范priority: 30这样当规则冲突时项目特定的规则会覆盖框架级别的框架级别的会覆盖语言级别的逻辑清晰排查也方便。4. 规则不生效的完整排查链路4.1 第一步确认文件是否被加载排查的第一步是确认 CodeBuddy 到底有没有读到你的规则文件。最直接的方法是看日志。CodeBuddy 在启动时会在控制台输出加载了哪些规则文件如果你用的是 VS Code 插件版本可以在输出面板里找到 CodeBuddy 的日志通道。如果日志里没有出现你的规则文件名那说明文件根本没被扫描到。这时候要检查文件路径是否正确大小写、目录名拼写文件扩展名是否是.md文件编码是否是 UTF-8文件权限是否可读如果日志里出现了文件名但后面跟着一个 warning 或者 error那说明文件被扫描到了但解析失败。这时候要检查 frontmatter 的 YAML 语法特别是缩进和特殊字符转义。4.2 第二步确认 glob 是否命中文件加载成功之后下一步是确认 glob 有没有命中你正在编辑的文件。这个环节最容易出问题因为 glob 不匹配是静默的不会有任何提示。我的做法是临时把 glob 改成**/*看看规则是否生效。如果生效了说明规则内容本身没问题问题出在 glob 的写法上。然后逐步缩小 glob 的范围直到找到那个不匹配的边界。还有一个技巧在规则文件里写一条明显的规则比如所有函数必须加// RULE_TEST注释然后让 CodeBuddy 生成一个函数看它有没有加这个注释。这样比看日志更直观。4.3 第三步确认规则内容是否被正确解析有时候 glob 命中了文件也加载了但规则内容没有被正确解析。这种情况通常是因为规则内容里包含了 CodeBuddy 无法理解的语法或者规则之间互相矛盾导致模型不知道该听谁的。我遇到过一次规则里写了所有变量必须用const声明同时又写了需要重新赋值的变量用let声明。这两条规则本身不矛盾但 CodeBuddy 在解析时把它们当成了互斥条件结果两条都没执行。后来我把它们合并成一条默认用const需要重新赋值时用let问题就解决了。4.4 第四步确认优先级是否被覆盖如果以上三步都没问题但规则还是不生效那就要检查优先级了。可能你写的规则被另一条更高优先级的规则覆盖了。排查方法是把所有规则文件的priority列出来看看有没有冲突。特别是当项目里同时存在CODEBUDDY.md和.codebuddy/rules/下的规则时CODEBUDDY.md里的规则会无条件覆盖其他所有规则。如果你在CODEBUDDY.md里写了一条跟.codebuddy/rules/里相反的规则那后者永远不会生效。5. 让规则稳定生效的实操配置方案5.1 推荐的目录结构经过多次调整我现在用的目录结构是这样的project-root/ ├── CODEBUDDY.md # 项目级通用规范只放最核心的几条 ├── .codebuddy/ │ └── rules/ │ ├── 00-global.md # 全局规范priority: 1 │ ├── 10-typescript.md # TS 语言规范priority: 10 │ ├── 20-react.md # React 框架规范priority: 20 │ └── 30-project.md # 项目特定规范priority: 30 └── src/ └── ...文件名前面的数字是为了让字典序排列时有个稳定的顺序虽然priority字段已经能控制优先级但文件名有序在排查时更直观。5.2 每个规则文件的模板每个规则文件我都用同一个模板开头--- description: 一句话说明这条规则管什么 glob: src/**/*.{ts,tsx} priority: 10 --- # 规则标题 ## 必须遵守 - 规则一 - 规则二 ## 禁止事项 - 禁止一 - 禁止二description写清楚方便日后维护时快速定位。glob尽量精确不要用**/*这种全匹配否则规则会应用到不该应用的文件上反而造成干扰。5.3 CODEBUDDY.md 里该放什么CODEBUDDY.md的优先级最高所以它应该只放那些无论如何都不能违反的规则。比如提交信息必须遵循 Conventional Commits 格式不允许在代码里硬编码密钥所有公开 API 必须有 JSDoc 注释这些规则数量不宜多控制在 5 到 10 条以内。放太多了一方面维护困难另一方面会跟.codebuddy/rules/下的规则产生大量冲突排查起来很痛苦。5.4 验证规则是否生效的自动化方法手动验证太累我写了一个简单的脚本每次修改规则后跑一遍#!/bin/bash # check-rules.sh echo 检查规则文件编码 find .codebuddy/rules -name *.md -exec file {} \; echo 检查 frontmatter 格式 for f in .codebuddy/rules/*.md; do head -1 $f | grep -q ^---$ || echo 警告: $f 缺少 frontmatter 起始标记 done echo 检查 glob 是否为空 for f in .codebuddy/rules/*.md; do grep -q ^glob: $f || echo 警告: $f 缺少 glob 字段 done这个脚本能覆盖 80% 的常见问题剩下的 20% 需要实际跑 CodeBuddy 来验证。6. 几个让我印象深刻的真实踩坑案例6.1 案例一glob 里的反斜杠有一次我在 Windows 上写规则glob 写成了src\\components\\**\\*.tsx因为 Windows 的路径习惯用反斜杠。结果规则完全不生效。后来改成src/components/**/*.tsx才正常。glob 语法里统一用正斜杠不管什么操作系统。6.2 案例二frontmatter 里的中文冒号还有一次我在description里写了中文其中包含了一个中文冒号。YAML 解析器把这个中文冒号当成了键值分隔符导致整个 frontmatter 解析失败。后来我把中文冒号改成了英文冒号或者用引号把整个字符串包起来问题就解决了。6.3 案例三规则文件之间的循环引用最隐蔽的一次是我在10-typescript.md里写了参考20-react.md的组件规范又在20-react.md里写了参考10-typescript.md的类型规范。CodeBuddy 在解析时陷入了循环引用最后两条规则都没加载。这个坑花了我一个下午才找到因为日志里只显示了一个模糊的 circular reference 警告没有指出具体是哪个文件。6.4 案例四规则内容太长导致截断CodeBuddy 对单个规则文件的内容长度是有限制的。我有一份规则文件写了将近 5000 字结果只有前 2000 字左右生效了后面的内容被静默截断。后来我把这份文件拆成了三个每个控制在 1500 字以内问题就解决了。具体限制是多少官方没有明确说明但根据我的测试单个文件控制在 2000 字以内是比较安全的。7. 规则写得好不好直接决定 CodeBuddy 好不好用7.1 规则要具体不要抽象代码要写得优雅这种规则等于没写。CodeBuddy 不知道什么叫优雅。你应该写函数长度不超过 50 行、嵌套层级不超过 3 层、变量名用驼峰命名法。具体的规则才能被模型理解和执行。7.2 规则要可验证每条规则最好都能通过某种方式验证。比如所有导出函数必须有 JSDoc 注释这个可以通过 lint 工具验证。代码要有良好的可读性这个就没法验证。可验证的规则才能形成闭环否则你永远不知道它有没有被执行。7.3 规则数量要克制我见过有人写了 200 多条规则结果 CodeBuddy 的表现反而变差了。因为规则太多模型在生成代码时要同时满足所有约束很容易顾此失彼。我的经验是单个项目的规则总数控制在 30 条以内每条规则都经过实际验证确实有效。7.4 定期清理失效规则项目在演进规则也需要定期清理。我每个月会花半个小时过一遍所有规则文件把那些已经不适用的、跟当前代码风格冲突的、或者从来没被触发过的规则删掉。规则文件越精简CodeBuddy 的表现越稳定。8. 关于规则加载机制的几个常见误解8.1 误解一规则文件越多越好不是。规则文件多了之后加载顺序、优先级冲突、glob 重叠的问题会呈指数级增长。我建议一个项目最多 5 个规则文件每个文件管一个明确的领域。8.2 误解二规则写了就会生效规则写了只是第一步还要经过加载、解析、glob 匹配、优先级排序四个环节任何一个环节出问题都会导致规则不生效。而且这些环节都是静默的不会主动告诉你哪里出了问题。8.3 误解三CODEBUDDY.md 和 rules 目录是等价的不等价。CODEBUDDY.md的优先级最高且不支持 frontmatter 和 glob它的规则会应用到所有文件。.codebuddy/rules/下的规则支持精细化的 glob 匹配和优先级控制。两者定位不同不能互相替代。8.4 误解四规则不生效是 CodeBuddy 的 bug大多数情况下不是。规则不生效都是配置问题要么是文件位置不对要么是 frontmatter 格式错误要么是 glob 没匹配上。CodeBuddy 的规则加载机制本身是稳定的只是它的静默失败设计让排查变得困难。9. 一套可以直接抄的规则配置如果你不想从头折腾可以直接用我下面这套配置作为起点。这套配置在我自己的项目里跑了三个月稳定性没问题。CODEBUDDY.md# 项目核心规范 ## 提交信息 - 遵循 Conventional Commits 格式 - 类型包括 feat、fix、docs、style、refactor、test、chore ## 安全 - 禁止硬编码任何密钥、token、密码 - 敏感配置必须通过环境变量注入 ## 注释 - 所有导出函数必须有 JSDoc 注释 - 复杂逻辑必须有行内注释说明意图.codebuddy/rules/10-typescript.md--- description: TypeScript 语言级别规范 glob: src/**/*.{ts,tsx} priority: 10 --- # TypeScript 规范 ## 类型 - 禁止使用 any必要时用 unknown 加类型守卫 - 接口名以 I 开头类型别名以 T 开头 ## 变量 - 默认用 const需要重新赋值时用 let - 禁止使用 var.codebuddy/rules/20-react.md--- description: React 组件开发规范 glob: src/components/**/*.tsx priority: 20 --- # React 规范 ## 组件 - 函数组件优先禁止使用 class 组件 - 组件名用 PascalCase ## Hooks - 自定义 Hook 以 use 开头 - 禁止在条件语句中调用 Hook这套配置的核心思路是CODEBUDDY.md放最核心的、跨领域的规则.codebuddy/rules/按语言和框架分层每层用 glob 精确控制适用范围用 priority 控制冲突时的优先级。10. 最后分享几个排查时的小技巧第一个技巧如果你不确定规则有没有生效可以在规则里加一条所有新生成的函数必须包含// CB_RULE_ACTIVE注释然后让 CodeBuddy 生成一个函数。如果注释出现了说明规则生效了如果没有说明规则没加载或者没匹配上。这个方法比看日志快得多。第二个技巧修改规则文件后CodeBuddy 不一定会立即重新加载。有些版本需要重启编辑器有些版本需要手动触发一次重新加载。如果你改了规则但没生效先试试重启。第三个技巧如果你在团队里推广 CodeBuddy建议把规则文件纳入版本控制并且在 README 里写清楚每个规则文件的作用和优先级。这样新成员加入时不用重新踩一遍坑。第四个技巧规则文件里的description字段不要偷懒写清楚这条规则管什么、为什么要有这条规则。三个月后你自己回来看没有 description 的规则文件你根本不知道当初为什么这么写。规则加载这件事说复杂也复杂说简单也简单。核心就是搞清楚文件放哪里、frontmatter 怎么写、glob 怎么匹配、优先级怎么排。把这四点搞定了CodeBuddy 的规则系统就能稳定为你所用。我在实际使用中最大的体会是规则不在多在于精在于每一条都经过验证确实生效。与其写 100 条不知道有没有用的规则不如写 10 条每条都稳定执行的规则。