SWE-agent

一、引言

人类在进行软件工程任务时,从集成开发环境(IDE)中受益。如果把 LLM Agent 看作有需求和能力的终端用户,那它们同样需要配备 LLM 友好的专门接口。基于此诞生的 SWE-agent 是一个帮助 Agent 自主使用计算机解决软件工程任务的系统。通过其自定义的智能体-计算机接口(ACI)与计算机交互,强智能体创建和编辑代码文件、浏览代码仓库以及执行测试和其他程序的能力得到显著增强。

ACI 提供了一组用于查看、搜索和编辑文件的简单操作。采用护栏机制来防止常见错误,并在每一步操作后,Agent 都会受到关于命令执行结果的简洁反馈。

二、ACI 的设计

1 核心目标

  • 帮助 Agent 在历经先前的操作后,依然清晰地理解应用都当前状态
  • 妥善管理历史信息,避免过往的上下文产生干扰 (上下文腐烂)
  • 提供一套让 Agent 高效、可靠调用的动作指令
  • 通过指令动作的文档说明以及环境反馈机制弥补语言模型 (LM) 的短板

基于此,SWE-agent

  • 规定 LM 的可用命令
  • 定义了如何将环境状态反馈给 LM
  • 追踪所有历史命令与观察结果,并在每一步中管理这些信息的格式化与整合方式,将其与高层指令合并输入给 LM

作者通过网格搜索筛选出了最佳的 ACI 配置

2 设计原则

  • 动作应当简单易懂(精简指令集)
  • 动作应当紧凑高效(原子操作):重要操作(如编辑)应当尽可能整合到最少的动作中(步骤少,最好一步完成)
  • 环境反馈应当信息丰富但简洁:环境状态和 Agent 近期操作的影响
  • 护栏机制减轻错误传播并加速恢复:例如语法检查器,可以帮助智能体识别迅速纠错

3 核心组件

包括 搜索与导航、文件查看器、文件编辑器以及上下文管理。

在每一步操作中,SWE-agent 都会先生成一段“思考”和一个具体命令,随后将命令在环境中执行后的反馈结果整合进来。(ReAct)

1)搜索与导航

用于在代码库中进行导航,找到相关的文件和具体内容

  • find_file :代码库中搜索文件名
  • search_file:文件中定位字符串
  • search_dir:目录中定位字符串

搜索文件名或文件/目录内的字符串,输出搜索结果摘要。

每次搜索最多返回50条结果,如果超过,就建议智能体编写一个更具体的查询(防上下文过载)

2)文件查看器

Agent 找到想查看的文件后,调用 open 命令使用交互式文件查看器,每次做多显示100行内容,Agent 可使用 scroll_downscroll_up 来移动显示窗口,或 goto 命令直接跳转到指定行。

为了方便文件内导航和定位代码,还会显示文件的完整路径,文件总行数、当前窗口前后省略的行数,以及每行可见代码前标注的行号

3)文件编辑器

让 LM 有创建和编辑文件的能力。edit命令与文件查看器配合使用,允许 Agent 替换当前打开文件中特定范围的行。命令的三个参数:起始行号、结束行号和替换文本。编辑后,文件查看器自动显示更新后的内容,帮助 Agent 立即观察到效果。

在编辑功能中集成了一个代码检查器,以便在 Agent 编辑文件时,提醒其可能引入的错误。筛选出的部分错误会连同编辑前后的文件内容片段,展示给 Agent。无效编辑会直接丢弃,要求 Agent 重新尝试编辑。

这种设计能大大降低智能体在写代码时“越改越乱”的概率!

4)上下文管理

SWE-agent 通过提供丰富信息的提示词、错误消息以及历史处理器确保上下文简洁且信息丰富。
Agent 会受到关于如何正确使用 bash 和 ACI 命令的指令、文档以及演示。

每一步操作中,要求 Agent 生成思考和行动,如果生成的格式不正确、系统会触发错误响应,要求 Agent 重试、直到收到格式正确的生成为止,并忽略所有错误历史生成。

环境响应会用特定模板来显示计算机的输出,但如果没有输出,也会包含:“命令执行成功,未产生任何输出”。

为了进一步提高上下文的相关性,最近 5 条之前的观察记录会被折叠。通过移除过往观察记录中的大部分内容,保留计划和行动等核心信息。这样大幅减少不必要的上下文。

三、SWE-agent 的行为

成功的往往更早结束,花的 token 也更少:“如果它迟迟解不出来,大概率是解不出来了”。成功的任务通常干脆利落,而失败的任务往往是在反复试错中白白消耗预算。所以,与其盲目给智能体加预算,不如去优化它的思考路径和工具使用效率!

我们在给 AI 设计工具(ACI)时,其实就是在通过观察 AI 怎么用工具、哪里会卡壳,来反向研究“AI 到底是怎么思考的”。这就像心理学家通过观察人类怎么使用工具来研究人类心理一样。

四、ACI 组件配置

  1. 提示词模板(Prompt templates):这些模板用于向语言模型阐明任务设定、展示可用命令列表、将状态变量的值注入环境响应中以增强上下文,并提供初始的任务背景信息。
  2. 命令文件(Command files):这些文件包含了 Bash 或 Python 函数及脚本的源代码。通过直接操作这些文件的代码内容,可以轻松地对命令进行修改、添加或删除。此外,文件中添加的文档说明也可以被注入提示词中,从而帮助模型了解可用的命令。
  3. 控制流(Control flow):可以通过配置参数来指定解析模型响应以及处理历史对话记录的具体方法。
  4. 环境变量(Environment variables):在配置中还可以指定那些可能与命令及 Shell 交互的变量的初始值。

配置可以写在 yaml 文件中,定义 Agent 可以使用的命令、编写在单次任务轨迹中展示给 Agent 的提示词、控制 Agent 和 环境之间的输入/输出接口

五、提示词的设计

0 提示词工作流

  1. 系统提示词、演示、问题模板在任务周期(episode)的一开始提供给 LM
  2. LM推理后生成思考和行动
  3. 根据生成,在环境中执行行动
  4. 下一步的提示词(包含输出)、没有输出的下一步提示词、错误提示,模型须重试

1 系统提示词模板

描述了交互任务的设定、Agent 可调用的命令以及预期的回复格式。是任何一次任务周期(episode)中的第一条消息,其内容在所有任务实例中保持不变,并且在消息历史记录中用还不会被移除或折叠。

**SETTING**:You are an...
**COMMANDS**:{documentation}
**RESPONSE FORMAT**:
your output using two fields; discussion and command. Your output should always include *one* discussion and *one* command field EXACTLY as in the following example:
### DISCUSSION
First I’ll start by using ls to see what files are in the current directory. Then maybe we can look at some
relevant files to see what they look like.
```
ls -a
```
You should only include a *SINGLE* command in the command section and then wait for a response from the shell before continue with more dicussion and commands.

最后这段告诉 LM 命令区域只能包含一条命令然后等待 shell 返回响应才能继续后续的讨论或下达新命令。讨论区域中输入的所有内容会被保存, 以便后续参考。除了上述列出的特殊命令外,可以自由使用其他 bash 命令(find、grep、cat、ls、cd 等)
COMMAND {documentation} 的内容为

CategoryCommandDocumentation
File vieweropen <path> [<line_number>]Opens the file at the given path in the editor. If line_number is provided, the window will move to include that line.
goto <line_number>Moves the window to show line_number.
scroll_downMoves the window up 100 lines.
scroll_upMoves the window down 100 lines.
Search toolssearch_file <search_term> [<file>]Searches for search_term in file. If file is not provided, searches in the current open file.
search_dir <search_term> [<dir>]Searches for search_term in all files in dir. If dir is not provided, searches in the current directory.
find_file <file_name> [<dir>]Finds all files with the given name in dir. If dir is not provided, searches in the current directory.
File editingedit <n>:<m> <replacement_text>
end_of_edit
Replaces lines n through m (inclusive) with the given text in the open file. All of the replacement_text will be entered, so make sure your indentation is formatted properly. Python files will be checked for syntax errors after the edit. If an error is found, the edit will not be executed. Reading the error message and modifying your command is recommended as issuing the same command will return the same error.
create <filename>Creates and opens a new file with the given name.
TasksubmitGenerates and submits the patch from all previous edits and closes the shell.

2 演示提示词模板

系统提示词后,作为第二条消息。向 Agent 展示一个完整的任务轨迹,即开发集中某个任务实例是如何被成功解决的。一定程度上帮 LM 理解正确的指令用法,让 Agent 能发出格式正确的指令。

Here is a demonstration of how to correctly accomplish this task.
It is included to show you how to correctly use the interface.
You do not need to follow exactly what is done in the demonstration.
--- DEMONSTRATION ---
{{INSTANCE PROMPT}}
......
--- END OF DEMONSTRATION ---

3 实例提示词模板

向 Agent 介绍具体的任务实例。

  1. 展示问题陈述

  2. 一段简短的指令,重申系统模板中的几个关键点

    • 每轮交互只能有一个思考或动作

    • 不支持的交互式 shell 命令

    • 提醒它注意编辑代码时的缩进问题

  3. 提示(tips,这些提示是作者反复试错,从失败中总结出来的)

We're currently solving the following issue within our repository.
Here's the issue text:
ISSUE:

IMPORTANT TIPS:
1.xxx
2.xxx

(Open file: {open_file})
(Current directory: {working_dir})
bash-$

最后的命令行提示符,标志任务正式开始,Agent 应该发出它的第一个命令

4 下一步提示词模板

如果 Agent 回复规范且包含一个具体动作,系统会使用两种简单的模板来呈现动作的输出结果。

{OBSERVATION}
(Open file: /path/to/open/file.py)
(Current directory: /path/to/cwd)
bash-$

最后一个提示符,提示 Agent 继续发出下一个动作

如果动作没有产生输出,不展示任何输出的话会引起 Agent 困惑,这种情况下仍需告知:

the command ran successfully and did not produce output

5 旧观察结果折叠提示词模板

旧的观察结果会被折叠,并被替换为一行占位符,告知 Agent 观察结果被省略并标明被折叠的行数

Old output omitted (101 lines)

目的是减少token和过时信息的干扰

6 错误信息提示词模板

Agent 的回复不总是格式规范。一旦发生不规范的回复,向 Agent 展示一条错误信息,明确指出,并要求重新生成,且不要再犯错

Your output was not formatted correctly. You must always include one
discussion and one command as part of your response. Make sure you do
not have multiple discussion/command tags.
Please make sure your output precisely matches the following format:
DISCUSSION
Discuss here with yourself about what your planning and what you're
going to do in this step.
```
command(s) that you're going to run
```

如果 Agent 生成格式不规范的回复,随后又生成了有效的回复,系统会修改消息历史,将错误回复及其动作移除(去噪)。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐