1. 为什么你的 Cursor 总在“自由发挥”用 Cursor 写代码的人大概率都遇到过这种场景你明明在项目里定好了目录结构、命名风格、错误处理方式结果 Agent 一出手接口命名一会儿驼峰一会儿下划线日志库今天用log明天用logger甚至连你反复强调的“别用 any”都当耳旁风。每次开新对话你都得把同一段提示词再贴一遍贴到怀疑人生。问题的根子不在模型笨而在于上下文没有被固化。你发给模型的提示词其实是三部分拼起来的基础系统提示 你的临时输入 项目上下文。前两部分每次都在变第三部分如果没人喂模型就只能靠猜。猜出来的东西自然和你的项目约定对不上。Cursor Rule 就是来解决这件事的。它把“需要反复交代的约定”从聊天框里抽出来写进.cursor/rules目录下的 MDC 文件让模型在每次请求时自动带上。你可以把它理解成给项目配了一份“员工手册”新来的 Agent 一进门先读手册再干活。这篇面向日常用 Cursor 写代码的开发者重点讲三件事MDC 文件的骨架怎么写、frontmatter 怎么配才能精准触发、以及怎么用对比动作验证规则真的生效了。适合已经用过 Cursor、但还在靠“复制粘贴提示词”续命的人。2. 把提示词固化成规则TaoToken 前置准备规则写好了最终还是要落到模型调用上。如果你希望规则文件里的约定能被稳定执行模型侧的接入最好也固定下来别今天换一个明天换一个。我自己的做法是统一走 TaoToken 的接口模型对话、编码计划、密钥管理都在一个控制台里省得来回切。具体来说日常调试规则效果时用模型对话页面直接试写长期项目、跑 Agent 任务时用 Coding Plan密钥在 API Keys 页面生成接入文档在 doc 里查。这样规则文件改完模型侧不用重新配环境直接验证就行。需要提前准备的东西不多一个可用的 API Key、Cursor 里已经打开的项目、以及.cursor/rules目录没有就手动建一个。Key 的生成入口在控制台的 API Keys 页面接入方式参考官方文档模型对话入口用来做单轮验证。地址统一用https://taotoken.net/api不要带多余参数。注意规则文件本身不依赖任何特定模型但模型侧接入稳定规则的可复现性才高。别一边改规则一边换模型那样你分不清是规则生效了还是模型碰巧听话。3. MDC 规则文件骨架与 frontmatter 配置MDC 可以理解成“带元数据的 Markdown”。文件头用 frontmatter 声明这条规则怎么触发下面正文写具体约定。先看一个最小可用的骨架--- description: 项目通用编码规范约束命名、日志与错误处理 globs: alwaysApply: false --- # 项目编码规范 ## 命名 - 变量与函数使用小驼峰类名使用大驼峰 - 常量全大写下划线分隔 - 禁止使用单字母命名循环下标除外 ## 日志 - 统一使用项目封装的 logger禁止直接 console.log - 错误日志必须带上下文对象禁止只打字符串 ## 错误处理 - 异步调用必须 try/catch 或 .catch - 禁止吞掉异常catch 块里至少要记录日志frontmatter 里几个字段决定了规则的触发方式这是最容易配错的地方。对照表如下字段作用典型取值description规则用途说明Agent Request 模式下模型靠它判断是否调用一句话描述globs文件匹配模式Auto Attached 模式下命中才加载src/**/*.tsalwaysApply是否始终注入上下文true / false四种触发类型对应关系是这样的Always 就是alwaysApply: true规则永远在上下文里Auto Attached 靠globs匹配比如你打开src/api/user.ts匹配src/**/*.ts的规则才会加载Agent Request 靠description模型自己判断“现在该不该用这条规则”Manual 则要你在对话里用规则名手动引用。我试过把命名规范设成 Always把“数据库迁移脚本规范”设成 Auto Attached 匹配migrations/**效果比全塞进一条规则好很多。规则文件建议控制在 500 行以内太长就拆成多条可组合的小规则比如naming.mdc、logging.mdc、error-handling.mdc分开写。项目级规则支持嵌套。你可以在根目录放全局约定在子目录放局部约定project/ .cursor/rules/ base.mdc backend/ .cursor/rules/ api-style.mdc frontend/ .cursor/rules/ component-style.mdc这样后端和前端各自的约定互不干扰Agent 走到哪个目录就读哪本手册。4. 验证规则是否生效一次对比请求规则写完不验证等于没写。最直接的办法是做一次“触发前 vs 触发后”的对比。先准备一个故意违反约定的文件比如src/utils/format.tsexport function Format_Date(d: any) { console.log(formatting); return d.toISOString(); }这段代码踩了三个坑函数名大写下划线、参数用了any、直接console.log。先不加载规则让 Agent 检查这个文件请检查 src/utils/format.ts 是否符合项目编码规范并给出修改建议。没有规则时模型通常只会泛泛地说“建议加类型”“命名可以更规范”不会精确指出你项目里“禁止 any”“禁止 console.log”这两条硬约定。接着把naming.mdc和logging.mdc放进.cursor/rules其中命名规则设alwaysApply: true日志规则用globs: src/**/*.ts。再发一次同样的请求这次模型的输出会明显不同它会直接点出Format_Date违反小驼峰约定、any违反类型约束、console.log违反日志规范并给出改写后的版本import { logger } from /lib/logger; export function formatDate(d: Date): string { logger.info(formatting date, { input: d }); return d.toISOString(); }对比两次输出如果第二次能稳定命中你写在规则里的具体条款说明规则生效了。如果还是泛泛而谈多半是 frontmatter 配错了——比如该用 Auto Attached 的写成了 Manual模型根本没加载到。想更省事的话可以在模型对话页面里单轮测试规则文本确认措辞清晰后再落盘到 MDC 文件。规则本质是提示词指令越具体、边界越清楚模型执行越稳。5. 规则不生效这几个坑我踩过规则写了但模型不理。先查 frontmatter。alwaysApply: false且globs写错路径规则就不会被加载。比如你写globs: src/*.ts它只匹配src下一层src/api/user.ts是匹配不到的得用src/**/*.ts。Agent Request 模式不触发。这个模式完全靠description让模型自己判断。描述写得太虚比如“一些规范”模型不知道什么时候该用。改成“当修改 TypeScript 文件中的函数命名或日志调用时使用”命中率会高很多。规则之间互相打架。根目录一条规则说“用双引号”子目录一条说“用单引号”模型就懵了。嵌套规则要有明确的覆盖关系子目录规则负责细化不要和父级直接冲突。规则太长被截断。单文件超过 500 行模型可能只读到前半段。把大规则拆成多条用globs或description分别触发比堆在一个文件里靠谱。改了规则没重启会话。Cursor 的规则在会话开始时加载改完 MDC 文件后最好开个新对话再验证不然你测的还是旧上下文。Manual 规则忘了引用。设成 Manual 的规则不会自动加载必须在对话里用规则名显式引用。如果你发现某条规则死活不生效先确认它是不是 Manual 类型。6. 把规则接进你的日常编码流规则文件调通之后下一步是让它和模型调用形成固定链路。我的习惯是项目里.cursor/rules跟着代码一起进版本控制团队里谁拉代码谁就继承这套约定模型侧统一走 TaoToken 的接入方式密钥在 API Keys 页面管理接入细节查 doc长期跑编码任务用 Coding Plan单轮验证规则用模型对话。这样一套下来你不再需要每次开对话都重新交代一遍项目约定Agent 进门先读手册答非所问的情况会明显减少。规则写得好不好直接决定模型是“帮你干活”还是“给你添乱”。先从一条命名规范开始跑通触发和验证再逐步把日志、错误处理、目录结构这些约定补进去比一次性写一大坨更容易维护。
