尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CodeBuddy规则不生效?搞懂CODEBUDDY.md与rules加载机制

CodeBuddy规则不生效?搞懂CODEBUDDY.md与rules加载机制 1. 规则文件写了却没反应问题到底出在哪刚上手 CodeBuddy 那阵子我踩过一个特别典型的坑花了大半个下午精心写了一份CODEBUDDY.md把项目的编码规范、目录约定、命名风格、提交信息格式全塞了进去结果在对话里让它帮我改一个函数它给出的代码跟我的规范八竿子打不着。我当时第一反应是这工具是不是不支持自定义规则差点就放弃了。后来翻了不少资料、做了几轮对照实验才发现问题根本不在工具本身而在于我没搞懂它的规则加载机制——文件放错位置、frontmatter 写错、glob 匹配不上任何一个环节出问题规则都会静默失效连个报错都不给你。这篇就把我踩过的坑和后来摸清楚的加载逻辑完整梳理一遍。核心围绕三样东西CODEBUDDY.md这个规则载体、rules这套校验规则体系、以及frontmatter和glob这两个决定规则生不生效的关键字段。如果你正在用 CodeBuddy或者从别的 AI 编程工具比如 Cursor、Trae 这类同样支持 rules 的工具迁移过来发现规则时灵时不灵那这篇基本能帮你把问题定位到具体某一层。我会从整体设计思路讲到具体实操再到常见故障排查尽量让刚接触的人也能照着复现。先说结论性的判断规则不生效九成以上是加载路径和匹配条件的问题而不是规则内容本身写得不好。很多人一上来就怀疑自己规则写得不够详细其实方向反了。工具读不到你的规则你写一万字也是白搭。所以下面我会把它到底从哪里读、按什么顺序读、什么条件下才应用这三件事讲透。2. 规则加载机制的整体设计与思路拆解2.1 为什么要有 CODEBUDDY.md 和 rules 两套东西很多人第一次接触会困惑既然有了CODEBUDDY.md为什么还要单独搞一套rules目录这俩不是重复了吗其实它们解决的是两个不同层次的问题理解这一点是后面所有操作的基础。CODEBUDDY.md更像是项目级的全局说明书。它通常放在项目根目录作用范围是整个仓库内容偏向这个项目是什么、用什么技术栈、有哪些通用约定。你可以把它理解成给 AI 看的一份 README只不过这份 README 是专门用来约束 AI 行为的。它的特点是全局生效、内容宽泛、加载优先级相对靠后。而rules目录下的规则文件是细粒度的、可条件触发的。它允许你针对特定文件类型、特定目录、特定场景写专门的规则。比如所有.tsx文件必须用函数式组件、api/目录下的请求必须走统一封装、测试文件里禁止使用only。这些规则如果全塞进CODEBUDDY.md文件会变得又臭又长而且没法做到只在编辑某类文件时才提醒 AI。所以设计上的分工很清晰全局通用的放CODEBUDDY.md场景化、条件化的放rules。我后来养成的习惯是CODEBUDDY.md只保留不超过一屏的核心约定剩下的全部拆到rules里按主题管理。这样维护起来清爽出问题也容易定位——某类文件规则失效我直接去看对应的那个 rule 文件就行不用在几千字的 md 里大海捞针。2.2 加载顺序与优先级谁覆盖谁这是最容易踩坑的地方。规则不是全都读进来然后合并这么简单它是有优先级和覆盖关系的。根据我的实测和多方资料对照大致的加载逻辑是这样的层级来源作用范围优先级1用户级全局规则所有项目最低2项目根CODEBUDDY.md当前项目中3rules目录下的规则文件按 glob 匹配高4对话中临时指定的规则当前会话最高这个顺序背后的逻辑其实很符合直觉越具体、越靠近当前操作的规则优先级越高。用户级全局规则是你个人的通用偏好项目级规则是这个项目的特殊要求而rules里的规则是针对具体文件的精确约束临时对话指令则是你当下的即时意图。当它们冲突时更精确的那一层说了算。我踩的第一个大坑就在这里。当时我在用户级全局配置里写了一条优先使用箭头函数又在项目CODEBUDDY.md里写了本项目统一使用function声明结果 AI 一会儿用箭头一会儿用 function我还以为是它记性不好。实际上是我自己制造了规则冲突而我没搞清楚覆盖关系导致行为看起来飘忽不定。规则冲突不会报错只会表现为时灵时不灵这是最坑的地方。提示写规则前先想清楚这条规则应该放在哪一层。个人偏好放用户级项目约定放项目级文件类型相关的放 rules。不要在多处重复定义同一条规则否则覆盖行为会让你怀疑人生。2.3 frontmatter 和 glob决定规则生不生效的开关如果说加载路径决定规则能不能被读到那frontmatter和glob就决定规则读到了之后会不会被应用。这两个是 rules 文件里最关键的元数据也是最容易写错的地方。frontmatter是文件顶部用---包裹的那段元信息通常包含规则的描述、触发条件、适用范围等。glob则是用来匹配文件路径的模式串决定这条规则对哪些文件生效。举个我实际在用的例子--- description: React 组件编码规范 globs: - src/components/**/*.tsx - src/components/**/*.jsx alwaysApply: false --- - 组件必须使用函数式写法禁止 class 组件 - Props 必须显式定义类型 - 每个组件文件只导出一个组件这里globs就是核心。它用的是标准的 glob 匹配语法**表示任意层级目录*表示任意文件名。如果我把globs写成src/component/*.tsx少了个 s或者少了个**那src/components/button/index.tsx这种嵌套路径就匹配不上规则自然不生效。我遇到过的规则写了不生效至少一半是 glob 写错导致的。alwaysApply这个字段也值得单独说。它控制规则是始终应用还是仅在匹配到 glob 时应用。如果你希望某条规则无条件生效就设成true这时候globs可以留空。但如果你既设了alwaysApply: true又写了globs不同工具的处理方式可能不一样有的会忽略 globs有的会取并集。为了行为可预测我的建议是二选一不要同时用。3. 核心细节解析与实操要点3.1 目录结构文件到底该放哪规则不生效第一个要排查的就是文件放对地方了吗。CodeBuddy 读取规则是有固定路径约定的放错位置它根本不会去看。常见的正确位置有这么几个项目根目录的CODEBUDDY.md全局项目规则项目根目录下的.codebuddy/rules/目录存放各个 rule 文件用户主目录下的全局配置目录存放跨项目的个人规则我一开始把规则文件随手放在了docs/目录下心想反正都是 md 文件它应该能扫到吧。结果当然是不生效。工具不会递归扫描整个项目去找规则文件它只认约定好的那几个路径。这一点跟很多人的直觉相反但恰恰是最需要记住的。.codebuddy/rules/这个目录名也要注意大小写和拼写。我见过有人写成.codeBuddy、.code-buddy、codebuddy/rules少了前面的点全都不行。目录名是硬编码匹配的差一个字符都读不到。建议直接从文档复制目录名别手打。3.2 frontmatter 字段逐个拆解frontmatter 里每个字段都有明确用途写错了轻则规则不生效重则整个文件被跳过。我把常用的几个字段整理成表方便对照字段作用常见错误description规则描述帮助识别写成中文导致某些解析器乱码globs匹配生效的文件路径路径写错、漏写**、用了反斜杠alwaysApply是否无条件应用与 globs 同时设置导致行为不确定priority规则优先级数值写反以为越大越优先关于globs的写法有几个细节必须强调。第一路径分隔符统一用正斜杠/即使在 Windows 上也是。我有个同事在 Windows 上写规则习惯性用了反斜杠src\components\*.tsx结果一条都没匹配上排查了半天。第二**和*的区别要分清*只匹配当前层级的文件名不跨目录**才匹配任意层级。第三多个 glob 用列表形式写不要用逗号拼在一行不同解析器对逗号分隔的支持不一致。# 推荐写法列表形式清晰且兼容性好 globs: - src/**/*.ts - src/**/*.tsx # 不推荐逗号分隔兼容性存疑 globs: src/**/*.ts, src/**/*.tsx3.3 规则内容的写法怎么让 AI 真的照做文件放对了、frontmatter 写对了接下来才是规则内容本身。这里也有讲究。我早期写的规则特别客气比如建议尽量使用 TypeScript 的严格模式结果 AI 经常忽略。后来我改成祈使句、明确指令效果明显好转。核心原则是规则要写成明确的、可判定的指令而不是模糊的建议。尽量、建议、最好这类词会让 AI 觉得这是可选项。改成必须、禁止、统一使用这种强约束词执行率会高很多。另外规则条目要具体到可操作比如不要写注意代码质量而要写函数参数超过 3 个时必须使用对象参数。还有一点规则之间不要自相矛盾。我见过一个项目的规则里同时写着禁止使用 any和复杂类型可以先用 any 占位AI 遇到这种情况就会随机选一条执行表现出来就是规则时灵时不灵。写规则前通读一遍确保没有互相打架的条目。4. 实操过程与核心环节实现4.1 从零搭一套能生效的规则体系下面这套流程是我现在每个新项目都会走一遍的照着做基本不会踩加载的坑。第一步在项目根目录创建CODEBUDDY.md只写最核心的全局约定控制在 30 行以内# 项目约定 - 技术栈React 18 TypeScript Vite - 包管理器pnpm禁止使用 npm 或 yarn - 提交信息遵循 Conventional Commits - 所有新增代码必须通过 ESLint 检查第二步创建.codebuddy/rules/目录按主题拆分规则文件。比如react-components.md、api-layer.md、testing.md。每个文件顶部写清楚 frontmatter--- description: API 层请求规范 globs: - src/api/**/*.ts alwaysApply: false --- - 所有请求必须通过 src/api/client.ts 导出的实例发起 - 禁止在组件内直接使用 fetch 或 axios - 请求函数必须显式声明返回类型 - 错误必须统一走 handleApiError 处理第三步验证规则是否真的被加载。这一步很多人跳过结果出了问题不知道从哪查。我的做法是故意写一条容易触发的规则然后让 AI 做一件违反它的事看它会不会纠正。比如规则里写禁止使用 var然后让 AI 写一段用 var 的代码如果它主动改成 let/const说明规则生效了如果它照写 var说明规则没被读到。4.2 glob 匹配的实测与调试glob 写对与否光看是看不出来的得实测。我常用的调试方法是用一条必然触发的规则来验证匹配范围。比如我想确认src/components/**/*.tsx到底匹配哪些文件就先写一条规则在此文件顶部添加注释// RULE-ACTIVE然后让 AI 编辑不同层级的组件文件看哪些文件被加了注释。实测下来几个容易出错的 glob 场景你想要的正确写法错误写法后果所有 ts 文件**/*.ts*.ts只匹配根目录components 下所有层级src/components/**/*.tsxsrc/components/*.tsx漏掉子目录排除测试文件需配合 ignore 字段在 globs 里写!多数工具不支持关于排除这里要单独提醒很多工具的 globs 字段不支持!取反语法。我一开始想当然地写了!**/*.test.ts结果整条规则直接失效。正确做法是用单独的 ignore 字段或者干脆把规则写成只匹配非测试文件的正向模式。这个坑我踩得挺深因为!在命令行 glob 里是支持的很容易迁移过来。4.3 规则生效的完整验证流程把上面几步串起来一个完整的验证流程是这样的确认文件路径正确根目录CODEBUDDY.md.codebuddy/rules/确认 frontmatter 语法正确---成对、YAML 缩进正确确认 globs 能匹配到目标文件用必然触发规则实测确认规则内容无冲突、无模糊表述在对话中触发一次观察 AI 是否遵守这五步里第 3 步是最容易被跳过、也最容易出问题的。我建议把它固化成习惯每加一条带 globs 的规则都先验证匹配范围再写具体内容。顺序反了的话你会花大量时间怀疑规则内容其实是 glob 根本没匹配上。5. 常见问题与排查技巧实录5.1 规则完全不生效的排查清单遇到规则一点反应都没有按这个顺序查基本能定位排查项检查方法典型问题文件位置确认在约定目录放错到 docs/ 等目录文件名确认拼写和大小写.codeBuddy大小写错frontmatter确认---成对只写了开头没写结尾YAML 语法用 YAML 校验器过一遍缩进用了 Tabglobs用必然触发规则实测路径写错、漏**规则冲突通读所有规则多条规则互相矛盾我印象最深的一次是 frontmatter 的---只写了开头。文件长这样--- description: 某规则 globs: - src/**/*.ts - 规则内容...结尾的---漏了导致整个 frontmatter 解析失败规则文件被静默跳过。这种错误不会报错只会表现为规则不生效特别隐蔽。后来我养成了习惯写完 frontmatter 先数一下---是不是两个。5.2 规则时灵时不灵的真相比完全不生效更让人抓狂的是时灵时不灵。这种情况几乎都是规则冲突或 glob 部分匹配导致的。规则冲突的典型场景用户级规则和项目级规则打架。比如用户级写了使用单引号项目级写了使用双引号AI 在不同文件里表现不一致看起来就像随机行为。解决办法是统一规则来源把冲突的规则合并到最高优先级那一层删掉低优先级的重复定义。glob 部分匹配的场景规则只对部分文件生效。比如globs写的是src/**/*.ts但你的项目里有些文件是.tsx那这些文件就不受规则约束。表现出来就是改 .ts 文件时规则生效改 .tsx 时失效。排查方法是列出所有目标文件类型逐一确认 glob 覆盖到了。5.3 几个我踩过的独家坑第一个坑规则文件里写了 Markdown 标题被误解析成 frontmatter 的一部分。我在规则内容里用了# 标题结果某些解析器把它当成了 YAML 的注释或结构导致规则内容错乱。后来我改成用列表和加粗不再在规则文件里用#标题。第二个坑中文标点导致 YAML 解析异常。frontmatter 里的description如果用了中文全角冒号或引号某些解析器会报错。我的做法是description尽量用英文或者用引号把中文内容包起来。第三个坑规则写太多AI记不住。我一度在一个 rule 文件里塞了 50 多条规则结果 AI 只遵守了前几条。后来我拆成多个小文件每个文件不超过 10 条执行率明显提升。规则不是越多越好聚焦才有效。第四个坑改了规则文件但没重新加载。有些工具会缓存规则改完文件需要重启会话或触发重新加载才生效。我改完规则直接测试发现没变化以为写错了其实是缓存。改完规则先重新加载再验证。5.4 跨工具迁移时的注意事项从 Cursor、Trae 这类同样支持 rules 的工具迁移过来时有几个地方不能直接照搬。虽然大家的概念相似都有 rules、都有 frontmatter、都用 glob但字段名和目录约定往往不一样。比如有的工具用.cursor/rules/有的用.trae/rules/CodeBuddy 用的是.codebuddy/rules/。直接复制目录结构肯定不行。我的做法是迁移时只搬规则内容frontmatter 重新写。把原工具的规则正文提取出来在新工具里按新工具的 frontmatter 规范重新组织。这样虽然麻烦一点但能避免看起来迁移了实际没生效的问题。另外不同工具对 glob 语法的支持程度也有差异迁移后一定要重新验证匹配范围。6. 把规则体系维护成长期资产规则体系搭起来只是开始真正体现价值的是长期维护。我现在的做法是把规则当成代码一样管理每次发现 AI 犯了某类错误就补一条规则每次规则失效就排查是加载问题还是内容问题。时间长了这套规则就成了项目的隐性知识库新人接手时看规则文件就能快速理解项目约定。有一点体会特别深规则的价值不在于写得多全而在于每一条都真的生效。我见过太多项目规则文件写得洋洋洒洒实际生效的没几条反而给人这工具不好用的错觉。与其追求大而全不如先把三五条最关键的规则调通、验证生效再逐步扩展。这个思路跟我一开始踩坑时的心态正好相反——那时候我总想一次把所有规范都写进去结果一条都没生效白白浪费了一个下午。最后分享一个我常用的小技巧给每条规则加一个验证用例。比如规则是禁止使用 any我就在心里记一个触发场景让 AI 写一个带 any 的函数。每次改完规则用这个用例快速验证一遍。这样规则库越大验证成本也不会失控。规则这东西写是次要的能稳定生效才是关键。
返回列表