你给 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 Checkpoint | Cursor 在每次 Agent 重要改动前都会快照,一键全部回滚 |
| 中间你还手动改了文件 | git checkout / source control 面板 | checkpoint 只追踪 Agent 的改动,不记你手动改的 |
| 改动跨多个 Agent 回合 + 你手动改的 | git diff 后选择性 git checkout | git 看得到全部;checkpoint 抓不到手动改动 |
| 开始前从没 commit | 先 git 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_file → grep → edit_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,模型看了通常会跳过。