字节跳动技术团队 2024年10月25日
豆包MarsCode Agent 登顶 SWE-bench Lite 评测集
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

豆包MarsCode Agent在软件工程领域展现出强大能力,涵盖多Agent协作框架、代码检索、代码编辑等方面,在SWE-bench Lite评测中表现优异

豆包MarsCode开发了多Agent协作框架,包含Searcher、Manager等7类角色,根据问题类型分配求解管道,适应不同开发场景,各Agent配备相应工具集,在动态和静态修复场景下有不同的协作求解流程

为Agent提供多种跨语言适配的代码检索工具,包括代码知识图谱、语言服务器协议等,代码知识图谱能实现广泛全面的代码检索,语言服务器协议解决部分盲区问题,还统一封装了其他通用检索能力

开发相对稳定的代码编辑方式豆包MarsCode AutoDiff,其编辑描述与git冲突表现方式类似,编辑后进行静态代码诊断,检查是否引入新错误

在SWE-bench Lite数据集上评测,豆包MarsCode Agent成功求解118个实例,求解率达39.33%,在错误定位能力上处于领先地位,且分析了动态静态求解的实例分布

2024-10-24 18:03 重庆


大语言模型(LLM)能力正在迅速提升,对包括软件工程在内的诸多行业产生了深远影响。GPT-4o、Claude3.5 等 LLM 已经逐步展现出胜任复杂任务的能力,例如文本总结、智能客服、代码生成,甚至能够分析和解决数学问题。在这一趋势下,AI Agent,即能够感知外部环境、操作工具并具有一定自主决策能力的智能体,受到了越来越多的研究关注。

豆包MarsCode 在软件工程领域进行了一系列关于 AI Agent 应用的探索和尝试,通过构建 Agent 框架并为其提供代码检索、调试和编辑的交互接口和工具,使得 Agent 有可能接管部分软件工程开发任务。

SWE-bench Lite 是由普林斯顿大学提出的一个极具挑战性的、针对 LLM 解决真实 GitHub Issue 的 benchmark,近期受到工业界、学术界和创业团队的广泛关注。近日,豆包MarsCode Agent在 SWE-bench Lite 排行榜上位列第一。


01

多 Agent 协作框架

开发者在日常的开发工作中常常会遇到各种问题,例如:

上述多样化的程序修复和开发任务通常无法用一种固定的模式来进行处理。例如,一些简单的缺陷修复或功能扩展仅需对代码进行 review 即可完成;而较深的异常堆栈或复杂的逻辑错误仅凭阅读代码往往很难发现问题所在,需要通过动态执行代码并追踪相关变量才能暴露出相关缺陷,从而对其进行修复。

因此,我们采用了多 Agent 协作的框架来适应不同的开发场景。如下图所示,多 Agent 协作框架中包含以下 7 类角色:

我们为不同的 Agent 配备了相应的工具集以支撑其完成指定任务,各 Agent 配备的工具集如下表所示。值得注意的是,我们并没有令每个 Agent 都拥有所有工具的使用权,而是尝试限制各个 Agent 的能力和职责范围,从而降低单个 Agent 解决当前环节问题的难度,以提高任务执行的稳定性和输出结果的质量。

在动态调试修复场景下,各 Agent 的协作求解流程如下:

a.若问题已解决,则通过 diff 工具获取当前代码变更作为该问题的修复方案,动态调试结束;

b.若仍未解决,则再次将复现过程中异常堆栈和其他输出信息返回给 Programmer;

在动态过程中,我们通过在 Docker 容器中搭建一个运行环境沙箱,以实现动态调试的问题复现和运行验证。

在静态修复场景下,由于无法直接对问题进行复现和动态验证,需要制定针对该问题的静态修复方案。过程如下:


02

代码检索

我们为豆包MarsCode Agent 提供了多种可跨语言适配的代码检索工具,以适应各种软件工程开发场景下的代码检索需求。

代码知识图谱

Code Knowledge Graph

代码知识图谱是将代码元素、属性以及元素之间的关系表示为图结构,从而帮助 Agent 更好地理解和管理大规模的代码库。在这种图结构中,顶点代表代码的实体(如函数、变量、类等),边则代表实体之间的关系(如函数调用、变量引用、类的继承关系等)。通过这种方式,代码知识图谱可以为代码库提供更丰富且结构化的信息。

我们通过程序分析的技术,将仓库中的代码,文档信息进行分析组织,生成一个以变量,函数,类,文件等代码语义节点为实体,文件结构关系、函数调用关系,符号索引关系为边的多向图。构成一张融合了代码,文档,仓库信息等多数据源的代码知识图谱。

在给定的代码库中,每个节点和边都通过唯一标识符进行标记,确保每个代码实体在整个代码库中都是唯一的。在这种设计中,代码知识图谱将使用图属性来存储代码实体及其依赖关系。每个节点记录其在代码库中的位置、类型和名称。每条边标识两个节点之间的关系类型,以及关系在代码中的位置。

比如对下面这样一段代码:

// file: main/fileA.gopackage main
import (    "ckg-prompt/main/cmd/pkg_b"    "fmt")
// StructA structtype StructA struct{}
// FunctionA method for StructAfunc (a *StructA) FunctionA() pkg_b.StructB {    x := pkg_b.NewStructB() // Instantiate StructB    return x}
// XFunction functionfunc XFunction() {    x := pkg_b.NewStructB() // Instantiate StructB    x.FunctionB() // Calls FunctionB}

它的代码知识图谱如下图所示:

图1 代码知识图谱元素构成

在构建完成代码知识图谱后,Agent 的代码检索请求将通过下图中的管道进行处理并实现召回。

最后将候选实体列表 1 & 2 & 3 进行合并,通过精排模型,得到最终实体列表 X,返回给 Agent,完成代码检索。

图2 代码知识图谱召回流程

在豆包MarsCode Agent 中,代码知识图谱工具能够实现广泛、全面的代码检索,为 Agent 提供了 repo 内知识问答的能力。目前,代码知识图谱支持包含 C、C#、CPP、Java、Kotlin、Javascript、Typescript、TSX、Rust、Golang、Python、Lua 在内的 12 种常用编程语言。


语言服务器协议

Language Server Protocol

代码知识图谱能够应对大部分目标工程下的类、函数定义与引用的检索需求,但仍存在以下盲区:

为解决上述问题,豆包MarsCode Agent 利用通用的语言服务协议(Language Server Protocol)实现用户机器上全局、精确的代码召回。

语言服务器协议是一种由 Microsoft 开发的协议,广泛适配包含编程语言、标记语言、多种工具和框架在内的语法体系,在 IDE 场景下具有很好的通用性。豆包MarsCode Agent 调用语言服务器协议实现代码召回的过程如下图所示:

图3 语言服务的召回流程

Agent 调用语言服务器进行代码召回的过程与开发者在 IDE 中使用“Ctrl+左键”点击某个标识符进行代码跳转的过程是一致的,但由于 Agent 的数字定位和计算能力较弱,我们增加了模糊定位功能以进一步强化 Agent 使用 LSP 工具的能力:

这三个服务的优先级自上而下由高到低,使用第一个成功得到响应的 LSP 请求结果作为工具的输出。


其他通用检索能力

除 LSP 和 CKG 外,我们将通用的项目内文件检索(find file)、项目或文件内标识符检索(grep)等能力在豆包MarsCode Agent 框架下进行统一的封装,从而为 Agent 提供调用风格一致的代码检索工具库。


03

代码编辑

代码编辑描述

在我们对研发域 AI Agent 的长期探索过程中,尝试了各种使用 LLM 进行代码编辑描述的方式,发现目前 LLM 的代码修改能力普遍较弱。如下是我们曾经探索(失败)过的代码编辑方案:

Unified diff 格式的变更是将原始文件和修改后文件以一种统一的方式展示出来,比如:

--- example.txt+++ example.txt@@ -1,4 +1,4 @@ This is a sample file.-It contains multiple lines of text.-Here is another line.-Goodbye!+It contains a few lines of text.+Here is yet another line.+See you later!

Unified diff 的代码编辑描述有着非常严格的格式要求,而且 LLM 很难正确计算变更的代码行号增量,从而导致生成的 Unified diff 无法成功 apply。

我们在所有的代码检索的结果中都对代码添加了行号,希望 Agent 能正确填写修改范围并完成修改,然而即便是 GPT-4,也不能完全正确地提供需要修改的代码范围,时常会出现 1~2 行的偏移,从而导致修改后出现重复行或误删;

为 LLM 提供整个文件的内容和修改描述,要求  LLM 输出修改后的完整文件内容。这种方式能够避免 LLM 进行行号的计算,但显然每次代码编辑都使用闭源模型生成整个文件是非常不经济的,且在一些长文件中几乎不可用。我们也正在尝试通过 SFT 获取一个专门的代码编辑模型实现全文重写的能力,但这是一个长期计划。

经过大量的探索和尝试,我们认为 LLM 的代码编辑描述需要具备以下特点:

基于此,我们注意到 Aider 的代码变更方式(https://aider.chat/docs/benchmarks.html#the-benchmark),受此启发并开发了我们目前认为相对稳定的代码编辑:豆包MarsCode AutoDiff。

AutoDiff 的代码编辑描述与 git 冲突的表现方式是类似的,Agent 需要在 Conflict 标识栅栏中提供需要编辑的文件路径、代码原文、替换代码。AutoDiff 会对该代码编辑块进行解析,尝试在给定文件中匹配与 LLM 提供代码原文片段相似度最高的片段,并用 LLM 提供的替换代码进行替换操作,随后结合修改文件的上下文对替换代码的缩进进行自动调整。最后修改前后的文件进行差异对照从而获取 Unified diff 格式的变更文件。上述修改是模拟进行的,并未实际在用户设备上落盘,只是为了获取 Unified diff 格式的变更文件,最终代码修改需要经过后续的静态代码诊断。

```diffs/playground/swe_ws/testbed/matplotlib__matplotlib__3.6/lib/matplotlib/figure.py<<<<<<< SEARCH        elif constrained_layout is not None:=======        elif constrained_layout in [None, False]:>>>>>>> REPLACE
<<<<<<< SEARCH        else:=======        elif constrained_layout in [None, False]:            self.set_layout_engine(layout='none')>>>>>>> REPLACE

静态代码诊断

尽管 AutoDiff 能够正确完成大部分的代码编辑请求,但仍然会存在诸如类型错误、变量未定义、缩进调整错误、括号没有正确闭合等 LLM 常见的代码编辑语法问题,针对这些问题,我们使用语言服务器协议对 AutoDiff 修改前后的文件进行静态代码诊断,过程如下:

图4 代码编辑过程中的静态代码诊断


04

实验结果分析


我们在 SWE-bench Lite 数据集上对豆包MarsCode Agent 的性能进行了详细评测。

SWE-bench 是由普林斯顿大学提出了一个极具挑战性的针对 LLM 解决程序逻辑 bug 的 benchmark。该数据集整理了真实的来自 Github 的12 个工业级 Python 代码大仓中的 2294 个 issue 问题。给定一个代码库以及对要解决 issue 问题描述, Agent 需要从代码仓中检索并编辑代码,最终提交能解决相关问题的代码补丁。在 SWE-bench 中解决问题通常需要同时理解和协调多个函数、类甚至文件之间的更改,要求模型与执行环境交互,处理极长的上下文并执行比传统代码生成更复杂的推理。作者评估表明,Claude2 和 GPT4 仅能解决其中 4.8%和 1.7%的实例。

SWE-bench 中测试实例在各 repo 中的分布

不同代码仓样本的求解难度也参差不齐


由于 SWE-bench 的难度很大,在后续的研究中,开发者们发现在 SWE-bench 的2294个实例上进行评测是一个时间与 Token 投入巨大且令人沮丧的过程,无法验证短期内的进展。所以 SWE-bench 作者从原本的数据集中抽取了300个 Issue 描述完整、求解逻辑清晰、相对易于解决的300个实例,组成 SWE-bench Lite 数据集。目前,SWE-bench Lite 数据集已经成为 Agent 解决软件工程问题水平的评测标杆,已有20多家企业与研究组织参与了 SWE-bench Lite 评测和提交中。

豆包MarsCode Agent 在最新的 SWE-bench Lite 评测实验中,成功求解了其中的 118个实例,求解率达到39.33%。

下表展示了评测实验结果的详细分析:

豆包MarsCode Agent 的错误定位能力

我们对目前 SWE-bench Lite 排行榜上排名前三的工具(CodeStory Aide,Honeycomb 和 AbanteAI MentaBot)进行了错误定位能力评估。对于一个 patch,如果它修改的文件和 gold patch 所修改的文件相同,则认为错误定位正确,否则错误。分析结果如图6所示:

豆包MarsCode Agent 通过代码知识图谱、语言服务等代码检索工具,在300个实例中成功定位到了 245 个实例的待修改文件(成功率81.7%),而 CodeStory Aide 为221(成功率73.7%),Honeycomb为213(成功率71%),AbanteAI MentatBot 为211(成功率70.3%)。从代码检索和错误定位能力看,豆包MarsCode Agent 处于领先地位。

图6 各方案在成功解决数量、成功定位上的对比

豆包MarsCode Agent 动态静态求解的实例分布

我们分析了实验中静态和动态求解的实例分布,如下图所示,在所有实例中,有104 / 300 = 34.67%的实例被 Planner Agent 认为适合动态求解,196 / 300 = 65.3%的实例被认为适合进行静态求解,通过动态方式成功求解53个实例,求解率为51%,静态方式成功求解65个实例,求解率为33%。由于动态调试有缺陷复现和和验证的过程,表现在求解率上略高于静态修复。在被求解的118个实例中,有44.9%的实例是由动态方式修复,55.1%的实例由静态方式修复。

图8 豆包MarsCode Agent 实验中

静态与动态求解分布


05

未来展望

豆包MarsCode Agent 团队致力于 AI Agent 方法在软件工程领域的落地和应用。在未来将持续关注以下优化方向:

欢迎大家通过我们的论文了解更多信息:https://arxiv.org/abs/2409.00899





加入我们

大模型算法研究员(校招):

https://job.toutiao.com/s/ikWpYxK6

算法实习生-开发者AI(实习):

https://job.toutiao.com/s/ikWsMK7x


阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

豆包MarsCode Agent 软件工程 代码检索 代码编辑 SWE-bench Lite
相关文章