在C语言项目里给上百个函数调试加日志,在Java工程里对着八百年没人动的老代码做重构,在Python脚本里批量处理几千个文件——这些场景我都经历过,而且每次都被同一个问题折磨:AI代码编辑器上一轮对话还记得我们的约定,换了个话题或者过了几天,它就把之前的要求忘得一干二净。直到我开始认真研究Rules(规则文件),才发现之前一直在靠对话里的零散指令硬扛,完全是低效玩法。
今天这篇是“工具Cursor”系列的第六篇,前五篇聊了基础配置、快捷键、对话技巧、代码补全和重构思路,这次专门拆开讲Rules。而且这期不只是讲Rules本身,我会把Rules、Skill、Commands和subAgents这几个概念串起来讲,但重点还是落在Rules上——因为它是整个体系的地基,地基没打好,后面三个功能全都白搭。这篇内容适合刚接触AI编程助手、被“AI总是忘记我说过的话”折磨的开发者,也适合已经在用Cursor但想进一步规范团队协作、统一代码风格的朋友。
1. Rules到底在解决什么问题
1.1 AI编程助手的“金鱼记忆”
先说说我为什么觉得Rules是AI编程工具里最值得研究的功能。用过Cursor或者其他AI代码编辑器的人应该都有这种感觉:对话开头给它交代了背景,说“这个模块我们用的是状态机模式,不要在控制器里直接写业务逻辑,错误码统一用五位数字”,前几轮它还能遵守,等聊到几十轮之后,或者你新建了一个对话窗口,它又开始在控制器里一通乱写。
这不是AI变笨了,而是它的上下文窗口有限,每次对话的“记忆”都在被新的内容覆盖。就像你带了个实习生,你今天告诉他“咱们项目里不要用var声明变量”,明天他又忘了,因为你的话只是“口头交代”,没有写进他随身携带的工作手册里。Rules就是那份工作手册。
1.2 规则文件是工程约定不是玄学
很多人问,我在提示词里把要求写清楚不就行了?为什么还要专门搞一套规则文件?这里有个关键区别:提示词是“临时指令”,Rules是“长期约定”。临时指令在当次对话有效,一旦对话轮次变多、上下文被压缩,或者开启新对话,就失效了。而规则文件每次对话都会自动加载,相当于每次开工前AI都会先读一遍工作手册,再开始干活。
我举个例子。假设你正在维护一个老旧的JSP项目,里面充斥着各种陈年历史遗留代码。你希望AI帮你改代码的时候保留原有的“丑陋但稳定”的风格,不要顺手把代码重构得面目全非。这种约束用对话交代,大概率过几轮就失效;但如果写进项目的Rules文件里,每次对话开始AI都会看到“这是遗留系统,改动范围尽量小,不要在修改函数时给整个文件做现代风格重构”,效果完全不同。
1.3 为什么是Cursor而不是提示词模板
最早我是在一些开源项目里看到类似“AGENTS.md”这样的文件,后来Cursor把这套思路产品化了,形成了成体系的规则机制。和普通的prompt模板对比,Rules最大的优势是它的“常驻性”和“分层性”。常驻性就是上面说的,自动加载、无需重复交代;分层性是指你可以在全局、项目、局部文件三个层面分别定义规则,优先级各不相同,这让团队可以在保持统一规范的同时,允许不同项目有自己的特化约定。
这套机制背后其实就是很多人说的“上下文工程(Context Engineering)”,不是搞什么玄学提示词,而是系统性地管理AI每次能看到什么、遵循什么。你给AI的上下文越稳定、越结构清晰,它的输出就越可预期。
2. Rules体系全景:全局、项目与局部
2.1 全局规则:你的编程价值观
先聊全局Rules。这个概念很好理解:放在用户层面,对所有项目生效的规则。我在全局规则里写的基本上是长期稳定的个人偏好,比如:
- 代码中的注释使用中文还是英文
- 变量命名风格是驼峰还是下划线
- 默认生成的代码需要附带错误处理还是允许裸奔
- 优先使用标准库而不是第三方依赖
- 修改代码时保留原有格式习惯
这些规则不会频繁变动,它代表的是你作为一个开发者的“编程价值观”。就像你带团队的时候说“我们组写接口必须带参数校验”,这是对人说的;全局Rules就是对AI说的同样的话。
2.2 项目规则:每个仓库的宪法
项目规则放在项目的.cursor/rules目录下,比如.cursor/rules/project-rules.mdc这样的文件。它约束的是这个项目里所有对话的行为,无论谁打开这个项目、无论开多少个对话窗口,只要Rules文件存在,AI就会遵守。
我在项目规则里通常会放这些内容:
- 项目的技术栈和目录结构说明
- 模块划分和依赖方向
- 代码风格细节(比如这个项目禁用lombok、字段必须显式getter/setter)
- 测试规范(改动必须补测试,测试文件放哪个目录)
- 提交信息的格式要求
- 当前阶段正在重构的模块,尽量避免AI在这些模块上做大面积改动
项目规则的意义在于它是团队共享的。我在带小团队协作的时候,把项目Rules文件提交到仓库里,所有成员打开这个项目,AI都自动继承这些约定,等于把“资深开发者的经验”固化成了团队资产。新同学接手项目的时候,AI不会上来就乱写代码,它先读了规则再动手。
2.3 局部规则、.cursorrules和规则文件格式
除了全局和项目两级,Cursor还支持局部规则。这里的局部规则指的是可以绑定到某个文件、某个目录的规则。比如你有一个核心算法文件,不希望AI乱动,可以在该文件所在的目录下加规则。这种局部规则在日常使用中我用得相对少,但它非常适合“重点保护区域”的场景。
另外需要提一下.cursorrules文件。早期版本的Cursor会读取项目根目录下的.cursorrules文件,现在新版更推荐使用.cursor/rules目录下带元数据的规则文件。二者其实可以共存,旧的单文件方式简单粗暴,适合个人项目;新方式支持过滤条件(哪些文件类型/路径匹配这条规则),更适合复杂项目。如果你打开老项目看到.cursorrules文件,可以直接迁移到.cursor/rules目录下,管理起来更清晰。
规则文件的格式是带frontmatter的Markdown,前面可以有类似globs(匹配哪些文件)、description(描述这条规则作用)之类的元信息,后面是具体的规则正文。我最初用的时候看到这个结构愣了一下,后来想通了:它其实是想让规则文件既能给人看又能给机器解析。人看正文就知道项目约定,AI通过元信息就能判断“这条规则在什么场景下生效”。
2.4 不同层级规则的优先级经验
关于优先级,实际使用中我的经验是这样的:局部规则针对性强,优先级最高;项目规则次之;全局规则作为兜底。但这并不是绝对的,因为具体的行为还取决于模型对上下文的权重判断。
我有一次遇到的情况是:全局规则写了“默认使用Python类型注解”,项目规则里某个老模块明确写了“此目录禁止新增类型注解以保持兼容”,结果AI在这个老目录里改代码的时候还是加了注解。后来我意识到,看不出问题是“优先级设置”,真正的问题是项目规则里那句话写得太笼统,AI没有把它当成针对这个目录的硬性要求。把规则改成“该目录下所有文件不新增类型注解,现有注解保持不动”之后,情况就好了。
所以优先级不是靠文件位置就能解决所有问题的,规则本身的措辞是否足够明确、有没有例外的说明,都会影响最终效果。
3. 怎么才能写出一套能用的Rules
3.1 先写目标,再写约束
我最初写规则文件的时候也走过弯路,一上来就堆了一堆“不要这样做、不要那样做”,结果AI反而束手束脚,改出来的代码四平八稳但没啥用。后来我总结出一个经验:写规则要先写清楚目标,再写约束条件。
比如:
目标:保持模块可测试性。 约束:不要在业务代码中直接new依赖对象,统一通过构造函数注入。这比单纯写“不要直接new”要好很多。因为AI理解了目标是“可测试性”,当它遇到边界情况时,能自己推理出该怎么做,而不是傻傻套用一条禁令。写规则本质上是在给AI传递“你的工作目标是什么、边界在哪里、什么情况下可以灵活处理”,而不是把它变成一个什么都不懂的纪律委员。
3.2 规则行文颗粒度怎么定
这是我最想分享的经验之一。规则写得太粗,AI看了等于没看;写得太细,每条都管到具体变量命名,AI反而会被大量琐碎约束分散注意力,影响代码质量。
我的建议是分层处理:全局规则写“永远成立”的粗颗粒度约定,比如“注释必须说明为什么而不是什么,不要写废话注释”,项目规则写“和这个项目强相关”的中等颗粒度约定,比如“本项目的DTO转换统一在service层完成,controller不允许出现转换代码”,局部规则才写“极度精细”的必守条款。
在写每条规则之前,先问自己一句:这条规则对AI的行为改变有多大?如果删掉它,AI输出的代码会有什么不同?想不清楚这点,就别写进去,规则堆太多反而稀释了重点。我见过有人往规则文件里写了上百条规则,结果AI执行起来简直像戴了脚镣,代码风格变得极其怪异。
3.3 用示例体现偏好,胜过空讲道理
AI模型本质上是通过海量代码学会写代码的,它也天然擅长“模仿示例”。写规则的时候,与其长篇大论解释“我们的错误码格式是10001开头”,不如直接给一段示例代码展示“正确做法”。
比如规则里可以写:
错误码规范:业务错误码统一使用模块前缀+三位数字,示例: - 用户模块错误码:10001、10002 - 订单模块错误码:20001、20002要求AI输出日志格式的时候,直接给它一段示例日志的样子,AI下次生成的日志就会有模有样。这其实就是在利用模型的小样本学习能力,给它几个“参考样本”,它比只看文字描述要可靠得多。
3.4 规则库要定期维护,不是一次写完就完事
我在实际项目中是把规则文件当成真正的“项目文档”来维护的。每次遇到AI反复犯同一个错、每次找到一条“要是当时跟AI说了就好了”的经验,都会补进规则文件里。有时候一个季度下来,项目规则文件能从几行膨胀到上百行,然后我会做一次精简合并,删掉那些已经过时的约束。
最早我为某高校合作项目做模拟项目X的时候,团队里五个人同时改一个仓库,AI生成代码的命名风格五花八门。后来我们把命名规范、目录结构说明、接口定义习惯全部打进项目规则,并且约定任何人在code review中发现AI产生的风格问题,第一件事不是手动改,而是先想“需不需要补一条规则”。这么操作了一个多月,AI生成的代码越来越像团队老成员的手笔,肉眼可见地稳定了。
4. 实操:一套完整Rules的诞生过程
4.1 准备阶段:盘点问题与抽丝剥茧
动手写Rule之前,先花点时间回答几个问题:
- 这个项目里,AI最常犯的低级错误是什么?
- 团队代码规范里,哪些是新人最容易违反、AI也最容易踩的?
- 这个项目的架构核心是什么?哪些模块改动时必须特别小心?
把这些问题梳理清楚,你会得到一张“规则需求清单”。我举个例子,假设你在做一个Python的FastAPI项目,复盘下来发现AI经常犯这几个错:接口路由函数的返回类型没有写response_model、数据库查询没有加超时控制、异常处理全部都是print堆栈而不是返回统一格式。
那你的规则清单就是:接口定义需要response_model、数据库操作需要统一封装超时、全局异常处理器负责返回统一错误载荷。
4.2 规则文件的主体设计
接下来就是搭建规则文件。我在项目里创建一个.cursor/rules目录,里面按主题拆分成几个文件,而不是把所有规则塞进一个巨型文件里。比如说:
python-api-rules.mdc:负责接口层规范database-rules.mdc:负责数据访问规范testing-rules.mdc:负责测试要求error-handling-rules.mdc:负责异常和错误码
每个文件开头用frontmatter写清楚这个文件匹配哪些路径。比如数据库规则文件定义globs: ["**/db/**", "**/models/**"],这样AI在处理数据层代码时才加载它。这样做的好处是:规则文件不会在对话开始时把全部内容一股脑塞进上下文,而是按需加载,让AI在特定场景下看到特定规则,既省了上下文空间,也避免了不同规则的干扰。
关于frontmatter,有些版本里叫globs,作用是声明这条规则对哪些文件生效,有些还支持alwaysApply。这个设计我觉得是整个Rules系统最有价值的地方,初期很多人会忽略它,直接把所有规则都设为alwaysApply,结果上下文塞得满满当当,事无巨细全都管,反而什么都管不好。
4.3 放置方式与生效验证
规则文件写好后放在项目的.cursor/rules目录下,确认文件编码、格式没问题。启动编辑器之后,新开一个对话窗口,可以先用一个简单的对话验证规则是否被正确加载:直接问AI“根据我的项目规则,新增一个接口应该遵循哪些步骤?”如果AI能准确说出你的规则内容,说明加载成功;如果它答非所问或者复述得牛头不对马嘴,就要检查文件路径和frontmatter的写法。
更实际的办法是:丢一段故意违反规则的上游代码给它看,让它挑毛病。规则生效的话,AI会准确地指出这段代码哪里违反了项目约定。我曾经把一段“在Controller里直接访问数据库”的违规代码扔给AI看,它马上指出“根据项目规则,Controller不允许直接调用数据访问层,需要经过Service层”,那一刻我确信规则真的起效了。
4.4 规则生效前后对比,眼见为实
为了让大家直观感受,我贴一段简单的规则示例,这是我在一个真实项目里简化出来的:
--- description: 接口层通用约束 globs: ["**/api/**", "**/controller/**"] --- - 接口函数必须显式声明请求体类型和响应模型,禁止返回裸Dict。 - 所有接口统一返回 { "code": 0, "data": ..., "message": "ok" } 结构。 - 接口内不做业务判断,业务逻辑下沉到service层。 - 新接口必须在文档字符串中标注接口用途和调用方。这段规则贴在文件顶部时,AI和它对话时生成的接口代码会非常规矩:返回结构、责任划分、文档说明一个不少。没有这段规则的时候,它经常是图省事直接返回一个字典,调用方还得猜字段结构。
如果你觉得规则还不够显眼,可以把最关键的规则放到文件的开头,因为AI读上下文时对前部内容的注意力通常更集中。这个细节很多帖子不会提,但实测下来对结果有明显影响。
5. 常见坑与排查技巧
5.1 规则写得像散文,AI当成参考而非规矩
在我看过的很多规则文件里,最常见的毛病是写得像散文,语气委婉、充满“可以尝试”“可能需要”之类的字眼。AI对这样的规则就真的“参考性遵守”,心情好了遵守,心情不好就忽略。
我踩过一次:在规则里写“建议不要使用any类型”,结果AI理直气壮地在大量新代码里用了any,然后我拿着规则去质询它,它表示“那条规则是建议性的,我认为这里可以用any”。后来我改成“本项目禁止在新增代码中使用any。如确需使用,必须注释说明原因并经过review”,情况才好转。
规则是用给另一个智能体看的,语气要明确、边界要清楚,不要害怕用“必须”“禁止”“一律”这样的词,也不需要太客气。当然,明确措辞不代表语气僵硬,你完全可以在规则里写清楚“为什么”,让有判断力的模型理解背后的原因。
5.2 规则和业务场景错配
还有一次,我在一个前端项目里定义了“组件必须使用函数式组件,禁止使用类组件”,本来是为了响应Hooks的流行趋势,但项目里其实有一些边界场景必须用类组件才能实现,结果AI严格贯彻规则,把那些边界场景也全改成函数式,导致出现bug。
后来我学乖了,凡是规则涉及“禁止”的,都要预留例外条款,并在项目规则里明确声明“本规则存在例外,当出现复杂错误边界时需要类组件时,经团队讨论确认后可用,并在代码注释里写明原因”。这样AI既不会乱七八糟地破例,也不会死板地在不合适的场景强推规则。
5.3 上下文塞爆,规则之间互相抢注意力
有些人会把所有规则全放在一个文件里,又把alwaysApply设成true,导致每次对话AI都要加载一大篇规则。规则太多太杂,上下文空间被大量占用,真正有效的核心指令反而被稀释。遇到这种情况,AI明显会“变笨”,生成质量下降。
我的建议是善用globs按需加载,把规则拆开。还有一点,规则的顺序也很重要。把最核心、最不能违反的规则放在每个规则文件的前部,这样它在加载时不太容易被截断或忽视。我在规则文件的开头固定放“本项目铁律”,第一条永远是“禁止在Service层直接写SQL”,接着才是各种推荐性做法。实测下来,违反铁律的概率大幅下降。
5.4 规则冲突怎么排查
规则多了以后,一个很现实的问题是不同规则之间可能互相冲突,比如全局规则说“所有代码都要尽量简练”,项目规则说“接口必须完整写清楚请求体校验”,这时候AI就会陷入两难,输出结果时而有前者风格时而有后者风格,非常不稳定。
排查冲突的办法是:把规则文件全部展开,逐条检查是否存在互斥表述。我做过一次“规则审计”,把全局和项目规则放在一起,找出了三条明显冲突的规则:一条强调“注释越少越好”,另一条要求“核心算法必须写详细流程图注释”。这俩的确冲突。我最终把“注释越少越好”改成“注释只解释Why,不要解释What”,冲突就解决了。
如果还想排查得更细,可以开启对话里的详细日志或调试信息,查看AI实际加载了哪些规则、每条规则的匹配情况。由于工具版本不断更新,具体入口可能有变化,但思路是一样的:让机器告诉你它看到了什么,比你对着规则文件猜一百遍都直接。
6. 一次完整的Rules应用实例:模拟项目X
为了让大家对整套流程有更落地的感觉,我用我们内部一个代号叫“模拟项目X”的工程讲一次完整的实战过程。这个项目是一个后台管理系统的前端,用React加TypeScript,涉及大量表格页、表单页和权限控制逻辑。
项目初期,AI生成的代码风格混乱,有的页面用Hooks封装数据,有的页面直接在组件里fetch,表格列的写法也是五花八门。我们几个人一致认为这不是靠人工review能解决的,必须靠规则约束。
经过讨论,我们在项目根目录下建立了这样的规则文件体系:
global-rules.mdc:团队通用约定,包括命名规范、注释语言、格式化偏好、模块职责划分。react-pages-rules.mdc:页面级规则,规定页面组件统一使用函数组件,数据请求通过自定义Hooks完成,页面不允许直接操作全局状态。table-rules.mdc:表格页专用规则,明确CRUD页面的表格写法,包括列定义、分页方式、搜索表单和操作按钮的统一模式。
在react-pages-rules.mdc中,我们特意放了一段示例代码,描述一个标准的列表页面应该长什么样子,包括useState、useEffect、自定义Hooks的调用顺序都做了示范。AI照着这个模板生成后续页面,风格高度统一,code review时几乎不需要改结构,只调一下细节就好了。
这个过程给我最大的启发是:Rules真正起作用的时候,你没有感觉。AI生成的东西看起来“本来就该是这样”,这就是规则生效的最好证明。
7. Rules只是起点,后面还有Skill、Commands和subAgents
把Rules单独拿出来写一整篇,是因为它确实是整个“AI辅助开发提效体系”里最基础的一块。Rules解决的是“AI每次干活前要知道什么”;接下来的Skill解决的是“AI在特定场景下该怎么干活”,它是把一套成体系的提示词和工作流程封装成可复用的技能包;Commands解决的是“用户如何便捷地调用AI做某件事”,相当于预设了一个功能按钮;subAgents更进一步,可以让不同的AI角色负责不同环节,比如一个负责读代码、一个负责写测试、一个负责审查逻辑。
我看到很多人在研究这些功能的时候,一上来就研究subAgents或者复杂的Skill组合,结果因为它们没有把Rules写好,AI执行时连基础的项目背景都不知道,跑起来完全不是预期的效果。所以这期我花了大量篇幅把Rules讲透,后面几篇再分别展开Skill、Commands和subAgents的时候,大家就能在同一个地基上往上盖楼了。
对我来说,Rules最好的打开方式不是照搬网上那些花里胡哨的“最强规则集”,而是花一晚上时间,把这周遇到的所有AI“不听话”场景记下来,逐个归纳成几条清清白白的规则,写进项目里,第二天用一天验证效果。试上一周,你会明显感觉到AI“上道”了。这就是我实际使用中最有价值的一套方法,没有之一。