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,必须拆。