1. 规则文件写了却没反应,问题到底出在哪
刚上手 CodeBuddy 那阵子,我踩过一个特别典型的坑:花了大半个下午,认认真真在项目根目录写了一份CODEBUDDY.md,把团队的编码规范、命名约定、目录结构、提交信息格式全都塞了进去,自认为写得滴水不漏。结果打开对话窗口让它帮我改一段代码,生成的东西跟没写规则时一模一样——该用驼峰的地方还是下划线,该加注释的地方还是光秃秃一片。那一刻我甚至怀疑是不是软件没装对。
后来折腾了小半天,翻文档、看日志、反复试,才把这件事彻底搞明白:规则文件不生效,九成不是工具坏了,而是你没搞清楚它到底从哪里读规则、按什么顺序读、什么条件下才会把规则塞进上下文。这跟 Cursor 里加 rules、Trae 里配编码规范是同一类问题,很多人第一次用都会栽在这里。
这篇就把 CodeBuddy 的规则加载机制从头到尾拆一遍,重点讲清楚CODEBUDDY.md和rules目录这两套东西各自的定位、加载优先级、frontmatter里glob字段怎么用、以及那些文档里不会明说但实际会坑死人的细节。不管你是刚装完 CodeBuddy 想跑通第一个项目的新手,还是已经在用但总觉得规则"时灵时不灵"的老用户,看完应该都能对号入座。顺带也会聊聊 CodeBuddy 和 WorkBuddy、Trae 这些工具在规则体系上的差异,避免你把 A 工具的写法直接搬到 B 工具上。
先说结论,方便你带着答案读:CODEBUDDY.md是全局性的、始终注入的项目说明文件,而rules目录下的规则是带条件的、按需触发的,两者加载时机和生效范围完全不同。你写的东西不生效,大概率是放错了地方,或者glob匹配没写对,或者文件根本没被识别到。下面一层层拆。
2. 先搞懂 CodeBuddy 的规则体系是怎么设计的
2.1 两套规则机制:全局说明 vs 条件规则
CodeBuddy 的规则体系其实分成两条线,很多人混为一谈,这是第一个大坑。
第一条线是CODEBUDDY.md。这是一个放在项目根目录(或者用户级配置目录)的 Markdown 文件,作用是给 AI 提供项目级的背景说明。你可以把它理解成"给新同事看的上手指南"——项目是干什么的、用什么技术栈、目录怎么组织、有哪些约定俗成的规矩。它的特点是无条件加载:只要你在项目里发起对话,这份文件的内容就会被读进去,作为系统提示的一部分。
第二条线是rules目录。这个目录下可以放多个规则文件,每个文件通过frontmatter(就是文件开头用---包起来的那段元数据)来声明自己的触发条件。比如"只对src/**/*.ts生效"、"只在编辑测试文件时生效"。它的特点是条件加载:只有当你的操作命中了规则声明的条件,这条规则才会被注入上下文。
为什么这么设计?因为上下文窗口是有限的。如果把所有规则无脑全塞进去,一是浪费 token,二是规则之间会互相干扰——你给 React 组件定的规矩,硬套到 Python 脚本上就是灾难。所以 CodeBuddy 用"全局说明 + 条件规则"的组合,既保证基础背景始终在线,又让细粒度的规范按需出现。
2.2 为什么你的规则"看起来写了但没生效"
理解了上面这套设计,很多"不生效"的现象就能解释了。我整理了几种最常见的情况:
- 把条件规则写进了
CODEBUDDY.md:CODEBUDDY.md里不支持frontmatter条件语法,你写了glob也不会被解析,它只会当成普通文本读进去,自然起不到"只对某类文件生效"的作用。 - 把全局说明写进了
rules目录:rules下的文件如果没有正确的frontmatter,或者glob匹配不到你正在编辑的文件,那这条规则就永远不会被触发。 - 文件位置放错:
CODEBUDDY.md必须在项目根目录,rules目录也有固定的位置要求,放错层级等于没写。 glob写得太窄或太宽:写窄了匹配不到,写宽了又可能被其他规则覆盖。- 文件名或扩展名不对:
rules目录下的文件通常要求是.md,且frontmatter格式必须严格,多一个空格都可能解析失败。
我当时的错误就是第一种:把所有东西一股脑写进CODEBUDDY.md,还天真地以为在里面写个"以下规则仅适用于 TypeScript 文件"就能生效。实际上 AI 读到这句话,只会把它当成一句普通描述,根本不会做条件判断。
2.3 和 Cursor、Trae 的规则机制对比
既然热搜里一堆人在问"cursor 怎么加 rules"、"traecode 编码规范 rules",这里顺带对比一下,免得你跨工具套用踩坑。
| 工具 | 全局说明文件 | 条件规则机制 | 触发方式 |
|---|---|---|---|
| CodeBuddy | CODEBUDDY.md | rules目录 + frontmatter | glob 匹配 + 手动引用 |
| Cursor | .cursorrules/ 项目规则 | .cursor/rules目录 | glob + 描述匹配 |
| Trae | 项目规则文件 | rules 配置 | 规则描述 + 文件匹配 |
可以看到,主流工具的思路是一致的:一个全局的、一个条件的。但具体文件名、目录结构、frontmatter 字段名各有差异。你在 Cursor 里写惯了.cursorrules,直接复制到 CodeBuddy 里改成CODEBUDDY.md,如果里面带了 Cursor 特有的语法,是不会被识别的。这一点后面还会细说。
3. CODEBUDDY.md 的正确写法与加载时机
3.1 它到底该放哪、什么时候被读
CODEBUDDY.md的位置有两个层级,理解这个层级很关键:
- 项目级:放在项目根目录,只对当前项目生效。这是最常用的。
- 用户级:放在用户配置目录下,对你所有项目生效。适合放一些个人偏好,比如"注释用中文"、"回答尽量简洁"。
加载时机上,它是在对话初始化阶段就被读取的,也就是说,只要你在这个项目里发起任何一次对话,它的内容就已经在上下文里了。这跟rules的"按需注入"完全不同。所以如果你发现某条规则"有时候生效有时候不生效",那它多半不该放在CODEBUDDY.md里,而应该做成条件规则。
提示:
CODEBUDDY.md的内容会占用上下文窗口。如果你的项目说明写得特别长(比如超过几千字),会挤占实际对话的可用空间。建议控制在合理长度,把细节性的、条件性的规范挪到rules目录。
3.2 一份能真正生效的 CODEBUDDY.md 长什么样
空谈没用,直接给一份我实际在用的模板。假设是一个 TypeScript + React 的前端项目:
# 项目说明 这是一个基于 React 18 + TypeScript 的后台管理系统,使用 Vite 构建,状态管理用 Zustand,请求库用 Axios。 ## 技术栈 - 框架:React 18 + TypeScript 5 - 构建:Vite 5 - 状态:Zustand - 样式:Tailwind CSS - 请求:Axios + 自封装 request ## 目录结构 - src/components:通用组件 - src/pages:页面级组件 - src/hooks:自定义 hooks - src/utils:工具函数 - src/api:接口定义 ## 通用约定 - 组件文件用 PascalCase,工具函数用 camelCase - 所有导出函数必须写 JSDoc 注释 - 禁止使用 any,必要时用 unknown 加类型收窄 - 提交信息遵循 Conventional Commits这份文件的特点是:只写"始终成立"的东西。技术栈、目录结构、通用命名约定,这些不管你编辑哪个文件都成立,所以放这里合适。而那些"只对某类文件成立"的规矩,比如"React 组件必须用函数式写法"、"测试文件必须用 describe/it 结构",就该挪到rules目录里去。
3.3 常见写法误区
我见过太多人在这份文件里犯这几类错误:
- 写成任务清单:比如"帮我重构登录页"、"修复首页 bug"。
CODEBUDDY.md是背景说明,不是待办列表,写这些没用。 - 塞入大量代码片段:有人喜欢把整个组件的范例代码贴进去,指望 AI 照抄。这既占上下文,又容易让 AI 过度拟合某一种写法。范例可以放,但要精简。
- 用 Cursor 的语法:比如 Cursor 里有些特殊的引用语法,搬到 CodeBuddy 里不认。
- 写得太抽象:"代码要优雅"、"保持良好风格"——这种话 AI 读了等于没读,必须具体到可执行的规则。
一句话总结:CODEBUDDY.md要写具体的、全局的、可执行的背景信息,别写条件规则,别写空话。
4. rules 目录与 frontmatter 加载机制深挖
4.1 rules 目录的结构与文件识别
rules目录是条件规则的主战场。它的典型结构是这样的:
项目根目录/ ├── CODEBUDDY.md └── .codebuddy/ └── rules/ ├── react-component.md ├── typescript-style.md └── test-convention.md注意几个关键点:
rules目录通常藏在.codebuddy/这样的隐藏目录下,具体路径以你所用版本为准,但位置固定,不能随便挪。- 每个规则文件是独立的
.md文件,一个文件一条(或一组)规则。 - 文件名本身不影响触发,触发完全靠文件内的
frontmatter。
这里有个特别容易踩的坑:很多人把规则文件直接丢在项目根目录,或者丢在rules的上一级,然后疑惑为什么没生效。目录层级错了,工具根本扫不到。
4.2 frontmatter 字段逐个拆解
frontmatter是规则文件的灵魂,它决定了这条规则什么时候被激活。格式是文件开头用三个短横线包起来的一段 YAML:
--- description: React 组件编码规范 glob: "src/components/**/*.tsx" alwaysApply: false --- # React 组件规范 - 一律使用函数式组件 - Props 必须定义 interface - 事件处理函数以 handle 开头逐个字段说:
description:规则的描述。有些版本会用它做语义匹配,也就是 AI 根据你的操作意图去判断要不要加载这条规则。写清楚、写具体,别写"一些规范"这种废话。glob:文件匹配模式,决定这条规则对哪些文件生效。这是最容易写错的地方,下面单独讲。alwaysApply:布尔值。设为true时,这条规则无视glob,始终加载。适合那种"全项目都要遵守"的规则,但既然全项目都要遵守,其实放CODEBUDDY.md更合适,所以这个字段要慎用。
注意:不同版本的 CodeBuddy 对 frontmatter 字段的支持可能有差异。有的版本可能用
globs(复数),有的用glob(单数),有的还支持trigger之类的字段。写之前最好确认一下你当前版本的字段名,写错了不会报错,只会静默失效——这是最坑的地方。
4.3 glob 匹配规则与常见写错案例
glob是重灾区,我见过各种奇葩写法。先把基本语法理清楚:
| 模式 | 含义 | 示例匹配 |
|---|---|---|
* | 匹配单层任意字符 | *.ts匹配a.ts,不匹配dir/a.ts |
** | 匹配任意层级 | src/**/*.ts匹配src/a/b/c.ts |
? | 匹配单个字符 | a?.ts匹配ab.ts |
{a,b} | 匹配 a 或 b | *.{ts,tsx}匹配a.ts和a.tsx |
[abc] | 匹配括号内任一字符 | [abc].ts匹配a.ts |
再看几个我实际踩过的错误写法:
src/*.tsx:以为能匹配src下所有 tsx,实际上*不跨目录,src/components/Button.tsx匹配不到。正确写法是src/**/*.tsx。**/*.ts:这个能匹配所有 ts 文件,但如果你只想匹配src下的,就写宽了,可能误伤配置文件。./src/**/*.tsx:前面加./有的版本不认,直接写src/**/*.tsx更稳。src/**/*.{ts,tsx}:这个写法本身没问题,但要确认你的版本支持花括号展开,不支持的话得拆成两条规则。
我建议的做法是:写完 glob 后,故意去编辑一个应该匹配的文件和一个不该匹配的文件,看规则是否按预期触发。别靠猜,实测最靠谱。
4.4 规则的加载优先级与冲突处理
当多条规则同时命中一个文件时,谁说了算?这是很多人没想过的问题。
一般来说,加载优先级遵循这样的逻辑:
alwaysApply: true的规则优先级最高,始终注入。glob匹配越精确的规则,优先级越高。比如src/components/Button.tsx这种精确路径,比src/**/*.tsx更优先。- 同优先级下,后加载的覆盖先加载的,或者多条规则同时注入由 AI 综合判断。
这里有个实战经验:不要让多条规则对同一件事给出矛盾的要求。比如一条规则说"用分号",另一条说"不用分号",AI 会无所适从,生成结果随机摇摆。规则之间要保证一致性,冲突的规则要么合并,要么删掉一条。
5. 从零到一:让规则真正生效的完整实操
5.1 环境确认与目录初始化
动手之前,先确认你的 CodeBuddy 版本和目录约定。不同版本(尤其是 CodeBuddy CN 和海外版)在路径上可能有细微差异。我的建议是:
- 打开你的 CodeBuddy,找到规则相关的设置项或文档入口,确认
rules目录的准确路径。 - 在项目根目录创建对应的隐藏目录结构。
- 先放一个最简单的规则文件,测试能否被识别。
别一上来就写十几条规则,那样出了问题你根本不知道是哪条坏了。先跑通一条,再批量加,这是我一贯的做法。
5.2 写第一条能生效的规则
拿一个最典型的场景:只对 React 组件文件生效的规范。
第一步,创建文件.codebuddy/rules/react-component.md。
第二步,写 frontmatter 和内容:
--- description: React 函数式组件编码规范,适用于所有 tsx 组件文件 glob: "src/**/*.tsx" --- # React 组件规范 1. 一律使用函数式组件,禁止 class 组件 2. 组件 Props 必须用 interface 定义,命名以 Props 结尾 3. 事件处理函数统一以 handle 开头,如 handleClick 4. 组件必须有默认导出 5. 复杂逻辑抽成自定义 hook,放在 src/hooks 下第三步,验证。打开一个src/components/下的.tsx文件,让 CodeBuddy 帮你写一个新组件,观察它是否遵守了上述规范。如果遵守了,说明规则生效;如果没遵守,按下面的排查流程走。
5.3 验证规则是否真的被加载
怎么确认规则被读进去了?有几个办法:
- 直接问:在对话里问"当前项目有哪些编码规范",看它能不能说出你规则里的内容。能说出来,说明加载了。
- 故意违反:让它写一段明显会违反规则的代码,看它是否主动纠正。
- 看行为差异:把规则文件临时改名或移走,对比生成结果。如果结果没变化,说明规则本来就没生效。
我一般用第一个办法,最快。如果它答不上来,那基本可以确定规则没被加载,直接去查路径和 frontmatter。
5.4 多规则协同的实战配置
一个真实项目里,规则往往不止一条。分享一套我常用的组合:
.codebuddy/rules/ ├── react-component.md # 组件规范,glob: src/**/*.tsx ├── typescript-style.md # TS 规范,glob: src/**/*.ts ├── test-convention.md # 测试规范,glob: **/*.test.ts └── api-layer.md # 接口层规范,glob: src/api/**/*.ts每条规则各管一摊,互不干扰。typescript-style.md管纯 ts 文件,react-component.md管 tsx,测试文件单独一套。这样 AI 在编辑不同类型的文件时,加载的规则是精准的,不会串味。
配置的时候注意:glob之间尽量不要重叠。比如src/**/*.ts和src/api/**/*.ts就重叠了,src/api下的文件会同时命中两条规则。如果这两条规则内容不冲突还好,冲突了就麻烦。要么把范围错开,要么明确优先级。
6. 规则不生效的排查清单与避坑经验
6.1 一张速查表搞定九成问题
我把这些年遇到的"规则不生效"问题整理成一张表,按这个顺序排查,基本能覆盖九成情况:
| 现象 | 可能原因 | 排查方法 | 解决 |
|---|---|---|---|
| 完全没反应 | 文件位置错 | 确认CODEBUDDY.md在根目录、rules在正确隐藏目录 | 移到正确位置 |
| 完全没反应 | frontmatter 格式错 | 检查---是否成对、YAML 缩进是否正确 | 修正格式 |
| 部分文件生效 | glob 写窄了 | 用实际文件路径对照 glob 模式 | 放宽或修正 glob |
| 时灵时不灵 | 规则放错层级 | 条件规则误放CODEBUDDY.md | 挪到 rules 目录 |
| 规则互相打架 | 多条规则冲突 | 检查是否有矛盾要求 | 合并或删除冲突规则 |
| 改了没变化 | 缓存未刷新 | 重启对话或重载项目 | 重新加载 |
| 字段不识别 | 版本字段名不同 | 对照当前版本文档 | 改用正确字段名 |
6.2 那些文档不会告诉你的坑
几个我踩过、但官方文档基本不提的坑:
坑一:frontmatter 里的中文冒号。YAML 对格式极其敏感,description: 规范里的冒号必须是英文半角。如果你输入法没切,打成中文冒号:,整个 frontmatter 解析就废了,而且不会报错,规则静默失效。这个坑我栽过不止一次。
坑二:glob 里的反斜杠。Windows 用户习惯写src\components\*.tsx,但 glob 标准用的是正斜杠/。反斜杠在有的实现里会被当转义符,导致匹配失败。统一用/。
坑三:规则文件编码。如果文件保存成了 GBK 之类的编码,中文内容可能乱码,frontmatter 也可能解析异常。统一用 UTF-8。
坑四:alwaysApply滥用。有人图省事,把所有规则都设成alwaysApply: true,结果上下文被塞满,AI 反而抓不住重点,生成质量下降。条件规则就该有条件。
坑五:规则太长。单条规则写了几千字,AI 读到后面忘了前面。规则要精炼,一条规则聚焦一件事。
6.3 规则写得好,AI 才听话:几条实战心得
最后分享几条让规则真正"管用"的心得:
- 规则要可执行,不要可意会。"代码要清晰"是废话,"函数不超过 50 行"才是规则。
- 用肯定句,少用否定句。"使用 const"比"不要用 var"更容易被遵守。
- 给例子。一条规则配一个正例一个反例,AI 理解得最准。
- 定期清理。项目演进后,过时的规则要删,否则会误导 AI。
- 版本控制。把
CODEBUDDY.md和rules目录一起提交到 Git,团队共享,别只放在本地。
关于 CodeBuddy 和 WorkBuddy 的区别,简单说一句:两者在规则体系上思路相近,但具体文件命名和目录约定不同,别把 CodeBuddy 的CODEBUDDY.md直接改名丢进 WorkBuddy 就以为能用。跨工具迁移规则时,一定要重新对照目标工具的文档确认字段和路径。
规则这东西,写对了是效率倍增器,写错了就是自我感动。我现在的习惯是:每加一条规则,立刻用一个真实文件验证一遍,确认生效了再继续。宁可慢一点,也别攒一堆"看起来写了其实没用"的规则文件。毕竟,规则的价值不在于你写了多少,而在于 AI 真正遵守了多少。