SWE-agent:Agent-Computer Interface 为什么会改变表现

原始来源

John Yang 等,2024:SWE-agent: Agent-Computer Interfaces Enable Automated Software Engineering,本页按 arXiv v3 阅读。

本页是原创学习导读,不含原文复刻;论文版权与完整内容以原始来源为准。

学完这一篇,你应该能做到什么

  • 用自己的话解释 Agent-Computer Interface(ACI)为什么不只是“工具列表”。
  • 从 Issue 开始,完整走过定位、查看、复现、编辑、测试和提交补丁的闭环。
  • 说明命令设计、反馈格式、上下文管理和防错护栏分别解决什么问题。
  • 比较定制 ACI 与通用 Shell:两者都能操作仓库,为什么模型使用后的结果仍可能不同。
  • 设计一个只改变 ACI、不改变模型权重的对照实验,并正确解释实验能证明什么。

一句话抓住它

SWE-agent 的关键贡献不是“再做一个会写代码的 Agent”,而是把语言模型当作一种新的计算机用户:固定同一个模型,仅改变它能发出的动作和收到的反馈,也可能显著改变最终的软件工程表现。

先把问题说清楚:能运行 Shell,为什么还需要 ACI

假设模型收到一个真实 GitHub Issue:“某个配置解析函数错误地接受了负数超时时间,请修复并补测试。”如果只给它普通 Shell,它理论上已经可以使用 ls、grep、cat、sed、Python 和测试命令完成任务。问题在于“理论可表达”不等于“模型能稳定完成”:

  • grep 可能返回几千行,真正相关的三行被淹没;
  • cat 整个大文件会迅速消耗上下文;
  • sed 或重定向能编辑文件,但多行修改容易转义错误或误伤其他位置;
  • 命令成功却没有输出时,模型可能误判为失败;
  • 一次错误编辑如果没有语法检查和清楚反馈,会污染后续每一步;
  • 旧工具输出一直留在历史中,模型看到的可能是修改前的过期代码。

人使用 IDE,不是因为 Shell 无法修改文件,而是因为 IDE 把搜索、跳转、编辑、语法检查和运行反馈组织成更适合人的界面。论文提出同样的设计问题:语言模型也有自己的优势和限制,因此需要为它设计专用界面。

三个容易混淆的术语

术语在本文中的含义不等于什么
LM Agent在循环中根据观察选择动作的语言模型系统单次生成一段补丁文本
ACIAgent 与计算机之间的抽象层,规定动作、动作说明、环境反馈和历史如何进入下一轮单纯给模型几个函数名
Environment仓库、文件系统、终端、解释器和测试系统共同形成的可变化外部状态模型内部“觉得代码应该正确”

ACI 的完整契约:输入、状态、动作、反馈与停止

可以把一轮 SWE-agent 抽象成下面五部分:

部分具体内容为什么重要
输入Issue 描述、仓库初始状态、命令文档、可能的示范决定 Agent 知道目标以及可用动作
内部运行状态消息历史、最近观察、当前打开文件、工作目录、已发生编辑、成本或步数让下一轮决策建立在“现在发生了什么”之上
动作搜索、打开/滚动文件、按行编辑、执行程序或测试、提交把模型生成的意图转成仓库变化
环境反馈搜索摘要、带行号代码窗口、编辑后的新内容、lint 错误、测试输出、明确的无输出提示给模型可验证的下一步依据
停止主动 submit,达到成本上限后提交已有编辑,达到上限且无编辑,或连续格式错误导致提前结束防止循环无限运行,并明确最终补丁来自哪个状态
flowchart TD
    I["Issue + 仓库初始状态"] --> P["模型判断下一步"]
    P --> S["搜索 / 导航"]
    S --> V["有限窗口查看文件"]
    V --> R["复现问题并读取真实输出"]
    R --> E["按明确范围编辑"]
    E --> G{"语法与编辑护栏通过?"}
    G -->|"否:拒绝编辑并解释"| P
    G -->|"是:展示更新后代码"| T["运行定向测试与必要回归"]
    T --> Q{"外部验收通过?"}
    Q -->|"否:保留失败证据"| P
    Q -->|"是"| D["检查 diff / 清理临时文件"]
    D --> X["submit 输出最终补丁"]

这张图最重要的地方是两条回路:编辑失败不是“继续假装成功”,测试失败也不是“靠模型重新相信自己”。环境把失败变成下一轮可消费的证据。

论文怎样设计动作空间

SWE-agent 的 ACI 建立在 Linux Shell 上,并没有禁止普通命令;它额外提供了一组更适合语言模型的高频动作。

1. 搜索与仓库导航

  • find_file 按文件名定位候选文件。
  • search_file 在一个文件内搜索字符串。
  • search_dir 在目录范围内搜索字符串。

搜索结果不是无限打印。论文实现会汇总匹配位置,并对过多结果要求模型缩小查询。这里的机制不是“搜索算法更神奇”,而是控制观察的形状:一次给出足够形成全局判断的摘要,又避免把上下文塞满。

2. 有界文件查看器

open 打开文件后,界面一次最多展示一个有限行窗口;scroll_up、scroll_down 和 goto 用来移动。反馈同时给出:

  • 文件完整路径;
  • 文件总行数;
  • 当前每行的行号;
  • 窗口上方和下方还有多少行未显示。

模型因此知道“我看到的是文件的一部分”,而不会把截断内容误当成完整文件。

3. 与查看器结合的精确编辑

论文中的 edit 以“起始行、结束行、替换文本”为主要参数,一次完成多行替换。成功后,系统自动展示修改后的文件窗口;如果 lint 检测到选定错误,编辑会被丢弃,并把错误附近的代码和原因返回给 Agent。

这是一个小但关键的事务语义:

尝试编辑 → 校验 → 成功则提交到工作树并展示新状态
                 → 失败则保持旧状态并说明如何重试

相比之下,脆弱的 Shell 编辑可能出现“文件已经被改坏,但模型还没意识到”的半失败状态。

4. 上下文处理也是接口的一部分

ACI 不只定义命令。SWE-agent 还管理命令说明、示范、格式错误消息和历史观察:

  • 每轮要求产生一个判断和一个动作;格式不合法时要求重试;
  • 无输出命令会返回明确的“命令成功但没有输出”,消除静默歧义;
  • 较旧观察会被压成简短记录,只保留近期较完整的反馈;
  • 当前编辑后的内容重新进入观察,降低继续依据旧代码推理的概率。

因此,ACI 的准确公式更接近:

ACI = 动作空间 + 动作文档 + 环境反馈格式 + 防错护栏 + 历史整理规则。

一次完整运行:修复负数超时时间

下面是为了教学构造的轨迹,不是论文原样案例。Issue 要求:parse_timeout("-1") 应抛出 ValueError,但当前错误地返回 -1。

轮次Agent 的目标ACI 动作环境反馈如何改变下一步
1了解仓库和已有测试执行状态检查,搜索 parse_timeout返回定义和测试文件的少量匹配,而不是整个仓库
2阅读实现上下文open src/config.py,跳到匹配行显示带行号的 100 行内窗口,并提示上下仍有内容
3先证明缺陷存在执行目标测试或最小 Python 调用真实输出显示负数被接受,建立修改前基线
4找到项目既有错误语义搜索相邻配置校验和 ValueError 测试发现项目通常在解析后检查范围,而不是静默截断
5修改实现和测试对明确行范围执行 edit若缩进错误,lint 拒绝修改;修正后返回更新代码
6验证局部行为运行新测试和原有配置测试新旧测试都通过,说明目标缺陷已修且局部回归未出现
7验证补丁边界查看 diff,确认无临时脚本发现只改实现与测试,没有无关文件
8终止submit系统从工作树最终状态收集补丁

注意第 3 步不能省略。若 Agent 没有复现问题,它可能修改了错误的函数;第 6 步也不能只问模型“你觉得正确吗”,而要让外部测试产生证据。

对应的最小控制循环

state = initialize(issue, repository, command_docs)
 
while state.cost < budget and state.format_errors < error_limit:
    context = build_context(
        issue=state.issue,
        instructions=state.command_docs,
        recent_observations=state.recent_observations,
        compressed_history=state.older_history,
    )
    thought, action = model(context)
 
    if action.name == "submit":
        return collect_patch(state.repository)
 
    result = execute_with_guardrails(action, state.repository)
    state.update(action, result)
 
return collect_patch(state.repository) if state.has_edits else None

伪代码没有声称复刻论文实现;它用最少结构展示关键因果链:模型权重不变,build_context、action 的定义和 result 的反馈方式改变,下一轮行为就会改变。

定制 ACI 与通用 Shell 到底差在哪里

任务通用 Shell 可能的路径定制 ACI 的路径机制上的收益
找类定义find、grep 参数组合,输出可能过长一个搜索动作,结果聚合并限制数量减少参数和观察歧义
看大文件cat 全文件或手工 sed -n固定窗口、行号和剩余范围控制 token,同时保留位置感
多行编辑重写文件、复杂 sed 或临时脚本明确行范围的替换动作少一次转义和中间状态
编辑出错命令可能部分生效,需自行诊断lint 拒绝无效编辑并返回局部错误阻止错误向后传播
命令无输出无法立即区分成功、失败或卡住明确说明成功且无输出消除状态歧义

这不是说 Shell 不专业,也不是说今天的 Agent 永远不能熟练使用 Shell。论文比较的是特定模型、特定提示、特定预算和特定任务下的接口适配。核心工程结论是:接口是系统的一部分,不能把它当成对所有模型都中性的管道。

论文证据:它支持什么,不支持什么

论文 v3 在 SWE-bench 与 HumanEvalFix 上评测,并对搜索、编辑、文件窗口和上下文处理做消融。主要结果包括:

  • GPT-4 Turbo 配合 SWE-agent 在当时完整 SWE-bench 的 2,294 个任务上解决 12.47%(286 个);
  • 在 300 题 SWE-bench Lite 上,SWE-agent 为 18.0%,带示范的 Shell-only 为 11.0%;论文摘要性描述还报告相对默认 Shell 基线多 10.7 个百分点,对照具体配置时应同时看表格与示范条件;
  • 消融中,移除专用编辑、采用逐个翻阅搜索结果、使用完整文件视图或保留完整历史,都比论文选定配置表现更差;
  • 同一 ACI 换用 Claude 3 Opus 也能完成部分任务,说明效果不完全局限于一个基础模型。

证据边界

这些是 2024 年论文在当时模型、数据集、提示、成本上限和实现上的结果。它们支持“ACI 会影响行为与通过率”,但不能证明某个命令集合对所有模型、仓库和预算都最优,也不能当成今天的排行榜。消融同时改变了具体接口配置,不能把全部差异归因于某一个孤立细节。

常见失败模式,以及怎样读懂它们

  1. 搜索过宽:Agent 反复阅读不相关结果。修复方向是限制范围、汇总命中并提示细化查询。
  2. 局部定位错误:找到了同名符号,却没有追踪真正调用路径。需要复现脚本、调用方搜索和测试反馈共同约束。
  3. 编辑循环:连续多次编辑同一区域但不运行代码。这通常说明反馈面不足,或 Agent 没有把测试当成状态观测。
  4. 通过目标测试但制造回归:局部成功不等于仓库验收。ACI 必须能运行适当回归并查看最终 diff。
  5. 过早提交:模型把“代码看起来合理”误作完成。停止条件应绑定外部成功证据,而不是自然语言自信。
  6. 工具过多且重叠:多个命令都能做相近事情,选择本身消耗推理。更好的 ACI 往往是少而清楚,而不是无上限扩充。

历史贡献与今天的工程解释

原典真正建立的观点

SWE-agent 把 HCI 式的接口思考系统性引入语言模型 Agent:模型不是透明地“通过工具接触世界”,而是通过某种被设计过的动作和观察表示接触世界。论文用真实仓库任务和消融说明,接口设计无需更新模型权重也能改变下游表现。

今天可以怎样应用

  • 把工具 schema、参数名、错误语义和输出截断都纳入评测版本管理。
  • 给文件编辑定义原子性:失败时不留下半修改状态,成功时返回修改后的局部证据。
  • 让搜索、日志和测试结果支持过滤、分页或按需展开,而不是默认倾倒全部内容。
  • 记录“模型版本 × 提示 × ACI 版本 × 环境版本”,否则回归时无法判断变化来自哪里。
  • 用真实任务比较接口,而不只让人类阅读工具说明后主观判断“应该更好用”。

不应从论文推出什么

  • 不能推出“定制命令永远优于 Shell”;能力更强的模型、不同任务或改良 Shell 包装可能得到不同结论。
  • 不能推出“通过测试就一定满足产品意图”;测试只覆盖被编码的行为。
  • 不能推出“接口优化可以替代模型能力、仓库质量或评测设计”。ACI 是系统的一层,不是全部。

与 Harness Engineering 的关系

ACI 主要处理 Agent 与计算机交互时的即时动作和观察;Harness Engineering 进一步把范围扩展到仓库知识、隔离环境、架构约束、CI、可观测性、合并方式和持续清理。可以把 ACI 看成 Harness 中最靠近每一步行动的接口层。

自测:你是否真的掌握了 ACI

  1. 为什么“Shell 能表达所有操作”不能反驳 ACI 的价值?
  2. 一个编辑动作返回“成功”为什么还不够?它至少应返回什么状态证据?
  3. 若只更换搜索工具并保持模型、任务、提示和预算不变,这个实验能回答什么?仍有哪些混杂因素?
  4. 为“修改配置解析器”写出至少五步、包含失败回路的 Agent 轨迹。

上一篇:SWE-bench · 下一篇:Building Effective Agents · 返回 里程碑原典目录