用 Cursor Rules 与 MCP 自动化重复代码审查:一份可照做的实操教程

👁 52 次阅读

配图
配图

为什么重复代码审查需要 Rules 与 MCP

重复代码审查的成本通常不在第一次审查,而在每次都要重新解释同一套标准。今天提醒检查空指针,明天提醒补测试,后天又有人忘记权限校验。看似是人的问题,本质是流程没有被写进工具。Cursor 的 Rules 解决『判断标准不稳定』,MCP 解决『模型看不到本地与外部系统证据』。两者组合后,代码审查才可能从一次性对话变成可重复执行的流程。
很多团队已经用 Cursor 做补全和问答,但审查仍停留在复制 diff、粘贴到聊天框、人工整理结论的阶段。这样做的问题有三点:输入不完整、标准不一致、结论不可追溯。Rules 把标准固定下来,MCP 把文件、命令输出和外部系统状态带进上下文,二者配合才能减少重复沟通。
本文不追求一次性搭建复杂平台,而是给出一条能逐渐加码的路径:先写最小规则,再接入只读 MCP,最后用固定提示词和检查清单把流程跑顺。每一步都可以单独验证,避免一上来就堆配置。

先明确边界:Rules 管判断标准,MCP 管外部证据

Rules 是写进项目里的审查契约,适合放必须遵守的检查顺序、输出格式、严重级别、禁止事项和团队约定。它不应该承担读取实时数据的工作,也不应该把每个业务的细节都塞进去。MCP 是模型调用外部工具和数据的通道,适合读取变更文件、测试输出、issue 状态、日志、数据库结构和静态扫描结果。把两者混在一起,规则会变得又长又难维护。
一个简单判断法是:如果一句话在每次审查中都不变,就写进 Rules;如果一句话需要看当前仓库、当前分支或当前环境,就交给 MCP 或命令。比如『每条问题必须给出文件与证据』属于 Rules;『读取本次 diff 涉及的文件』属于 MCP 或命令。这样分工后,规则可以版本化,工具可以替换,审查流程不会绑死在某个模型版本上。
还要注意权限边界。MCP 工具能读多少目录、能不能写文件、能不能访问生产数据,必须提前限制。代码审查优先使用只读能力,密钥通过环境变量或本机密钥管理传递,不要写进仓库。规则里明确写出『无法确认的内容标记为待验证』,可以降低模型把猜测当结论的风险。

准备工作:把审查流程拆成五个阶段

在写配置前,先把重复审查拆成可观察的阶段。阶段越清楚,Rules 和 MCP 越容易各司其职。

  1. 变更发现:确定本次审查范围,列出改动文件与 diff 统计。
  2. 规则检查:按统一标准检查类型、边界、错误处理、权限、测试与可维护性。
  3. 工具取证:运行 lint、测试、类型检查,读取相关文件和调用方。
  4. 汇总报告:按阻断、重要、建议三档输出,每条包含文件、证据、影响与修复建议。
  5. 人工复核:确认高风险结论,处理待验证项,决定是否合并。

这五个阶段里,第一和第三阶段最适合自动化,第二阶段适合 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 或静态扫描工具。这样加码最稳,也最容易看出哪一步真正减少了重复劳动。

订阅 AI 百事知

每周精选 AI 工具评测、行业资讯与使用教程,第一时间送达。

🔗 相关阅读(你可能还想看)

📄 Perplexity Pro 学生免费一年怎么领:验证流程、失败排查与免费版区别全解
📄 AI效率工具提升办公效率的实战方法
📄 Notion AI 数据库自动化实战教程:从零搭建智能工作流到自动化闭环
📄 2026年AI生成PPT工具实战教程:从选型到精修的完整工作流指南
📄 ChatGPT Projects 实战教程:从零建立持续工作流,告别重复上传与提示词
📄 Notion AI 完整使用教程:从零开始掌握 AI 写作、数据库自动化与团队知识库构建(2026 最新版)
📄 NotebookLM 使用教程:从入门到精通的完整指南(2026年最新版)
📄 ChatGPT Slides 实战教程:6 步把一次对话变成团队可协作的演示稿,导出 PPTX 前先验这三样(2026 官方指南)
OpenAI 10 月中旬上线的 ChatGPT Slides,把演示稿从单人文件搬进 Space:从对话、文件、大纲或
📄 用 AI 做竞品调研:从抓取到对比表的完整流程
从调研问题、合规抓取、字段设计到 AI 抽取与人工校验,给出可照做的竞品对比表流程,并附清洗、补全和行动建议。
🤖 想直接和 AI 对话?
免费体验 DeepSeek V4 等顶级模型,无需注册,随问随答
🎯 立即体验 AI 工具

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

🤖 嘟嘟客服
滚动至顶部
🤖 嘟嘟客服
🤖 嘟嘟客服
';i.value='';m.innerHTML+='
...
';fetch('/dify-chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({query:q,user:'w'+Date.now()})}).then(function(r){return r.json()}).then(function(d){var a=d.answer||'暂时无法回复';m.removeChild(m.lastChild);m.innerHTML+='
'+a+'
'}).catch(function(){m.removeChild(m.lastChild);m.innerHTML+='
网络异常
'})">发送