Aider 陷阱合集
Aider 的坑和 IDE 类工具很不一样——Git 自动提交、
/add /drop手动管理、多模型切换,每一个机制都能咬你一口。7 个真实坑。踩过新坑?提 Issue 或 PR。
陷阱 1:自动 commit 吃进了你的工作树变更
症状
- 你在项目里改了几个文件还没 commit
- 让 Aider 改一个别的文件
- 它生成代码后自动 commit,把你未 stage 的变更也一起打包提交
根因
Aider 默认开启 auto-commits: true。它 commit 的范围是整个工作树 diff,不区分"我改的"和"用户改的"。Aider 觉得"改完就提交"是好事,不知道你有别的工作正在进行。
出坑
git reset HEAD~1 # 取消最后一次 commit,文件回到工作树
git status # 核对哪些是你的、哪些是 Aider 的
# 手动 commit 该 commit 的,丢弃该丢的
预防 三选一:
- 开会话前先
git stash:把你未完成的工作藏起来,Aider 的 commit 才干净 - 关闭自动 commit:
aider --no-auto-commits,或在.aider.conf.yml里auto-commits: false - 开独立 feature 分支:
git checkout -b feature/xxx再开 Aider,弄脏也只是脏分支
陷阱 2:/add 漏文件,AI 靠脑补填空
症状
- 让 Aider 改
ServiceA,它顺利改完 - 但 ServiceA 依赖的
UtilB里的函数签名其实已经变了,Aider 不知道,生成的代码调用了根本不存在的签名 - 跑起来
TypeError
根因
Aider 只把 /add 过的文件真正读进上下文。Map 模式会索引项目结构(名字+位置),但不读内容。依赖文件没 /add,AI 只能基于文件名猜。
出坑
/add src/utils/UtilB.ts
# 把依赖也加进来,让它重新看一遍
重新看一下 ServiceA 依赖的 UtilB,确认你用的签名是对的
预防 改之前先让 Aider 自己列出依赖:
/ask
我要改 ServiceA。列出它直接依赖的所有文件,
以及它的公开接口被哪些文件调用。
给我 /add 的命令,我一次性加齐。
然后把它列的都 /add 进来再开始 /code。
陷阱 3:切了模型,行为突然变了
症状
- 原来用 Claude,习惯了它的严谨风格
- 为了省钱切到 DeepSeek,同一个提示词产出质量断崖下跌
- 复杂重构开始出奇怪的 bug,Architect 模式给的方案也变得粗糙
根因
不同 LLM 的"指令理解能力"差异很大。同样一句 /architect 设计 WebSocket 通知系统:
- Claude Sonnet:会追问需求、考虑异常路径
- DeepSeek:直接给一个方案,细节覆盖不全
- 本地 7B 模型:给一个结构对但细节漏洞很多的方案
出坑
- 复杂任务发现模型跟不上:切回 Claude 做这一步,做完再切回便宜模型
- 配
--weak-model分工:主推理用强模型,commit message/简单任务用弱模型
预防
配置分层(.aider.conf.yml):
model: claude-sonnet-4-5 # 主模型
weak-model: deepseek/deepseek-chat # 弱任务(commit message、简单补全)
editor-model: claude-haiku-4-5 # 编辑器补全
或按任务类型切:
| 任务 | 建议模型 |
|---|---|
/architect 方案设计 | Claude Sonnet/Opus |
/code 实现已有方案 | DeepSeek 够用 |
/ask 问答/解释 | 任意 |
| 大型重构 | Claude Opus |
陷阱 4:Lint/Test 自动循环,账单爆炸
症状
- 配了
auto-lint: true和auto-test: true - Aider 改完跑 lint 失败,它自己修,又失败,又修……循环几轮
- 一次对话下来 token 消耗是预期的 5 倍
根因 Aider 的 auto-lint/test 是 "失败就让 LLM 再改一次"。如果问题根本不是代码能修好的(比如环境配置、依赖版本),它会永远修不好,一直重试直到达到默认上限。每次重试都烧 token。
出坑
/undo # 回滚本轮修改
/lint-cmd none # 临时关掉 auto-lint
# 手动修根本问题(环境、配置),再打开 auto-lint
预防
- 限制重试次数(
aider --max-reflections 3) - lint 命令用
--fix模式让 linter 先尝试自动修复,而不是报错扔给 AI:
lint-cmd: "eslint --fix" # 不是 "eslint"
- 测试命令跑 fail-fast:
test-cmd: "pytest -x --maxfail=1"
陷阱 5:Map 模式过期,引用了已删除的文件
症状
- 项目结构变了(删了目录、重命名了模块)
- Aider 还"记得"旧结构,生成 import 路径引用不存在的模块
- 或者
/ls列出的文件和磁盘对不上
根因 Map 模式的索引在会话开始时生成,会话中如果 git 层面大变(切分支、rebase、大规模删除),Map 不自动刷新。
出坑 退出 Aider 重进,Map 会重建。 或者在会话里:
/reset # 清空会话上下文
/map-refresh # 重新扫描项目结构(取决于版本是否支持)
预防
- 切分支后重启 Aider(别在同一会话里跨分支操作)
- 大规模文件变更后也重启
- 长会话定期
/reset刷新状态
陷阱 6:Architect 方案漂亮,Code 执行跑偏
症状
/architect给出一个清晰的方案,你很满意- 切回
/code让它实现,头一两个文件还对,越往后越偏 - 最后成品和 Architect 方案几乎不一样
根因 Aider 的 Architect 和 Code 模式共享会话上下文,但 Architect 阶段的设计很长,随着 Code 阶段不断改代码,早期的 Architect 方案被上下文压缩逐步丢失。
出坑
# 每实现一步后,复核一次方案
/ask 对照 Architect 阶段的方案,当前实现偏离了哪些点?
预防
- Architect 方案生成后立刻写进文件:
把这个方案写到 docs/arch.md,我们照这个文件实现 - 实现阶段明确引用文件:
/add docs/arch.md 按这里的方案实现下一步 - 复杂任务每个模块开独立会话:一个会话做一个子模块,避免长会话漂移
陷阱 7:/commit 后 --amend 失控
症状
- 你让 Aider 改一下刚才的某个文件(已经自动 commit 了)
- 它做完又 commit 了一次
- 你想"合并到刚才的 commit",让它
--amend - 结果 amend 把你之前 stash 的内容吃进来了,或者把 Aider 的两次改动合进去,历史反而更乱
根因 Aider 的 commit 时机是"改完就提交",不是"原子化每个逻辑改动"。你手动 amend 会混入所有当前 staged 内容。同时 Aider 本身不支持精细的 commit 粒度控制。
出坑
git reflog # 找回 amend 前的状态
git reset --hard HEAD@{N} # 回滚
# 用 interactive rebase 重新整理
git rebase -i HEAD~5
预防
- Aider 会话结束后统一 squash:
git reset --soft HEAD~N # N = Aider 的 commit 数 git commit -m "feat: add notifications" - 别在 Aider 会话进行中用
--amend - 关键 checkpoint 自己打 tag:
git tag wip-before-aider,出事能回
贡献新陷阱
模板见 claude-code.md 结尾。
相关方法论
- Aider 完整指南
- common/task-decomposition.md — 任务拆解(Aider 尤其依赖)
- common/debugging.md — 系统化调试