Code Researcher整体架构与运行流程如论文中下图所示:
信息输入部分
可以看到,作为信息输入部分,整个Code Researcher以代码仓库及错误报告作为主要信息来源,代码仓库中包含所有的代码细节和代码提交记录,整体庞大而复杂;而错误报告主要是由开源项目kBenchSyz提供的279个Linux内核崩溃信息提供,包含错误堆栈和其他噪音信息。在分析阶段,Code Researcher采用了5类可执行工具:
- search_definition(sym) : 基于全部代码库或指定代码文件的针对函数,字段,关键字等模糊搜索能力search_code(regex) : 正则表达式搜索代码库能力,整个工具中最重要的部分,可以用来搜索函数调用,指针引用及参数赋值等关键行为search_commit(regex) : 正则表达式搜索代码库提交历史能力done : 表述已经获取了足够的信息,完成了上下文收集,可以进入到故障修复环节close_definition(sym) : 在记忆中删除关于某些符号的内容,用于上下文管理
代码走读策略
关于代码走读策略,Code Researcher以迭代往复的方式通过大模型判断是否搜集到了足够的信息,并按照以下三种策略进行上下文收集:
- 控制流与数据流追踪:对于控制流,关注函数调用关系的传递关系,分支与循环等;对于数据流,关注某个变量参数的传递及对另一个变量值的影响。在代码走读过程中,通过对函数全文的搜索得到数据流关系,而通过对关键字符号定义的搜索或设值语句的正则搜索,可以找到数据的传递关系模式与反模式:在代码工程中,认为异常就是代码的反常模式。通过对于某些关键模式的搜索,比如对ptr==NULL的搜索,或者ptr\s=.alloc(.*)模式的搜索,可以找到代码库中的判空模式或者设值模式。(作者注:这点在java中也很常见,比如common-error.log内典型NPE错误中的堆栈指出的位置通常是未进行判空保护)提交历史的搜索与分析:Code Researcher支持在提交记录中按照某些关键字进行正则匹配,找出和关键字相关的提交记录,并作为潜在的故障分析依据。
上下文结构
关于结构化上下文,论文中并没有给出详细的罗列依据,仅在附录中给出的例子。这里,我贴出论文中的一步上下文并进行简要分析:
- 代码搜索工具的结果:在上下文中通常仅包含代码文件名和代码行,符合搜索条件的代码所属方法签名,搜索到的代码行及上下2行代码详情。代码提交历史搜索结果:受限于对话窗口,代码提交的历史结果被压缩到最相关的100行,并且只使用与提问最相关的5次提交记录作为上下文
问题解决合成
在合成阶段,对前面分析过程中获取到的代码及提交内容进行过滤,使用大模型将上下文中与修复崩溃任务无关的动作和结果进行过滤,仅保留与修复崩溃有关的所有上下文信息,利用这部分信息,让大模型尝试对崩溃故障的代码进行修复。在验证阶段,使用相关工具重新编译并运行相关代码片段,如果没有出现崩溃,则认为已经修复了相关故障。
最终效果
从最终的基准测试效果来看,同样是基于GPT-4o作为代码走读推理模型,并使用o1作为补丁生成模型,针对Linux内核故障类问题,Code Researcher可以达到58%的问题解决率,而传统的SWE-agent只能实现37.8%的正确率。同时,针对每一个故障的分析过程,Code Researcher平均阅读了10个代码文件,而SWE-agent只阅读了1.33个代码文件。可以看到,相较于通用的开源SWE-agent,经过精心设计的专业代码问题修复Agent可以实现更多的文件阅读效率和问题解决的正确率。
我们在实践过程中的经验
工作可以从以下方面展开:a. 系统提示词优化:系统提示词的好坏将会对整个Agent执行过程中的问题解决路径及结论正确性产生决定性影响。我们在提示词中对角色设定、代码走读原则、工具使用规范、任务终止条件、任务输出规范、示例参考等进行了详细的描述,并根据实际运行过程中遇到的常见问题不断进行调整和优化。
b. mcp工具优化:mcp工具的优化包括工具description优化和工具设计优化
- description优化:mcp工具的描述信息将会直接影响大模型在推理阶段的工具选择和参数填充,在实践过程中,我们不断收集模型在工具选择和参数填充过程中的错误案例,分析模型这期间的thinking记录,以此不断优化对于工具的描述;工具设计优化:传统的API设计理念是对系统能力的设计使用简洁、一致、可扩展作为设计目的,而提供给大模型的工具更应该从“语言”这一特性出发。比如在工作初期我们使用的代码搜索mcp工具就支持复杂的正则匹配搜索逻辑,乍看之下这个工具非常“强大”,但是依赖模型自主规划填参的Agent去调用时,其参数的填写和使用过程往往非常不尽如人意。即便我们在系统提示词的工具调用规范中罗列了非常多的工具使用规则,仍然在实际使用过程中存在非常多的参数错填情况。而当把工具变成按照关键字进行模糊搜索时,整体成功率提升显著。在这里我们的经验是将复杂的工程逻辑交还给工程,模型只去做其擅长的推理理解、流程控制和工具选择。
c. 业务场景丰富与测试集构建:对于提示词和mcp工具的优化离不开好的测试集作为基准测试对调优结果进行回归验证。在Agent开发最早期,我们只是针对用户对代码运行过程中的系统报错或响应内容中的错误码进行诊断分析,而在实际的代码相关Agent开发过程中,除了错误码理解,还有很多诸如代码接口参数设值链分析,代码接口返回值传递链分析,代码变更影响面评估,db变更影响面评估等诸多场景。我们对已有场景梳理成16大功能类别,并给出50余项测试用例用于日常回归测试。