首页
/ aider 实战实录:用对话式编程读懂陌生仓库并完成 CSS 下拉菜单弹跳动画练习

aider 实战实录:用对话式编程读懂陌生仓库并完成 CSS 下拉菜单弹跳动画练习

2026-09-08 21:41:25作者:凌朦慧Richard

这是一篇对 aider 官方示例聊天实录的深度解读与复现指南。示例发生在 The Odin Project 的 CSS Exercises 开源练习仓库中,目标是为 animation/03-dropdown-menu 的下拉菜单补上"弹跳式展开"动画。文章完整保留并逐段剖析实录中的每一次交互,说明 aider 如何通过文件清单理解陌生仓库、用 /add 命令加入练习说明、在获得许可后把目标 CSS/JS 文件纳入会话,并最终以 aider: ... 前缀的自动 git 提交收尾;同时结合本仓库源码解释这些行为背后的实现位置,并给出可直接照做的复现步骤。

这篇实录的定位与读法

本篇文章的讨论对象是仓库中的 css-exercises.md,它是 aider 官方维护的示例聊天总览页中"Example chat transcripts"系列的一份。总览页把这类文章定位为"展示用 aider 编程是什么体验"的对话记录:用户既可能是写全新代码,也可能是在一个陌生仓库里探索、理解与修改既有代码,css-exercises 属于后者——它演示了"读懂一个陌生开源练习仓库,并按其 README 的要求完成动画练习"的完整闭环。

在阅读这类实录之前,总览页给出了一套约定,本篇文章中每一段对话都可以对照这套约定去解析:

  • > 开头(灰底引用)是 aider 工具自身的输出,例如文件加入会话、补丁应用、git 提交等通知;
  • #### 开头的是 用户输入的消息(在终端里每行都带有 #### 前缀);
  • 其余正文是 LLM 的回复,其中常包含彩色高亮的"edit block"(编辑块),用来精确描述对代码的修改;
  • 每当 LLM 提出一个代码修改建议,aider 都会把它自动应用到源文件,随后用一句描述性提交信息自动提交到 git(详见该页"HISTORY 说明"一节的约定文字)。

第一轮对话:先让 aider 读懂一个完全陌生的仓库

实录的第一句用户提问非常朴素:what is this repo?(这是什么仓库?),随后 LLM 基于启动时提供的文件清单给出了概括——该仓库收集了一组 CSS/HTML 练习、解答与示例,覆盖 Flexbox、Grid、Animation、Foundations、Margin & Padding 等主题,并包含练习用图片等资源。

这轮对话的价值在于它揭示了 aider 的使用姿势之一:打开会话时把整个目录交出去,先建立"仓库地图",再定位到具体练习。这里 LLM 判断依据是会话开始时的文件列表,而非打开任意文件——aider 会结合版本库结构构建一个供模型理解的仓库概览,让模型在修改前先对项目全貌形成认识。这一点在后续轮次中体现得更清楚:模型能立刻报出练习目录的路径(animation/03-dropdown-menu/)与相关文件命名(style.cssscript.js),正是因为它先掌握了仓库布局。

第二轮对话:用 /add 把练习说明放进会话上下文

#### /add animation/03-dropdown-menu/README.md

> Added animation/03-dropdown-menu/README.md to the chat

用户使用 /add 命令把练习说明加入会话,aider 返回 "Added ... to the chat" 确认。/add 是 aider 会话控制的核心命令,它在源码中的职责定义是:

"Add files to the chat so aider can edit them or review them in detail"(把文件加入对话,以便 aider 编辑或详细审查它们)

其实现位于 aider/commands.py 中的 cmd_add:命令支持相对/绝对路径、目录展开与 glob 通配;只把真正存在的文件纳入会话,并对被 aiderignore--subtree-only 排除、位于 git 仓库之外等情形给出提示。一个关键前提是:LLM 只能看到并编辑被"加入会话"的文件——这正是整段实录中反复出现 add 通知的原因。

README.md 入会后,LLM 立即读懂了练习要求:为下拉菜单加入"展开到接近最终状态时产生回弹(bounce)错觉"的动画;期望效果以 GIF 展示;hint 提示使用 transform-origin 属性,并在 @keyframes 规则里加入一个中间帧来制造回弹效果。这展示了 README 即需求文档的常见打法:把练习说明文本喂给模型,由它反推实现要点,再由用户确认是否动手。

第三轮对话:让 aider 动手改代码

用户提出 can you make the changes suggested in the readme?(能按 README 的建议做修改吗)。此时模型没有直接改文件,而是做出了一个非常"人味"的回应:

我需要看 animation/03-dropdown-menu/style.cssanimation/03-dropdown-menu/script.js 的内容,请提供这两个文件。

这正是 aider 的权限模型的体现:文件只有先进入会话,模型才能读取与修改。当模型主动要求查看文件时,aider 会询问用户是否授权加入,实录中出现的交互即为此机制:

> animation/03-dropdown-menu/style.css
> animation/03-dropdown-menu/script.js
> Add these files to the chat? y

用户输入 y 授权后,模型看到两个文件的真实内容,随即提出如下编辑方案(这就是上文提到的"edit block"):

animation/03-dropdown-menu/style.css
<<<<<<< ORIGINAL
.visible {
  display: block;
}
=======
.visible {
  display: block;
  animation: expand 0.3s ease-out;
  transform-origin: top;
}

@keyframes expand {
  0% {
    transform: scaleY(0);
  }
  80% {
    transform: scaleY(1.1);
  }
  100% {
    transform: scaleY(1);
  }
}
>>>>>>> UPDATED

随后 aider 输出两条关键通知:

> Applied edit to animation/03-dropdown-menu/style.css
> Commit bb3a813 aider: Added bounce animation to dropdown menu.

第一条说明编辑块被自动应用到目标文件(带文件路径前缀 + ORIGINAL/UPDATED 分隔的编辑块格式,正是示例总览页中讲解的 transcript 编辑块写法);第二条说明改动已被自动提交,提交信息以 aider: 前缀开头。

第四轮对话:验证与收尾

用户反馈 that worked!(成功了),模型确认改动生效并说明随时可以继续协助。整段实录在"提出需求 → 授权文件 → 自动改码 → 自动提交 → 人工验证通过"的正反馈里结束——这也是用 aider 做小步迭代修改的标准闭环。

自动提交的背后:改动如何变成一次 git 提交

"Applied edit" 与 "Commit" 几乎同时出现并非巧合,这是 aider 的 auto-commit(自动提交)机制。在源码 aider/coders/base_coder.py 的 auto_commit 中可以看到完整链路:

  • 当编辑被应用后,aider 调用 self.repo.commit(fnames=edited, context=context, aider_edits=True, coder=self)
  • 提交成功后在工具输出区展示结果(对应实录中的 Commit bb3a813 ...);
  • 若提交失败(如当前目录并非 git 仓库或发生 git 错误),会打印 "Unable to commit: ..." 并继续,而不是中断会话;
  • 之后用户仍可通过 /undo 撤销并丢弃每一次 aider 自动提交(详见 base_coder.py 中的提示逻辑)。

aider/repo.py 的 commit 方法中,aider_edits 参数会改变提交消息与署名语义:当改动由 aider(LLM)生成时,提交信息会自动加上 aider: 前缀(见 repo.pycommit_message = "aider: " + commit_message 一行),这正是实录中 "aider: Added bounce animation to dropdown menu." 这一提交信息的来源。

需要说明适用前提:auto-commit 依赖工作目录是一个 git 仓库,且相关文件已被 git 跟踪——示例中的 CSS Exercises 练习仓库满足该条件,因此 /add 与自动提交都畅通无阻。

CSS 技术要点拆解:如何实现"弹跳式展开"

抛开对话外壳,这段练习本身也值得单独剖析,它演示了 README 的 hint 如何一步步转化为真实动画代码。练习要求"下拉菜单展开到接近最终状态时产生回弹",模型给出的实现由三个 CSS 知识点构成:

  1. animation: expand 0.3s ease-out;——给元素挂上名为 expand 的关键帧动画,时长 0.3 秒,缓动曲线为 ease-out(先快后慢,模拟"展开落定"的物理感);

  2. transform-origin: top;——这是 README 明确 hint 的属性。下拉菜单通常挂在触发按钮正下方、自上而下展开,因此把变换原点设在顶部 top,让 scaleY 缩放以顶边为轴进行,视觉上才是"从顶部撑开";

  3. @keyframes expand 的中间帧——README hint 的另一半。完整序列是:

    • 0%scaleY(0),高度收缩为 0,隐藏状态;
    • 80%scaleY(1.1),先"过冲"到 110% 高度;
    • 100%scaleY(1),回落定格到标准高度。

    "过冲再回弹"(overshoot-and-return)是制造 bounce 错觉的经典手法:物体不会直接停在终点,而是越过终点再弹回来。配合 .visible { display: block; }(原本通过切换 display 显隐菜单)与新加的 transform 动画,菜单每次出现都会自带一次轻微的弹跳手感。

最终生效的样式相当于:

.visible {
  display: block;
  animation: expand 0.3s ease-out;
  transform-origin: top;
}

@keyframes expand {
  0%   { transform: scaleY(0); }
  80%  { transform: scaleY(1.1); }
  100% { transform: scaleY(1); }
}

说明:动画属性只会作用于"添加 class 触发显示"的那一次显现;display 的显隐切换本身不参与过渡,这正是需要把 transform 而非 height 作为动画目标的原因——transform 可以单独流畅插值,而 display 是不可动画属性。

复现这段练习:从克隆仓库到跑通一次对话

如果你希望亲自体验与实录完全一致的流程,可以按以下步骤操作(以 CSS Exercises 开源练习仓库为例):

  1. 准备一个 git 仓库环境,把 The Odin Project 的 CSS Exercises 练习仓库克隆到本地并进入 animation/03-dropdown-menu/ 目录(aider 的自动提交功能要求工作在 git 仓库内);
  2. 确认 style.cssscript.jsREADME.md 就位,它们就是这次练习的载体;
  3. 在该目录启动 aider 会话;
  4. 依次发起与实录相同的操作:
    • 直接提问 what is this repo?,观察 aider 基于仓库文件清单给出的概括;
    • 输入 /add animation/03-dropdown-menu/README.md,把练习说明加入会话;
    • 输入 can you make the changes suggested in the readme?,当 aider 请求查看 style.cssscript.js 时回复 y 授权加入;
  5. 等待 aider 输出 edit block 并自动应用,随后在浏览器/测试环境确认下拉菜单出现了"回弹展开"效果,即用人工验证兜住模型输出。

运行 aider 需要先完成安装与模型配置,通用安装方式参见仓库文档(例如 install.md 系列);示例练习的具体安装方式以 CSS Exercises 仓库自身说明为准。

从这段实录提炼出的通用工作流

虽然表面是一道 CSS 练习题,但整个对话其实浓缩了一套可复用的"AI 结对改代码"范式,适用于任何陌生/既有代码库:

阶段 实录中的体现 aider 侧机制
建立仓库认知 "what is this repo?" 基于文件清单概括项目 会话开始即载入仓库结构概览
引入需求文档 /add .../README.md cmd_add 把文件加入会话上下文
补全必要上下文 模型主动索要 style.cssscript.js,用户 y 授权 权限模型:LLM 只能读写已入会话的文件
让模型产出改动 edit block(ORIGINAL/UPDATED 分隔)描述对 style.css 的修改 aider 自动应用编辑
留下可回退的痕迹 Commit bb3a813 aider: Added bounce animation... auto_commit + repo.pyaider: 前缀提交,可 /undo 回退
人类验收 "that worked!" 人工确认效果即会话闭环

如果你对这种"transcript 式"的学习材料感兴趣,仓库还提供了多个同类示例,例如对既有 JS 游戏仓库的探索与修改跨文件协调的复杂改动与调试,以及语义化的搜索替换改造。它们与本文的区别只在于任务领域,交互范式——"读懂 → 加文件 → 请求改动 → 授权 → 自动应用 → 自动提交 → 验证"——是完全一致的,值得对照阅读。

总而言之,css-exercises 实录是一段小而完整的"从零理解并修改真实仓库"示范:模型并没有凭经验瞎写,而是先读练习 README、再向用户申请查看实现文件、最后把 hint 翻译成一段 20 行的 CSS。理解这段对话,也就理解了 aider 的会话权限模型、自动提交约定与 edit block 的形态,而这恰恰是把 aider 用于任何真实项目前最值得补的一课。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391