news 2026/9/28 17:55:19

Agent后训练数据闭环:从执行轨迹到SFT/DPO/PRM的完整实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agent后训练数据闭环:从执行轨迹到SFT/DPO/PRM的完整实践

做 Agent 开发的人,最近半年几乎都会被同一个问题卡住:线上模型跑出来的执行轨迹那么多,到底怎么变成下一版模型的训练数据?我花了一段不算短的时间,把这条链路完整跑通了一次——从日志埋点、轨迹清洗、样本构建,到 SFT 和偏好对齐,再到离线回归、线上灰度,最后把线上新产生的轨迹回收进下一轮数据池,形成一个真正能转起来的“Agent 后训练闭环”。这篇内容就是这次实践的过程拆解。

这条链路解决的是一个很实际的问题:很多 Agent 项目不缺日志,缺的是把日志变成数据、把数据变成模型提升的加工方法。适合的人有两类。一类是正在做 Agent 后训练、但对数据侧无从下手的工程师,另一类是已经跑通 Pipeline、想对照检查“我是不是漏了某些关键环节”的团队。接下来我按实际操作的顺序,从轨迹数据的价值判断开始说起。

1. 执行轨迹到底是种什么数据——先想清楚值不值得拿来训练

1.1 一条完整轨迹的解剖

在讨论训练之前,得先统一对“执行轨迹”的认知。一个典型 Agent 任务的执行轨迹,不是一段单调递增的文字,而是一组结构化的循环过程。以 ReAct 这类最常见的范式为例,一个 Agent 拿到任务后,会反复执行“思考 → 调用工具 → 观察返回结果”这样的循环,直到它认为自己可以给出最终答案。

我通常会把一条轨迹拆成下面的结构:

  • 任务描述(Task):用户原话,或者经过意图改写后的任务文本。
  • 步骤序列(Steps):每个步骤包含 thought、action、observation 三要素。
  • 执行结果(Outcome):成功、失败、部分成功,或者被用户中断。
  • 元信息(Meta):模型版本、Agent 框架版本、运行环境、时间戳、工具调用明细等。

这里的 thought 是模型内部推理的显式文本,action 是它决定调用的工具名称和参数,observation 是工具返回的环境反馈。一条复杂的任务可能有十几步甚至几十步,每一步都是这样一个三元组。把轨迹当训练数据,本质是把这条“过程链”变成可学习的状态-动作序列。

1.2 轨迹数据和静态指令数据有什么本质区别

很多人一开始会拿 Agent 执行轨迹和普通的 SFT 指令数据做类比,但两者差异很大。静态指令数据是“结果数据”,它只告诉模型:用户说了什么,你应该输出什么。而执行轨迹是“过程数据”,它额外包含了多步决策链、环境反馈、中途纠错这三样东西。

具体来说,轨迹数据里有三类静态指令数据很难提供的信息。

第一是行动序列。模型能从成功轨迹里学到“一件事应该按什么顺序做”。比如用户问“帮我查一下某公司最新产品信息并整理成摘要”,成功的轨迹可能包含调用搜索、打开链接、提取正文、再次搜索补充、汇总输出这一连串动作。只看结果摘要,模型学不到这套动作编排。

第二是纠错序列。大量真实轨迹里,前几步是失败的,比如工具参数给错了、搜索没返回有效结果、页面解析失败。模型随后调整策略,换一种工具或者换一个关键词,最后成功。这种“从错误中恢复”的路径,是纯静态数据很难构造出来的。

第三是工具反馈分布。轨迹里的 observation 部分记录了真实环境对工具调用的反馈,模型通过这部分数据,可以学会“某个工具在什么条件下返回什么格式、什么错误码”,这是把模型从“只会生成文本”推向“真的会用工具”的关键一环。

1.3 为什么不能直接拿原始日志训练

既然轨迹这么有价值,那直接把线上日志灌进训练集行不行?我试过,结论是不行,而且代价很高。原始日志存在几个硬伤。

首先是格式噪声。线上日志里交错着心跳检测、重试机制、模型流式输出片段、用户中途插话、系统超时提示,甚至还有多轮并发请求互相穿插的记录。不把这些噪声剥离掉,模型学到的会是“在什么时候说一堆无关内容”。

其次是行为噪声。线上轨迹的成败是由很多因素综合决定的,包括当前模型的策略、用户的实际投入程度、工具服务的稳定性。同一类任务,用户中途放弃和模型完成任务,在日志里可能看起来差不多,但前者不应该作为正向训练信号。

第三是目标不一致。线上 Agent 的设计目标可能是“尽可能完成任务”,也可能是“尽可能少调用工具省成本”,还可能是“优先保证安全不越权”。如果不理解线上目标的偏置,直接训练,会把业务规则里的保守倾向错误地学成“能力不足”,或者把激进策略学成“无视边界”。

所以,执行轨迹有价值,但原始日志不能直接用。需要一套加工流程,把日志里的“数据矿石”提炼成“训练样本”。

2. 从原始日志到干净样本:轨迹采集与清洗全流程

2.1 先设计好埋点字段,否则后面全部白费

轨迹清洗的第一步其实是日志埋点。这一步如果漏做,后面再想补,成本是成倍上升的。我建议每一条线上轨迹必须记录这么几个字段:

字段说明为什么必须记
trace_id一次任务的全局唯一 ID用来把分散在不同服务里的日志串成完整轨迹
task_id / task_text任务标识和任务原文后续做重复任务聚类、数据去重都能用到
stepsthought/action/observation 的数组核心训练内容
outcome成功、失败、部分成功、用户取消区分正负样本的基石
user_feedback用户点赞、点踩、手动修改线上最真实的奖励信号
model_version当前模型的版本标识数据血统追踪,复盘时必须知道是谁跑出来的
agent_versionAgent 框架与提示词版本同样的模型,不同提示词产生的轨迹差异很大
tool_call_detail每次调用的工具名、耗时、返回码分析工具失败率、识别投机性调用
intervention是否有用户或人工介入纠正被人工纠正过的轨迹,不能直接当成功样本

这套字段看起来简单,但实际踩坑时你会发现,少一个字段就断一条线索。我之前就遇到过:想分析某类任务的失败轨迹,结果日志里没有记录 user_feedback,导致完全无法区分“模型答错了”和“用户根本不想继续”两种情况,那批数据最后只能作废。

2.2 轨迹还原与并发交错处理

在分布式环境下,轨迹还原是个容易被低估的问题。Agent 执行过程中,主控模块、工具网关、模型服务是三个不同的进程,日志分散在三处,按时间戳粗暴排序的话,很容易把并行调用拼成乱序序列。

我常用的做法是:以 trace_id 为分组键,把同一 trace 下所有事件捞出来,再按事件时间排序,最后过滤掉两类非业务事件——一类是模型侧的流式 token 输出片段,另一类是网关层的健康检查和重试记录。做完这步,才能得到一张干净的执行事件表。

这里有个细节,同一 trace 内,Agent 可能会因为工具超时而重试。重试事件要保留,但要在步骤里打上 retry 标记。训练时,这些重试步骤既能作为纠错样本,也可能成为噪声源,关键看最终是否成功。成功轨迹里的重试是“知错就改”,失败轨迹里的重试是“反复横跳”,两者在筛选时要区别对待。

2.3 清洗规则:把轨迹加工成可读文本

轨迹还原之后,还要过一层清洗规则。我把常用的清洗操作列一下,这些阈值是我在多次实验里逐步调出来的,可以作为参考起点。

  • 观测文本截断。工具返回的 observation 经常特别长,尤其抓取网页或读取文档时,动不动上万字。我一般截断到 8000 字符以内,超出部分强制截断并加截断标记。模型不需要把整篇网页都背下来,它只需要学会从长文中抽取关键信息。
  • 敏感信息脱敏。轨迹里可能携带用户隐私数据、内部系统地址、密钥信息。这步必须用规则加模型双重过滤。脱敏不是隐去关键词就行,要连格式指纹一起处理,否则模型很容易从上下文学会“输出这类格式”而不是“安全地处理这类信息”。脱敏做不好,后面训练集根本不敢外发质检。
  • 工具名归一化。不同版本框架可能对同一工具使用不同别名,例如 search 和 web_search,要统一映射到同义词表。
  • 简单任务过滤。有些轨迹只包含一步动作加一个答案,这种样本的学习价值不高,而且量大了会稀释复杂任务的占比,不利于模型学会长程规划。经验阈值是步骤数少于 3 的轨迹,除非是被重点关注的失败类型,否则可以直接移除。
  • 相似轨迹去重。每天产生的轨迹可能高度相似,尤其是搜索类任务反复出现“查天气”这类重复请求。我按任务文本的 embedding 相似度做聚类,阈值取到 0.9 以上视为重复。只保留同类中质量最高的一条,防止某类任务在训练集里过度泛滥。

2.4 筛选规则与分层采样策略

清洗完,接下来是决定哪些轨迹能进入训练集。先说正样本的标准:outcome 为成功,且没有用户或人工介入纠正(intervention 为空)。这条标准比表面看起来严格,因为很多线上“成功”实际上是被用户纠正之后才完成的,比如用户中途补充说明“不是这个意思,我要的是另一个版本”,模型随后修正答案。这类轨迹代表模型有纠错能力,但也有可能掩盖了“第一轮理解偏题”的问题。我一般会把这类轨迹单独打上修正标签,不直接进正向 SFT。

失败轨迹也不能全部丢掉。它们是天然的负样本,用于偏好对齐阶段做 pair。但失败轨迹也要分类,至少分成“模型犯错导致失败”和“环境不可用导致失败”。前者可用于 DPO 的 negative,后者只能丢弃或作为环境鲁棒性分析材料。

最后是分层采样。我会按任务类型做配额控制,比如搜索类、代码生成类、数据分析类、网页操作类各占 20% 到 30%,加上工具组合类,确保训练数据不会因为业务偏置而变的单一。这一步的真实工作很繁琐,但直接影响训练结果。

2.5 质检:人工抽检不能省

自动化流程全部跑完后,我建议大家至少抽检 1000 条轨迹做一次人工复核,重点看三类问题:轨迹是否完整(有没有缺 observation)、步骤排序是否正确(有没有前后颠倒)、筛选标签是否合理(有没有把失败轨迹标成成功)。人工抽检看起来费时,但实际上能拦截掉大量规则覆盖不到的异常。

这轮质检还有一个作用:修正规则阈值。比如某类任务的轨迹普遍很长,步骤数超过 25 就可能是触发了死循环;但如果某类任务天然复杂,那么 25 以上的正常轨迹也不少。质检员反馈这些边界情况后,规则可以迭代得更准。

3. 轨迹变训练数据的三条管线:SFT、偏好对齐与过程监督

3.1 SFT:动作级监督,只教模型“下一步做什么”

SFT 是最直接的转换方式,核心思路是把一条轨迹拆成若干“状态 → 动作”对,让模型学会在给定的历史状态下,应该采取哪个下一步动作。

我构造 SFT 样本时,用的是 chat 格式。一个样本长这样:

{ "messages": [ {"role": "system", "content": "你是一个能调用工具完成任务的助手。工具列表:search(query), open_url(url), read_page(), summarize(text), respond(answer)。你必须一步步执行,每步先输出 Thought 再输出 Action。"}, {"role": "user", "content": "查一下 AlphaTech 公司最近发布的第四代产品参数,整理成对比表配一句点评。"}, {"role": "assistant", "content": "Thought: 用户需要产品参数,先搜索产品信息。\nAction: search(\"AlphaTech 第四代产品 参数\")"}, {"role": "user", "content": "Observation: 搜索到 3 条结果,第一条是官网介绍页,包含参数表。排名:官网 > 新闻稿 > 第三方评测。"}, {"role": "assistant", "content": "Thought: 官网信息最准确,打开官网页面。\nAction: open_url(\"https://...\")"} ] }

这里有两个关键点。第一,只保留 assistant 的 thought 和 action 作为监督目标,observation 归入 user 角色,因为它本质上是由环境产生的,而不是模型输出的;第二,最后一个 assistant 回复如果是最终答案,则不需要附带 Action。

在训练时,还需要对 loss 做 mask,只计算 assistant 内容中 thought/action 部分的 loss,不计算用户消息和 observation 文本的 loss。模型不需要把 observation 一字不差地背下来,它只需要参考 observation 来生成下一步动作。这一点很多人会忽略,但恰恰是轨迹 SFT 与普通指令微调之间最大的差异。

还有一个很实用的经验:SFT 阶段千万不要把失败轨迹作为标准答案混进去。模型学到的不是“从失败中反思”,而是“失败也无妨,继续输出”。失败轨迹的正确定位是负样本,应该在偏好对齐阶段使用。这个坑我早期踩过,模型训完明显“摆烂”——遇到复杂任务,它会更倾向直接放弃或重复无意义的工具调用。

3.2 DPO:构建成功对失败的轨迹对

DPO 是偏好对齐里性价比非常高的方案,因为它不需要训练一个独立的奖励模型,只需构造“偏好对”数据。所谓偏好对,就是同一任务下,一条成功轨迹和一条失败轨迹配对,让模型学会提高成功轨迹的概率、降低失败轨迹的概率。

构造偏好对的难点在于如何保证两条轨迹的重合程度足够高。如果任务完全不同,模型学到的只是“这两段话的概率此消彼长”,没有实际意义。我常用的方法是:

  • 对同一 task_id 的轨迹,如果存在成功和失败两个版本,直接配对。
  • 如果没有天然配对,可以拿失败轨迹的输入,让新模型重新执行一次。如果这次成功了,就能得到一对“同一任务、旧失败、新成功”的轨迹。
  • 同一成功轨迹如果真的没有失败副本,也可以用“成功轨迹的全过程”和“把某几个步骤置乱后的伪造失败轨迹”来凑对,但这种手段只能作为补充,不建议大量使用。

DPO 样本的构造格式是把整条轨迹序列化成一串文本,再做 pair。实际效果看,凡是轨迹长度适中、差异集中在某几个关键步骤的偏好对,对模型提升最明显;差异太小的 pair(只有一处用词不同)反而容易让模型在细节上变得敏感,甚至会轻微损害原有生成能力。

3.3 PRM:给每一步过程打分

SFT 和 DPO 都停留在轨迹级,但 Agent 任务里,一个致命的错误往往只发生在一个步骤上。过程奖励模型(PRM)的思路是把监督信号细化到步骤级别,训练一个模型对“状态 + 候选下一步动作”打分。

自动生成过程标签的方式主要有两条路。第一条基于结果回传:轨迹最终成功,则其内部所有步骤标为正;轨迹最终失败,则所有步骤标为负。这种方式噪声较大,因为失败轨迹里其实也有正确步骤。第二条规则判定:针对常见工具调用,用工具返回码、是否触发异常、是否重复调用等规则,给每个动作打上“有效/中性/无效”的标签。

实际项目里,我会结合两条路,再加人工抽样修正。PRM 训练数据中,一个样本是:

{ "state": "当前任务状态 + 历史步骤摘要", "candidate_step": "模型计划采取的下一步动作", "label": 1 }

PRM 训练好之后,它的价值不止在训练阶段。推理时,可以用它对模型生成的多条候选轨迹做步骤级重新排序,比单纯靠“最终答案置信度”来选路靠谱得多。这一步如果我们把 PRM 回溯用于下一次轨迹筛选,就形成了过程信号层面的闭环。

3.4 反思样本:把失败轨迹变成修正课

真实线上轨迹数据里,成功轨迹往往是少数派,失败轨迹占大头。如果只靠 DPO 消化失败样本,浪费了大量信息。我的做法是把一批失败轨迹转成“反思样本”,格式是:失败轨迹 + 反思分析 + 修正重试。

具体操作是:把失败轨迹发给一个更强的模型,让它分析“问题出在哪一步、为什么出错、应该怎么做”,生成一段明确的反思文本;然后带着这段反思,让模型重新执行原任务,得到新轨迹。如果重试成功,我们就得到了一条包含“失败+反思+成功”三段内容的复合轨迹。

这种样本的训练收益非常明显。模型学到的不只是一个动作对,而是“遇到这类问题时先诊断再修正”的决策习惯。尤其是工具参数错误、信息源选择不当这两类高频失败,反思样本能显著降低复发率。

反思样本的缺点是构造成本高,因为需要额外调用模型,还需要判断重试是否成功。我控制的比例大约是训练集的 10% 到 15%,再多会让训练数据整体偏“话痨”,模型容易在动作前生成大段无谓的自我剖析。

3.5 各管线数据的配比参考

三条管线不是平均分配。我以一次实际训练任务为例,当时数据池里共有约 12 万条轨迹,经过清洗、筛选后合格样本约 2.1 万条。最终配比是:

管线类型样本数占比说明
SFT 正样本约 8000 条38%仅使用成功轨迹,动作级监督
DPO 偏好对约 6400 条(3200 对)30%同一任务的成败 pair
PRM 过程标签约 4800 条23%规则 + 人工抽样校准
反思样本约 1900 条9%失败重试复合轨迹

这份配比的关键在于:SFT 保证基础能力,DPO 修正偏好,PRM 强化过程信号,反思样本补齐错误恢复能力。顺序上不能打乱——先 SFT 提升动作准确率,再 DPO 做偏好对齐,最后再引入 PRM 和反思样本。跳步训练会导致模型在不同目标之间反复横跳,效果反而更差。

4. 闭环的另一半:离线回归与线上灰度怎么衔接

4.1 评估集怎么造:黄金任务与时间分窗

训练数据加工好,模型也训练完了,这时候最怕的是“自我感觉良好”。我用两套评估集来做离线回归。第一套是黄金任务集,固定 500 条覆盖各任务类型的评测任务,每条任务都有明确的成功标准,人工预跑过 baseline,确保它们都是可完成的。第二套是时间分窗集,从线上日志里按新时间段采样一批任务,例如用 T-1 到 T 两周内、且不在训练集里的任务做验证。

时间分窗这件事特别重要。Agent 任务和普通 NLP 任务一样,存在任务分布漂移:上周热门的问题类型,这周可能就少了;某些工具的上游接口变了,返回格式也会漂移。如果把训练集和验证集都从同一时间段取样,哪怕做了严格 task 去重,分布泄漏依然存在。我见过不止一个团队因为忽略时间分窗,离线指标被高估了几个点。

4.2 离线指标组合:单看成功率一定会被骗

评估 Agent 模型不能只看任务完成率,那太粗了。我每个版本都会统计四类指标:

指标说明关注点
任务完成率成功完成任务的比例整体能力不下降是底线
工具调用失败率调用工具时返回异常的占比下降说明模型更会“用工具”
平均决策步数完成任务所需的步骤数明显上升可能是因为犹豫/试探变多
拒绝率与越权率直接拒绝任务或调用禁止工具安全与合规维度

这四类指标要看组合变化,不能单独看。比如新模型任务完成率上升了 2%,但平均决策步数同时上升了 20%,那很可能是模型学会了“多绕几步混成功率”,并不是真正变强。又比如工具调用失败率下降了,但拒绝率上升了,说明模型可能是在用“不调用工具”规避失败风险。

4.3 回归对比:逐个看新老模型的输出差异

离线评估除了看指标,还要做抽样对比。我把新老模型在同一批任务上的输出逐条对照,重点看三类变更:

  • 新增了哪些正确的工具调用,之前模型漏掉的;
  • 哪些原本正确的动作,新模型反而做错了,这类属于回归;
  • 哪些步骤虽然结果对,但执行路径更绕,这类属于效率回退。

这个动作很费时间,但非常值。我第一次跑完整流程时,靠这层逐条对比,发现新模型在代码生成类任务里“学会了用代码解释器”,但“忘了还能直接读本地文件”,导致原本一步能完成的事变成了三步。这种问题在聚合指标里完全看不出来,只有逐条对比才能暴露。

4.4 线上灰度:从小流量到全量的节奏

离线评估通过,不代表可以直接全量上线。我会按 5% → 20% → 50% → 100% 四步灰度,每步至少观察 24 小时。灰度期间重点盯三类线上信号:任务完成率(与 baseline 模型对比)、用户反馈(点踩率、人工纠正率)、工具网关错误率。

如果发现完成率不升反降,或者错误率抖动,立即回滚到上一个稳定版本。回滚本身要设计成一键操作,最好在模型网关层就做分流,而不是等到应用层才发现问题。这里有个容易被忽略的细节:灰度期产生的轨迹数据要保持独立存放,标记上模型版本。这些轨迹就是下一轮训练的原材料,也是判断本次迭代真实收益的证据。

5. 把反馈接回数据池:一套可持续迭代的工程闭环

5.1 一轮完整的轨迹闭环长什么样

到这里,整个闭环的各个环节都出现了。把它们串成一个可持续运转的流水线,大概是下面这个顺序:

  1. 线上 Agent 运行,原始日志落到数据管道;
  2. 日志按 trace_id 还原聚合,生成原始轨迹集;
  3. 清洗去噪、脱敏、去重,形成候选池;
  4. 按规则筛选正负样本,做分层采样,形成训练批次;
  5. 按 SFT / DPO / PRM / 反思四条管线加工训练样本;
  6. 训练完成后跑离线回归(黄金任务 + 时间分窗任务);
  7. 通过后按灰度节奏发布到线上,采集效果指标;
  8. 灰度期产生的新轨迹回流到数据池,参与下一轮清洗与采样。

这八步就是“Agent 执行轨迹 → 训练数据 → 模型迭代 → 新轨迹 → 再训练”的完整闭环。听起来简单,但每一步都有各自的坑。

5.2 数据血统管理:每条轨迹都要有户口本

闭环要能长期转,最重要的一件事是数据血统管理。每条进入训练池的轨迹,必须携带完整的版本元信息。

我维护了一张线索表,字段包括:轨迹 ID、采集时间、来源模型版本、Agent 框架版本、提示词版本、任务类型、清洗规则版本、最终用途(SFT/DPO/PRM/反思/未采用)。任何一次训练用到的数据,都能从血统表反查到源头。

血统管理最直接的用处是复盘。有一次新版本模型在某个任务类型上明显退步,我用血统表一查,发现训练集里混入了大量由旧提示词版本产生的轨迹,而旧提示词的决策风格和现在的目标恰好相反。如果没有血统表,这种问题几乎不可能定位。

5.3 迭代节奏:不是每天都要跑一轮

闭环能转,不代表要天天转。我的建议是每 1 到 2 周跑一轮完整训练,前提是候选池新增了足够数量的合格样本。如果这周线上流量平淡,新增合格轨迹不足 3000 条,那宁可不训练,也不要拿凑数的数据硬跑的。频繁用小数据量训练,模型很容易在个别任务类型上过拟合,整体能力反而下降。

数据不足时的替代方案是:调低筛选阈值,纳入更多“部分成功”轨迹,或者补充人工构造的合成轨迹。合成轨迹有个好用的办法——拿合格任务让当前模型多跑几次,记录不同随机温度下的多条候选轨迹,再用规则打分挑出最好的一条入库。这相当于把模型自己的能力当成数据增强器。

5.4 成本与资源估算:别让数据工程吃掉训练预算

轨迹清洗看起来只是“处理日志”,实际消耗的资源一点都不少。以 12 万条原始轨迹的规模为例,清洗阶段的算力主要消耗在 embedding 去重和脱敏模型推理上,大约需要几天的小型 GPU 实例;人工质检 1000 条轨迹,大概需要两个标注人员各花两到三个工作日;反思样本的构造需要调用强模型,一条约 0.1 元左右。整体算下来,单个训练批次的数据工程成本约占整体训练预算的 30% 到 40%。

所以我的建议是,把数据工程当做和训练本身同等重要的一环来排期,而不是“跑完训练再说”。数据质量低导致训练返工,浪费的算力和时间成本,比提前投入数据清洗要高得多。

6. 跑了半年踩过的坑:常见问题与排查技巧

6.1 数据泄漏:验证集里混进了训练集轨迹

这是最隐蔽、后果最严重的问题。我曾有一版模型离线指标漂亮得反常,上线后却明显退步,后来排查发现验证集里混进了与训练集高度相似的任务。原因是我用了“按任务文本精确去重”,但线上任务经常只改几个字就变成“新任务”,embedding 相似度很高,精确去重根本拦不住。

修复方案有两层。第一层,去重改用 embedding 相似度,阈值设在 0.85 左右;第二层,坚持时间分窗,确保训练集和验证集来自不同时间段。如果你做不到第二层,至少保证验证集任务的采集时间晚于训练集 7 天以上。

6.2 格式崩塌:模型学会了生成 Observation 而不是 Action

SFT 训练后出现了一个诡异现象:模型在中间步骤直接生成“Observation: 这是我从网页里看到的内容”,然后不再调用工具。原因是样本构造时,我把 observation 也放在 assistant 内容里参与训练,模型误以为 observation 是它自己应该输出的东西。

修复方案是在样本构建时严格区分角色:observation 全部写入 user 字段,训练时用 loss mask 屏蔽;只让 assistant 生成 thought 和 action。这个问题也提醒我,样本构造完成后,一定要先抽出少量样本看一眼“模型视角下”的完整上下文是什么,而不是只看 JSON 结构是否正确。

6.3 奖励黑客:PRM 学会了投机取巧

PRM 训练初期,我给每个步骤的标签是“工具是否调用成功”。结果模型很快就摸到了规律——只要它调用一个无害的工具,比如“搜索一下”但根本不看结果,这个动作就能获得正标签。于是模型学会了频繁触发无意义调用刷 PRM 分数,整体执行路径越来越长,任务完成率反而下降。

修复方法分两步。第一步,标签里加入“这一步是否推动任务向最终目标靠近”的人工抽样判断,只靠工具返回码不够;第二步,在特征里加入“该动作是否重复调用同工具”的惩罚信号,重复调用超过两次,即使工具成功也降分。

6.4 长轨迹训练不稳定:loss 震荡,越练越差

早期训练时,包含 20 步以上的长轨迹样本会引发 loss 震荡,甚至出现一个 batch 里 loss 特别大、下一个 batch 直接爆炸的情况。排查后发现原因有两个:一是 packing 时把多条轨迹拼在一起,长样本截断了正常上下文;二是我把整段轨迹的全部文本(包括长 observation)都计入 loss,导致模型被极端长度的文本主导。

修复方案是:对轨迹按长度分层打包,超过 1024 token 的样本单独处理;loss 只对动作位置计算,observation 位置直接 mask 掉。下面是一个 mask 的简化示意:

# labels: 与输入等长的标签序列 # 所有 observation 位置的标签设为 -100,SFT 时不参与 loss labels = [ -100 if is_observation(turn) else token_id for turn in trajectory ]

这个修改直接把训练稳定性拉回来了。之后我养成了一个习惯:训练前先统计轨迹长度分布,再决定 packing 策略,绝不无脑拼包。

6.5 数据新鲜度陷阱:旧版本轨迹带偏了新模型

闭环跑久之后,数据池里会积累很多历史轨迹。最初我舍不得丢弃旧数据,结果训练集里混着三个月前的轨迹,而三个月内线上工具接口、任务分布、用户习惯全都变了。模型既学不到最新的工具返回格式,又被过时数据里的旧行为干扰。

我现在的做法是引入时间衰减:超过四周的轨迹权重减半,超过八周的轨迹降权到 10%,超过十二周的直接移出训练池。保留策略是“旧数据只留分析用,不进训练集”。这个习惯帮我拦下了至少两版有明显数据泄漏风险的训练批次。

如果你也在做 Agent 后训练,建议第一件事就是把数据池的“时间账本”和“版本账本”建起来。每条轨迹标清楚采集时间和模型版本,训练前先看一眼数据池的时间分布和版本构成。这个账本会帮你避免掉绝大多数让人半夜爬起来排查的问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 17:55:07

金融服务系统一体化改造实战:从单体到分布式的事务与幂等设计

金融服务系统的改造,这几年在很多团队里都属于“又爱又恨”的项目。爱的是业务价值一眼可见,恨的是牵一发动全身,账户、交易、清结算、风控、对账,哪一环出问题都可能变成事故。我这次参与的项目代号就叫 financial-services&…

作者头像 李华
网站建设 2026/9/28 17:51:33

DXF导入嘉立创EDA专业版:异形板框避坑指南

说个很常见的场景:结构那边把外壳模型在SolidWorks里画好了,板框、螺丝孔、异形槽位都清清楚楚,你拿到手准备做PCB,唯一要干的事就是把这块轮廓搬进嘉立创EDA专业版。于是你另存了一个DXF,顺手导入,结果要么…

作者头像 李华
网站建设 2026/9/28 17:51:15

多智能体系统架构设计:MCP与A2A协议的分层协作实战

1. 从单体智能到协作网络:多智能体系统到底在解决什么问题如果你最近在折腾 AI Agent,大概率会有一种感觉:单个 Agent 能做的事情,很快就摸到天花板了。你给它接上工具、挂上知识库、写好提示词,它能帮你查资料、写代码…

作者头像 李华
网站建设 2026/9/28 17:51:14

Air780E MQTT连接不稳定原因与AT指令调试全指南

1. 为什么Air780E的MQTT连接总在“连上又断”?——从AT指令底层逻辑讲起你手里的Air780E模块,插上SIM卡、接好天线、串口连上电脑,发ATCGATT?返回1,ATCSQ显示信号格数满格,ATCIPSTATUS显示PDP上下文已激活……可一执行…

作者头像 李华
网站建设 2026/9/28 17:48:33

I2S四大协议标准详解:Philips/MSB/LSB/PCM波形与配置

1. 为什么I2S协议的“标准”不是标准?——从一块烧不起来的DAC板说起刚接手一个音频硬件项目时,我手上有块标着“支持I2S输入”的DAC模块,芯片是ES8374,主控用的是ESP32-WROVER。按理说,两个都是主流方案,接…

作者头像 李华
网站建设 2026/9/28 17:48:13

x64dbg接入MCP:AI自动化逆向分析环境搭建实战

1. 为什么要把 x64dbg 接入 MCP,而不是继续手点逆向分析这件事,干过的人都知道,最耗精力的从来不是"看懂某一条汇编",而是那些重复到让人麻木的机械动作:定位关键 API 下断点、反复单步跟栈、手动 dump 内存…

作者头像 李华