SWE-agent:普林斯顿开源的自主软件工程智能体
📖 简介
📝 详细介绍
1. 开篇:从一场"扫雷"式的代码巡检说起
今年Q2,我接手了一个遗留的微服务仓库,12万行核心代码,团队只有4人,但线上Issue积压了300+。每次迭代光处理存量缺陷就要花掉一半人力,新功能排期被无限后压。业务方天天催,研发同学被反复打断,士气很低。
我当时的第一个念头是:能不能让一个AI智能体自动完成代码库巡检、定位疑似缺陷、并直接生成修复补丁,把工程师从"刷Issue列表"的低效劳动中解放出来?
2. 需求拆解
把"缓解存量缺陷压力"这个业务问题拆成技术指标:
- 数据:代码托管在自建GitLab,需支持SVN式目录结构、多分支并行,且要求至少1万+代码文件的克隆/浏览速度可接受;
- 性能:单个Issue从定位到输出补丁,平均耗时不能超过10分钟(人工基线为80分钟/Issue);
- 成本:每个Issue的分析token成本控制在0.7美元以内,否则300个存量Issue的清理成本会失控;
- 部署约束:公司内网隔离,无法直接联网访问HuggingFace或OpenAI API,必须走私有化模型网关。
3. 方案设计:为什么押注SWE-agent
备选方案我评估了CrewAI和AutoGPT。CrewAI灵活性高但侧重多角色编排,对代码仓的文件系统级操作(如git diff)支持薄弱;AutoGPT输出不稳定,且需要额外的沙箱容器做命令执行,工程改动量大。
SWE-agent正好卡在"自主文件操作"与"结构化输出"的交叉点:它原生实现了Agent-Computer Interface(ACI),内置基于SQLite的文件查看器、正则搜索、编辑与重写工具,并且输出严格遵循Observation/Action格式。这意味着我可以直接复用它的标准Docker镜像,在自建GitLab上通过SSH拉代码,改造面最小。
最终取舍:不重新造Agent框架,只做模型接入和审计日志层的适配。
4. 落地实现
4.1 数据准备:代码仓蒸馏
SWE-agent默认按Issue粒度运行。初期我们只喂high-priority标签的Issue,并做了三步清洗:
# 1. 从GitLab导出全部Issue元数据(标题/描述/标签)
glab api "projects/:id/issues?labels=high-priority&state=opened" > issues.json
# 2. 过滤掉无代码关联的纯配置类Issue(只保留包含.py/.java/.sql路径的)
jq '.[] | select(.description | test("(src/|*.py|*.java)"))' issues.json > filtered_issues.json
# 3. 将Markdown描述转换为SWE-agent统一输入格式(problem_statement + hint)
python3 convert_to_swe_format.py --input filtered_issues.json --output swe_input/
关键配置:在swe_input/中为每个Issue单独建目录,并在reproduce.py里写入最小复现用例(无用例的直接标记为skip)。
4.2 构建:模型网关对接与推理参数
由于内网模型网关只兼容OpenAI协议,我在config.yaml中直接指定了base_url:
# config.yaml
model:
name: "code-llama-34b-instruct"
base_url: "http://10.0.8.5:8000/v1"
api_key: "internal-gateway-key"
temperature: 0.2
max_tokens: 4096
# 构建镜像(预拉取依赖,避免运行时外网请求)
docker build -t swe-agent:internal .
--build-arg HUGGINGFACE_OFFLINE=1
--build-arg PIP_INDEX_URL=http://mirrors.internal/pypi/simple/
4.3 部署:基于Docker Compose的批量任务队列
直接跑官方命令效率太低,我包装了一个循环批量处理脚本:
#!/bin/bash
# batch_run.sh
export SWE_AGENT_MODEL=codellama34b
export SWE_AGENT_MAX_ROUNDS=15
for issue_dir in swe_input/*/; do
issue_id=$(basename $issue_dir)
mkdir -p output/$issue_id
docker run --rm
-v $(pwd)/$issue_dir:/workspace/issue
-v $(pwd)/output/$issue_id:/workspace/output
-v /etc/gitlab-ssh:/root/.ssh
swe-agent:internal
--config config.yaml
--repo /workspace/repo
--problem_file /workspace/issue/problem.md
--output_dir /workspace/output || true
done
这里把SSH密钥目录挂载进容器,让Agent能直接git pull与git push到内部的feature分支。
5. 效果与数据
运行一周后(实际处理26个高优先级Issue),与历史人工统计对比:
| 指标 | 人工基线 | SWE-agent | 变化 |
|---|---|---|---|
| 单个Issue平均响应时长 | 80分钟 | 7.2分钟 | ↓91%(估) |
| 高优先级Issue识别准确率 | 78% | 84% | ↑6% |
| 补丁被review接受的比率 | 75% | 58% | 纯数据,小幅下降 |
| 单个Issue的token成本 | / | 0.52美元 | 低于0.7预算 |
注:响应时长和成本为估算值,基于日志中的Token消耗和Docker容器运行时长计算。
6. 踩过的坑
6.1 LLM重复生成同一修复动作导致死循环
现象:Agent在尝试修改一个文件时,连续输出完全相同的edit命令四次,直至达到max_turns=15上限,且没有新的分析日志。
排查:查看SWE-agent的日志输出,发现前一次的edit实际已经成功(文件已变更),但Agent的上下文观察里显示No changes。问题出在file_viewer输出的缓存——旧URL未失效。
解决:在config.yaml中关闭文件查看器缓存,并设置max_retries_before_fail: 2,强制Agent在连续相同动作时走replan逻辑。
6.2 私有网关的json_mode兼容
现象:部署后API返回200,但Agent始终拿不到带结构体签名的工具调用响应,所有动作卡在EXPLORATION阶段。
排查:用curl直接打网关对比,发现响应里的finish_reason是stop而非tool_calls,内网网关不支持OpenAI的tools协议。
解决:在模型配置中强制engine: "code-llama-34b-instruct-tool",在网关侧做一个轻量适配层,将tool_calls转换为带JSON的纯文本,再通过output_parser提取。这一层大约加了50行Python代码。
7. 复盘与扩展
做对的事:优先选择与代码仓操作强绑定的SWE-agent而非通用Agent框架;对所有模型输出加了独立审计日志目录,方便回溯错误补丁。
可改进的:补丁率只有58%,很大程度是因为我们没有在reproduce.py里投入足够的测试用例编写时间。下次应优先让Agent生成pytest失败用例再修复,而不是直接改代码。
扩展方向:目前只能处理单Issue闭环,未来可以接入仓库的CI流水线,让SWE-agent直接创建Merge Request并唤起人工审批,形成真正的自动维修闭环。
AI 项目推荐
智能体- 标签
- #AI编程 #软件工程 #智能体 #普林斯顿
- 浏览
- 👁️ 14
- 发布日期
- 2026-08-30