PAST-Bench 给出的分环节评分,用途不是找最低分,而是决定先动哪一层。个人 Agent 的失分通常散落在提示、工具定义、记忆策略、任务拆解这四类可改动面上;如果按“哪块看着最别扭”来动手,很容易改到低频环节,高频掉分的环节还原地不动。可以把流程固定成一条链:穷举可改动面 → 用固定任务集跑基线并收集按环节结果 → 把掉分频次和改动成本放进同一张表排序 → 只改一项复跑同一批任务 → 把排序结果存档作为下一轮起点。
PAST-Bench 这类按环节给分的评测,适合当归因表而不是总分榜:先用固定任务集和不改动的基线跑一轮,拿到每个环节的失分次数与可指认的 run 证据,再按“失分频次高、证据确凿、改动成本低”排出先后。边界是任务集、工具集、模型与超时口径必须一致,否则环节之间不可比;单轮跑批只说明这一批任务上的表现,不能外推到全部场景。
列出当前 Agent 的全部可改动面
先穷举再排序。把候选改动项按提示、工具定义、记忆策略、任务拆解四类写全,每一项都要填上“改动会影响到哪个环节”。填不出影响环节的条目先放进待定列,等基线跑完再决定要不要纳入。
| 类别 | 候选改动项 | 主要影响环节 |
|---|---|---|
| 提示 | 系统提示里的角色设定、输出格式约束、停止条件、失败重试话术 | 计划生成、输出解析 |
| 提示 | 少样本示例的数量与覆盖场景 | 指令遵循、格式稳定 |
| 工具定义 | 工具名与描述措辞、参数 schema、必填字段校验 | 工具选择、参数填充 |
| 工具定义 | 返回体裁剪、错误信息的结构 | 工具结果理解、错误恢复 |
| 记忆策略 | 写入时机、检索条数、摘要压缩比例 | 多轮一致性、长任务 |
| 记忆策略 | 过期与冲突处理规则 | 事实一致性 |
| 任务拆解 | 是否先出计划、子任务粒度 | 计划可行性、步骤数 |
| 任务拆解 | 串并行选择、重规划触发条件 | 工具编排、失败恢复 |
穷举完成后,建议本轮只圈 5 到 8 个候选。候选太多,后面“一项一项改、一批一批复跑”排不开,归因也会互相污染。
跑一批固定任务并收集按环节的结果
需要一轮不改任何配置的基线跑批。跑之前把模型版本、温度、工具白名单、单步超时、任务集版本都固定住,中途换任何一项,后面的环节对比都不成立。下面是一份通用配置骨架,字段名按你实际使用的跑批工具替换即可。
bench: past-bench
tasks:
file: tasks/personal_agent_smoke.jsonl # 固定任务集,本轮不再增删
fields: [id, goal, tools_allowlist, max_steps]
repeat: 3 # 同一任务重复次数,用来看抖动
seed: 1234
run_id: r1_baseline
output:
dir: runs/r1_baseline
per_run: run.jsonl # 一行一次执行,含各环节得分
per_stage: stage.jsonl # 一行一个 (任务, 重复, 环节)
log: agent.log
跑完先做一致性校验,再谈归因。验证方式很直接:输出条数与任务数量和重复次数吻合。
wc -l runs/r1_baseline/run.jsonl # 应等于 任务数 × repeat
wc -l runs/r1_baseline/stage.jsonl # 应等于 任务数 × repeat × 环节数
jq -r 'select(.stage == null or .lost == null) | .task_id' runs/r1_baseline/stage.jsonl
最后一条命令用来捞缺失字段的记录。如果 run.jsonl 的实际行数少于任务数乘重复次数,通常是超时或进程崩溃造成的残批,先补齐再归因,不要拿残批去排优先级。
把掉分频率和改动成本放进同一张表
这张表是整条链的核心,列的定义和填表口径要提前定死:
- 环节:与 stage.jsonl 中的 stage 字段逐字一致,方便回查。
- 出现频次:该环节失分的 run 数,后面跟一个总 run 数一起写,例如 4/30。
- 证据条目:能指认到具体 run id 和日志行号的条目,一条证据只归一个环节,跨环节的失分记到最先出错的那一环。
- 改动成本等级:低 / 中 / 高,按改动面大小、是否需要重写工具定义、是否需要连带回归其他环节来定,同一轮内用同一把尺子。
下面是填法示例,括号内为占位,不代表任何真实跑批结果:
| 环节 | 出现频次 | 证据条目 | 改动成本等级 |
|---|---|---|---|
| 工具选择 | (次数)/(总 run 数) | run id + 日志行号若干条 | 低 |
| 参数填充 | (次数)/(总 run 数) | run id + 轨迹片段行号 | 中 |
| 多轮一致性 | (次数)/(总 run 数) | run id + 记忆写入日志行号 | 高 |
| 重规划 | (次数)/(总 run 数) | run id + 计划变更日志行号 | 高 |
排序规则可以写成一句话:先做频次高、证据确凿、成本低的那一项;同一环节有多个候选改动项时,先做能解释最多失分的那一条;如果一个改动项会同时影响多个环节,复跑时要额外确认它有没有把别的环节带坏。频次建议用计数而不是百分比,小样本下百分比容易给出错误印象。
只改一项并复跑同一批任务
单变量原则:一轮只改一个改动项,其余全部保持基线配置。复跑范围就是基线那一批任务,重复次数、seed、工具白名单、超时、评分版本都要对齐,否则前后两轮不可比。
for d in runs/r1_baseline runs/r2_tool_desc; do
echo "$d"
jq -r 'select(.lost == true) | .stage' "$d/stage.jsonl" | sort | uniq -c
done
对比口径上需要对齐的项:任务集版本、重复次数、模型版本、工具集、超时阈值、评分脚本版本。任何一项不同,先补跑对齐再判读。判读通常分三种情况:目标环节失分下降、其他环节没变,说明这项改动作用在了目标环节;目标环节没变而别的环节变了,说明改动跑偏或存在耦合,回到表里重新排序;两边都变差,先回滚,再补证据。
把这次的排序结果留成下次的起点
每轮跑完,把排序结果落成一份可追加的记录,字段至少包含:环节、改动项、改动前后的环节表现、下一轮待办。下一轮开始时先读这份记录,把未完成的待办和本轮新暴露的环节合并成新的候选表,避免从零重排。
{
"round": "r2",
"stage": "tool_selection",
"change": "缩短工具描述并补一条调用示例",
"before": {"lost_runs": "<从 r1 stage.jsonl 汇总>", "total_runs": "<r1 总 run 数>"},
"after": {"lost_runs": "<从 r2 stage.jsonl 汇总>", "total_runs": "<r2 总 run 数>"},
"evidence": ["<run_id + 日志行号>"],
"next": "确认参数填充环节是否被连带影响",
"status": "已复跑"
}
保存时保留原始 run 目录路径,别只留下汇总数字。等任务集扩充或模型更换后,需要重新跑基线再复用这份排序,不能直接沿用旧结论。