aider 示例对话实录完全指南:用回放式实战看懂终端 AI 结对编程的编辑与提交流程
aider 是一个运行在终端里的 AI 结对编程工具。为了让你在真正动手之前,就能直观理解“和 aider 一起写代码到底是一种什么样的体验”,官方在 aider/website/examples/README.md 下维护了一套 示例对话实录(chat transcripts) 合集。这些实录记录了从新建 Flask 应用、探索开源 2048 仓库、跨多文件重构加调试,到写“黑盒”测试、落地 NO_COLOR 规范、下载并分析人口普查数据等一系列真实任务的全过程。读完本文,你将能够读懂每一份实录中的“人机对话语法”,掌握 aider 的自动编辑、自动 git 提交与“把文件加入会话”三大核心工作机制,并知道如何把实录中展示的工作流复制到自己的项目里。
示例合集是“看操作说明书”最好的方式
大多数 AI 编程工具的说明文档只会告诉你“输入提示词,就能得到代码”。而 aider 的示例合集用近乎逐字逐句的方式,把一次真实的终端会话完整回放出来,包括:
- 用户输入了什么自然语言指令;
- 大语言模型(LLM)如何把指令翻译成对源码的具体改动;
- aider 如何在 LLM 每次给出修改建议后自动把补丁应用到源文件;
- aider 如何基于改动内容生成一条描述性的 git 提交信息并完成提交;
- 当 LLM 想查看某个文件、但该文件尚未加入会话时,aider 如何征得用户同意后才将其加入。
换句话说,这套实录是理解 aider 设计哲学——“LLM 只看得见并改得了被‘加入会话’的文件,其他代码只能通过仓库地图间接感知”——最生动的教材。所有实录的源文件都保存在仓库的 aider/website/examples/ 目录下,每一份对应一个独立的 .md 文件。
按任务类型速览:合集里的十二场实战
README 中收录的实录覆盖了多种典型编码场景,下面对它们逐一展开,并说明每一场实录中最值得关注的看点。
从零开始搭建:Hello World Flask App 与 Pygame Pong
- hello-world-flask.md:从空文件起步,运行
aider app.py,aider 会自动创建空的app.py并“加入聊天”。随后用户分四步提出要求:先加一个返回 “Hello, World!” 的/hello端点,再加/add/3/5这种返回两数之和的路径参数路由,然后加/fibonacci/X返回第 X 个斐波那契数,最后删掉/hello端点。注意观察:每个修改建议都附带一段“编辑块”,aider 每轮都输出Applied edit to app.py,并提交如Commit 414c394 aider: Added a /hello endpoint…这样的记录——这就是最典型的“增量开发 + 自动提交”节奏。 - pong.md:同样从零开始,但玩法更复杂。LLM 先拆解出“安装 Pygame、初始化窗口、编写 Paddle/Ball 类、游戏循环、碰撞检测、计分显示”等步骤清单,再分步交付
pong_game.py;随后用户继续提出“自定义球拍大小与颜色、调整球速”等定制需求。它展示了 aider 如何承接一个多步骤、状态持续演进的任务。 - 最简起点 hello.md:只有一句“change hello to goodbye”,对应的编辑块仅有两行变更,是理解编辑块格式的最短范例。
探索并修改既有仓库:2048 游戏与 CSS 练习
- 2048-game.md:用户先
git clone了一个开源的 JavaScript 2048 游戏仓库,然后不加任何文件参数直接运行aider,先问“这个仓库是干什么的”“计分是怎么实现的”。当 LLM 需要查看js/game_manager.js等源文件时,会主动请求查看,aider 在征得用户同意后自动把该文件加入会话。这是理解“按需加文件”流程的典型场景。 - css-exercises.md:用户在 CSS 练习仓库中运行
aider,先用一句话问“这个仓库是什么”,再用/add命令把animation/03-dropdown-menu/README.md练习说明加入会话,最后让 aider 依据练习要求补全动画代码。它演示了/add命令与“只读练习说明即可编程”的用法。
复杂多文件改动与协作调试
- complex-change.md:这是 README 里标记为“相当复杂”的一场。用户想把
tests/test_main.py中的输入方式改为使用prompt_toolkit提供的 mock 工具,涉及多个源文件的协调改动。实录中有三个值得留意的细节:一是首轮改动并不正确,用户把报错信息和prompt_toolkit文档片段粘回聊天,双方“协作调试”;二是用户在会话外用编辑器改了文件,aider 侦测到这些带外改动后主动询问是否提交;三是用户在某轮回答不理想时按下^C中断 LLM,给出更明确的说明后重试。 - semantic-search-replace.md:任务是把
aider/coder.py中所有包含[red]的self.console.print()调用改成去掉颜色标记的self.io.tool_error()。文档特别强调,这不是简单的字符串替换:被改的调用点存在多种换行格式与语义差异,LLM 必须“理解语义再逐一改写”。这是验证模型是否具备“语义级重构”能力的好样本。
测试编写与仓库地图的力量
- add-test.md:整场实录最有教学价值。aider 没有获得被测函数及仓库其他代码的源码,仅靠基于 ctags 生成的“仓库高层地图”(见 ctags.md)就完成了这些推理:找到
cmd_add()的签名 → 判断它是Command类的方法所以要先实例化 → 推知构造Command需要InputOutput与Coder实例 → 拆解InputOutput的构造参数 → 认为Coder太复杂而采用MagicMock。由于cmd_add()没有类型注解,LLM 合理但错误地假设它接收一个list;用户用/run pytest tests/test_commands.py触发测试后得到AttributeError: 'list' object has no attribute 'split'的报错,LLM 依据报错把参数改回空格分隔的字符串,下一次/run即通过。**“让 LLM 写测试,再由/run的报错闭环纠错”**正是这套实录想要传达的协作模式。
规范落地与数据分析型任务
- no-color.md:用户把 no-color.org 的 NO_COLOR 规范全文粘进聊天——内容是“凡是默认输出 ANSI 颜色的命令行软件,都应检查
NO_COLOR环境变量,当它存在且非空时不得输出颜色”。LLM 据此判断需要修改aider/io.py,并请求把该文件设为“可读写”再动手;改完后用户继续要求补测试用例。它示范了“把外部规范粘贴进来,让 aider 自动定位需要改的文件并落地实现 + 测试”。 - census.md:一场端到端的数据分析:让 aider 推荐合适的美国人口普查数据集、写代码下载数据、提出若干可检验的假设、验证其中一条,最后对结果做汇总并画图。它展示了 aider 在“数据处理脚本”这类任务上同样适用。
文档与“非源码文件”的维护
- update-docs.md:因为
aider/main.py的main()函数参数被更新,用户让 aider 同步修订README.md中关于命令行参数的描述。改动是语义级的:不仅替换了参数名(如--history-file拆成--input-history-file与--chat-history-file),还补齐了新参数--apply FILE、--yes的说明。对“文档和代码要保持同步”的场景很有参考价值。 - asciinema.md:目标文件是一份
.cast录屏 JSON,里面含有大量 ANSI 转义序列。用户要求删掉“hello.py>提示符下方多余的转义码”,LLM 直接对一长串转义序列做精细编辑。这证明 aider 的编辑能力不局限于编程语言,也能处理配置、数据、录屏等任何文本格式文件。
下表汇总了各场实录的启动命令与核心看点,便于快速查阅:
| 实录文件 | 典型启动命令 | 核心看点 |
|---|---|---|
| hello-world-flask.md | aider app.py |
从空文件起步、分步加端点 |
| pong.md | aider |
多步骤游戏开发与定制 |
| hello.md | aider hello.py |
最小编辑块范例 |
| 2048-game.md | git clone + cd + aider |
探索陌生仓库、按需加文件 |
| css-exercises.md | aider + 会话内 /add |
只读说明文件驱动编码 |
| complex-change.md | aider tests/test_main.py aider/getinput.py |
跨文件改动、粘贴报错协作调试、^C 打断重试 |
| semantic-search-replace.md | aider aider/coder.py |
非字面量的语义级批量替换 |
| add-test.md | aider tests/test_commands.py |
仅凭仓库地图写黑盒测试、/run 闭环纠错 |
| no-color.md | aider |
粘贴外部规范并自动定位改动文件 |
| census.md | aider |
下载数据、检验假设、绘图 |
| update-docs.md | aider ./README.md aider/main.py |
让文档跟随代码自动更新 |
| asciinema.md | aider hello.cast |
编辑含转义序列的非源码文本 |
看实录前需要知道的三个幕后机制
原 README 的 “What's happening in these chats?” 一节明确总结了三条运行规则,它们贯穿所有实录,是读懂回放的前提:
- 改动自动落盘:每当 LLM 提出一处代码修改,
aider会把它自动应用到源文件上。实录中每条编辑块之后紧跟的Applied edit to <文件名>就是这个动作的输出。 - 提交自动生成:应用编辑之后,aider 会为改动生成一条描述性的 git 提交信息并提交到仓库。你会在实录中反复看到形如
Commit 414c394 aider: Added a /hello endpoint…的行,其中aider:前缀表明该提交由 aider 自动创建。 - “文件进会话”才能被读写:LLM 只能看到并编辑“已加入聊天会话”的文件。用户通过命令行参数(如
aider app.py)或会话内/add命令添加文件;当 LLM 主动要看某个文件时,aider 会先征求用户同意再加入会话。因此实录里会出现大量“文件被加入/移出会话”的通知。
以上三条机制都能在源码中找到对应实现:
- 会话内文件管理命令定义在 commands.py 中:
cmd_add()的职责是“把文件加入聊天,使 aider 能编辑它们或详细审查它们”;对应的移除命令cmd_drop()(commands.py)用来“把文件移出会话以释放上下文空间”——这正是“Context 有限、文件需按需装载”这一设计的直接体现。 - 在 add-test.md 里用户反复使用的
/run命令,其实现位于 commands.py:执行一条 shell 命令并把输出加回聊天,供 LLM 根据报错迭代修正。别名是!。 - 至于“编辑块 / 自动提交 / 会话文件”这类格式约定与命令行参数的用法,仓库的 edit-formats.md 与 usage 文档 提供了更系统的说明。
实录版式:一眼分清三种角色、看懂编辑块
示例页面的排版在 README 的 “Transcript formatting” 一节有明确约定(网页端通过 .chat-transcript 样式渲染,参见 chat-transcript-css.md,它本身就是一场“如何用 CSS 美化实录页面”的实录):
- 以
####开头的标题行,是用户写给 aider 的自然语言消息; - 放在引用块(blockquote)里、以
>开头的行,是 aider 工具自身的输出,例如Applied edit to app.py、Commit <hash> …、文件加入/移出会话的通知; - LLM 的回复在网页版以蓝色字体呈现,并且常常包含“彩色化的编辑块(edit block)”,用来精确指定对代码的修改。
README 用一个将 print("hello") 改为 print("goodbye") 的例子给出了编辑块的样板:
hello.py
<<<<<<< ORIGINAL
print("hello")
=======
print("goodbye")
>>>>>>> UPDATED
这个格式很容易读懂:<<<<<<< ORIGINAL 与 ======= 之间是改前内容,======= 与 >>>>>>> UPDATED 之间是改后内容,文件路径写在块顶。也就是说,LLM 并不直接重写整个文件,而是给出“在哪个文件、把哪一段原文替换成哪一段新文”。这属于一种搜索/替换式的“diff”类编辑格式;关于不同编辑格式(whole、diff、diff-fenced 等)的取舍与 --edit-format 强制指定方式,可参考 edit-formats.md 的完整讲解。仓库中与此对应的实际实现位于 aider/coders/ 目录下的各类 coder 模块(如 editblock_coder.py、udiff_coder.py 等),它们把不同编辑格式解析出来再落地为真实文件修改。
编辑块与“文件即会话”模型:实录背后的机制拆解
把上面的现象串联起来,就能还原出一套完整的协作模型:
- 用户选择上下文。启动时把待办文件跟在
aider命令后面,或随时用/add、/drop增删。之所以需要这样做,是因为 LLM 的上下文窗口有限——把整个仓库塞进去既不现实也不必要,只让 LLM 接触“本次任务涉及的文件”,反而能让它聚焦(这也正是 no-color.md 里 LLM 会请求“把aider/io.py设为可读写”的原因:文件加入前它无权修改)。 - LLM 返回编辑块。aider 把用户的自然语言、已加入会话的文件内容、以及对仓库全局结构的概览一起提交给 LLM,LLM 用上文的编辑块格式给出精确改动。
- aider 应用并提交。编辑块被解析后应用到源文件,紧接着生成提交信息。实录中提交信息往往是对改动的自然语言摘要(如
aider: Removed the /hello endpoint from the Flask app.),说明提交信息也由 LLM 依据 diff 生成。 - 出错就用
/run闭环。测试失败或运行报错时,用户执行/run <命令>,输出被回填到会话中,LLM 据此自我修正。复杂任务(如 complex-change.md)甚至可以跨多个回合反复“试错—读报错—改代码”。 - 带外改动会被发现。用户在编辑器里手动改了文件、或 git 工作区存在未提交改动时,aider 会在继续对话前提示“Git repo has uncommitted changes”,询问是否先提交,避免把半成品状态混进自动化流程。
值得注意的是,LLM 对仓库的理解并不仅靠“已加入会话的文件”。在 add-test.md 这类场景中,aider 还依赖基于 ctags 生成的仓库符号地图,据此在不看源码的情况下推断类结构、构造参数与函数签名。这项机制在仓库中有独立文档说明,见 ctags.md 与 repomap.md。这也解释了为何实录中的 LLM 常常表现出“仿佛了解整个仓库”的能力——它读的是压缩后的符号地图,而不是每一个文件。
如何亲手复现实录中的工作流
每份实录的第一行都给出了可复现的启动命令。最小的完整流程可以浓缩为以下几步(以最简的 hello 场景为例):
# 1. 准备一个 git 仓库(aider 的自动提交依赖 git)
git init
# 2. 创建初始文件
echo 'print("hello")' > hello.py
# 3. 启动 aider 并把文件加入会话
aider hello.py
进入交互界面后输入一句自然语言(例如 change hello to goodbye),就会看到实录中的经典回放:LLM 给出 hello.py 的编辑块 → aider 输出 Applied edit to hello.py → 自动完成一次描述性提交。更多命令(/add、/drop、/run、/help 等)的会话内用法可查阅 commands.md,而启动参数与配置的完整说明见 options.md。
把某个具体文件加入会话即可定向修改它;不加任何文件参数启动则适合“先探索、后按需加文件”的工作流(如 2048-game.md 所示)。掌握“启动命令 + 会话内 /add + /run 验证”这套最小操作集之后,你就可以把实录里那些动辄横跨十几次对话的任务,平移到自己真实项目的日常迭代中。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00