你在 Cursor 里让 agent 改 Header.tsx,与此同时另一个 terminal 跑着 Claude Code 也在改同一个文件;或者你开了 Cursor Composer 的后台模式 + 主聊天同时跑;或者团队两个人各自启了 agent 改同一段代码。结果文件被互相覆盖、git status 里出现一堆既不是你也不是任何一个 agent 完整意图的”半成品”。Cursor、Claude Code、Aider 之间没有任何文件锁——它们各自基于读到的那一刻的内容写回,后写的覆盖先写的。这篇给出”立刻停手 → 找回两侧意图 → 手动合并 → 防再发”的固定流程。
常见原因
按出现频率从高到低排序。
1. 两个 agent 在同一 workspace 同时跑
最经典:Cursor 的 Chat / Composer + Claude Code CLI 跑在同一目录。两边都是”读 → 想 → 写”,没人通知对方。
如何判断:git status 显示某个文件既不是你刚改的、也不完全是任何一个 agent 输出过的;或者文件里出现两套不同风格的命名 / 注释混在一起。
2. Cursor 后台 agent + 前台 chat 同步运行
Cursor 的 Background Agent 自己跑任务时,你又在前台 chat 里改同一文件。Background 跑完时 disk 状态已变,它的 patch 基于旧版本,apply 出来就是错位 hunk。
如何判断:Cursor 提示 “patch could not be applied cleanly” 或 “file has been modified externally”。
3. 多人在同一仓库各跑各的 agent
两个开发者各自分支但都用 agent 改同一段代码,merge 时冲突看起来像两个”AI 风格”在打架。
如何判断:git merge 冲突标记里,两侧都不像人写的,且都”看似合理但实现路径完全不同”。
4. Watch 模式 / autopilot 触发的隐性写入
某些 agent(Cursor Auto Apply、Aider 的 --auto-commits)会在你没主动确认时就改盘。你正在改 Header.tsx,agent 后台也改了,IDE 提示”文件已被外部修改是否重载?”。
如何判断:IDE 出现”reload from disk”提示,而你没手动改过那个文件。
5. 不同模型的”风格冲突”
GPT 偏函数式、Claude 偏更分块的命令式,让两个 agent 改同一个模块时,重构方向可能南辕北辙。即使没硬冲突,merge 后代码也是”两套思路缝合体”。
如何判断:git log -p 看两个 commit,发现一边把 if/else 改成 switch,另一边把同一 switch 改回 ternary。
最短修复路径
Step 1:立刻停手
所有正在跑的 agent 全部停掉——退出 Cursor(或至少关闭 Composer / Background Agent)、终止 Claude Code CLI、杀掉任何 autopilot / watch 进程。继续编只会让 race condition 越叠越多。
# 找出所有可疑 agent 进程
ps aux | grep -E '(cursor|claude|aider|cline)' | grep -v grep
# 必要时杀掉
pkill -f "claude-code"
pkill -f "aider"
确认 disk 状态稳定 30 秒不变后再进行下一步。
Step 2:备份当前一切,再看 git 状态
防止接下来的合并操作再次丢东西:
git stash push -u -m "multi-agent-mess-$(date +%s)"
# 或者
git branch backup/conflict-snapshot-$(date +%s)
git stash pop # 恢复改动到工作树
然后看清谁动了什么:
git status
git diff
git log --all --oneline -10
Step 3:分别还原两个 agent 的”意图版本”
把两侧的改动各自独立成一份完整文件,方便对比:
# 假设 Cursor 改完已经 commit
git show <cursor-commit-sha>:src/Header.tsx > /tmp/cursor-version.tsx
# Claude Code 的改动还在工作区
cp src/Header.tsx /tmp/claude-version.tsx
# 都拿到原始版(agent 改动之前)
git show HEAD~2:src/Header.tsx > /tmp/original.tsx
用 IDE 的 3-way diff 同时打开 original.tsx、cursor-version.tsx、claude-version.tsx:
code --diff /tmp/cursor-version.tsx /tmp/claude-version.tsx
# 或
diff3 /tmp/cursor-version.tsx /tmp/original.tsx /tmp/claude-version.tsx
Step 4:选一个主版本,hunk-by-hunk 合并另一侧
选定主版本(通常是改动意图更明确、覆盖范围更大的那一侧)作为基础,然后逐 hunk 把另一侧的改动叠加上来:
# 把主版本写回工作树
cp /tmp/cursor-version.tsx src/Header.tsx
# 用 add -p 交互式选择 Claude 的 hunk
git diff --no-index src/Header.tsx /tmp/claude-version.tsx | less
# 手动复制有用的 hunk 到 src/Header.tsx
或者更直观,用 Cursor / VS Code 的 “Source Control” 面板,逐 hunk 点击 ”+” stage 你想要的部分,跳过冲突遗留物。两侧都改了同一行时,主版本说了算——不要试图融合,融合通常会引入两边都不曾测试过的新行为。
Step 5:用清晰的 commit message 收尾
git add src/Header.tsx
git commit -m "merge: resolve cursor+claude divergence on Header.tsx
- kept cursor's restructuring of nav menu
- ported claude's a11y label fixes (lines 42-58)
- discarded both agents' duplicate handleClick implementations
- next: single agent per overlap file"
明确写下”留了什么、丢了什么、为什么”,下次出问题能 git log 直接看明白。
Step 6:建立”重叠文件单一 agent”约定
未来同一文件只让一个 agent 动。最简单做法:
# 工具 A:你做主,前台 Cursor 改 src/components/
# 工具 B:Claude Code 跑后台任务,只动 scripts/、tests/、docs/
# 在 CLAUDE.md 写明
echo "Owned by Cursor: src/components/, src/pages/" >> CLAUDE.md
echo "Owned by Claude Code: scripts/, tests/, docs/" >> CLAUDE.md
或者在 .cursorignore 里临时屏蔽对方负责的目录,让 Cursor 看不到。
预防建议
- 同一 workspace 同一时间只跑一个编码 agent;多 agent 并行只在分目录或 git worktree 隔离时允许
- 用 git worktree 让两个 agent 各自有独立工作树:
git worktree add ../proj-claude feature-claude,互不影响 - 在 CLAUDE.md /
.cursorrules/ AGENTS.md 里写明”目录所有权”,比如src/api/由 Cursor 负责、scripts/由 Claude Code 负责 - agent 完成一个任务立刻 commit,再切下一个 agent;commit 是 agent 之间的交接信号
- 关掉容易引入隐性写入的功能:Cursor 的 Auto Apply、Aider 的
--auto-commits,改成手动确认 - 团队多人开发时,PR 描述里标注哪些文件用了哪个 agent,便于 review 和后续 merge 决策