Cursor Composer 大刀阔斧改错

Composer 一次改 10+ 文件、把能跑的代码改坏。先用 Cursor checkpoint 或 git 快速回滚,再收紧 prompt 和模式让它保持外科级。

你给 Composer 写了”清理一下这段”或”统一下风格”,回头一看 git status 显示 14 个文件变更、500+ 行改动、连命名约定都改了,能跑的测试现在挂三个。问题不在模型”贪心”。Composer 在 Agent 模式下会把任何模糊指令当成”我可以做我认为对的事”,跨整个仓库读文件,把它认为相关的全改了。

最快的修法:先回滚,后排查。 如果这次乱改来自 Agent 模式,在聊天时间线里点出问题那一步之前那条消息上的 Restore Checkpoint 按钮。如果中间还混了你手动改的内容、或者改动早于 checkpoint,就改用 git checkout HEAD -- .。然后换成 Manual 模式或 Cmd+K、用一个有边界的 prompt 重发,别再用 Agent。

先回滚:checkpoint 还是 git

截至 2026 年 6 月(Cursor 3.5 / Composer 2.5),你有两条 undo 路径,按”这些改动是谁做的”来选。

情况用哪个为什么
所有乱改都来自同一个 Agent 回合聊天时间线里 Restore CheckpointCursor 在每次 Agent 重要改动前都会快照,一键全部回滚
中间你还手动改了文件git checkout / source control 面板checkpoint 只追踪 Agent 的改动,不记你手动改的
改动跨多个 Agent 回合 + 你手动改的git diff 后选择性 git checkoutgit 看得到全部;checkpoint 抓不到手动改动
开始前从没 commitgit diff > patch,再回滚丢弃前先留证据

checkpoint 存在本地、和 git 历史分开,回滚一个 checkpoint 不会动你的 commit。它是编辑器里一个快速的”糟了”按钮,不是版本控制,重要的东西还是要 commit 进 git。详见 Cursor checkpoints 文档

常见原因

1. Prompt 用了动词模糊词

“clean up”、“refactor”、“improve”、“polish”、“modernize” 这类词没有上限。模型把它们读成”做你认为应该做的全部”,于是改命名、抽函数、重排参数、加注释一起来。

如何判断:把 prompt 第一句的动词拎出来。“clean up” 是 unbounded,“rename foo to bar in login.ts” 不是。

2. Agent 模式默认有写多文件 + 跑命令的权限

Composer 在 Agent 模式下可以 read_filegrepedit_file 跨整个仓库迭代,还能跑终端命令。你只问了一件事,它”顺便”修了它认为相关的另外 8 件。

如何判断:聊天输入框底部的模式标签是不是 Agent;Agent 模式下一次回复会列出十几个 tool call。

3. 没列”不要碰”的清单

模型不知道哪些文件神圣。migrations/generated/vendor/schema.prisma、第三方 SDK 包装层这些都是高危区,你不说它就改。在仓库根放一个 .cursorignore 可以把这些路径完全排除出上下文。

如何判断:跑 git diff --stat,看是否有改动落在”我从来没让你碰过这”的目录。

4. 没 commit 就连发多 prompt

一句 prompt → 它改了 → 不满意 → 再来一句 → 又改。3 轮后 diff 已经混在一起,最后 revert 起来分不清哪改哪没改。checkpoint 这里也能帮忙,但只限 Agent 回合。

如何判断git log --oneline 看上一次 commit 是不是今早或几天前。

5. 模型选错(小任务用了重写型模型)

在 Agent 模式下,重推理模型倾向”大刀阔斧”重构,快模型倾向保守 patch。截至 2026 年 6 月,Cursor 选择器里有 Claude Opus 4.7、Sonnet 4.6、GPT-5.5、Gemini 3.1 Pro,以及 Cursor 自家的 Composer 2.5,还有 Auto。一行字的外科级修改用顶级推理模型(比如 Opus 4.7)反而容易误伤;Sonnet 4.6 或 Composer 2.5 通常 patch 得更紧。

如何判断:看输入框旁边模型选择器里的名字。一行小任务配顶级推理模型就是 mismatch。

6. 规则没说”小改动优先”

没有项目规则时,模型按训练时学到的”好工程师风格”行动——其中就包括”看到丑代码就重构”。你必须显式写 “don’t refactor unless asked”。

如何判断:看仓库里有没有 .cursor/rules/*.mdc(当前格式)或根目录的旧版 .cursorrules。没有 “minimal edits” / “don’t refactor” 类条款就要补。

动手前先确认

  • 确认问题出在哪个入口:Composer / Cmd+K / chat。Cmd+K 限定在选区局部,Composer 是仓库级,杀伤范围差很大。
  • 出问题立刻别再发 prompt。如果是 Agent 回合,checkpoint 是你最快的 undo;否则先 git diff > /tmp/diff.patch 留证据,再决定要不要 revert。
  • 记下 Cursor 版本(Help → About)、当前模型和模式。同一 prompt 换模型或换模式,行为可能完全不同。

需要收集的信息

  • 触发 misedit 的 prompt 全文。
  • git diff --stat 输出,列出哪些文件改了多少行。
  • 当前模型 + 模式(Agent / Ask / Manual)+ 是否开了 Max mode。
  • 是否有 .cursor/rules/.cursorrules,以及是否有 .cursorignore

最短修复路径

按”先止血再修方法论”顺序。

Step 1:回滚 + 留证据

如果乱改是单个 Agent 回合,直接在聊天时间线里 Restore Checkpoint。否则:

git diff > /tmp/composer-misedit.patch   # 留个 patch 备查
git stash                                # 临时收起,不丢
# 或直接 revert:
git checkout HEAD -- .                   # 丢掉所有未 commit 改动

Step 2:分类筛留——只保留你要的

如果只是 5/14 文件想留:

git stash pop                            # 取回 patch
# 在 Cursor 的 source control 面板逐文件 discard,
# 或命令行:
git checkout HEAD -- path/to/unwanted-file

也可以用 git add -p 交互式只 stage 想要的 hunk。

Step 3:重写 prompt,加 explicit scope

把 unbounded 词换成 surgical 词,并写明禁止的动作:

原:refactor the auth module
改:In src/auth/login.ts only:
    1. Replace the magic string "DEFAULT_TIMEOUT" with the constant from config.
    2. Do NOT change function signatures.
    3. Do NOT touch any other file.
    4. Do NOT add or remove comments.
    Output a unified diff, at most 30 lines.

Step 4:切到 Manual 模式或 Cmd+K

在聊天输入框用 Cmd+.(macOS)/ Ctrl+.(Windows/Linux),或 Shift+Tab,在 Agent / Ask / Manual 之间切换。选 Manual:它只改你 @ 的文件,不会自主跨仓库迭代。(Ask 是只读的,只想要分析时用它。)

要锁到最紧的范围就用 Cmd+K:先选中要改的代码块再触发,权限缩到选区内。

Step 5:在项目规则里写死”保守原则”

优先用当前格式:建一个 .cursor/rules/minimal-diff.mdc,设 alwaysApply: true,让它注入每一次会话。(根目录单文件 .cursorrules 仍可用,但 2026 年起已 deprecated;也可以用 AGENTS.md。)

---
description: Keep edits minimal and scoped
alwaysApply: true
---
- Make the minimum change required to satisfy the prompt.
- Do NOT refactor, rename, or reformat code that is not explicitly mentioned.
- Do NOT touch files in: migrations/, generated/, vendor/, schema.prisma.
- If the task seems to require changes outside the listed files, STOP and ask first.
- Preserve existing comments and import order unless asked to change them.

确认规则已生效:打开聊天输入框,规则应出现在上下文 / rules 指示里。没有 frontmatter、或 alwaysApply: false 的规则会被静默跳过,除非有 glob 命中或模型主动选用。

Step 6:危险任务前 commit

养成 Composer 大任务前 git commit -m "wip: before composer" 的习惯。失败 revert 成本秒级,而且你有一个 checkpoint 单独保证不了的干净基线。

怎么确认已经修好

  • 在 Manual 模式下用同一请求重跑,确认 git diff --stat 只列出你 @ 过的文件。
  • 让队友打开同一 workspace 用同样 prompt 重跑。如果是规则在起作用,diff 应该一致。
  • 跑测试 + lint,确认没引入风格 / 行为漂移。

如果还是没修好

  • 把 prompt 缩到极小:单一动词 + 单一文件 + 单一目标行。
  • 确认规则确实加载了。Cursor 3.x 有个已知坑:alwaysApply: true 的规则可能被当成 “requestable” 而没自动注入;看聊天里的 rules 指示,并回滚最近一次 .mdc 改动,逐项确认是哪条没起作用。
  • forum.cursor.com 搜 “composer over-edits”,附 Cursor 版本 + 模型 + prompt + diff。
  • 抓 View → Output → “Cursor” 日志,贴到论坛 Bug Reports。

常见问题

不用 git 能 undo Composer 的改动吗?

能,前提是改动来自 Agent 模式。在聊天时间线里点出问题那步之前那条消息上的 Restore Checkpoint。checkpoint 在每次 Agent 重要改动前快照文件,但不记你手动敲的改动,所以混合改动还是得用 git。

Agent、Ask、Manual 模式有什么区别?

Agent 是自主的:读仓库、改多文件、跑命令。Manual 只改你 @ 的文件、不跨文件迭代。Ask 是只读(只分析、不改)。用 Cmd+. / Ctrl+.Shift+Tab 切换。

哪个模型最不容易过度改?

截至 2026 年 6 月,一行字、单文件的外科级改动,Sonnet 4.6 或 Cursor 自家的 Composer 2.5 通常 patch 得最紧。Opus 4.7 这类顶级推理模型更适合真正的大型多文件工作,但在小任务上倾向大刀阔斧重写。

我的 .cursorrules 不生效,为什么?

两个常见原因。一是这个文件已被 .cursor/rules/*.mdc 取代(deprecated),迁移过去即可。二是 .mdc 规则只有带 frontmatter 且 alwaysApply: true(或有匹配的 globs)时才自动应用;纯 .md 文件或 alwaysApply: false 会被当成按需触发、静默跳过。

怎么不让它碰生成文件或 vendored 文件?

把这些路径加进仓库根的 .cursorignore,让它们完全不进上下文;同时在 alwaysApply 规则里再写一条 “do NOT touch” 清单做双保险。

预防建议

  • 每次开 Composer 前先 commit,给自己一个干净基线,也给 checkpoint 一个明确的底。
  • prompt 模板里加 “Constraints” 段:allowed files / forbidden files / max diff lines。
  • 默认用 Manual 模式或 Cmd+K,只在确定要 multi-step 时手动切 Agent。
  • 写死一个 .cursor/rules/*.mdc “minimum diff” 规则,加一份 .cursorignore 神圣路径清单。
  • 给重要文件加显眼注释:// DO NOT MODIFY without ticket #1234,模型看了通常会跳过。

相关阅读

标签: #排查 #Cursor #排查 #误改