Aider 如何在 SWE Bench Lite 上取得 SOTA 26.3%:基准方法论、仓库地图与可靠的 LLM 代码编辑
本文围绕 aider 官方发布的 SWE Bench Lite 基准测试报告展开,完整还原其 26.3% pass@1 成绩的测试方法、"plausible solution" 判定标准与分模型得分明细,并结合当前仓库源码剖析支撑该成绩的核心机制:基于 AST 静态分析的仓库地图、可靠的代码编辑格式、tree-sitter 内置 Lint 与自动测试修复流程,帮助读者理解 aider 这一交互式(而非全自主 Agentic)AI 结对编程工具的技术路线。
Aider 在 SWE Bench Lite 基准上取得了 26.3% 的成绩,成为当时的 state-of-the-art(此前榜首为 Amazon Q Developer Agent 的 20.3%)。该结果主要来自 aider 现有的三类特性:静态代码分析(仓库地图)、可靠的 LLM 代码编辑(多种编辑格式与提示策略)、以及面向 AI 结对编程的务实交互体验。
需要明确口径:本文所述 aider 的全部成绩均为 pass@1,且未使用 SWE Bench 的 hints_text 提示。官方 SWE Bench Lite 排行榜也只接受不带 hints 的 pass@1 结果。文中对比的其他 Agent 数据(AutoCodeRover、OpenDevin 等)在 2024/05/30 曾修正过一次,改用 AutoCodeRover 的 pass@1 均值和 OpenDevin 不使用 hints 的成绩,以保证"apple-to-apples"可比。排行榜的原始数据与绘图逻辑分别存放在 swe-bench-lite.txt 与 swe_bench.py。
交互式工具,而非全自主 Agent
Aider 有意保持"有限且窄"的 Agentic 行为,以避免长时间等待、高 token 成本,以及用户反复审查错误方案。值得注意的是,aider 当时不使用 RAG、向量搜索、工具调用,也不让 LLM 自主搜索网络或单方面执行代码。
Aider 首先是一个让工程师在真实代码库中通过聊天界面完成真实工作的交互式工具:用户可以提出改动请求,并实时看到编辑过程。Aider 也能提供修复 lint/测试错误等额外帮助,但用户始终握有完全的交互控制权,可以随时纠正误解、及时把跑偏的方向拉回正轨,从而节省时间与 token 成本。
这一设计立场直接体现在源码中:aider 的命令行参数里既有面向交互的确认流程,也有面向无人值守场景的自动接受开关。当前仓库 args.py 中定义了 --yes-always 参数(始终自动接受编辑建议),以及 args.py 中的 --auto-lint(默认开启)、--auto-test(默认关闭)等参数——基准测试正是通过组合这些开关把 aider 置于"自动接受 + 自动修 lint + 自动跑测试"的无人值守模式。
基准测试方法(Benchmark methodology)
在基准测试中,aider 在每个问题对应的 git 仓库中启动,问题描述作为"用户"发出的第一条聊天消息提交,之后 aider 按正常流程运行,仅做以下修改:
- aider 的每条建议都不经用户确认直接接受;
- 一个简单的 harness(测试框架)在 aider 产出的代码不是 plausibly correct("看起来正确")时重试该 SWE Bench 问题。"Plausibly correct" 的判定标准是:aider 报告其已成功编辑仓库,且没有引入语法错误、没有破坏任何既有测试;
- 若解不"plausible",harness 从零重新拉起 aider 再试一次,并在 GPT-4o 与 Opus 两个模型之间交替使用;
- 若六次尝试后仍未找到 plausible 解,harness 从中选择 edit/lint/test 问题最少的一个作为最终提交。
必须强调:aider 与基准 harness 只能访问各问题仓库中既有的测试,被"扣住"的验收测试(acceptance tests)只在基准跑完后用于统计哪些题目被正确解决。
整个基准流程模拟了开发者用 aider 解决一个 GitHub issue 的真实过程:
-
在仓库中用如下命令启动 aider(表示接受所有建议,并用 pytest 跑测试):
aider --yes --test-cmd pytest其中
--test-cmd用于指定测试命令,当前仓库 args.py 中该参数的 help 即 "Specify command to run tests";历史上与"始终自动接受建议"对应的开关在当前源码中为--yes-always(args.py)。 -
聊天开始时粘贴 GitHub issue 的 URL 或文本。Aider 会拉取 URL 内容然后尝试解决问题;
-
如果 aider 产出的代码 lint 或测试不干净,用户可以借助 git 回滚(revert)再试一次,甚至换用另一个 LLM。Aider 与 git 深度集成,AI 的改动随时可以撤销。
文档同时指出:在基准场景之外,让任何 AI Agent 在你的代码库上无人值守运行都可能不明智或至少效率极低。aider 设计为交互式使用,正是为了让用户能参与并指导 aider 的工作、审批其建议——这样在最初的指令含糊、或 AI 走错方向时,用户能立即给出反馈或纠正。
仅用 GPT-4o 时 Aider 已是 SOTA
如果基准 harness 只使用 aider + GPT-4o 来找 plausible 解,成绩为 25.0%,本身已追平当时的 state-of-the-art(随后才被本文主结果、即 GPT-4o 与 Opus 组合的 26.3% 超越)。单用 GPT-4o 的一次尝试成绩(20.3%)就已追平当时排行榜榜首条目。
Aider 配合 GPT-4o 与 Opus 交替尝试
harness 按固定顺序交替运行 aider + GPT-4o 和 aider + Opus:总是先用 GPT-4o,然后与 Opus 交替,直到为每个问题找到一个 plausible 解为止。下表对 300 道题中被发现的 plausible 解做了逐轮拆解,并给出其中最终被验证为正确解决的 79 道题的细节。几个值得注意的观察:
- 仅第一轮尝试(aider + GPT-4o)就解决了 20.3% 的问题,追平了当时官方榜首的 Amazon Q Developer Agent;
- 计入第二轮后,aider + GPT-4o 与 Opus 合计得分 23.6%。前两轮尝试拿到了约 75% 的全部 plausible 解和约 90% 的全部正确解;
- 其后仍有一条长尾,两个模型继续贡献解,直到某道题的最后一轮(第六次)尝试才正确解决。
| 尝试轮次 | Agent | Plausible 解数量 | Plausible 解占比 | 正确解决数量 | 正确解决占比 | SWE Bench Lite 得分 |
|---|---|---|---|---|---|---|
| 1 | Aider with GPT-4o | 208 | 69.3% | 61 | 77.2% | 20.3% |
| 2 | Aider with Opus | 49 | 16.3% | 10 | 12.7% | 3.3% |
| 3 | Aider with GPT-4o | 20 | 6.7% | 3 | 3.8% | 1.0% |
| 4 | Aider with Opus | 9 | 3.0% | 2 | 2.5% | 0.7% |
| 5 | Aider with GPT-4o | 11 | 3.7% | 2 | 2.5% | 0.7% |
| 6 | Aider with Opus | 3 | 1.0% | 1 | 1.3% | 0.3% |
| 合计 | 300 | 100% | 79 | 100% | 26.3% |
如果只按模型维度拆分,可以看到 aider + GPT-4o 优于 Opus。但这不是公平的直接对比:GPT-4o 总是先手,因此先接触了所有"最简单"的题目;Opus 看到的都是 GPT-4o 第一轮未找到 plausible 解的题。即便如此,aider + GPT-4o 产出的 plausible 解质量更高,后续被验收测试判定为"解决了问题"的概率更大。这一轮次顺序偏差的存在,使该观察只能视为倾向性证据。
| Agent | Plausible 解数量 | 正确解决数量 | 正确解决占 plausible 解比例 |
|---|---|---|---|
| Aider with GPT-4o | 239 | 66 | 27.6% |
| Aider with Opus | 61 | 13 | 21.3% |
| 合计 | 300 | 79 | 26.3% |
以上数字与仓库中保留的排行榜原始数据一致,见 swe-bench-lite.txt(26.3% Aider|GPT-4o|& Opus、25.0% Aider|GPT-4o、20.3% Amazon Q Developer Agent、19.0% AutoCodeRover、18.0% SWE-Agent + GPT-4、16.7% OpenDevin、11.7% SWE-Agent + Opus)。swe_bench.py 中的 plot_swe_bench() 函数会解析该文件(按 % 切分百分比与模型名)并绘制 pass@1 柱状图,对 Aider 条目使用高亮配色加粗显示。
用仓库地图(Repository Map)而非 RAG
解决 SWE Bench 问题的关键第一步是判断仓库的哪些部分与问题相关、哪些文件需要编辑。大多数编码 Agent 使用 RAG、向量搜索,以及供 LLM 交互式探索代码库的工具的组合。
Aider 走的是另一条路:使用仓库地图(repository map)帮助 LLM 理解 git 仓库的布局、代码结构与内容。仓库地图通过对代码抽象语法树(AST)和调用图的静态分析生成,为整个代码库提供紧凑而信息量大的摘要,并持续裁剪以展示与当前聊天状态相关的仓库上下文——这是通过对代码调用图做图优化(graph optimization)实现的。
当用户提出代码修改请求时,LLM 可以借助仓库地图决定编辑哪些文件。LLM 只需返回一段普通文本回复,说明它需要编辑哪些文件以及原因。Aider 会识别 LLM 提到的仓库中的文件名,并询问用户是否将其加入聊天。文件加入聊天后,LLM 就能看到该文件的完整内容并对其进行编辑。文档给出的典型交互示例:
#### Please add a new /factorial/N endpoint.
To add a new /factorial/N endpoint, the most likely file that needs to be
edited is app.py. Please add app.py to the chat so I can proceed with the
changes.
> app.py
> Add these files to the chat? yes
这种工作流对交互式聊天来说自然且顺手,在 SWE Bench 题目上表现良好:Aider 在 70.3% 的基准任务中正确识别出需要编辑的文件。
这一 70.3% 的统计是如何计算的?每个 SWE Bench 任务都关联一个由人类开发者编写、用于解决该 issue 的 "gold" patch,该 patch 揭示了可以解决问题的文件。判定"Aider 是否找对了文件"就是把 aider 加入聊天的文件与 gold patch 涉及的文件比对。当然,aider 本身看不到也无法以任何方式使用 gold patch 及其中的文件名,这些信息只用于基准过程之外的统计计算。
可靠的代码编辑(Reliable code editing)
选定要编辑的文件后,下一步当然是编辑源码来修复问题。
Aider 做了大量工作,确保 LLM 不仅能写代码,还能可靠地编辑代码。Aider 拥有一组经过大规模基准测试打磨的提示策略与代码编辑后端,这些基础能力确保 LLM 产出的代码能被正确地整合进现有代码库与源文件。当前仓库 aider/coders/ 目录下按编辑格式组织了多种 coder 实现(如 editblock、udiff、wholefile、architect 等),与仓库的 benchmark/ 工具链共同构成"提示策略 + 编辑格式 + 量化评测"的闭环。
仓库地图在这里同样发挥作用:让 LLM 能看到整个仓库中相关的类、函数和变量,从而确保新增代码时尊重并利用项目既有的 API 与约定。
即便如此,仍会出现 aider 无法干净地完成 LLM 指定编辑的情况,通常原因是 LLM 没有遵守其系统提示中的编辑指令。Aider 完成时会返回一个编辑结果状态,指明是否成功应用了全部编辑;基准 harness 将该编辑状态作为判断"plausible 解"的判据之一。
Lint 与自动修复
Plausible 解的另一个关键判据是通过基础 lint 检查,即代码没有语法或其他致命错误。Aider 在每次 LLM 编辑后都会 lint 代码,并主动提出自动修复发现的问题。
从源码看,lint 能力由 linter.py 中的 Linter 类实现:lint() 方法(linter.py)读取文件内容后优先走内置检查器,也可通过 set_linter()(linter.py)挂载外部 lint 命令;内置检查基于 tree-sitter 解析 AST,覆盖绝大多数主流编程语言。命令行侧对应 args.py 中的 --lint-cmd(按语言指定 lint 命令,可多次使用)与 --auto-lint(默认开启编辑后自动 lint)。
Aider 展示 lint 错误给 LLM 时使用了一种新颖格式:借助抽象语法树为每条错误展示相关的代码上下文,帮助 LLM 理解问题并做出正确修改。文档给出的示例:
app.py:23:36: F821 undefined name 'num'
app.py:
...⋮...
6│class LongNum:
...⋮...
19│ def expound(self, threshold):
20│ number = self.basis
21│ while number < threshold:
22│ number *= self.factor
23█ return num
24│
25│
...⋮...
> Attempt to fix lint errors? yes
在基准测试中,这些 lint 修复建议总是被自动接受。完成时,aider 报告一个 lint 结果状态,说明是否产出了没有遗留 lint 错误的代码;基准 harness 用该状态作为判断 plausible 解的判据之一。
测试与自动修复
Plausible 解的最后一条判据是所有测试必须通过。Aider 可以配置运行仓库测试的命令,并会自动尝试修复任何测试失败。
例如,在 Python 项目中用户可以这样启动 aider:
aider --test-cmd pytest
对应源码中 args.py 定义的 --test-cmd(指定测试命令)与 --auto-test(编辑后自动运行测试,默认关闭;基准 harness 将其打开),以及 args.py 中的 --test(跑一次测试、修复发现的问题后退出)。
在基准测试中,aider 配置的测试命令会运行每个问题仓库中已存在的测试。SWE Bench 的问题基于大型开源项目的仓库,这些项目有相当完备的既有测试套件。因此,如果 aider 破坏了任何既有测试,或者它新建的测试不通过,测试环节都会失败。与编辑和 lint 一样,aider 会报告一个测试结果状态,说明是否仍有遗留的失败测试;harness 将其纳入 plausible 判定。
必须再强调一次:aider 无法运行、甚至无法看到用于判定方案是否正确解决问题的扣住的"验收测试"。那些测试只在 aider 与基准 harness 之外运行,仅用于计算最终基准统计。
如何判定一个"plausible 解"
每次 aider 执行完毕,都会报告编辑、lint、测试三步各自的结果,每一步要么成功、要么返回表示仍有未解决问题的状态。
基准 harness 用这些结果判定 aider 是否产出了当前 SWE Bench 任务的 plausible 解:plausible 解指 aider 返回时声明其编辑仓库没有遗留任何编辑、lint 或测试错误。此时,aider 的改动被记录为该 SWE Bench 实例的 model_patch,留待之后用验收测试评估。
如果解不 plausible,harness 会再次从零拉起 aider 实例处理同一问题,并在 GPT-4o 与 Opus 之间交替,每个模型各给三次尝试,共六次。一旦找到 plausible 解就接受它,harness 随即进入下一题。
文档还指出一个重要细节:仓库可能在 aider 开始编辑前就带有 lint 或测试错误。无论未解决的错误是 aider 造成的还是本来就存在,六次尝试后都可能找不到 plausible 解。若六次尝试全部失败,则从现有"最好"的解中挑选一个作为 model_patch。选择标准是忽略测试结果,按以下优先级:
- 挑选编辑与 lint 均成功完成的解;
- 挑选编辑至少部分成功且 lint 成功的解;
- 挑选编辑成功的解;
- 挑选编辑至少部分成功的解。
基准分数的计算
基准 harness 为全部 300 个 SWE Bench Lite 实例各产出一个 plausible 解并保存为 model_patch。
另有一个独立评估脚本,用完整测试套件(包括扣住的验收测试)测试这些解。最终验收测试时,会丢弃 aider 对测试文件所做的一切修改,确保使用的是未篡改的、正确的测试套件。评估脚本将测试结果与"gold" patch(人类开发者编写的正确解法)的测试结果比对;两者一致,则该候选解视为正确解决了问题。
这些验收测试始终只在 aider 与基准 harness 之外运行,仅用于统计正确解决的实例数,在 aider 尝试解题的过程中从未被运行、使用或看到。
最终,Aider 正确解决了 300 个 SWE Bench Lite 实例中的 79 个,即 26.3%。
关于 pass@1 口径与对比数据的说明
aider 的 "agent" 内部会对解题做多次"尝试",但最终只挑选并返回一个候选解;只有这一个候选解会经过验收测试并计入基准分,因此它是 pass@1 结果。作为对照,pass@N(N>1)会尝试 N 次并对全部 N 个解做验收测试,其中任意一个通过即记为 pass@N 成功——两类结果不可直接比较。
文中图表对比的其他 pass@1(未使用 hints)成绩参考:Amazon Q Developer Agent(v20240430-dev)20.3%、AutoCodeRover 19.0%、SWE-Agent + GPT-4 18.0%、OpenDevin 16.7%、SWE-Agent + Opus 11.7%。图表于 2024/05/30 做了两处更正:其一,改用 AutoCodeRover 的 pass@1 均值(此前误展示其未明确标注的 pass@3 结果);其二,改用 OpenDevin 不使用 hints_text 提示的最佳成绩(此前展示的是其未注明使用了 hints 的成绩)。
结语:成绩背后的工程取向
回到仓库中这份报告 2024-05-22-swe-bench-lite.md 的核心论点:Aider 的 SOTA 成绩并非来自"更强的 Agent 框架",而是来自一组扎实的确定性工程——静态分析驱动的仓库地图替代 RAG、经基准打磨的可靠编辑格式、tree-sitter 内置 lint 与上下文化的错误呈现、git 深度集成带来的零成本回滚,以及"编辑 + lint + 测试"三态汇报构成的可判定完成条件。这些特性既是基准得分的来源,也是日常使用中工程师可以逐一审视、随时纠偏的交互能力。对希望复现类似评测流程的开发者,仓库内的 benchmark/ 目录(含 Docker 化运行、benchmark.py 统计报告与 --model/--edit-format/--threads 等参数)提供了可参考的完整工具链。
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 StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
