news 2026/9/9 12:30:44

aider 实战解读:从探索陌生仓库到给开源 2048 游戏加一个 10x 随机奖励

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
aider 实战解读:从探索陌生仓库到给开源 2048 游戏加一个 10x 随机奖励

aider 实战解读:从探索陌生仓库到给开源 2048 游戏加一个 10x 随机奖励

【免费下载链接】aideraider is AI pair programming in your terminal项目地址: https://gitcode.com/GitHub_Trending/ai/aider

本篇基于 aider 官方示例对话实录 2048-game.md 展开。完整记录了一次真实场景:开发者进入一个从未见过的 JavaScript 2048 开源项目,让 aider 解释"这个仓库是什么""计分机制如何实现",并最终当场提出新需求——"10% 概率给 10 倍加分奖励",由 aider 直接修改代码并自动提交。读完本文,你能完整掌握 aider 探索陌生代码库、按需将文件加入对话上下文、看懂其 ORIGINAL/UPDATED 编辑块与自动 git 提交机制,并能把同一套人机协作流程迁移到自己的项目上。

这篇对话实录演示了什么

该文档位于仓库 aider/website/examples/2048-game.md,属于站点 docs 中的 "Example chat transcripts"(示例对话实录)合集,用于展示 "用 aider 编程是一种什么体验"。

整段对话围绕一个用户此前完全没有看过的开源 JavaScript 2048 游戏项目展开,共经历三个回合:

  1. what is this repo?—— 让模型仅凭已加入会话的文件先描述仓库性质;
  2. how does the scoring work?—— 模型主动索要关键源文件js/game_manager.js,经用户确认后自动加入会话,并详细讲解计分逻辑;
  3. can we add some randomness? maybe 10% of the time give the user a 10x bonus?—— 用户提出功能改造,模型给出分步方案、产出编辑块,aider 自动落盘修改并提交 commit。

实录最值得注意的细节在文档开头即被点明:模型想查看某个源文件时,aider 会在获得用户许可后把它自动包含进对话会话。这正是 aider "边读边改"工作方式的核心,也是本文接下来要重点拆解的部分。

前置准备:克隆一个 git 仓库再启动 aider

对话实录第一屏的命令揭示了 aider 的使用前提:

$ git clone <上游 2048 游戏的开源仓库> $ cd 2048 $ aider

整个示例选择的是一个 JavaScript 实现的 2048 网页游戏仓库(HTML/CSS 负责界面、JavaScript 负责游戏逻辑、meta 文件负责图标与移动端启动图)。它体量小、逻辑清晰、便于演示,是非常合适的"试手靶场"。

从中可以提炼出两条可复用的经验:

  • aider 面向的是 git 仓库。自动提交、/undo回滚等能力都建立在仓库的提交历史上(详见后文),所以建议先git clone或进入已有 git 项目再启动;
  • 用什么语言的项目都行。本次示例是 JavaScript 网页游戏,而该文档所在仓库中的其它实录还覆盖了 Python(Flask、Pygame)、CSS、Asciinema cast 文件等,说明这套"探索 + 改造"流程与具体技术栈无关。

读懂实录规则:先弄清楚 transcript 里各符号的含义

直接阅读原始对话前,建议先了解 transcript 的排版约定。在 examples/README.md 中有明确说明,这对正确理解全文至关重要:

  • >开头的行是aider 工具自身的输出(如Applied edit to ...Commit ...);
  • ####标题行是用户用自然语言输入的聊天消息
  • 模型回复中的编辑块(edit block)会被着色高亮,形如:
hello.py <<<<<<< ORIGINAL print("hello") ======= print("goodbye") >>>>>>> UPDATED

更关键的是 examples/README.md 归纳的三条"背后发生了什么":

  1. 每当模型给出一次代码修改建议,aider自动把它应用到源文件
  2. 应用完编辑后,aider用一句有描述性的提交信息自动提交到 git
  3. 模型只能看到并编辑"已加入对话会话"的文件。用户可以通过启动参数或在对话中输入/add命令添加文件;而当模型主动请求查看某个文件时,aider 会先询问用户是否同意,同意后该文件即被加入会话——实录中会看到每一次文件被加入或移除时都有对应提示。

这三点构成了理解整个 2048 示例的框架:模型所讲的一切"只见其文件",它动手改的也只有加入会话的文件。

第一回合:让模型认识未知仓库

用户的第一条消息极其简短:

#### what is this repo?

模型基于启动时加入会话的文件名列表作答:这是一个基于 Web 的游戏仓库,很可能是 2048 类游戏,包含承载游戏逻辑的 JavaScript、负责界面的 HTML/CSS,以及图标、触屏启动图等 meta 文件——并主动表示"需要特定部分代码或想加新功能,请告诉我"。

这个回合的价值在于展示了 aider 对陌生仓库的初步定位能力:即使没有读过源码,仅凭仓库文件构成就能给出大体判断,同时把主动权交还给用户——下一步看哪里、改哪里,由用户决定。

第二回合:理解计分机制,并见识"文件加入会话"

用户接着提问:

#### how does the scoring work?

模型没有凭空猜测,而是表示"要看相关代码",并点名请求文件内容js/game_manager.js,认为计分逻辑很可能在其中。随后实录出现关键的工具交互:

> js/game_manager.js > Add these files to the chat? y

即:模型点名文件 → aider 向用户弹出确认 → 用户输入y同意 → 文件被加入会话。模型随即在上下文中看到文件内容,开始讲解。

底层机制:文件如何进入"可看可改"集合

这一交互对应 aider 的"会话文件"管理机制。在源码层面:

  • 对话启动时可把文件名作为参数传入,Coder 会把它们存入会话文件集合(如 base_coder.py 中维护的abs_fnames,而组装给模型的内容则由get_files_content读取);
  • 会话中途则用/add命令添加、/drop命令移除(聊天命令清单见 commands.md),其实现位于 commands.py 的cmd_add:解析文件名 → 过滤掉被 aiderignore/忽略的文件 → 命中仓库内文件后加入集合;
  • 而当模型在回复中"点名"某个尚未加入的文件时,从 base_coder.py 中围绕mentioned_rel_fnames/get_file_mentions的处理逻辑可以推断:aider 会解析模型消息里出现的文件名、将其与仓库可添加文件匹配,再向用户请求确认——这正是实录中"Add these files to the chat? y"这一行的来源。

理解这一点能避免新手常见的困惑:"为什么我让 aider 改某个文件,它却一直说自己看不到?" 答案是它只能编辑加入会话的文件,请务必先用启动参数或/add把它放进来。

模型对计分的讲解(原文核心内容)

文件到手后,模型的讲解完全对应 2048 的经典规则:

  1. 两个值相同的方块(tile)合并时,生成一个值为两者之和的新方块;
  2. 分数加上新合并方块的数值。

对应的关键源码片段如下(节选自js/game_manager.js):

if (next && next.value === tile.value && !next.mergedFrom) { var merged = new Tile(positions.next, tile.value * 2); merged.mergedFrom = [tile, next]; self.grid.insertTile(merged); self.grid.removeTile(tile); // Converge the two tiles' positions tile.updatePosition(positions.next); // Update the score self.score += merged.value; // The mighty 2048 tile if (merged.value === 2048) self.won = true; }

讲解要点是逐行的:

  • 找到相邻且值相同、且未被合并过的方块tilenext
  • 用二者值之和创建新方块merged,并以mergedFrom记录来源用于动画;
  • 插入新方块、移除两个旧方块、更新位置;
  • self.score += merged.value累计得分——新增的合并值就是本次得分
  • 若合并结果恰好为 2048,则self.won = true判定获胜(代码注释戏称 "The mighty 2048 tile")。

这一段是全文的"信息地基":用户正是基于"得分 = 合并方块的值"这一事实,才能在下一回合提出"加分时随机翻倍"的需求。

第三回合:实现"10% 概率给 10 倍加分奖励"

用户提出需求:

#### can we add some randomness? maybe 10% of the time give the user a 10x bonus?

模型没有立刻丢代码,而是先给出分步实施方案

  1. 生成一个 0 到 1 之间的随机数;
  2. 判断该随机数是否小于等于 0.1(即 10% 概率);
  3. 若命中,则把合并方块的值乘上 10 再加进分数。

随后是写给js/game_manager.js的编辑块:

js/game_manager.js <<<<<<< ORIGINAL // Update the score self.score += merged.value; ======= // Update the score with a 10% chance of 10x bonus var bonus = Math.random() <= 0.1 ? 10 : 1; self.score += merged.value * bonus; >>>>>>> UPDATED

编辑块:aider 与模型交换改动的"标准协议"

这段ORIGINAL / UPDATED结构就是 aider 的核心编辑格式(edit block)。其含义非常直白:ORIGINAL部分是源文件中的既有代码,UPDATED部分是替换后的新代码。只要模型给出的 ORIGINAL 能在文件中唯一精确匹配,aider 就能安全地把改动落到磁盘。这也是为何用户在第一回合的讲解中已经见过被注释的计分行——模型必须"照抄原文",替换才能成功。

从仓库证据看,这一格式贯穿整个 edit 类 coder 的实现(如 editblock_coder.py、相关 prompts 文件等),并在其它实录文档中大量出现;更多可用的编辑格式见 edit-formats.md。

修改落地与自动提交

实录最后是两行带>前缀的 aider 工具输出:

> Applied edit to js/game_manager.js > Commit eb9d882 aider: Added a 10% chance of giving the user a 10x bonus when two tiles merge.

第一行表示编辑已应用成功;第二行表示 aider 已自动创建一次 git 提交,提交信息由模型根据 diff 内容自动撰写,完整概括了本次改动。

源码深挖:自动应用与自动 commit 是怎么实现的

示例中"改完即提交"的流畅体验,对应 aider 的两个核心机制。

自动提交(auto commit)

每轮编辑完成后,Coder 会触发auto_commit,其入口在 base_coder.py:把被编辑的文件集合交给repo.commit,成功后记录last_aider_commit_hash并把提交结果回填到对话上下文,让模型"知道自己改了什么、提交到了哪里"。

提交信息生成与 "aider:" 前缀

提交的真正执行在 repo.py 的commit方法:先取 diff,再通过get_commit_message(repo.py)把 "# Diffs:" 与对话上下文组装成 prompt,交给提交信息模型生成一句话 commit message。

至于实录中出现的aider:前缀,对应 repo.py:当开启--attribute-commit-message-author--attribute-commit-message-committer时,aider 生成的提交信息会统一加上"aider: "前缀,便于在历史里区分"AI 做的改动"和"人类做的改动"。与之配套的提交归属控制参数定义在 args.py 附近。默认情况下这些开关关闭,提交信息不带前缀,具体行为以当前仓库版本和你的启动参数为准。

出了问题怎么办

自动提交并非不可撤销。在 commands.md 的命令表里可以找到/undo:撤销最近一次由 aider 创建的提交;/drop用于从会话中移除文件以释放上下文空间;/commit则用于提交会话外(比如你自己手动改的)内容。相关提示在 base_coder.py 的show_undo_hint中也有体现——一旦检测到会话开始后 HEAD 移动过,aider 会提醒可用/undo丢弃它的提交。

把这套实录转化为可复用的工作流

回顾整段对话,可以提炼出一个在任何代码库上都适用的 aider 协作节奏:

  1. 先建仓库上下文git clone目标项目后cd进目录再执行aider;必要时先把主入口或关键文件用/add加入会话。
  2. 先理解,再动手:第一、二回合展示了"问清这是什么仓库 → 索要相关源文件 → 弄懂关键逻辑"的顺序。模型不会读全部代码,它只依据会话内文件作答,所以探索阶段的价值在于把"该看的文件"喂进会话。
  3. 自然语言提需求,模型负责翻译成代码:第三回合证明,一个附带模糊概率描述的产品想法("maybe 10% of the time give the user a 10x bonus")可以直接被转译成精确的Math.random() <= 0.1 ? 10 : 1
  4. 信任自动落盘与提交,但保留审计手段:aider 会逐条应用编辑并自动 commit;借助带描述的提交信息、/undo撤销能力,以及各编辑格式的文档(edit-formats.md),可以随时核对、回退每一次 AI 改动。

需要提醒的是:实录中提交信息以模型在对话当时的状态生成,你本地得到的 hash 与措辞会因模型、上下文而异;本仓库当前版本下是否需要 "aider:" 前缀,取决于是否开启 args.py 中对应的归属标注参数。本文基于 2048-game.md 的原文对话及其所在仓库的代码实现展开,未对示例之外的项目行为做额外推断。

【免费下载链接】aideraider is AI pair programming in your terminal项目地址: https://gitcode.com/GitHub_Trending/ai/aider

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 12:29:35

基于SSM的市民之家服务指南系统设计与实现:毕业设计实战解析

带2026届学生做毕业设计指导时&#xff0c;我经常会遇到一类选择题&#xff1a;既想用Java方向的老牌技术栈&#xff0c;又想做出一个业务完整、演示效果看得过去的系统。市民之家服务指南这个题目&#xff0c;就是在这种心态下被反复选中的——它本质上是“政务服务信息展示办…

作者头像 李华
网站建设 2026/9/9 12:28:45

孤岛微电网MATLAB仿真:风光储建模与调试全攻略

上个月在做一个园区级微电网预研项目时&#xff0c;甲方工程师随口问了句"电网断了你们怎么办"&#xff0c;我拿出仿真波形告诉他&#xff0c;孤岛模式下频率跌落能控制在0.2Hz以内、电压波动不超过5%&#xff0c;切换时间小于50ms。他看完之后的第一反应是&#xff…

作者头像 李华
网站建设 2026/9/9 12:28:17

C语言实现UTF-8与GBK编码转换:原理、源码与实战

简介&#xff1a;面向单片机与嵌入式开发者的 UTF-8 转 GBK 编码转换 C 语言实现资源&#xff0c;重点解决资源受限环境下中文字符显示与多系统数据交换问题。压缩包内包含 2 个文件&#xff1a;Utf8ToGbk.c 负责查表法转换逻辑的具体实现&#xff0c;Utf8ToGbk.h 提供函数声明…

作者头像 李华
网站建设 2026/9/9 12:27:45

2026程序员兼职全攻略:AI重构下的新赛道与接单实战

1. 2026年程序员兼职&#xff0c;到底还有没有搞头做程序员这行&#xff0c;白天在公司写代码&#xff0c;晚上还能不能靠代码再赚一份钱&#xff1f;这个问题在2026年被问到的频率明显变高了。不是大家突然变穷了&#xff0c;而是大环境变了&#xff1a;主业的涨薪空间被压缩&…

作者头像 李华
网站建设 2026/9/9 12:27:17

轻量级Ruby流程编排:ruflo实战与从零封装指南

不用怀疑&#xff0c;今天聊的不是某个网红或者潮流品牌&#xff0c;而是一个Ruby世界里的小众方向&#xff1a;以ruflo为代表的轻量级流程编排库。我自己在几个项目里踩过不少回调嵌套和状态机的坑之后&#xff0c;开始尝试这类工具&#xff0c;发现思路一旦打开&#xff0c;很…

作者头像 李华
网站建设 2026/9/9 12:26:27

商圈热力分析实战:Python爬取POI与行政区反查

做商圈分析、选址评估或者城市热力研究&#xff0c;最头疼的其实不是模型怎么搭&#xff0c;而是数据怎么来。以前我手动处理过一批商圈POI&#xff0c;先在网页上查&#xff0c;再挨个标行政区&#xff0c;折腾了几天眼睛都快瞎了。后来干脆写了一套Python爬虫&#xff0c;把地…

作者头像 李华