上一篇,我们沿着 RLHF、PPO、GRPO 和 DAPO,看了不同后训练算法“吃”的数据有什么区别。
这一次先不急着进入训练。我们从一次 Benchmark 开始。
假设同一个 Coding Benchmark 上,旧模型通过了 74 个任务,新模型只通过 68 个。最直接的结论似乎是:模型退化了。
但这 6 个失败任务里,可能有的容器没有启动,有的工具权限发生变化,有的上下文被 harness 提前裁掉,还有的只是 verifier 超时。即使确实是模型问题,我们也需要知道它从哪一步开始偏离。
一个最终分数回答不了这些问题。它只告诉我们结果,却没有保存结果形成的过程。
这正是 trajectory 的位置。
Benchmark 产出分数,Trajectory 负责解释分数。
它把模型决策、工具执行、环境变化、评估结果和系统版本组织成一条行为证据链。Benchmark 用它判断结果是否可信、变化来自哪里;后训练再从中挑选可学习的经验,转换成 SFT、偏好学习或强化学习样本。
所以这篇文章真正讨论的不是“如何多记一些日志”,而是:分散在各系统里的观测数据,怎样被组装成一条可复现、可判定、可归因,也能继续进入训练的 trajectory。
- 对话、Telemetry 和 Trajectory 不是一回事
最容易得到的是对话记录:用户说了什么,模型回复了什么,工具返回了什么。它适合阅读,却不一定适合复现。
更底层的是 telemetry,包括模型网关 trace、工具日志、容器指标、测试报告和截图。它们足够详细,却分散在不同系统中,也不天然表达 Agent 的行为语义。
Trajectory 位于两者之间。它不复制所有原始日志,而是围绕一个 task,把有因果关系的事件按顺序组织起来:
Task Snapshot ↓Observation -> Model Action -> Tool Result -> State Change ↓Verifier Result + Failure Attribution其中原始 prompt、完整测试日志、Patch 和截图可以继续留在对象存储中,trajectory 只保存必要摘要和引用。网关延迟、GPU 利用率等指标也不需要逐项复制,只保留与本次执行相关的状态和关联标识。
因此更准确的关系是:
Telemetry 是原材料Trajectory 是围绕任务组织的数据产品Training Sample 是面向算法的下游派生物- 一次 Benchmark,本质上是七个变量共同作用
模型只是评测系统中的一个变量。要解释一次结果,至少要同时知道:
Task × Model × Harness × Tool × Environment × Budget × VerifierTask 决定目标和初始状态;Model 产生决策;Harness 组织上下文和循环;Tool 把动作落到外部系统;Environment 保存真实状态;Budget 限制 token、时间和调用次数;Verifier 决定怎样算成功。
只要其中两个变量同时变化,就不能把结果差异简单归因给模型。例如更换模型时也升级了 system prompt,即使成功率提高,也只能说整套方案变好了,不能证明模型单独贡献了多少。
Task 本身也不是一条 prompt。SWE-bench 的任务同时绑定 issue、代码仓库 base commit、测试与执行环境;WebArena 则使用可独立部署的网站环境和程序化 validator。它们都在说明:Benchmark 的输入不是一句问题,而是一组可重置、可执行、可验收的状态。
这七个变量会成为 trajectory 的版本坐标。后面判断 Better、Same、Worse,或者定位 Harness、Environment 问题,都依赖它们。
- 一次具体 rollout,会在哪些系统留下数据
任务准备好后,当前 policy 才开始 rollout。一次 Coding Agent 执行,表面上是一串“模型回复、工具返回”;在系统内部,它会同时在模型网关、harness、工具网关、执行环境、verifier 和调度系统中留下记录。
下面仍然使用“修复登录接口偶发 500”这个任务。为了看清数据关系,我们构造一条接近生产日志的示例;其中数值只是示意,采集位置和因果关系才是重点。
任务运行在仓库提交4f21c9上,当前策略是policy@13。Agent 搜索代码并修改异常处理后,在第 4 轮决定运行登录模块测试。
模型网关:这次决策是怎样生成的
模型网关记录到:这次请求输入约 8200 个 token,其中 6100 个命中前缀缓存;首 token 等待 430 毫秒,模型继续生成 186 个 token,最后返回一个run_tests工具调用。
这些数据能回答模型调用的版本、成本和延迟,却只能证明Agent 想运行测试。如果请求在网关重试两次,或者实际响应模型与请求模型不同,也应当在这里暴露。
Harness:模型作决定时看见了什么
Harness 知道这是第 4 轮循环,使用system prompt v8和tool schema v5。由于前文过长,上一步刚做过一次上下文压缩,任务还剩 8 分钟执行预算。
这一层解释的是行为条件。即使 policy 完全相同,只要工具描述、上下文裁剪或最大循环次数改变,Agent 就可能不再作出相同决策。
工具网关:动作有没有真正执行
工具网关收到run_tests(test_login.py),参数校验通过,沙箱权限允许,未触发重试。测试进程运行 6.8 秒后返回exit code = 1。
这说明工具确实执行了,但还不能直接说“修复失败”。退出码只代表整组测试里至少有一个失败项,具体发生了什么还要看环境状态。
执行环境:代码和测试发生了什么变化
环境侧显示,Agent 一共修改了两个文件。原本失败的test_login_500从 fail 变成 pass,但原本正常的test_session_refresh从 pass 变成 fail;测试期间没有产生额外网络请求。
到这里我们才知道,Agent 找到了目标 bug,同时引入了回归。工具返回值是一条 observation,环境前后的差异才更接近事实。
Verifier:为什么最后仍然是 0 分
Verifier 的规则不是“目标测试通过即可”,而是目标测试必须通过,并且已有测试不能回退。因此它给目标修复记+1,给新增回归记-1,最终 reward 为 0,失败类型标记为regression。
这个 0 分比简单的 pass/fail 多了一层信息:模型并非完全没有解决问题,而是解决方式破坏了原有行为。后续无论做过程监督、失败分类还是 hard case 回流,都需要保留这两个 reward 分量。
调度系统:这条数据花了多少资源
调度侧记录到,这条 rollout 排队 420 毫秒,模型推理消耗约 2.1 GPU 秒,测试消耗 6.8 CPU 秒,全程没有抢占和 OOM。
这些数据不决定任务对错,却决定训练数据的成本,也能帮助排除基础设施噪声。例如测试容器因 OOM 被杀死时,不应该把它直接标成模型能力失败。
把六个视角放在一起,才得到一条可以解释的轨迹:
模型网关:想调用 run_testsHarness:第 4 轮,刚完成上下文压缩工具网关:调用成功,测试进程 exit 1执行环境:目标用例修复,但出现一个回归Verifier:reward = 0,failure = regression调度系统:无 OOM,排除基础设施失败**网关记录调用,工具记录执行,环境记录事实,verifier 负责判定,调度系统解释成本与噪声。**任何一层缺失,都可能把同一个结果归因给错误的对象。
- 从这条 rollout 抽象出四类数据
上面的数据来自不同系统,也有完全不同的保存方式。把它们全部塞进一条超大的 JSON,查询和权限都会很快失控。
更自然的做法,是先按用途分成四类:
| 数据形态 | 回答的问题 | 例子 |
|---|---|---|
| Trace / Span | 一个操作经过哪里、花了多久 | 模型请求、工具执行、verifier 检查 |
| Event | 某个时间点发生了什么 | 选择工具、压缩上下文、修改文件 |
| Metric | 整体是否出现趋势或异常 | Token、延迟、错误率、GPU 利用率 |
| Artifact | 判断所依赖的原始证据是什么 | Prompt、Patch、截图、测试日志 |
OpenTelemetry 的 GenAI 语义约定已经覆盖模型、token、tool call 和 evaluation 等常见观测对象。不过它仍在持续演进,而且并不负责定义完整的训练数据模型。更合适的用法,是借它统一 trace 和基础字段,再由训练系统补上 task、policy、harness、environment 与 verifier 的版本关系。
落到离线数据层,也不需要一开始就设计一张包罗万象的宽表。可以先围绕一次 rollout 建四张事实表:
task / model / harness / tool / env / verifier | fact_rollout(含 Budget) / | \ fact_model_call fact_tool_execution fact_evaluation | fact_state_transition | patch / log / screenshotfact_model_call保存模型决策及其成本,fact_tool_execution保存动作是否执行,fact_state_transition保存环境前后差异,fact_evaluation保存判定过程。大体积内容进入对象存储,事实表只保留引用。
四张事实表通过 rollout 标识和步骤顺序重新拼接。组装后的结果不再是一堆日志,而是一条带业务语义的记录:
Trajectory ro_0017├─ Context:login_500@3 / policy@13 / repo 4f21c9 / Budget 10 分钟├─ Step 1..4:观察、模型决策、工具执行、环境变化├─ Outcome:reward 0 / regression└─ Evidence:patch、测试日志、模型与工具 trace 引用这条记录还必须绑定版本坐标:
(task_version, model_version, harness_version, tool_version, environment_version, verifier_version)版本不是附属元数据,而是 trajectory 身份的一部分。没有它,就无法判断两次评测是否真的可比,也无法重放当时的行为。
从 telemetry 到 evaluated trajectory,大致经历四步:先按 rollout 关联多源事件,再按 Agent 实际看到的顺序重建 action 和 observation,然后挂接环境状态与原始证据,最后运行 verifier 并补上 reward、有效性和失败分类。
到这一步,trajectory 才同时具备三种用途:回放一次执行、解释一次评测,以及作为训练样本的上游数据。
- Trajectory 如何判断 Better、Same、Worse
单次 pass/fail 只能判断一个 case 的结果。要比较 baseline 和 candidate,还需要把同一个 task 下的多条 trajectory 放在一起。
比较至少包含四个维度:
- •结果:是否完成任务,reward 各分量如何变化;
- •行为:走了多少步,调用了哪些工具,第一处分歧在哪里;
- •效率:消耗多少 token、时间和计算资源;
- •稳定性:重复运行后,通过率和失败类型是否稳定。
因此结果分类不应该只有 Good 和 Bad,而应至少有五种:
| 分类 | Trajectory 给出的证据 |
|---|---|
| Better | 成功率或质量提高,且不是环境或 verifier 变化造成 |
| Same | 结果差异处于正常波动范围,行为和成本没有明显恶化 |
| Worse | 在可比条件下,成功率、质量或稳定性明确下降 |
| Invalid | 环境、工具、任务或 verifier 异常,本次结果不应计入模型分数 |
| Inconclusive | 样本不足,或模型之外的多个变量同时变化,无法归因 |
这里有两个很容易被忽略的情况。
第一,结果相同不代表 trajectory 相同。两个模型都通过任务,candidate 却多调用了十次搜索工具、消耗三倍 token,它在 outcome 上是 Same,在效率上却可能是 Worse。
第二,单条随机 rollout 很难证明模型退化。对非确定性 Agent,应该在相同版本坐标和预算下重复采样,比较 pass rate、reward 分布和失败类型,而不是用一次成败下结论。
Verifier 在这里提供结果标签,但它不是唯一真值来源。确定性结果优先使用单元测试、数据库状态或程序化 validator;软性质量可以交给 reward model 或 LLM judge;冲突和低置信样本再进入人工复核。LLM judge 还需要防范位置偏差、冗长偏差和自我偏好。
- 同样是 0 分,Trajectory 如何定位问题
回到登录接口的例子。最终都是 reward 0,trajectory 却可能讲出完全不同的故事。
情况一:Model 问题
环境正常、工具可用、harness 和 baseline 一致。Candidate 看到了同样的测试失败,却修改了无关文件,或者在错误位置反复尝试。
此时第一处分歧发生在模型 action,后续环境失败是它的结果。经过重复采样仍稳定出现时,才有较强证据把问题归因给模型。
情况二:Harness 问题
模型调用前,关键报错已经被上下文压缩删除;或者工具 schema 改名,但 system prompt 仍使用旧名字。模型后面的动作确实不正确,却是在错误输入条件下产生的。
这种 trajectory 应用于修复 harness 或重跑评测,不应直接作为“模型能力退化”的证据。
情况三:Tool 或 Environment 问题
模型生成了正确的run_tests,但工具被权限策略拒绝;或者容器依赖安装失败,测试根本没有启动。它们都可能表现为任务失败,却属于评测无效。
工具网关回答“动作有没有执行”,环境快照回答“世界有没有按预期变化”。两者必须分开,否则一次 HTTP 200 或exit code = 0很容易被误当成任务成功。
情况四:Verifier 问题
环境状态已经满足目标,verifier 却读取了旧快照;或者 LLM judge 因答案位置、长度发生偏置。同一 trajectory 在 verifier v4 得 1 分,在 v5 得 0 分,首先应该检查判定逻辑,而不是训练模型。
情况五:Infrastructure 问题
Rollout 在生成中被抢占、OOM 或超时截断。只看最终输出,它像是模型半途放弃;连接调度记录后,才知道这是一条不完整数据。
实际归因可以遵循一条简单路径:
先检查任务、工具、环境和 Verifier 是否有效 ↓再检查 Harness、Budget 和版本是否可比 ↓找到 baseline 与 candidate 的第一处行为分歧 ↓最后才判断是否属于 Model 回归失败归因不是给日志贴标签,而是沿 trajectory 找到第一处改变因果方向的事件。
- 不是每条失败 Trajectory 都应该进入训练
完成评测和归因后,trajectory 才能进入数据筛选。
最先隔离的是 Invalid:环境启动失败、工具权限错误、verifier 冲突、调度 OOM。这些数据可以用于修复平台,却不应该训练模型,否则模型会被迫学习如何适应一套已经损坏的世界。
真正由模型行为造成的成功与失败,才进入候选池:
| Trajectory 类型 | 更合适的去向 |
|---|---|
| 稳定成功且路径简洁 | SFT 或高质量行为样本 |
| 同任务下成功与失败并存 | 偏好对、GRPO 组或过程分析 |
| 模型稳定失败但任务有效 | Curriculum、任务拆解或 hard case |
| 成功但代价明显升高 | 效率优化、cost-aware reward |
| Harness、Tool、Environment 失败 | 隔离并回流对应工程系统 |
假设同一个 task 采样 16 条 rollout,全部成功说明它对当前模型可能过于简单;全部失败则要继续区分“模型尚不会”和“任务已经损坏”。成功与失败混合的区域,往往最容易形成有区分度的训练信号。
在 GRPO 这类组相对训练中,如果同一 prompt 下所有输出奖励相同,组内优势会变成 0。DAPO 的 Dynamic Sampling 因此过滤全对和全错的组,继续采样有效组。但这些轨迹并非永久无用:全对任务可以进入回归集,全错任务可以用于课程学习和失败研究。
Trajectory 还会随模型更新而过期。policy@12的主要错误可能是不调用测试,policy@13已经解决它,却开始过度修改文件。旧数据仍可用于 SFT、经验回放和回归分析,但不能不带版本地冒充当前 policy 的 on-policy 数据。
因此训练价值不能只看 reward,还要同时考虑:
正确性 × 可判定性 × 难度 × 新颖性 × 当前策略相关性只有完成有效性检查和失败归因,Benchmark trajectory 才能安全地变成训练资产。
- Telemetry、Evaluated Trajectory 和 Train Sample 必须分层
生产系统最容易踩的坑,是建一张万能大表:工具日志、评分、训练 token、评测结果全部塞进去。开始很省事,后来谁也说不清一列是原始事实、派生标签还是某次算法专用的中间量。
更清晰的做法是拆成三个数据产品。
Raw Telemetry:保存原始证据
保存模型输入输出、网关 trace、工具日志、环境 observation、时间戳、错误码、资源指标和 Artifact。它尽量忠实记录各系统“观察到了什么”,不因为某个训练算法只需要一部分字段就提前丢弃信息。
Evaluated Trajectory:用于筛选和分析
在 raw telemetry 上重建 Agent 的行为顺序,关联 task、model、harness、tool、environment、verifier 版本,再补充 reward 分量、有效性、Better/Same/Worse 和失败归因。它回答“这次执行表现如何,以及我们为什么这么判断”。
Train Sample:用于某种训练目标
它是 evaluated trajectory 的派生物。SFT 可能只保留成功 action;偏好学习需要 chosen/rejected 配对;GRPO 需要同一 prompt 的一组 rollout、旧策略概率和组内 reward;某些步骤还要 mask 掉 observation,避免把环境返回错误地当成模型目标。
三者之间需要稳定的数据血缘:
raw_telemetry_ref -> evaluated_trajectory_id -> dataset_version -> training_run_id -> checkpoint_version这样模型出现回退时,才能从 checkpoint 反查训练集,从训练样本追到评估标签,再回到原始工具调用和环境状态。
评测数据还要单独隔离。训练集可以不断吸收 hard case,评测集则需要密封、版本冻结和污染检测。否则每次把线上失败回流训练,都可能顺手把评测答案喂给模型,最后得到一条越来越好看的曲线和一个没有泛化能力的系统。
- 先让每个 Benchmark 分数都可以被解释
实际落地可以从一个小而可验证的领域开始:例如有稳定单测的代码修复、结果可比较的 SQL 生成,或状态可查询的内部工作流。
第一版不必建设庞大的“Agent 数据中台”,只需要确保六件事:
- 每个 task 有可重置的环境、预算和明确 verifier;
- 模型网关、harness、工具、环境与 verifier 共享 rollout 标识;
- 每条 trajectory 绑定 task、model、harness、tool、environment、verifier 版本;
- 模型 action、工具结果和环境状态变化能够按顺序重建;
- Better、Same、Worse、Invalid 和失败归因有明确规则;
- 训练样本能够追溯到 evaluated trajectory 和原始证据。
做到这些,一次 Benchmark 才不再只留下排行榜上的一个数字:
Benchmark Run-> Raw Telemetry-> Evaluated Trajectory-> 结果比较与失败归因-> Training Sample-> New PolicyTrajectory 在这里连接了评测和训练。向上,它让我们知道分数能不能信、变化来自哪里;向下,它决定哪些行为值得学习,哪些故障应该隔离。
所以真正重要的不是“把 Agent 的所有日志都存下来”,而是让每一条 trajectory 都能回答三个问题:
当时发生了什么?为什么得到这个结果?它是否值得进入下一轮训练?
能回答这三个问题,Benchmark 产出的才不只是分数,而是一批可以持续改进模型的数据资产。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋
📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~