SWE-agent Traj Analysis

SWE-Agent Trajectory 分析报告

Traj 文件: scikit-learn__scikit-learn-i25076.traj 分析日期: 2026-07-06


目录

  1. 什么是 SWE-Agent 和 Traj 文件?
  2. 本次任务概述
  3. Traj 文件结构详解
  4. Agent 执行过程逐步分析
  5. 核心问题诊断
  6. 失败原因深度分析
  7. 关键指标与数据
  8. 初学者阅读 Traj 的指南
  9. 总结与启示

1. 什么是 SWE-Agent 和 Traj 文件?

SWE-Agent 是什么?

SWE-Agent 是一个自动化软件工程 Agent。它像是一个 AI 程序员,能够:

  • 阅读 GitHub 上的 Issue / PR 描述
  • 理解需要修改什么代码
  • 自己在代码仓库中搜索、读取文件
  • 编写脚本复现问题
  • 修改源代码来修复 Bug
  • 验证修复是否生效

可以把 SWE-Agent 想象成一个”AI 初级工程师”,你给它一个任务描述,它会自动尝试完成。

Traj(Trajectory)文件是什么?

Traj = Trajectory = 轨迹。这个文件记录了 Agent 的每一步思考和行动,就像一个”黑匣子”:

  • Agent 看到了什么(observation / 观察)
  • Agent 想了什么(thought / 思考)
  • Agent 做了什么(action / 动作)
  • 花了多长时间(execution_time / 执行时间)
  • 结果是什么(observation / 观察结果)

阅读 traj 文件,就像回放 Agent 的整个工作过程。这对于调试、分析失败原因、改进 Agent 非常有价值。

本次使用的模型

从配置文件可以看到,本次使用的是 openai/qwen-local——一个部署在本地的 Qwen(通义千问)开源模型,通过 http://localhost:8000/v1 提供 API 服务。这不是 GPT-4 或 Claude 等高级模型,而是一个本地运行的开源小模型


2. 本次任务概述

任务来源

任务内容

在 scikit-learn 的文档配置文件 doc/conf.py 中,将以下 URL 添加到 linkcheck_ignore 列表中:

1
https://github.com/joblib/threadpoolctl/#setting-the-maximum-size-of-thread-pools

背景说明: - scikit-learn 使用 Sphinx 构建文档 - Sphinx 的 linkcheck 功能会自动检查文档中外链的有效性 - 但是有些链接在浏览器中可以正常打开,却因为各种原因被 linkcheck 误报为”broken”(损坏的链接) - linkcheck_ignore 是一个配置列表,放在 doc/conf.py 中,用来告诉 Sphinx “这些链接不用检查” - 这个 PR 的目的就是把 threadpoolctl 的链接加入忽略列表

一句话总结:这个任务非常简单——找到配置文件,在已有的忽略列表里加一行 URL。


3. Traj 文件结构详解

这个 traj 文件是一个 JSON 格式的文件,包含以下几个顶层字段:

1
2
3
4
5
├── trajectory (核心) - 28 个步骤的详细记录
├── history - 52 条完整对话消息(系统+用户+助手)
├── info - 运行元数据(耗时、成本、编辑文件等)
├── replay_config - 完整的 Agent 配置(环境、模型、模板等)
└── environment - 环境标识("main")

3.1 trajectory 数组中每个步骤的结构

每一步(step)都是一个 JSON 对象:

1
2
3
4
5
6
7
8
9
10
{
"action": "python test_link.py\n", // Agent 执行的命令
"observation": "python: can't open...", // 命令执行后的输出
"response": "To address the issue...", // Agent 的文字回复(给用户看的)
"thought": "To address the issue...", // Agent 的内心思考
"execution_time": 0.1352, // 执行耗时(秒)
"state": { "working_dir": "/" }, // 当前工作目录
"query": [ ... ], // 发送给 LLM 的完整对话上下文
"extra_info": {} // 额外信息
}

重要字段说明

字段 含义 谁看
action Agent 决定执行的 bash 命令 环境执行
observation 命令的 stdout/stderr 输出 反馈给 Agent
response Agent 生成的自然语言回复 用户看到
thought Agent 的推理过程 用户看到
query 发送给 LLM 的完整 prompt 模型处理

3.2 query 中的消息类型

每条 query 消息都有 message_type 标识:

message_type 含义
system_prompt 系统提示词,定义 Agent 的角色
observation 环境反馈(用户消息形式,包含执行结果)
action Agent 的决策结果(模型输出)

3.3 info 中的关键指标

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"exit_status": "exit_format", // 退出原因
"edited_files30": "Empty...", // 编辑的文件(30次采样)
"edited_files50": "Empty...", // 编辑的文件(50次采样)
"edited_files70": "Empty...", // 编辑的文件(70次采样)
"submission": null, // 提交状态
"model_stats": {
"instance_cost": 0, // 花费:0(本地模型免费)
"tokens_sent": 236887, // 发送给模型的 token 数
"tokens_received": 15035, // 模型返回的 token 数
"api_calls": 27 // API 调用次数
}
}

4. Agent 执行过程逐步分析

整个轨迹共有 28 步(Step 0 ~ Step 27)。下面按照不同阶段来分析。

阶段一:重复的错误循环(Step 0 ~ Step 23,共 24 步)

这是整个轨迹最显著的特征——Agent 在 24 个连续步骤中做的是完全相同的事情

每一步发生了什么呢?

Agent 的 Action(动作)

1
python test_link.py

Environment 的 Observation(反馈)

1
python: can't open file '//test_link.py': [Errno 2] No such file or directory

Agent 的 Response(回复) - 每次都几乎一样:

“To address the issue described in the PR description, we need to add the specified URL to the linkcheck_ignore list…”

然后 Agent 会重复说明一个 5 步方案: 1. 找到并阅读相关代码 2. 创建一个 test_link.py 脚本来复现错误 3. 编辑 conf.py 文件,添加 URL 4. 重新运行脚本验证修复 5. 考虑边缘情况

画成流程图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌─────────────────────────────────────────────────┐
│ Step 0: Agent → 运行 python test_link.py │
│ 环境 → 错误:文件不存在 │
│ Agent → 「让我来告诉你该怎么做…」 │
├─────────────────────────────────────────────────┤
│ Step 1: Agent → 运行 python test_link.py │
│ 环境 → 错误:文件不存在 │
│ Agent → 「让我来告诉你该怎么做…」 │
├─────────────────────────────────────────────────┤
│ ... 重复 22 次 ... │
├─────────────────────────────────────────────────┤
│ Step 23: Agent → 运行 python test_link.py │
│ 环境 → 错误:文件不存在 │
│ Agent → 「让我来告诉你该怎么做…」 │
└─────────────────────────────────────────────────┘

核心问题:Agent 在”说”但不在”做”

Agent 的 responsethought 中描述了要做的事情,但它的 action 从未跟进: - 它说”创建 test_link.py”但从不执行 echo '...' > test_link.pycat > test_link.py - 它说”编辑 conf.py”但从不使用 str_replace_editor 工具 - 它说了 24 次”让我们找到配置文件”,但从未执行过 findgrep 命令

阶段二:尝试直接执行 Python 代码(Step 24 ~ Step 26,共 3 步)

在 Step 24-26 中,Agent 改变了行为——但仍然不对:

Step 24 的 Action

1
2
3
4
5
6
7
8
import subprocess

def run_linkcheck():
try:
result = subprocess.run(['make', 'linkcheck'], capture_output=True, text=True)
print(result.stdout)
print(result.stderr)
...

Agent 开始尝试把 Python 代码直接当作 bash 命令执行。Bash 当然无法理解 import subprocess,所以这次更是毫无效果。

关键观察:Step 24-26 的 observation 都是空字符串,这说明命令可能: 1. 根本没有被执行(因为格式错误被拦截) 2. 执行了但不产生任何输出(比如 Python 解释器因为语法错误静默退出)

阶段三:终止(Step 27)

Step 27: - action: 空字符串 - observation: 空字符串 - response: “Exit due to repeated format/blocklist/bash syntax errors”

exit_status = exit_format

这表示 SWE-Agent 框架检测到 Agent 一直在产生格式错误(也许是输出无法被正确解析为 “讨论+命令” 的格式),达到了最大重试次数,强制终止了 Agent


5. 核心问题诊断

5.1 问题一:HTML 实体编码(关键发现!)

仔细查看 action 中的内容,你会发现一个重大问题:

1
"action": "python test_link.py\n"

再看 response 中 Python 代码的写法:

1
result = subprocess.run(['make', 'linkcheck'], capture_output=True, text=True)

' 是 HTML 实体编码,代表单引号 '。这意味着:

Agent 的输出被 HTML 实体编码污染了!

当 Agent 尝试写文件时,如果内容中包含 ' 等 HTML 实体,那么写出来的 Python 代码就会是语法错误的。

这是 SWE-Agent 框架输出解析的问题,也可能是本地 Qwen 模型输出格式不规范导致解析器进行了错误的转义处理。

5.2 问题二:Agent 陷入了”描述循环”

这是典型的 LLM Agent 失败模式:

1
Agent 发现错误 → Agent 描述解决方案 → Agent 不执行方案 → 再次遇到同样错误 → 再次描述方案 → ...

为什么会这样?

可能的原因: 1. 模型能力不足:Qwen-local 是开源小模型,工具调用能力远不如 GPT-4/Claude 2. 上下文混乱:随着对话越来越长(52 条消息),模型迷失在上下文中 3. 缺乏工具使用训练:模型更擅长”解释怎么做”而不是”实际去做” 4. 框架格式限制:SWE-Agent 要求特定格式(DISCUSSION + 代码块),模型可能无法稳定生成

5.3 问题三:从未使用搜索工具

优秀的 SWE-Agent 执行流程应该是:

1
2
3
4
5
1. find / -name "conf.py"        ← 找到配置文件
2. cat doc/conf.py ← 读取文件内容
3. grep "linkcheck_ignore" ... ← 找到需要修改的位置
4. str_replace_editor ... ← 精确编辑
5. python test_link.py ← 验证修复

但本 Agent 的实际流程是:

1
2
3
1. python test_link.py  ← 跳过所有搜索,直接运行不存在的脚本
2. python test_link.py ← 重试
3. python test_link.py ← 重试 × 24

Agent 从未执行过以下关键命令: - find — 搜索文件 - grep — 搜索内容 - ls — 列出目录 - cat — 读取文件内容 - str_replace_editor — 编辑文件

5.4 问题四:没有尝试写文件

即使 Agent 知道要创建 test_link.py,它从未执行过真正的文件创建操作,比如:

1
2
3
4
cat > test_link.py << 'EOF'
import subprocess
...
EOF

或使用 str_replace_editor create /test_link.py


6. 失败原因深度分析

6.1 直接原因表

序号 直接原因 严重程度
1 Agent 重复执行不存在文件的命令 24 次 ⭐⭐⭐⭐⭐
2 从未创建 test_link.py 脚本文件 ⭐⭐⭐⭐⭐
3 从未使用搜索命令查找配置文件 ⭐⭐⭐⭐⭐
4 从未编辑任何源代码文件 ⭐⭐⭐⭐⭐
5 HTML 实体编码污染 action 内容 ⭐⭐⭐⭐
6 Step 24-26 试图在 bash 中运行 Python 代码 ⭐⭐⭐⭐
7 被框架因”格式错误”强制终止 ⭐⭐⭐

6.2 根本原因分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
┌──────────────────────────────────────────────────┐
│ 根本原因层 │
├──────────────────────────────────────────────────┤
│ │
│ 1. 模型能力瓶颈 │
│ ├─ Qwen-local(开源小模型) │
│ ├─ 工具调用(function calling)能力弱 │
│ └─ 计划→执行转化能力差 │
│ │
│ 2. 框架输出解析问题 │
│ ├─ HTML 实体编码污染 │
│ ├─ 格式解析要求严格 │
│ └─ 与开源模型的兼容性不佳 │
│ │
│ 3. Prompt 设计问题 │
│ ├─ 步骤指导过于抽象("找到相关代码") │
│ ├─ 未提供工具使用的具体示例 │
│ └─ 系统提示太简单(只有一句话) │
│ │
│ 4. Agent 循环检测机制缺失 │
│ ├─ 24 次相同操作未被检测 │
│ ├─ 没有"陷入循环"的自动终止 │
│ └─ 浪费了大量 token 和时间 │
│ │
└──────────────────────────────────────────────────┘

6.3 如果换用强模型会怎样?

假设相同的任务给 GPT-4 或 Claude,典型的正确执行路径可能是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Step 1: find / -name "conf.py" -type f
→ 找到 /doc/conf.py, /examples/.../conf.py 等

Step 2: grep -n "linkcheck_ignore" /doc/conf.py
→ 显示 linkcheck_ignore 列表的当前位置

Step 3: str_replace_editor str_replace /doc/conf.py
old_str: linkcheck_ignore = [
new_str: linkcheck_ignore = [
"https://github.com/joblib/threadpoolctl/#setting-the-maximum-size-of-thread-pools",

Step 4: python -c "import sphinx; ..." # 验证配置
或: grep "threadpoolctl" /doc/conf.py # 确认修改

Step 5: 删除临时文件(如有),提交

7. 关键指标与数据

7.1 执行统计

指标 数值 说明
总步数 28 包括最后的空步骤
有效步骤 0 没有任何一步产生了有意义的文件修改
重复操作 24 次 python test_link.py × 24
总执行时间 ~3.8 秒 所有步骤的 execution_time 总和
实际修改文件数 0 没有编辑任何文件
退出状态 exit_format 因格式错误被强制退出

7.2 Token 消耗

指标 数值
发送 Token 236,887
接收 Token 15,035
总共 Token 251,922
API 调用次数 27
花费 $0(本地模型)

思考:23.7 万 token 全部浪费在重复循环中。如果 Agent 在第一步就正确工作,可能只需要 5000-10000 token 就能完成这个简单任务。

7.3 模型配置

参数
模型名称 openai/qwen-local
温度 0.0(确定性输出)
Top P 1.0
API 地址 http://localhost:8000/v1
执行超时 30 秒/命令
总超时 1800 秒(30 分钟)
重试次数 最多 20 次

8. 初学者阅读 Traj 的指南

8.1 拿到一个 Traj,应该看什么?

第一步:看概览

1
2
# 统计总步数和 exit_status
python3 -c "import json; d=json.load(open('xxx.traj')); print(len(d['trajectory']), d['info']['exit_status'])"

第二步:扫描步骤摘要

1
2
3
4
5
6
7
# 看每一步的 action 和 observation
python3 -c "
import json
d=json.load(open('xxx.traj'))
for i, s in enumerate(d['trajectory']):
print(f'Step {i}: {s[\"action\"][:80]} | {s[\"observation\"][:80]}')
"

第三步:看关键信息

1
2
3
4
5
// info 中的关键字段
exit_status: "exit_format" | "exit_context" | "exit_cost" | ...
edited_files: 实际修改了哪些文件
submission: 是否成功提交
model_stats: token 消耗和成本

第四步:定位问题步骤 - 如果发现连续的相同 action → 可能陷入循环 - 如果发现 observation 为空 → 命令可能格式错误 - 如果发现 action 中有 HTML 实体 → 存在编码问题 - 如果 response 和 action 不匹配 → 模型执行能力差

8.2 正常 Traj vs 异常 Traj

正常的 Traj 特征

1
2
3
4
5
Step 0:  action=find ... ; observation=找到多个文件
Step 1: action=cat /path/to/file ; observation=显示文件内容
Step 2: action=str_replace_editor ... ; observation=文件已修改
Step 3: action=python test.py ; observation=测试通过
Step 4: action=submit ; observation=提交成功

异常的 Traj 特征(本次):

1
2
3
4
5
Step 0:  action=python test.py ; observation=文件不存在
Step 1: action=python test.py ; observation=文件不存在
...
Step 23: action=python test.py ; observation=文件不存在 ← 重复24次!
Step 27: action="" ; exit_status=exit_format ← 强制退出

8.3 快速评估 Agent 表现的检查清单


9. 总结与启示

9.1 本 Traj 的结论

这是一个完全失败的 SWE-Agent 执行案例:

  1. 任务本身极其简单:在配置文件的列表里加一行 URL
  2. Agent 的表现非常差:28 步中零进展,没有编辑任何文件
  3. 核心失败模式:Agent 能”说”不能”做”——描述了 24 次解决方案但从未执行
  4. 根本原因:开源小模型(Qwen-local)的工具调用能力不足 + HTML 实体编码问题 + 缺少循环检测机制

9.2 对 Agent 开发的启示

启示 说明
模型选型至关重要 开源小模型和前沿模型的差距在 Agent 场景下被放大
需要更好的格式解析 HTML 实体编码污染是框架层面的 bug
需要循环检测 检测到重复 action 应当终止并尝试不同策略
Prompt 可以更具体 提供具体命令示例比抽象指导更有效
工具描述要清晰 确保模型真正理解如何使用每个工具

9.3 对 LLM Agent 学习者的建议

  1. 从分析 Traj 开始学习:通过回放 Agent 的”思维过程”,能最直观地理解 Agent 的能力边界
  2. 注意 “说” 和 “做” 的差距:这是当前 LLM Agent 最常见的失败模式
  3. 模型能力是第一要素:同样的 SWE-Agent 框架 + 不同模型 = 天壤之别的结果
  4. Debug Agent 时先看 action:observation 是结果,action 才是 Agent 的决策,两者对比能快速定位问题

9.4 可复现的改进方案

如果想让这个 Agent 成功,可以尝试:

  1. 换更强的模型:使用 GPT-4、Claude 等强模型
  2. 修复 HTML 编码问题:在框架层对 action 进行 HTML 解码
  3. 优化 Prompt:添加具体的工具使用示例
  4. 添加循环检测:连续 3 次相同 action → 自动切换策略
  5. 提供更详细的实例模板:在 prompt 中展示正确的执行流程

文件信息 - 源文件: scikit-learn__scikit-learn-i25076.traj - Traj 文件大小: ~2.4 MB - 总步数: 28 - 框架版本: SWE-Agent 1.1.0 / SWE-Rex 1.4.0 - 模型: openai/qwen-local - 结果: ❌ 完全失败(exit_format)