SWE Trajectory 分析指标文档

SWE Trajectory 分析指标文档

0. 文档用途与 Schema 版本

本文档把 SWE-bench eval 管线里所有分析指标做成一张可导航的表,每项标注:字段路径、中文含义、聚合方式、对齐到 plan.md 的哪张图/哪个实验、已知缺陷。

  • v0.2 (taco-swe-v0.2):由 src/analysis/build_trajectory.py 在每个 task 完成时落盘到 *_trajectory.json。正在跑的 eval 产出的就是这个版本。

  • v0.3 (taco-swe-v0.3):post-hoc 升级,由 src/analysis/rebuild_v03.py 从 v0.2 升级得到 *_trajectory_v03.json。修正 v0.2 的规则假阴性(validation_after_editother_bash 细分)+ 加 semantic-equivalent / per-phase latency / reward_eval_share

  • 聚合层.claude/skills/trajectory-analyzer/analyze.py。所有 v0.3 新字段在聚合时即可从 v0.2 原始字段重算,不必等 rebuild_v03。

1. 数据来源(每 task 产物)

文件

内容

用途

*_final.json

SWE-bench raw result + extra_info.steps

build_trajectory 的输入

*_patch_generate.json

完整 multi-turn messages(含 reasoning_content

build_trajectory 提取 reasoning

*_trajectory.json

v0.2 分析 schema

analyze.py 的主输入

*_trajectory_v03.json

v0.3 升级(可选)

图 1/2/4 画图直接吃这个更方便

*.log

loguru 全量日志

debug,不用于分析

Schema 顶层:{schema_version, instance_id, data_id, task, rollout, token_usage_total, steps, outcome, derived}。下面的字段路径都省略这一层前缀。

2. 指标分类

2.1 规模与结果(Scale & Outcomes)

字段

中文

聚合

对齐

outcome.resolved

是否 test 全通过

算成功率 + bootstrap 95% CI

所有图的 y 轴基准

outcome.patch_nonempty

是否产出非空 patch

成功率(patch_rate)

图 4(未生成 patch = useless)

outcome.final_reward

最终奖励值(0/1)

Target 4 salvageability

rollout.num_steps

总步数

overall / 分层

图 3 cost 轴

rollout.num_tool_calls_total

总工具调用数

overall

实验 1

rollout.wallclock_s

总墙钟时间

summary + bootstrap

图 1/3

rollout.exit_action

退出动作([TASK DONE] / [Exceeds max step]

counter

图 4 terminal state

rollout.terminated_reason

task_done_called / step_limit_exceeded

counter

图 4

token_usage_total.total_tokens

prompt+completion 总量

sum

图 3 cost 代理

token_usage_total.prompt_tokens

prompt

sum(v0.3 新增)

图 3 上下文膨胀分析

token_usage_total.completion_tokens

completion

sum

图 3

token_usage_total.reasoning_tokens

reasoning token(如模型暴露)

sum

图 5 thinking 成本

token_usage_total.reasoning_chars_est

reasoning 字符估算

sum

图 5

overall.reasoning_token_share(派生)

reasoning_tokens / completion_tokens

scalar

图 5 thinking 膨胀

2.2 Latency 分解 → 图 1

plan.md §4.3 图 1:SWE trajectory latency decomposition。目标是把"这个 rollout 为什么慢"拆成 LLM decode / tool exec / reward eval / queue 四块,证明 tool 尾 ≠ LLM 尾。

Trajectory-level(每任务一行)

字段

中文

对齐

derived.latency_decomposition.llm_total_s

所有 step 的 LLM 延迟之和

图 1

derived.latency_decomposition.llm_p50_s / p95_s / max_s

LLM 步级延迟分位

实验 1

derived.latency_decomposition.tool_total_s

tool 延迟之和

图 1

derived.latency_decomposition.tool_p50_s / p95_s / max_s

tool 步级分位

实验 1 main(P95/P50 比率)

derived.latency_decomposition.reward_eval_s

SWE-bench 测试执行用时

图 1(需要从 agent 成本剥离)

derived.latency_decomposition.queue_wait_s

AReaL 队列等待(当前 null)

图 1 第四块,等 RL 接入

Step-level

聚合产出:每个 step 的 llm_latency_s / tool_latency_s 汇总。

v0.3 新增

  • latency_by_phase — 按 phase 分桶(localization / patch / verification / env_setup / inspect 等)分别给 LLM/tool 的 P50/P95/total。图 1 的真正 motif:patch-phase 的 LLM P50 是 localization 的 3.3×(n=199 实测 4.85s vs 1.48s)。

  • reward_eval_share = reward_eval_s / wallclock_s,每任务一个 ratio,用于判断"慢 trajectory 里有多少锅是 sandbox 的,不是 agent 的"。实测 P95=65.6%。

判定(judgment.experiment_1_long_tail

级别

条件

✅ strong

tool P95/P50 ≥ 5× 且 ≥ 2× LLM 比率 → 和 Heddle/SortedRL 差异化成立

⚠️ mixed

tool P95/P50 ≥ 3× 或 ≥ LLM 比率

❌ weak

其余

2.3 Phase 结构 → 图 2

plan.md §4.2–4.3 图 2:phase transition graph(localization → patch → test 的 motif)。

v0.2 phase 标签

来自 classify_phasesrc/analysis/build_trajectory.py:410

localization / other_bash / patch / edit_bash / inspect / test / submit / early_surrender

字段表

字段

中文

已知缺陷

derived.phase_summary.phase_sequence

step_idx 的 phase 序列

画 motif 直接用

derived.phase_summary.phase_counts

{phase: 步数}

derived.phase_summary.first_localization_step

首次 localization 的 step_idx

图 4 failure onset

derived.phase_summary.first_edit_step

首次 patch / edit_bash

图 2 节点

derived.phase_summary.first_test_step

首次 test(VERB_TEST 命中)

v0.2 假阴性严重(下文)

derived.phase_summary.context_before_edit

first_loc < first_edit

实测 100%,基本定义性成立

derived.phase_summary.validation_after_edit

first_test > first_edit

v0.2 严重假阴性:实测 0/62

derived.phase_summary.loop_segments

[[start_idx, end_idx], ...] 连续重复

图 4 harmful loop

v0.2 的 bug

VERB_TEST = {pytest, tox, unittest, nosetests, make, ...} 不含 python,导致 python -m pytestpython manage.py testpython reproduce.py 全部被 first_test_step 漏掉,进而 validation_after_edit 恒为 False。

v0.3 修复

rules_v03.is_validation_command 拓宽匹配:

  • test runner 裸词:pytest / tox / unittest / nosetests / jest / rspec / mvn test / gradle test / npm test / go test / cargo test

  • python -m pytest|unittest|nose|tox

  • python <path>/manage.py test|runtests.py|run_tests.py

  • python <path>/reproduce*|repro*|test_*.py|*_test.py|tests/*.py

  • make check|test

新字段:

  • derived.phase_summary.validation_after_edit_v03 — 拓宽后的判定

  • derived.phase_summary.validation_commands_v03 — 命中的原始命令(供 spot-check)

n=199 实测:97.5% 任务实际跑了验证,192 条被 v0.2 漏报

v0.3 other_bash 细分

rules_v03.reclassify_bash_intent:v0.2 把 33% 步数塞进 other_bash,图 2 motif 会糊。v0.3 拆成:

子类

规则

exploration

grep / find / ls / cat / head / wc

verification

任何命中 is_validation_command 的 + 裸 python / git diff|log|status|show

env_setup

pip / conda / apt / source / export / cd

truly_other

其余

n=199 实测:原 33% other_bashverification 15.5% + env_setup 15.5% + exploration 0.6% + truly_other 0.5%。

工作流闭环判定(judgment.workflow_health

原先因 validation_after_edit bug 一直报 ❌ broken,修正后应为 ✅ healthy。

2.4 Outcome overlap(hunk 行级)→ 实验 2 / 图 3 / 图 4

plan.md 实验 2:失败轨迹里有多少 salvageable signal。

文件级(v0.1 保留,语义粗)

字段

中文

derived.failure_analysis.localization_overlap_with_gold

agent 读过的文件集 vs gold 改过的文件集 Jaccard

derived.failure_analysis.edit_overlap_with_gold

agent 改过的文件集 vs gold 改过的文件集 Jaccard

Hunk 行级(v0.2 新增,用于 C4 salvage 主论证)

字段

中文

derived.failure_analysis.gold_hunk_count

gold patch 的 hunk 数

derived.failure_analysis.agent_hunk_count

agent patch 的 hunk 数

derived.failure_analysis.gold_lines_touched_total

gold 修改的总行数

derived.failure_analysis.agent_lines_touched_total

agent 修改的总行数

derived.failure_analysis.hunk_line_jaccard_overall

agent 行号集 ∩ gold 行号集 / 并集

derived.failure_analysis.hunk_line_jaccard_per_file

同上,按文件分

derived.failure_analysis.agent_touched_gold_line_recall

gold 行里有多少被 agent 碰到

derived.failure_analysis.agent_touched_gold_line_precision

agent 碰的行里多少落在 gold 内

derived.failure_analysis.salvage_label

full_success / near_miss / useful_patch_attempt / useful_localization / useless

derived.failure_analysis.failure_motif

task_done_resolved / task_done_unresolved / no_validation / stuck_in_loop / ...

derived.failure_analysis.failure_onset_step

推测的失败起点步 → 图 4 核心

derived.failure_analysis.edit_attempted / test_attempted

是否尝试过

v0.3 新增

  • derived.failure_analysis.semantic_equivalent_patchresolved=True AND hunk_line_jaccard_overall < 0.1。强先验:测试通过但没碰 gold 行 = 语义等价实现(或 gold 过拟合)。n=199 实测:18.8% 的 resolved 任务属于这批,不剔除会严重污染"hunk recall 作为 resolve 代理"的论证。

判定

judgment.experiment_2_salvage

  • salvageable = near_miss + useful_patch_attempt + useful_localization

  • ≥ 50% → ✅ / 25–50% → ⚠️ / < 25% → ❌

judgment.near_miss_sharpness:near_miss 的 hunk recall 分布

  • ≥50% 命中 recall ≥ 0.5 → ✅ sharp

  • ≥50% recall=0 → ⚠️ misleading(文件选对但行错,需要再切 near_miss_line_match vs file_only_match

2.5 Tool Capability

字段

中文

用途

derived.tool_stats.total_tool_calls

全 tool 调用数

基线

derived.tool_stats.failed_tool_calls

非 0 exit 的

derived.tool_stats.tool_failure_rate

总失败率

corr(·, resolved) → 实验 3

derived.tool_stats.first_tool_failure_step

首次失败位置

图 4 onset 代理

derived.tool_stats.consecutive_same_command_max

最长连续相同命令

卡住信号

derived.tool_stats.unique_bash_command_count

唯一 bash 数

探索多样性

derived.tool_stats.search_replace_attempt_count / *_failure_count

SR 成功/失败计数

SR 能力瓶颈检测

derived.tool_stats.bash_attempt_count / *_failure_count

bash 成功/失败计数

bash 能力

判定(judgment.tool_capability

级别

条件

❌ capability-blocked

≥20% 任务 SR 全失败 → 根本瓶颈在 SR 格式,不是策略

⚠️ frequent-failures

tool_failure_rate P50 ≥ 30%

✅ tool-reliable

其余


2.6 Thinking-lite → 图 5

plan.md §1.5:不要直接吃 raw thinking,但用轻量 thinking 特征预测 resolve。

v0.1 布尔(保留但已弃用聚合)

字段

已知状态

derived.thinking_lite.uncertainty_steps

有"not sure / maybe"之类的 step 列表。饱和(97% 命中),无区分度

derived.thinking_lite.hallucinated_file_steps

提到但没 actually read 的 .py 文件步。布尔版饱和(89%)

derived.thinking_lite.repeated_reasoning_steps

sha1 exact 匹配 → 死规则(1.6%),过严

derived.thinking_lite.has_plan_in_step1

step1 是否含 plan-like 短语。qwen3.6-27b 实测 0%

v0.2 连续(主力)

字段

中文

derived.thinking_lite.uncertainty_density

不确定步数 / 总步数

derived.thinking_lite.uncertainty_escalation_slope

step_idx → uncertainty{0,1} 的线性回归斜率

derived.thinking_lite.hallucinated_file_density

幻觉文件步数 / 总步数

derived.thinking_lite.hallucinated_unique_file_count

不同的幻觉文件数

derived.thinking_lite.hallucinated_occurrence_total

幻觉文件总 mention 次数

derived.thinking_lite.reasoning_ngram_self_similarity

相邻步 3-gram Jaccard 均值(替代 sha1)

derived.thinking_lite.reasoning_ngram_max_pair

最相似两步的 3-gram Jaccard(高 = 兜圈子)

derived.thinking_lite.reasoning_length_trend_slope

reasoning_chars vs step_idx 斜率(负 = 收缩)

derived.thinking_lite.reasoning_to_completion_ratio

reasoning_chars / total completion_chars

derived.thinking_lite.reasoning_chars_per_step

每步 reasoning 字符

derived.thinking_lite.early_surrender_signal

长度斜率 < 0 且 末步 < 首步一半

图 5 readiness 判定

任一布尔饱和或死 → ⚠️,必须用连续 density/ngram 维度。

Schema 缺口提醒(schema_gaps 自动 surface)

  • uncertainty_expressed 布尔饱和 > 90% → 弃用聚合,只用 density

  • repeated_reasoning_steps(sha1 exact)死 → 用 reasoning_ngram_max_pair 替代

2.7 Stratification → 图 6

plan.md §4.3 图 6:confound-controlled analysis。关键:不分层 → difficulty 和 repo 会偷换长度信号。

字段

聚合

task.difficulty

<15 min fix / 15 min - 1 hour / 1-4 hours / >4 hours

task.repo

GitHub repo 名

task.issue_len_chars / task.issue_has_stacktrace / task.issue_has_reproducer

Issue 特征,Target 4 salvageability 特征

task.gold_patch_files / gold_patch_lines_added/deleted

Gold patch 规模

task.fail_to_pass_count / pass_to_pass_count

需要修复的 test 数

聚合产出(stratification

  • by_difficulty[]:每桶 {n, resolved, resolved_rate, resolved_rate_ci95, insufficient_n}

  • by_repo[]:同上

  • v0.3 保护:n < 5 的桶不输出 rate,标 insufficient_n: true,避免"1/1=100%"或"0/1=0%"的误导

新增 by_loop_presence:按 loop_segments 是否为空分 {with_loop, without_loop},对比 resolved_rate / hunk_recall_mean / wallclock_s_mean

图 6 readiness

≥2 difficulty 桶有 n≥20 → ✅


2.8 Correlation → 实验 3

plan.md 实验 3:length-only scheduling 是否够用(Heddle/SortedRL 假设)。反驳路线:长度相关弱,过程特征相关强。

Marginal(correlations_with_resolved,Pearson 与 resolved)

feature

含义

plan.md 位置

num_steps

长度代理 1

实验 3 main null

total_tokens

长度代理 2

实验 3 main null

wallclock_s

长度代理 3

实验 3 main null

reasoning_chars_est

思考长度

图 5

localization_overlap_with_gold

文件级定位

过程特征

edit_overlap_with_gold

文件级编辑匹配

过程特征

hunk_line_jaccard_overall

行级编辑匹配(v0.2)

C4 主特征

agent_touched_gold_line_recall

行级召回

salvage 主特征

tool_failure_rate

tool 能力

实验 1 支撑

uncertainty_density

不确定密度

图 5

hallucinated_file_density

幻觉密度

图 5

reasoning_ngram_self_similarity

思考重复度

图 5

v0.3 新增 partial corr(控 difficulty)

correlations_partial_difficulty

  • by_bucket:每个 difficulty 桶(n≥10)内的 Pearson

  • pooled_weighted:n 加权平均

  • 用途:marginal corr 里 length ↔ resolved 的 -0.32 看着中等,partial corr 若接近 0 就说明 length 只是 difficulty 代理。n=199 实测 partial -0.30,几乎不变 → length 信号是真的。

判定 judgment.experiment_3_scorer

级别

条件

✅ strong

|corr(num_steps, resolved)| < 0.2 且 corr ≤ 0.05 → 复现 Beyond Resolution Rates

⚠️ mixed

0.05 < corr < 0.3

❌ weak

corr ≥ 0.3 → length-only 反而合理,plan 的 differentiator 不成立


2.9 AReaL-only 字段(当前 null)

字段

中文

何时填

rollout.policy_version_start / end

rollout 起止时的 policy version

AReaL 接入

rollout.head_offpolicyness

policy_now - policy_at_head

图 3 / Target 2

rollout.queue_wait_s

被 AReaL 队列延迟的时间

图 1 第四块

rollout.was_partial_rollout

是否被截断

Target 1/2

→ 对应 plan.md §5.1 Target 2(stale risk)、Target 3(learning utility)、§6.3 AReaL async control。

3. 判定阈值(analyze.py::_judge 权威)

实验 1(tool vs LLM 长尾)

tool_P95/P50 ≥ 5× AND ≥ 2×·LLM_P95/P50  → ✅ strong
tool_P95/P50 ≥ 3× OR ≥ LLM_P95/P50      → ⚠️ mixed
否则                                      → ❌ weak

实验 2(salvage 率)

salvageable = (near_miss + useful_patch_attempt + useful_localization) / n
≥ 50% → ✅ strong
25–50% → ⚠️ mixed
< 25%  → ❌ weak

实验 3(length-only 不够)

|corr(num_steps, resolved)| < 0.2 且 corr ≤ 0.05 → ✅ strong
0.05 < corr < 0.3                                → ⚠️ mixed
corr ≥ 0.3                                       → ❌ weak  ← plan 立论失败

图 readiness

条件

fig1

n ≥ 30 → ✅

fig2

n ≥ 30 且 ≥3 phases 占比 ≥5% → ✅

fig3

resolved ≥ 10 → ✅(否则 n≥30 可 salvage 兜底)

fig4

n ≥ 30 且 ≥3 salvage labels 占比 ≥5% → ✅

fig5

n ≥ 50 且无饱和(>90%)/死(<10%)信号 → ✅(否则 ⚠️)

fig6

≥2 difficulty 桶 n ≥ 20 → ✅

workflow_health

validation_after_edit 率 < 10% 且 context_before_edit 率 < 30% → ❌ broken
validation_after_edit 率 < 30% 或 context_before_edit 率 < 50% → ⚠️ weak
其余                                                            → ✅ healthy

4. v0.3 Roadmap

目前状态

触发方式

semantic_equivalent_patch 标记

✅ 已落地

analyze.py 实时 / rebuild_v03 写入字段

widened validation_after_edit_v03

✅ 已落地

同上

other_bash 细分(4 子类)

✅ 已落地

同上

reward_eval_share

✅ 已落地

同上

latency_by_phase

✅ 已落地

同上

failure_onset_summary

✅ 已落地

analyze.py 聚合层

by_loop_presence split

✅ 已落地

analyze.py 聚合层

bootstrap 95% CI

✅ 已落地

overall + stratification

partial correlation(控 difficulty)

✅ 已落地

analyze.py 聚合层

per-task JSONL 扁平导出

✅ 已落地

--per-task-out

n < 5 桶隐藏 rate

✅ 已落地

stratification

grounding_score(symbol 级幻觉)

⏳ 暂缺

未来 v0.4,需 symbol 抽取

AReaL 字段实填

⏳ null

等 @areal 训练接入


5. 用法速查

# 实时分析(任何时候都可以跑,对正在跑的 eval 零干扰)
python .claude/skills/trajectory-analyzer/analyze.py \
    --workdir <path> --out agg.json --per-task-out per_task.jsonl

# Eval 跑完后升级到 v0.3(增量模式,跑多少次都安全,默认 skip 已有)
./run_eval.sh rebuild_v03

# 或显式指定目录
python -m src.analysis.rebuild_v03 --workdir <path>

# 想重写已有 v03 文件(改了规则后)
python -m src.analysis.rebuild_v03 --workdir <path> --overwrite

6. 主要结论指向(n=199 quick read)

  • 实验 1:⚠️ mixed(tool P95/P50 ≈ LLM P95/P50,per-phase 拆分后 patch-phase LLM 是 localization 3.3×)

  • 实验 2:⚠️ mixed(30%+ salvageable,hunk-recall 在 near_miss 上 ✅ sharp)

  • 实验 3:⚠️ mixed(length 相关 -0.30,partial corr 确认真信号)

  • workflow_health:修正 v0.2 bug 后 → ✅ healthy(97.5% 任务跑验证)

  • 6 张图:1/2/3/4/6 均 ✅ ready;图 5 需要只用连续 density 维度

LICENSED UNDER CC BY-NC-SA 4.0