Cursor 的 diff 太大没法 review

Composer 一次给你 30 文件 / 2000 行 diff,怎么 review 都不放心——拆 PR 是唯一正确动作。

Composer 一次 turn 给你 30 个文件 / 2000 行 diff,apply 预览里红绿一片,滚到底也看不清哪些是核心改动、哪些是”路过顺手”清理。测试都过了你还是不放心——因为没有谁能负责任地 review 2000 行 AI 改动。这不是模型错,而是你给的 prompt 太宽 + 默认让 Composer 一次包圆。

止血方式不是更努力 review,而是 reject 后让它拆。

常见原因

1. 任务粒度太大,本该多次 Composer

“重构 auth 系统” 这种 prompt 必然出大 diff。模型尽力执行,把鉴权、session、API 中间件、tests、错误处理全改了。

如何判断:你的 prompt 里有不有 “system”、“module”、“everything”、“全部” 这种词。

2. Composer 把功能改动 + 顺手清理混了

模型实现新功能时,路过看到”这命名好丑”、“这函数好长”,顺手重构了。你 review 的时候很难区分哪些是必要、哪些是它的审美。

如何判断:diff 里既有新功能代码,又有 rename / extract function / reformat 这类改动。

3. Agent mode 多步连环、跨文件传播

Agent 一边改一边发现需要改另一处,连环 5 个 tool call 后改的文件数翻了 3 倍。

如何判断:Composer 这条消息展开后看到一长串 read_file / edit_file 链。

4. 用了重写型大模型在简单任务上

opus / gpt-5 在 agent 模式下倾向”大刀阔斧”。任务本身只需 patch 100 行,结果给了 800 行重写。

如何判断:模型给你”我把它重写得更现代了”的措辞 = 危险信号。

5. 没在 .cursorrules 里限制 diff 大小

模型默认没有 diff size 上限。如果你不说”keep PR ≤ 200 lines”,它就照训练时学到的”完整方案”输出。

如何判断cat .cursorrules 找 “max diff” / “minimum” 字样。

6. 让模型一次完成”完美方案”

如果 prompt 是”按业界最佳实践重构这个模块”,模型会把它理解为”输出一个完整的、符合最佳实践的版本”——也就是大 diff。

如何判断:prompt 里有 “best practice”、“clean architecture”、“完美” 字样。

动手前先确认

  • 确认问题是在 Composer / Cmd+K / chat 哪个入口;Cmd+K 一般不会出大 diff。
  • 立刻不要 apply。先 git diff > /tmp/big-diff.patch 留证据。
  • 记下 Cursor 版本、当前模型、是否 agent 模式 + Max mode。

需要收集的信息

  • 触发 diff 的完整 prompt。
  • git diff --stat 输出。
  • Composer 这条消息的 tool call 链截图(看是 1 次还是 N 次连环)。
  • 当前模型 + 模式 + 是否 Max mode。
  • 仓库 .cursorrules(看有没有 diff 限制条款)。

最短修复路径

按”先拆 → 后改协作”顺序。

Step 1:Reject,不要 apply

Composer 这条消息右上角点 “Reject”。不要被 “可惜” 心理推动 apply——大 diff 一旦 apply,cleanup 成本远高于 reject 重做。

Step 2:让 Composer 自己拆方案

新发 prompt:

The previous proposal is too large to review. Do NOT change code yet.
Instead:
1. Split it into 3-5 smaller PRs.
2. For each PR, list:
   - title (one line)
   - files touched
   - estimated diff size (lines)
   - what it accomplishes
   - dependencies on other PRs in this list
3. Order them so the riskiest is last.

得到 5 条小 PR 清单后挨个评估。

Step 3:单独执行每个小 PR

Now implement PR #1 only. Stay within the listed files. Do not start PR #2.

apply → run tests → commit → 切下一条。每条都是独立可 revert 的。

Step 4:清理 vs 行为变更分开

如果某条 PR 既改逻辑又 reformat,让模型再拆:

Split PR #2 again: one PR for "rename foo to bar" (mechanical), one PR for "add retry logic" (behavioral).
Apply the mechanical one first; review separately.

Step 5:在 .cursorrules 加 diff 上限规则

# .cursorrules
- Default to small, reviewable diffs (≤ 200 lines per response).
- When a task seems to require a larger change, STOP and propose a split plan instead.
- Never combine refactor / rename with behavioral changes in one diff.
- Always show diff size estimate before generating code.

Step 6:如果真的必须 apply 大 diff

无法拆的场景(例如生成器跑出来的):apply 前 commit 一次干净基线,apply 后立即 commit,附 message feat: bulk codegen output — DO NOT review line-by-line。这样至少 revert 是单条 git commit。

怎么确认已经修好

  • 同一个 prompt 重跑一次,确认模型现在主动提议”拆分方案”而不是直接出 2000 行。
  • 让队友拿同样 prompt 试,验证规则在团队配置里生效。
  • 每条小 PR 都能独立通过 CI / review,能 revert 不影响其它。

如果还是没修好

  • 把 prompt 缩到一句话 + 单文件 + 单功能。
  • 回滚最近一次 .cursorrules 改动确认规则是否真生效。
  • 在 forum.cursor.com 搜 “composer split PR”;附 prompt + 模型 + diff 大小。
  • 抓 View → Output → Cursor 日志贴 Bug Reports。

预防建议

  • prompt 模板里固定加:“Output diff size estimate first; if > 200 lines, propose split before coding.”
  • 默认用 Edit 模式或 Cmd+K,agent 模式只在确实需要 multi-step 时手动开。
  • 每个 Composer 任务一条 feature branch + commit 每个小步骤,方便回溯。
  • 已知大重构用 Claude Code 这种 CLI agent 跑,按文件显式 scope。
  • 团队 PR 规则:AI 生成的 diff > 300 行不接受 review,必须拆。

相关阅读

标签: #排查 #Cursor #排查 #大 diff