👁 52 次阅读

配图

为什么重复代码审查需要 Rules 与 MCP
重复代码审查的成本通常不在第一次审查,而在每次都要重新解释同一套标准。今天提醒检查空指针,明天提醒补测试,后天又有人忘记权限校验。看似是人的问题,本质是流程没有被写进工具。Cursor 的 Rules 解决『判断标准不稳定』,MCP 解决『模型看不到本地与外部系统证据』。两者组合后,代码审查才可能从一次性对话变成可重复执行的流程。
很多团队已经用 Cursor 做补全和问答,但审查仍停留在复制 diff、粘贴到聊天框、人工整理结论的阶段。这样做的问题有三点:输入不完整、标准不一致、结论不可追溯。Rules 把标准固定下来,MCP 把文件、命令输出和外部系统状态带进上下文,二者配合才能减少重复沟通。
本文不追求一次性搭建复杂平台,而是给出一条能逐渐加码的路径:先写最小规则,再接入只读 MCP,最后用固定提示词和检查清单把流程跑顺。每一步都可以单独验证,避免一上来就堆配置。
先明确边界:Rules 管判断标准,MCP 管外部证据
Rules 是写进项目里的审查契约,适合放必须遵守的检查顺序、输出格式、严重级别、禁止事项和团队约定。它不应该承担读取实时数据的工作,也不应该把每个业务的细节都塞进去。MCP 是模型调用外部工具和数据的通道,适合读取变更文件、测试输出、issue 状态、日志、数据库结构和静态扫描结果。把两者混在一起,规则会变得又长又难维护。
一个简单判断法是:如果一句话在每次审查中都不变,就写进 Rules;如果一句话需要看当前仓库、当前分支或当前环境,就交给 MCP 或命令。比如『每条问题必须给出文件与证据』属于 Rules;『读取本次 diff 涉及的文件』属于 MCP 或命令。这样分工后,规则可以版本化,工具可以替换,审查流程不会绑死在某个模型版本上。
还要注意权限边界。MCP 工具能读多少目录、能不能写文件、能不能访问生产数据,必须提前限制。代码审查优先使用只读能力,密钥通过环境变量或本机密钥管理传递,不要写进仓库。规则里明确写出『无法确认的内容标记为待验证』,可以降低模型把猜测当结论的风险。
准备工作:把审查流程拆成五个阶段
在写配置前,先把重复审查拆成可观察的阶段。阶段越清楚,Rules 和 MCP 越容易各司其职。
- 变更发现:确定本次审查范围,列出改动文件与 diff 统计。
- 规则检查:按统一标准检查类型、边界、错误处理、权限、测试与可维护性。
- 工具取证:运行 lint、测试、类型检查,读取相关文件和调用方。
- 汇总报告:按阻断、重要、建议三档输出,每条包含文件、证据、影响与修复建议。
- 人工复核:确认高风险结论,处理待验证项,决定是否合并。
这五个阶段里,第一和第三阶段最适合自动化,第二阶段适合 Rules 固定,第四阶段适合模板化,第五阶段必须保留人工判断。不要把第五阶段也交给模型,否则审查会变成看似完整但无人负责的报告。
第一步:建立可维护的 Rules 目录
建议把项目规则放在仓库的 .cursor/rules 目录,并按场景拆分文件。个人偏好可以放在用户级规则里,团队必须遵守的内容才提交到仓库。先创建最小目录和文件:
mkdir -p .cursor/rules touch .cursor/rules/review.mdc
文件名不要追求大而全。可以按审查场景拆成 review.mdc、security.mdc、test.mdc、frontend.mdc。每个文件只回答一类问题,模型更容易执行,团队也更容易 review 规则本身。
规则类型要按触发方式选择。总是需要遵守的团队约定可以用始终应用;只在特定文件范围生效的规则用 globs 自动附加;需要在对话里显式引用的规则用请求触发或手动触发。不要把所有规则都设成始终应用,否则上下文会被无关内容占满,审查重点反而被稀释。
规则分层建议
- 项目级规则:提交到仓库,包含审查顺序、输出格式、严重级别、禁止事项。
- 目录级规则:针对前端、后端、基础设施等不同目录,写局部约定。
- 个人级规则:放个人偏好,例如回答语言、注释风格,不强制团队接受。
- 临时规则:针对一次迁移或一次专项治理,用完删除,避免长期污染。
第二步:写一份能执行的 review.mdc
一份可执行的规则文件,重点不是写很多原则,而是让模型知道先做什么、后做什么、输出什么。下面是一个最小示例,frontmatter 负责触发范围,正文负责审查动作:
--- description: 提交前代码审查规则 globs: **/*.ts,**/*.tsx alwaysApply: false --- 审查目标 - 找出会导致运行失败、数据错误、安全问题、回归风险的变更 - 输出必须可执行,避免泛泛而谈 审查顺序 1. 读取变更文件列表与 diff 2. 读取相关测试、类型定义、调用方 3. 检查边界条件、错误处理、权限与数据流 4. 给出阻断、重要、建议三档结论 输出格式 - 文件与行号 - 问题证据 - 影响范围 - 修复建议 - 待验证项 禁止事项 - 不编造未读取的文件内容 - 不把猜测写成结论 - 不忽略测试失败与类型错误
这份规则的关键在三个地方。第一,审查顺序固定,模型不会一上来就下结论。第二,输出格式固定,每条问题都能落到文件和证据。第三,禁止事项明确,减少编造和空泛建议。规则不需要写『请认真审查』这类无法执行的话,而要写『先读取调用方』『必须引用测试输出』这类可验证动作。
如果团队有多语言仓库,不要把所有 globs 写进一个文件。TypeScript、Python、Go 的检查重点不同,拆开维护更稳。规则文件也要像代码一样 review,发现某条规则经常被误读,就改成更具体的动作,而不是继续堆形容词。
第三步:接入 MCP,让审查拿到真实上下文
MCP 的价值是让模型通过工具读取真实上下文,而不是靠人粘贴。先从只读的文件系统服务开始,成本最低,也最容易验证。可以在终端先确认命令能启动:
npx -y @modelcontextprotocol/server-filesystem .
然后在 Cursor 的 MCP 设置里新增 server,command 填 npx,args 依次填 -y、@modelcontextprotocol/server-filesystem、.。不同版本的界面字段名称可能不同,以本机界面为准。配置完成后,在对话里让模型读取某个文件,确认工具调用成功,再进入审查流程。
MCP 接入原则
- 先只读:文件系统、Git 历史、issue 查询优先,写操作最后再考虑。
- 最小范围:只暴露仓库目录,不要暴露整个主目录。
- 密钥外置:通过环境变量或本机密钥管理传递,不写入规则文件和仓库。
- 逐步增加:一次只接一个工具,确认稳定后再接下一个。
如果团队已有 Git、Issue、日志或静态分析相关的 MCP 服务,可以按同样方式接入。但没有必要一开始全部接上。审查流程最需要的通常是三类证据:本次 diff、相关源码与测试、命令执行结果。先把这三类跑通,比堆很多工具更有用。
还要在规则里写明工具使用顺序。例如先列变更文件,再读取相关测试,再引用 lint 与 test 输出。否则模型可能随机调用工具,报告看似丰富,实际缺少关键证据。
第四步:用命令把本地检查串起来
MCP 负责取上下文,命令负责产出可复现的证据。审查前至少运行三条命令:查看变更范围、查看 diff 统计、运行项目已有的检查。示例:
git diff --name-only origin/main...HEAD git diff --stat origin/main...HEAD npm run lint npm run test -- --runInBand
这些命令不是要求每次都必须全绿,而是要求审查报告引用真实输出。lint 失败时,报告要说明失败位置和是否与本次变更相关;测试失败时,要区分既有失败和新增失败;没有测试覆盖时,要明确写出缺口,而不是用『建议补充测试』一句带过。
在 monorepo 里,不要把所有包都跑一遍。先根据变更文件定位受影响包,再运行对应命令。规则里可以写『优先运行受影响包的检查』,但不要把具体包管理器写死。包管理器可能是 npm、pnpm、yarn 或 bun,规则应写判断方法,命令示例只作为参考。
如果命令输出很长,不要直接整段粘贴到对话里。让 MCP 读取输出文件,或者只保留失败摘要和关键堆栈。审查报告需要的是证据密度,不是日志长度。
第五步:设计稳定的审查提示词模板
规则固定后,还需要一个稳定的调用模板。模板不要写太长,重点是让模型按顺序执行,并引用规则和工具结果:
请按以下流程审查当前分支: 1. 读取 .cursor/rules/review.mdc 2. 列出 git diff --name-only origin/main...HEAD 的结果 3. 对每个变更文件读取相关测试与调用方 4. 执行或引用 lint 与 test 的输出 5. 按阻断、重要、建议输出表格 6. 每条问题给出文件、证据、修复建议 7. 无法确认的内容放入待验证
模板里尽量避免『全面审查』这种模糊目标。全面意味着没有边界,模型只能泛泛而谈。把目标拆成变更范围、证据来源、输出格式和待验证项,审查结果会稳定很多。
如果团队使用工单系统,可以在模板里加入『读取关联 issue 的验收标准』;如果有安全扫描,可以加入『引用扫描结果中的高风险项』。每加一个数据源,都要在规则里说明它解决什么问题,否则模板会越来越臃肿。
对比:三种做法在团队里的差异
下面的对比不是精确统计,而是根据常见团队实践做的定性归纳。重点看可重复性和可追溯性,而不是看单次审查速度。
| 维度 | 只用聊天窗口 | 只用 Rules | Rules 与 MCP 联动 |
|---|---|---|---|
| 输入稳定性 | 依赖临时粘贴,容易漏文件 | 标准较稳定,但上下文仍靠人补 | 规则固定,工具按需读取真实文件 |
| 标准一致性 | 每次提示词不同,结论波动大 | 审查顺序和输出格式统一 | 规则统一,证据来源也统一 |
| 可追溯性 | 结论难对应到文件和命令输出 | 能要求文件与行号,但证据可能缺失 | 可引用 diff、测试和工具结果 |
| 重复执行 | 每次重新组织上下文 | 可复用规则,仍需手动补上下文 | 模板加工具调用,适合反复执行 |
| 维护成本 | 低,但结果不稳定 | 中等,需要维护规则文件 | 较高,需要维护规则、工具和权限 |
| 适用场景 | 临时问答、小改动 | 团队统一审查标准 | 固定流程、多人协作、需要证据链 |
从对比可以看出,Rules 解决的是标准化,MCP 解决的是上下文获取。只写 Rules 不接工具,模型仍然可能缺少证据;只接 MCP 不写规则,工具输出会变成新的信息噪音。两者一起用,才适合重复审查。
常见坑与修正
规则写得太长
一个规则文件塞进安全、性能、测试、风格所有内容,模型会抓不住重点。修正方法是按场景拆分,每个文件只保留可执行动作,把背景说明放到单独的文档里。
规则与命令不一致
规则要求运行测试,但项目实际使用另一套命令,审查就会空转。修正方法是把命令写成判断流程,例如先读取项目脚本,再选择对应命令;示例命令只作为参考。
MCP 权限过大
为了省事把整个主目录暴露给文件系统工具,会带来不必要的风险。修正方法是只暴露仓库目录,优先只读,敏感数据不进上下文。
把工具输出当结论
MCP 返回的是证据,不是判断。测试通过不代表没有回归,扫描无告警也不代表没有逻辑问题。修正方法是在规则里要求区分『证据』『推断』『待验证』,并保留人工复核。
报告不可执行
只写『建议优化错误处理』没有价值。修正方法是要求每条问题包含文件、行号、触发条件、影响范围和最小修复建议。无法定位到文件的问题放入待验证,不进入阻断项。
落地检查清单与可执行建议
可以用下面的清单检查流程是否真的跑起来:
- 仓库里是否有独立的
.cursor/rules/review.mdc,并且规则文件经过团队 review。 - 规则是否写清审查顺序、输出格式、严重级别和禁止事项。
- MCP 是否只读、范围是否最小、密钥是否外置。
- 审查模板是否要求列出变更文件、引用命令输出、标记待验证项。
- 报告是否能对应到文件与行号,阻断项是否有明确修复建议。
- 团队是否约定人工复核责任人和合并前的最低检查项。
今天就能做的动作是:先在仓库里创建一份最小规则文件,只保留审查顺序和输出格式;然后用文件系统 MCP 读取一个真实变更文件,跑一次完整审查;最后把报告里反复出现的三个问题补进规则,而不是继续增加提示词。连续执行几次后,再决定是否接入 Git、issue 或静态扫描工具。这样加码最稳,也最容易看出哪一步真正减少了重复劳动。