PAST-Bench 定位个人 Agent 掉分环节、按归因结果决定先改哪一层

文章导读
PAST-Bench 给出的分环节评分,用途不是找最低分,而是决定先动哪一层。个人 Agent 的失分通常散落在提示、工具定义、记忆策略、任务拆解这四类可改动面上;如果按“哪块看着最别扭”来动手,很容易改到低频环节,高频掉分的环节还原地不动。可以把流程固定成一条链:穷举可改动面 → 用固定任务集跑基线并收集按环节结果 → 把掉分频次和改动成本放进同一张表排序 → 只改一项复跑同一批任务 → 把排序
📋 目录
  1. A 列出当前 Agent 的全部可改动面
  2. B 跑一批固定任务并收集按环节的结果
  3. C 把掉分频率和改动成本放进同一张表
  4. D 只改一项并复跑同一批任务
  5. E 把这次的排序结果留成下次的起点
A A

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

跑完先做一致性校验,再谈归因。验证方式很直接:输出条数与任务数量和重复次数吻合。

PAST-Bench 定位个人 Agent 掉分环节、按归因结果决定先改哪一层
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 + 计划变更日志行号

排序规则可以写成一句话:先做频次高、证据确凿、成本低的那一项;同一环节有多个候选改动项时,先做能解释最多失分的那一条;如果一个改动项会同时影响多个环节,复跑时要额外确认它有没有把别的环节带坏。频次建议用计数而不是百分比,小样本下百分比容易给出错误印象。

PAST-Bench 定位个人 Agent 掉分环节、按归因结果决定先改哪一层

只改一项并复跑同一批任务

单变量原则:一轮只改一个改动项,其余全部保持基线配置。复跑范围就是基线那一批任务,重复次数、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 目录路径,别只留下汇总数字。等任务集扩充或模型更换后,需要重新跑基线再复用这份排序,不能直接沿用旧结论。