☰
Agent执行轨迹如何转化为训练数据:后训练闭环的关键实践
2026/9/28 8:44:14 网站建设 项目流程

做 Agent 开发的人,几乎都会遇到同一个困惑:执行轨迹(trajectory)跑出来一大堆,日志攒了几个 G,但除了做排查分析,好像没什么别的用。更有意思的是,你明明觉得某个失败的轨迹“再试一次没准能成”,但模型下次还是会在同一个地方卡住,思路一模一样。原因很简单——你没有把执行轨迹变成训练信号。

这篇内容要聊的是后训练闭环(post-training loop)里最关键的一环:怎么把 Agent 执行过程中产生的轨迹数据,通过清洗、筛选、标注、格式转换,最终变成能真正提升模型能力的训练数据。我会从数据怎么采集、怎么判断哪些轨迹值得留、怎么构建出 SFT 和偏好数据、以及怎么让这套流程形成可持续迭代的闭环,逐段拆开说。适合正在做 Agent 工程化、或者准备对模型做后训练但还处于“不知道数据从哪来”阶段的团队参考。

1. 为什么执行轨迹是“天然的训练金矿”

很多团队做后训练,第一反应是去找公开数据集,或者雇人标注一批指令问答对。这些路不是不行,但成本高、质量难控,而且有一个致命问题:通用数据跟你的 Agent 实际干活的方式差得太远。你的 Agent 有自己的工具集、有自己的 prompt 模板、有特定的调用约定(比如 function calling 的 schema),这些逻辑只存在于你系统的执行过程中。而公开数据里根本没有这些东西。

执行轨迹恰恰是唯一一种“自带上下文”的数据。一条完整的轨迹从用户请求开始,记录模型在每一步的思考、工具选择、参数填充、调用结果、环境反馈,一直到最终结束。它天然包含了你系统的业务规则、工具定义、错误处理方式,甚至包含了用户真实的使用习惯——这些信息几乎不可能通过外部采购获得。

我们在实际项目里把轨迹数据用起来之后,几个明显的好处就出来了:

  • 轨迹能忠实还原任务上下文,不用像做指令数据那样费劲重写场景描述。
  • 失败轨迹是免费的负样本,能用来做偏好对训练,价值特别高。
  • 轨迹有明确的时间顺序,能看出模型在哪个环节掉链子,方便针对性增强。
  • 数据的“业务纯度”极高,全部来自真实场景,不会像网上数据那样五花八门带噪声。

有一个项目里的经验:当时我们做的是一个多工具调用的 Agent,最初只靠人工写了两百多条指令数据做微调,效果一般。后来把线上两周的执行轨迹拉下来,清洗出大概三千条有效样本,再配合几百个偏好对做 DPO,同样的评测集上工具调用准确率直接提升了十几个点。从那以后,我和团队就再也没有“跑完就丢轨迹”的习惯了。

1.1 执行轨迹的结构化拆解:一个轨迹里到底有什么

我们先看一条标准的 Agent 轨迹由哪些部分组成。不同框架(LangChain、MetaGPT、自研框架)的具体记录字段可能不同,但核心元素基本一致:

  • 用户输入(初始指令、附带上下文)
  • 历史会话(多轮情况下的前置消息)
  • 模型决策链(thought / action / observation 的交替序列)
  • 工具调用细节(工具名、入参、返回值、异常信息)
  • 环境反馈(中间状态、检索结果、执行结果)
  • 终止状态(成功、超时、失败、用户中断)

一条失败的轨迹往往不是一下子挂掉的,而是经历了一系列微小的错误决策后逐渐偏离。举例来说,某个 Agent 需要先查库存再下单,但模型可能是因为工具描述写得不够明确,误把“查询库存数量”理解成了“直接生成订单”。这类问题靠人工审日志也能发现,但如果你能批量把这类轨迹收集起来,转化成训练数据去修正模型的决策偏好,效率就会高出一个量级。

1.2 训练数据视角下的轨迹质量:什么才算“能用”

我们刚开始做轨迹转训练数据时,犯过一个错误:以为所有轨迹都能进训练集。后来数据清洗时统计了一下,线上轨迹的有效利用率只有不到四成。所以需要先建立几个判断维度:

  • 完整性:要包含足够长的上下文,至少要有“用户意图—多步推理—执行结果”的全链路。
  • 一致性:同一任务的成功轨迹和失败轨迹,前置条件尽量对齐,这样才能构造出有意义的偏好对。
  • 信息量:单步“对”或“错”要有明确依据(来自环境反馈或工具返回值),否则模型学不到东西。
  • 多样性:任务类型和工具覆盖要分散,不能清一色都是同一种流程。

判断轨迹能不能用,还有一个很关键的技巧:看终止时的环境反馈是否明确。如果一条轨迹以“工具返回空结果”告终,但你无法判断是工具本身没数据、还是模型传参错误,这条轨迹的“可学习性”就不高,放进训练集也只是一笔糊涂账。格言就是:模糊的错误不如明确的失败。

2. 从轨迹到训练数据的完整转换流程

我这边把“轨迹数据 → 训练数据”的工程过程拆成五步,每一步都对应明确的目标和产出物。团队不需要一上来就搞自动化大平台,先按这五步手工或者半自动跑通,后面再逐渐固化到代码里。

2.1 轨迹采集与打点:先解决“数据有没有”的问题

轨迹采集是地基,地基不牢,后面所有环节都是空中楼阁。你在框架里至少要保证每个 Agent 执行会话都能落盘一份独立的日志文件,包含会话 ID、时间戳、模型输入输出、工具调用记录和环境反馈。

这里有一个核心基础设施要求:可重建性(reproducibility)。只记“模型输出了什么”是不够的,还要记录模型推理时的完整上下文,包括 prompt 里的工具定义、系统提示词、截断策略等。因为这些内容决定了轨迹是否可复现、可分析。如果哪一天你要拿一条轨迹去构建训练样本,却发现当时的 prompt 模板已经改版了,这条轨迹的价值就大打折扣。

我们的做法是在框架层面埋点,对 send_message 和 tool_execute 两个核心方法统一包装一层记录逻辑。这样不管是哪个业务接入,只要走框架的主流程,轨迹都会自动落盘。格式上推荐 JSONL,一行一条事件,方便流式读取和大规模并行处理。

打点示例(伪代码结构):

{ "session_id": "8f3a7c2e", "sequence": 3, "timestamp": 1733456789, "event_type": "tool_call", "agent_id": "order_agent_v2", "tool_name": "query_inventory", "input": {"sku_id": "1002301"}, "output": {"stock": 38, "warehouse": "hz"}, "status": "ok" }

注意 output 里要记录的是工具返回的原始内容,不是模型理解之后的内容。这样才能在后续做“模型是否正确理解工具返回”的归因分析。

2.2 质量清洗与筛选:把垃圾挡在训练集外

采集到的原始轨迹,需要过几道筛子。第一道是规则过滤,把明显无意义的记录剔除,比如长度过短的交互(用户发了一句“你好”,然后没有下文)、测试时产生的假流量、因为系统异常(如 API 超时)导致的中断轨迹。

第二道是启发式评分。我们设计过一个简单的评分体系,给每条轨迹打 0~100 分,核心维度包括:是否完成最终目标、工具调用次数是否在合理范围、是否有重复无效调用、错误信息是否有明确指向性。评分低于阈值的轨迹直接不进候选集。

这里分享一个我们在实操中反复踩过的坑:不要用“模型自己评价自己”的方式来筛选轨迹。用 LLM 做 judge 评估长文本的语义质量还行,但评估轨迹决策是否正确时,大模型经常会被“看似合理的推理链”带偏,给出虚高的评价。更可靠的做法是,以环境反馈的客观结果为准——工具是否成功返回、目标字段是否满足、最终状态码是否为预期值。

筛选阶段另一个重要口径是用户维度。如果某个特定用户反复触发同一种失败模式,要考虑做去重,避免训练集中某一类型的错误占比过大导致模型过度拟合。我们的经验是同一个错误模式最多保留 5%-10% 的占比。

2.3 数据标注与增强:必要时补上“人工”这一步

清洗完之后,一部分高质量轨迹可以直接用,但更多场景下需要一定的人工介入,尤其是构造偏好对和白金样本(golden trajectory)。这一步往往是最贵的,也是最容易做出差异化价值的。

先看成功轨迹的增强:一条成功的轨迹可能只是“碰巧成功”,比如模型第一轮误打误撞选了正确的工具,但推理过程写得一塌糊涂。这类轨迹直接拿去做 SFT,模型学到的可能是一套错误的思维模式。所以对成功轨迹,人工标注员要审查它的决策链,看每一条 thought 是否逻辑自洽、是否指向正确行动。如果某个 thought 和 action 不匹配,要么修正 thought,要么整体抛弃。

再看失败轨迹的增强:收集失败轨迹通常是为了构造偏好对——同一任务下,成功轨迹作为 chosen,失败轨迹作为 rejected。如果找不到完全同任务的成功轨迹,可以人工走一遍“修正版轨迹”,即在失败轨迹的关键步骤上改出正确行为——这一步耗时,但效果比硬凑偏好对好得多。

实际项目中我们配备了一套轻量标注工具,标注员可以逐条查看轨迹的每个 step,看到模型输出、工具返回、环境状态,并一键打上标签(正确/错误/需改写)。这套工具早期是用几张 Airtable 表单 + 一个简单的 Web 界面搭起来的,花了两三天时间,但对数据质量的提升立竿见影。

2.4 训练格式组装:SFT 和偏好对到底长什么样

清洗和标注完成之后,下一个核心问题是:轨迹怎么组装成模型能吃的数据格式。这里分两类来说。

SFT 数据格式。对于 SFT,我们本质上是要教会模型“在这种上下文下,应该输出这样的下一步动作”。所以一条 SFT 样本是:(历史上下文 → 当前正确的输出片段)。关键不在于把整条轨迹塞到一个样本里,而是切成若干 (输入,输出) 对。比如一条 6 步成功的轨迹,可以切成 5 个训练样本,每第 n 个样本的输入是前 n-1 步的上下文,输出是第 n 步的模型动作。

这种切片做法有一个显著优点:让模型在任意中间状态下都能学会“下一步该做什么”,而不是只会从头到尾背一条完整流程。我们在 SFT 数据构建时,把每一条轨迹的中间步骤利用率提升了三倍以上,训练效率也高了很多。

偏好对格式。DPO 或 RLHF 需要的是“对同一输入,有两份不同质量的输出”。轨迹转偏好对,最直接的方式是对同一个任务,配套收集成功和失败的完整轨迹。如果完整的失败轨迹和成功轨迹长度差异太大(例如成功轨迹 10 步、失败轨迹 2 步就挂了),建议截取共同的“窗口段”,只保留分叉点前后的若干步,让模型聚焦在决策拐点上学习。这也是我们实践中发现的最能提升 DPO 效果的做法。

组装完之后,数据要统一转成你后训练框架要求的格式。如果用的是 Llama-Factory,SFT 数据通常是 Alpaca 风格或 ShareGPT 风格;如果用的是 TRL 的 DPOTrainer,偏好对需要严格包含 prompt、chosen、rejected 三个字段。数据格式的错误往往要到训练启动后才发现(跑一半报错或 loss 异常),所以建议组装完先跑一次小规模验证(几十条样本)确认格式没有问题再全量开跑。

2.5 质检与抽检:上线前的最后一道防线

数据不行,训练必废。所以在把数据送入训练流程之前,建议设一个强制质检环节。我们目前的做法是这样的:

  1. 规则校验:检查字段是否齐全、长度是否超标、是否包含非法字符(如工具返回值里的二进制内容混入文本)。
  2. 概率抽检:每批数据抽取 2%-5% 的样本,由人工(或高标准的 LLM judge)检查格式合理性和语义合理性。
  3. 分布校验:统计标签分布、工具覆盖分布、错误类型分布,如果有明显长尾缺失,返回上一步做补偿。

尤其要检查一个隐蔽问题:训练数据里的“正确答案”是否真的算正确答案。比如一条轨迹写的是“调用 query_order 返回成功”,但如果在采集那一刻工具本身有 bug,返回了错误的“成功”,模型学到的是在错误条件下行动。所以质检还要对齐工具日志和业务日志,确认成功状态是真实可信的。

3. 不同轨迹类型的最佳训练价值分析

从训练利用的角度,执行轨迹可以分为三种类型。在实操中,我们会针对不同类型采取不同的处理策略。

3.1 成功轨迹:SFT 的主要养料,但要“去伪存真”

成功轨迹是 SFT 数据的主力来源。只要任务目标是明确的、最终状态是成功的,就可以按 2.4 节的切片方式构建样本。唯一的问题是成功轨迹里可能包含“侥幸成功”和“低质量推理”,所以需要在 2.3 节的人工审阅阶段过滤掉一部分。

一个额外的经验:模型推理过程和最终动作同样重要。SFT 里除了让模型学会“调用哪个工具”,还要学会“为什么调用这个工具”。所以保留 thought 文本作为输出的一部分是有意义的,前提是 thought 写得好。有些 Agent 框架输出 thought 比较敷衍(比如固定输出“我需要调用工具来完成这个任务”),这类没有决策解释价值的 thought,切成 SFT 样本时直接用 action 部分即可。

3.2 失败轨迹:偏好对的负样本,价值被很多人低估

失败轨迹的价值不在于“让人看”——它是最好的偏好对负样本。DPO 训练时模型需要同时看到“做对了的”和“做错了的”,从而学会拉大两者之间的概率差。

这里分享一个核心心得:不是所有失败轨迹都适合做 rejected。判断标准是:这条轨迹是否在“它有实力做对”的情况下做错了。如果任务本身就超出模型能力范围(比如需要检索一个根本不存在的信息),拿它做负样本,模型学不到东西,还可能困惑于为什么同样的输入被标成错误。所以我们只保留“模型有潜力做对但因为某个决策失误而失败的轨迹”作为负样本,这个过滤条件能显著提升 DPO 的实际效果。

失败轨迹还有一个进阶用法:错误模式聚类。把大量失败轨迹按错误类型(选错工具、参数格式错误、过早终止、重复调用)聚类,可以发现系统性的缺陷。这时候不仅要做成训练数据,还要去看是不是工具描述写得太烂、或者框架层的参数转换逻辑有 bug。修复系统问题比加训练数据更直接,别本末倒置。

3.3 混合轨迹与长尾场景:构建评测集和困难样本挖掘的原料

除了成功和失败,还有一类轨迹价值很高:混合结果轨迹。比如某些任务部分成功,中间调用了两个工具,第一个成功、第二个失败。这类轨迹不能直接进 SFT 或 DPO,但它们是构建评测集的好材料——尤其是评估 Agent 在部分失败情况下能否正确恢复(recovery)的能力。

困难样本挖掘(hard mining)也依赖轨迹数据。每跑一轮新模型,就把线上轨迹里“新模型失败但旧模型成功”的样本挑出来,这类样本往往最能反映当前模型的盲区。我们有一个内部脚本,专门对比两版模型在相同任务上的成败差异,产出的差集直接进下一轮训练集。这个机制跑通之后,后训练的收益会越来越大,因为每一轮都在针对上一轮的缺陷做修正。

4. 后训练闭环设计与迭代机制

做完数据转换,只是解决了“一轮训练”的问题。真正能持续产生效果的,是建立一套 “执行 → 清洗 → 训练 → 验证 → 上线 → 再执行” 的闭环。下面是我认为闭环落地必须处理的几个环节。

4.1 闭环整体架构:从执行日志到上线评估的流向

我用一条线来概括整个闭环的流程:

线上/离线执行 → 轨迹采集 → 轨迹清洗筛选 → 数据格式转换 → SFT/DPO 训练 → 模型评测 → 定向灰度 → 新轨迹回流

光有这条线还不够,每一环都需要有明确的触发机制。比如轨迹库积累到多少条才触发一轮新训练?训练完成后的评测通过标准是什么?灰度上线后多久回收新轨迹?这些如果没有定义清晰,闭环很容易变成“有一搭没一搭地跑”。

以我们团队为例,目前的节奏是两周一轮。每两周从线上环境拉取全量轨迹,清洗出有效数据,和上一轮的数据合并(注意控制重复样本比例,一般不超过 30%),做一次增量训练,然后跑一套固定评测集,对比关键指标(工具调用准确率、任务完成率、无效调用率)。指标达到预设阈值就灰度给 5% 流量观察两天,没有问题再全量。

4.2 迭代策略:增量训练怎么避免“灾难性遗忘”

后训练做得多了,最头疼的问题是灾难性遗忘——模型学了新数据,忘掉了旧能力。轨迹数据因为任务分布集中(都来自你自己的业务),遗忘现象尤其明显。我们在实操中总结出两条缓解策略:

第一,数据混合比例要控制好。新数据和旧数据不应该是“替换”关系,而是“混合”关系。我们的经验是新一轮的数据量不要超过上一轮总数据量的 50%,并且要把上一轮的部分高质量数据按一定比例保留在训练集中。保留比例可以按任务类型调整,比如核心业务场景的数据强制保留 60%,边缘场景可以少留一些。

第二,利用参数高效的训练方式,降低遗忘风险。如果做 SFT 或 DPO 用的是 LoRA/QLoRA,每轮训练只更新少量参数,遗忘现象会轻很多。我们在项目早期用全参微调,虽然效果上限更高,但每轮都要重新跑很重的校验;后来切到 LoRA 之后,训练时间缩短了 70%,遗忘问题也解决了大半。对大多数 Agent 团队来说,LoRA + 定期全参微调(比如每三个月一次)是一个比较务实的组合。

4.3 验证与评测:不能只靠一个“准确率”走天下

后训练的评测要比普通模型评测复杂得多。普通评测是问一个问题、比对答案;Agent 后训练要评估的是多步决策质量。所以我们需要分层评测:

  • 单步工具选择准确率:每一步模型的工具选择是否正确。
  • 多步任务完成率:整条轨迹是否达到用户目标。
  • 效率指标:平均步数、无效调用率、重复调用率。
  • 鲁棒性指标:面对相同问题在不同 prompt 变体下的稳定性。

我们维护了一套基于真实任务回放的评测集,每条评测样本都来自人工筛选过的轨迹,带标准答案或评分规则。每一轮训练之后都跑同一套评测集,保证可对比性。顺便提醒一句:评测集和训练集要做重叠检测,避免“训练数据泄露到评测集”这种低级的但特别容易犯的错误。

4.4 数据飞轮怎么转起来:让执行系统“越用越聪明”

闭环转起来之后,理想状态是:系统每次执行任务都在为你“攒训练素材”。要实现这个飞轮效应,有几个隐性的前置条件:

  1. 执行任务的多样性要够。如果线上任务几乎都只有同一种模式,轨迹数据的多样性有限,飞轮转得再快也提炼不出新知识。
  2. 失败数据要被“看见”。很多团队习惯把失败的日志放到冷存储里就不管了,这等于把最有价值的素材扔了。失败轨迹不仅要保留,还要尽量结构化记录失败原因,方便自动筛选。
  3. 新策略上线后要给足够的时间“冒泡”。也就是说,你已经训练好的新模型要拿到一定比例的线上流量去产生新轨迹,否则闭环会断流。灰度流量的比例至少保持在 10% 以上。

当这些条件满足后,你会发现一个有趣的现象:你的 Agent 不是在“部署之后保持不变”,而是每跑两周就悄悄变聪明一点。这个状态,才真正称得上“后训练闭环”。

5. 落地过程中的常见问题与排查技巧

这一节整理我们踩过的坑。很多问题不试不知道,试了才明白为什么网上很少有人写清楚。

5.1 轨迹日志“长歪了”:埋点不全导致数据无法使用

最常见的问题是:日志里没有记录 prompt 版本。线上跑着跑着 prompt 改了,两周后拉轨迹发现上下文对不上。排查方法很简单——在采集阶段就把 prompt 模板的 version 字段记进轨迹,每条轨迹都带上版本号,筛选时自动排除掉与当前版本差异过大的历史轨迹。

还有一种是工具调用的入参记录过于简化,只记录了“最终结果”,没记录“传入参数”。这在模型误传参数但工具意外成功时特别伤:你想拿这条轨迹当正样本,结果发现根本看不出来模型传了什么参数。建议一切入参出参都原样落盘,别为了省存储做摘要,后续你会感谢自己没偷懒。

5.2 训练中 Loss 不稳定:先检查数据而不是模型

很多人一看到 DPO 训练 loss 异常就调超参,但数据的问题远比超参更常见。我们遇到过 loss 一路走低但评测效果变差的诡异情况,后来逐条检查训练数据,发现大量偏好对存在“chosen 和 rejected 非常相似”的问题——比如只是差的最后一步不同,或者两者的思考内容几乎相同但一个标了正一个标了负。这种偏好对会让模型学到很表面的模式,甚至直接“摆烂”降低整体置信度。

另一个隐蔽的问题是数据里混入了“隐含正确答案”。比如工具返回本身就包含答案,模型只需要复述而不是真正做推理。这类样本虽然 loss 能降下来,但对 Agent 的决策能力提升没有帮助。筛选阶段最好加一条规则:工具返回值里能直接提取到答案的轨迹,不进 SFT 训练集。

5.3 数据量够了效果还是不好:从覆盖度和多样性找原因

还有一种情况是,你攒了几千条轨迹,照着流程训练完,评测集上纹丝不动。这时绝大多数原因不是数据量不够,而是覆盖度不够。比如线上 80% 的轨迹都是同一种“查询类任务”,而评测集里新增了“创建类任务”,模型没学过,自然变差。

解决方向有两个:一是从历史存量轨迹里补挖少见任务类型,二是针对性地扩量采集(比如主动构造一批少见任务的执行请求,让当前 Agent 去跑,再人工校正)。后者听起来像是在“刷数据”,但本质上是一种可控的数据增强,在 Agent 场景下是合法且高效的。

5.4 评测集污染:最容易被忽视的致命细节

我在这件事上栽过很痛的跟头。有一次新训练完的模型在评测集上分数大幅提升,我们特别兴奋地上线了,结果线上表现反而下滑。查到最后发现,评测集里有一半样本在训练集里以相似甚至相同的形式出现过。这就是数据泄露(contamination)。

为了防这个问题,现在每一轮数据准备前都会跑一个去重脚本:基于语义相似度(用 embedding 做向量比对)把训练集和评测集的相似样本识别出来,相似度超过 0.85 就强制从训练集中剔除。这套机制看着简单,但救了我们很多次。

5.5 闭环没跑起来:多为组织和流程问题,而非技术问题

最后补一句实际的感悟:执行轨迹变训练数据这件事,纯粹的技术链路并不难,难的是跨团队的协作流程。模型团队要懂业务轨迹的结构,业务团队要理解训练数据的格式要求,数据标注团队要有领域知识。我们最后把整个流程用一个“数据周报”的方式串了起来——每周固定发布轨迹量、有效样本量、筛选率、训练指标,让参与方都看到数据转化的情况。有了这个透明机制,协作才真正顺畅起来。

6. 实操经验补充:从第一天起就该做的三件事

并不是所有人都需要马上把整个闭环建设到位。但如果看完这篇文章,你想从今天开始动手,我建议优先做以下三件事。这三件事成本低、见效快,而且不会给现有系统引入太多风险。

第一,把线上 Agent 的执行日志结构化。如果你的日志现在还是一条“会话 ID + 时间戳 + 一堆散乱的文本”,先去把这个结构理顺。哪怕不用训练数据,排查问题也会舒服很多。第二,从最近的失败轨迹里挑 50 条,手动整理出“修正版轨迹”,攒一版最小 SFT 集,做一次小规模 LoRA 微调,感受一下数据转化全流程的温度。第三,围绕线上任务搭建一个 100~200 条的评测集,明确之后每次模型变更都用它来验收。这三大件做完,后训练闭环的地基就已经打好了。

我在实际项目中越做越有体会的一点是:后训练不是一个“做完就交付”的功能模块,而是一条需要持续维护的数据管道。真正拉开团队差距的往往不是模型本身的 base 能力,而是谁能把执行过程中产生的真实数据高效地循环利用起来。工具链成熟度可以慢慢补,但对“轨迹即数据”这个认知的认同,最好从现在就开始。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询