← 返回总览

Aider 🔬 DEEP

💻 Coding Agents Python ⭐ 30k+ | GitHub → | 深度分析于 2026-05-17 18:59
Strategy-PatternSEARCH/REPLACEArchitectCoderRepoMapTree-sitterCache-WarmingChatChunksGit-FirstReflection-Loop15-Edit-Formats

🏗️ 核心架构

Aider 采用 Strategy Pattern(策略模式) 作为核心架构:Coder 基类(base_coder.py,2485 行)定义了完整的对话循环、文件追踪和 Git 集成,而 15+ 个编辑格式子类各自实现不同的代码编辑策略。

Coder 子类继承体系

Coder (base) — main_system: "Act as an expert software developer..."
├── EditBlockCoder — SEARCH/REPLACE block 格式(最流行)
├── EditBlockFencedCoder — fenced SEARCH/REPLACE
├── EditBlockFuncCoder — function-calling 变体
├── WholeFileCoder — 整文件替换
├── WholeFileFuncCoder — 整文件 function-calling 变体
├── SingleWholeFileFuncCoder — 单文件 func 变体
├── UnifiedDiffCoder — unified diff 格式
├── PatchCoder — git patch 格式
├── ArchitectCoder — 2 阶段:架构师 → 编辑器
├── AskCoder — 仅问答,不编辑
├── HelpCoder — 仅帮助显示
├── ContextCoder — 上下文管理
├── EditorEditblockCoder — editor 子编码器(editblock)
├── EditorWholeCoder — editor 子编码器(whole file)
└── EditorDiffFencedCoder — editor 子编码器(diff fenced)

这种设计允许 Aider 适配不同 LLM 的输出特性:强模型用 SEARCH/REPLACE 精准编辑,弱模型用 whole-file 整体替换,中间模型用 diff 格式。

🏛️ ArchitectCoder — 两阶段流水线(核心创新)

ArchitectCoder 是 Aider 最具创新性的架构模式:将「思考变更」与「应用变更」分离——这是所有编码 Agent 未来都会采用的方向。

两阶段工作流

🧠 Stage 1: Architect(架构师)

使用主模型(如 Claude)分析代码,用自然语言描述需要的变更

输出:变更描述文本

✏️ Stage 2: Editor(编辑器)

使用(可能不同的)editor_model,以更简单的编辑格式应用变更

输出:SEARCH/REPLACE 块

源码实现

class ArchitectCoder(AskCoder): edit_format = "architect" def reply_completed(self): content = self.partial_response_content # architect 的变更描述 editor_model = self.main_model.editor_model or self.main_model editor_coder = Coder.create( main_model=editor_model, edit_format=self.main_model.editor_edit_format, from_coder=self, ... ) editor_coder.run(with_message=content, preproc=False)

这种分离让强模型负责推理经济模型负责应用,兼顾质量与成本。也使得变更的「意图」和「实现」解耦,更容易审查和调试。

📝 提示词工程(源码级分析)

System Prompt 结构

EditBlockPrompts.main_system 的核心指令:

Act as an expert software developer. Always use best practices when coding. Respect and use existing conventions, libraries, etc. {final_reminders} Take requests for changes to the supplied code. ... Describe each change with a *SEARCH/REPLACE block* per the examples below.

System Reminder(编辑格式详细规则)

system_reminder 是一个 30+ 行的 SEARCH/REPLACE 块完整规范:

Few-Shot 示例

editblock_prompts.py 包含两个详细示例:

  1. "将 get_factorial() 改为使用 math.factorial" — 展示一个逻辑变更拆分为 3 个 SEARCH/REPLACE 块
  2. "将 hello() 重构到独立文件" — 展示跨文件编辑

动态提示词组件

  • {fence} — 自动检测围栏风格(三/四反引号,基于模型适配)
  • {final_reminders} — lazy_prompt 或 overeager_prompt,基于模型行为调整
  • {shell_cmd_prompt} / {shell_cmd_reminder} — 可选的 shell 命令支持
  • {language} — 检测用户语言
  • {quad_backtick_reminder} — 针对需要四反引号的模型的警告

🧩 ChatChunks — 上下文工程架构

消息被拆分为有序的 ChatChunks,用于缓存优化:

class ChatChunks: system: list # system prompt examples: list # few-shot 示例 done: list # 已完成的对话轮次 repo: list # repo map 上下文 readonly_files: list # 只读文件内容 chat_files: list # 可编辑文件内容 cur: list # 当前对话轮次 reminder: list # 格式提醒(仅 token 预算允许时注入)
关键设计reminder 块是策略性放置的——仅在上下文窗口有空间时注入。可以放在 system role 中,也可以追加到最后一个 user 消息末尾。这种设计确保核心指令不被截断,而辅助提醒在空间允许时提供额外指导。

🗺️ RepoMap — 上下文工程核心创新

RepoMap(867 行)是 Aider 对编码 Agent 领域最大的贡献——使用 tree-sitter 创建压缩但语义有意义的代码地图,适配 LLM 上下文窗口。

工作原理

1
Tree-sitter 解析:使用 tree-sitter 从所有仓库文件提取语义标签(类名、函数名、导入)
2
标签排序:基于当前对话中的提及和标识符交叉引用来排序标签
3
自适应大小:当没有文件在聊天中时,使用 map_mul_no_files=8x 倍的正常 token 预算提供更广阔的视图
4
SQLite 缓存:带缓存版本控制的标签缓存,确保增量更新高效
5
上下文窗口感知:根据剩余上下文窗口空间动态调整 repo map 大小

输出格式

repo_content_prefix + ranked_file_summaries # 每个摘要展示类/函数签名及行号 # 给 LLM 足够的上下文来决定请求哪些文件

🔥 Cache Warming — 缓存预热机制

Aider 实现了独特的 Cache Warming(缓存预热) 机制:

这解决了 Anthropic API 缓存 5 分钟 TTL 的问题——在用户思考期间,后台线程持续刷新缓存,下一次请求可以命中缓存,显著降低延迟和成本。

♻️ 主循环

Coder.run() → while True: → get_input() → 用户消息 → run_one(user_message) → preproc_user_input() → 检查命令、文件提及、URL → while message: → send_message(message) → format_messages() → ChatChunks 组装 → check_tokens() → 确保适配上下文窗口 → send() → litellm API 调用(含重试逻辑) → parse LLM response → 提取编辑 → apply edits → 写入文件 → auto_lint → 对变更文件运行 linter → auto_test → 若已配置则运行测试 → git commit → 自动提交变更 → reflected_message → 若 lint/test 失败,反馈给 LLM

Reflection Loop(反思循环)

应用编辑后,若 auto_lint=True(默认)且 linter 发现错误,Aider 将错误作为 reflected_message 反馈给 LLM。LLM 最多获得 max_reflections=3 次修复机会。

设计哲学:不是一次生成就期望完美,而是通过 Linter/Test 反馈形成闭环——LLM → 编辑 → 验证 → 反馈 → 修正,这与人类开发者 "编辑 → 编译 → 修错" 的工作流一致。

🧠 记忆系统

💬 Chat History

.aider.chat.history.md — 持久化对话历史

📋 ChatSummary

上下文过长时自动摘要压缩

🗺️ RepoMap

动态代码库上下文(见上文)

📂 文件追踪

abs_fnames / abs_read_only_fnames — 追踪聊天中的文件

🔄 Git Undo

每次变更自动提交,轻松回退

🧹 Context 清理

动态调整 repo map 大小适配窗口

⭐ 八大独特特性

1️⃣ 15 种编辑格式

大多数编码 Agent 只有 1-2 种,Aider 有 15+ 种策略适配不同模型能力

2️⃣ ArchitectCoder 2 阶段流水线

分离思考与应用——推理用强模型,编辑用经济模型

3️⃣ RepoMap

Tree-sitter 上下文工程,同类最佳——压缩但语义完整的代码地图

4️⃣ Cache Warming

后台线程保持 Anthropic prompt cache 存活,降低延迟与成本

5️⃣ ChatChunks

有序消息分块 + 策略性缓存断点,优化 API 缓存命中率

6️⃣ Reflection Loop

Auto-lint + auto-test → 将错误反馈给 LLM,最多 3 次修正机会

7️⃣ 默认不使用 Function Calling

使用结构化文本输出(SEARCH/REPLACE 块),而非 tool API

8️⃣ Git-First

每次变更自动提交,天然支持 undo 和 review

🔑 核心类

Coder EditBlockCoder ArchitectCoder WholeFileCoder UnifiedDiffCoder RepoMap ChatChunks CoderPrompts EditBlockPrompts ArchitectPrompts Commands ChatSummary Linter

📂 关键文件

💡 架构洞察

🔬 深度分析系统生成 · 基于 source code 阅读与架构还原 · 2026-05-17 18:59