资讯详情

Agentic SFT实战指南:轨迹数据构建、训练设置与评估观测

📅 2026/10/17 3:47:52 | 华诺云谱 👁 阅读
Agentic SFT实战指南:轨迹数据构建、训练设置与评估观测
最近一直在折腾 Agentic SFT智能体监督微调的东西踩了不少坑也推翻了不少之前的想法。团队内部交流的时候发现很多人对 Agentic SFT 的理解还停留在“把多步对话数据拼一起做 SFT”这个层面实际跑过之后会发现完全不是这么回事。这篇就当个人记录持续更新主要聊聊我从数据构建、训练设到评估观测的一些浅薄认知和实操教训希望能给正在搞 Agent 训练的同学一点参考。如果说传统 SFT 是“考前背题”那 Agentic SFT 更像是“模拟面试”。背题只需要记住标准答案而模拟面试要求你在一个动态环境里根据对方反馈不断调整自己的回答。这两者的训练数据、训练目标和评估方式本质上就是两套逻辑。1. 先理清概念Agentic SFT 到底改了什么东西1.1 传统 SFT 的假设与瓶颈传统 SFT 的训练样本是一个静态的“问题-答案”对。模型要学的映射是给定用户指令直接生成最终回答。这条路在对话、文案生成这类单轮任务上非常成熟但一旦放到 Agent 场景就开始暴露问题——真实环境里一个任务往往需要多轮交互模型要调用工具、读取返回结果、纠错重试最终才能完成目标。传统 SFT 训练出来的模型有两个典型毛病第一它把“问题”和“最终答案”强行绑定中间那些关键决策过程比如调用哪个工具、如何解析返回结果它根本没学过第二训练时模型看不到“动作之后的反馈”比如工具报错后该如何恢复这种临场应对能力在静态问答对里学不到。还有一个更隐蔽的问题传统 SFT 数据通常把一段多轮对话压成单轮问答来构造模型的上下文窗口在训练时被强行填充上用户消息和最终回答中间的工具调用痕迹被抹掉了。模型学到的认知是“用户提问我直接给结果”一旦推理时真实存在工具返回阶段模型就不知道怎么接话经常出现格式崩溃。1.2 Agentic SFT 的核心差异轨迹级监督Agentic SFT 的训练单元不再是单轮问答而是一条完整的轨迹trajectory。这条轨迹长这样用户指令、模型的思考与动作比如工具调用的结构化文本、环境返回的结果observation、模型下一步思考直到最终给出答案。这里最关键的差异是模型要学习“根据环境反馈调整决策”这个循环能力。每一步模型看到的都是当前可观察的状态包括用户原始需求、历史动作、最新工具返回它需要输出一个合理的 next action。这个模式和强化学习有些类似但 Agentic SFT 仍然属于监督学习的范畴——所有动作都是我们用标签数据直接指定的而非通过奖励探索获得的。用一个不严谨但好理解的类比传统 SFT 教模型“知道答案”Agentic SFT 教模型“会干活并且干到一半遇到意外知道怎么处理”。1.3 它和 RLVR、DPO 的关系很多同学问做了 Agentic SFT 还有必要做 RLVR基于规则的强化学习吗我的理解是SFT 是让模型“会”RL 是让模型“精”。Agentic SFT 的目标是把模型从“完全不会 Agent 交互”拉到“基本流程能走通”但它有一个天花板——监督信号来自固定标签模型只能模仿标注轨迹里的行为无法超越数据分布。如果只用 Agentic SFT模型遇到数据里没出现过的边缘情况比如工具超时、返回格式异常大概率还是崩。这时需要 RLVR 这类在线探索机制让模型自己尝试不同的恢复策略根据环境结果获得奖励信号。Agentic SFT 的价值在于给 RLVR 提供了一个不崩的初始化策略——跳过了“连格式都不对”的阶段RL 探索时不会频繁触发截断。至于 DPO直接偏好优化我在实践中的定位是“事后修正”。SFT 训练完以后模型可能在某些决策点比如该重试还是该放弃产生偏好偏移。这时可以收集一些好轨迹和坏轨迹做偏好对用 DPO 微调一下。但 DPO 的偏好对如果构造不严谨很容易让模型只是调整了措辞而不是真正改进行为。所以这个组合顺序是Agentic SFT 打底、RLVR 提上限、DPO 做策略微调——千万别颠倒。2. 数据构建Agentic SFT 的灵魂所在2.1 轨迹数据从哪里来这部分我踩的坑最多。刚开始我们尝试直接用真实用户日志里的多轮会话拼轨迹结果惨不忍睹。真实会话里大量无意义试探、重复操作和最终未完成的半截任务模型学这些只会变成“低效的模仿者”。目前我们用的可靠方案是“模拟环境采样 结果过滤 人工抽检”三件套在可控的模拟环境里比如一个测试用电商搜索系统把任务清单灌进去让一个能力较强的通用模型自主完成。只保留最终任务状态为“成功”的轨迹且核对每一步工具调用的参数合法、返回结果被正确解析。人工抽检 20%-30% 的轨迹主要看中间推理是否合理剔除“歪打正着”的成功案例。这个流程的核心是“环境可控”。模拟环境里的工具接口、报错规则都是我们自己定义的因此能精确控制轨迹分布想增加“重试后成功”的样本就故意注入工具报错。2.2 配比策略单步数据和轨迹数据的比例实验中我们发现如果把训练数据全部换成轨迹数据模型的单轮对话能力会出现明显退化尤其在通用问答上变得啰嗦、喜欢强行调用工具。最有效的做法是拿一定比例的常规指令数据做混合。目前我们比较稳的比例是单轮指令数据占 40%-50%多步轨迹数据占 40%剩余的 10%-20% 保留纯 reasoning 数据比如数学解题链。这个比例不是拍脑袋定的我分别试过 20% 和 70% 的轨迹占比结果 20% 导致 agent 能力基本没提升70% 导致通用能力崩掉。40% 左右是一个甜区。还有个细节同一个任务的多条变体轨迹要控制重复度。模拟环境里同一个任务查同样的商品轨迹会很相似如果不去重模型会过拟合到某几种固定的搜索路径上一旦真实环境里的搜索词分布稍微偏移表现立刻下滑。我们做了轨迹相似度去重按关键词重叠率超过 70% 的就归成一簇每簇最多保留 3 条。2.3 数据字段与序列格式设计Agentic 轨迹数据格式直接影响训练时的 mask 设计和模型是否能学会“何时停止”。我们内部用的格式大致如下{ instruction: 用户想买一款性价比高的降噪耳机预算500-800元, messages: [ {role: user, content: 帮我在商城找一款降噪耳机预算500-800}, {role: assistant, content: [SEARCH] 降噪耳机 500-800元}, {role: observation, content: 返回6条商品前3条为...价格区间...平均评分...}, {role: assistant, content: [SELECT] 第2款 型号A 价格699 评分4.8}, {role: observation, content: 商品详情... 库存充足符合预算}, {role: assistant, content: 我推荐你选择这款耳机价格699元... 理由...} ] }这里的关键点是把工具调用和 observation 都显式建模成消息角色。训练时对 observation 角色的 token 做 mask模型看不到 loss 信号避免模型去“预测环境返回什么”。它只需要学会根据 observation 内容生成下一轮决策这个机制保证了模型不会把环境和自身行为混为一谈。2.4 轨迹过滤的隐性标准只看最终成功还不够。要强制过滤下面几类轨迹否则训练效果大打折扣步骤过长的高 token 轨迹超过 20 步的轨迹往往包含大量无效尝试模型学多了会产生“长时间不收敛也正常”的错觉。模型中途自问自答的轨迹有些模型会在无 observation 的时候自己“猜测”工具返回这种轨迹要斩断。单步收益为负但不影响最终结果的轨迹比如先查了一轮无关内容再切回正轨这类轨迹里的子决策是错误的却在成功标签下被保留下来污染很大。这一块目前我们还没有一个全自动的完美解法相对靠谱的组合是规则过滤 奖励模型打分排序。对轨迹中每一步动作算一个过程奖励分最后把高分轨迹和低分轨迹都保留一部分——保留低分是为了模拟真实环境的多样性但比例要控制在 15% 以内且人工确认这些低分轨迹不是“逻辑混乱”。3. 训练设置比传统 SFT 敏感得多3.1 长序列打包与位置编码Agentic 轨迹天然是长序列几百到几千 token 都有。直接按完整序列训练会导致 batch 里的样本长度差距巨大短样本拖慢训练、长样本占用大量显存。我们采用了 packing序列打包策略把多条短轨迹拼进同一个训练序列由一个特殊的端符分隔并重新分配位置 id。具体做法是每条轨迹内部保持 token 之间的位置 id 连续跨样本的部分位置 id 重新归零。注意力 mask 采用块状 mask让不同样本之间不能互相 attend。这个设计如果不做模型会学到跨样本的不存在的语义关联推理时出现幻觉。另外一个坑是超过了模型上下文上限的轨迹。我们最初的基线模型是 8k 上下文于是把超过 8k 的轨迹直接删了。后来发现这是个错误因为很多真实任务本来就需要更长的历史把长轨迹全删掉等于训练时阉割了模型的长程决策能力。解决方式是把基线模型的 RoPE 基频调大在训练时渐进式扩展到 16k。实验数据上长轨迹的保留让最终线上任务成功率提升了接近 7 个点。3.2 Loss 掩码逻辑什么该算什么不该算训练时 loss 掩码可能是最容易被忽略、影响最大的设置。很多开源代码直接对 messages 里的每一条做 next token prediction loss这意味着模型会去学习预测 observation 和 tool 调用格式里的固定字段。结果就是模型确实学会了“打印工具调用”但根本没有理解“用返回结果来推理”。我们的掩码设置非常严格observation 角色的内容无条件 mask一条 token 都不算 loss。assistant 消息里非语义部分比如工具调用的结构化 schema 字段、参数名的固定字符mask。真正需要模型学会的内容工具调用时的参数值动态部分、模型自身的推理思考、对用户回复的自然语言保留 loss。对“思考”和“最终回答”两种 token 设置不同的 loss 权重通常思考部分权重为 1.0最终回答上调到 1.2-1.5。原因是最终回答直接决定任务是否完成优先级更高。这里补充一点很多团队会把整个 [SEARCH] 这类工具调用 token 全部 mask。我试过这个方案模型在推理的时候工具调用格式经常出错输出一堆不符合 schema 的垃圾。所以工具调用的“动作名称”和“参数名”要保留 loss让模型把这些固定格式背下来只 mask 与预测无关的“参数值”是一种更优的折中。参数值不用预测选型可以由复杂逻辑决定。3.3 训练超参学习率与 Epoch 的怪圈Agentic SFT 比普通 SFT 更容易过拟合。我们第一版训练时用了通用的 2e-5 学习率和 3 个 epoch结果模型严重退化生成的内容几乎全是训练轨迹里高频出现的同款话术。后续调参经验是学习率降低到 5e-6 到 1e-5 之间epoch 控制在 1-2 个。注意这说的是轨迹数据的 epoch混入的通用指令数据可以多训几轮因为它更抗过拟合。另一个被低估的参数是 weight decay我们加到 0.1 以后格式崩溃的问题明显变少。如果想偷懒可以直接采用 warmup 比例 3%、学习率 8e-6、batch size 128、bf16 混合精度这套起步配置。注意如果 base model 是之前做过 chat 指令微调的模型学习率要再打折到 5e-6 左右对已对齐模型的破坏能小一些。3.4 基座选型直接用 chat 模型还是一般预训练模型这是一个很关键的选型问题。我们一开始图省事直接拿了一个现成的 chat 模型做 Agentic SFT。结果发现两个问题一是 chat 模型本身已经具有强烈的“回答用户问题”的惯性很难学会“先调用工具再回答”二是它自带的安全对齐策略会在工具调用场景频繁触发拒绝。后来改成用“base 模型 轻度通用 SFT”作为起点训练更顺滑。具体是拿 base 模型先跑少量高质量的通用指令数据大概几千条让它具备基本的对话能力和格式遵循能力然后在这个基础上做 Agentic SFT 轨迹训练。这个中间步骤至关重要直接从 base 模型跳到轨迹训练模型连基本的 instruction following 都做不到轨迹训练根本上不了手。如果有条件的话推荐选基座的时候看一眼模型在长文本 retrieval 类任务上的表现。agent 场景对“从长 observation 中提取关键信息”的要求很高有些基座在这块很弱靠 SFT 硬拉效果很差。4. 评估与观测别只盯着成功率4.1 离线评估集的设计思路Agent 模型的离线评估很难做。最终成功率当然要看但它容易掩盖问题——很多失败发生在中间步骤最后一步失败导致成功率是 0你看不出模型到底哪一步崩了。所以我们的离线评估集设计成“逐步标注”的模式。每一条测试任务标注了关键决策点比如“是否选择了正确的搜索关键词”、“工具返回后是否提取了正确的信息”、“在第一次搜索无结果时是否执行了合理的改写重试”。这样模型跑完以后既统计最终成功率也统计每个决策点的通过率。这个做法的价值非常直接。有一版模型最终成功率没太大变化但“重试决策点”通过率从 30% 涨到了 65%——虽然任务没有全部成功但模型已经学会了遇到空结果时换一种说法继续尝试这就是 Agentic SFT 带来的实质进步。也让我意识到单看最终成功率会严重低估中间能力提升。4.2 过拟合信号怎么识别Agentic SFT 的过拟合和普通过拟合不太一样普通模型的过拟合信号是验证集 loss 开始上升而 agent 模型过拟合的表现更隐蔽loss 还在下降但评估集里的格式错误率开始上升模型越来越爱生成训练集里出现过的固定短语对新鲜指令的泛化变差。我用的一个简易检测方法是在训练过程中每隔一定步数加载 checkpoint跑一个固定的 20 条测试集看每条轨迹的“平均动作多样性”。如果发现模型的工具参数选择分布变得特别集中比如总是查同一个关键词同义词哪怕最终成功率看起来没问题也要警惕过拟合。另外可以做一个扰动测试——把测试问题里的关键词替换成同义词如果成功率掉得特别厉害说明模型是背了关键词映射而不是真理解了工具逻辑。4.3 和 RL 阶段的衔接评估Agentic SFT 做出来的模型最终还是要交给 RLVR 继续提效果。因此评估时一定要关注“这个模型是否适合做 RL 的初始化”这个指标单独看。有两个观测角度一是 RL 阶段早期几百步的成功率提升速度如果 SFT 模型质量高RL 起步提升会很快二是探索死区SFT 模型如果在某个动作上很固执比如总是不愿意调用某个工具RL 阶段很难把它纠正过来。所以我们在 SFT 评估的 checklist 里加了一条是否所有工具都被覆盖调用过如果某个工具在测试时候从未被触发就要检查是不是训练数据里这个工具的比例太低。5. 常见问题与排查技巧实录5.1 模型学会了格式但没有学会推理这个现象最典型。训练后模型很会输出 [SEARCH] ... 之类的格式但传入的 observation 内容明明是空列表它还会继续假装有结果并接着往下推。原因是训练数据里大量 observation mask 导致模型根本没学到“observation 是外部强约束”这一事实。排查手段把测试轨迹的 observation 改成一个明显矛盾的内容比如搜索结果为空但商品标题写着有货看模型是否坚持原来的回答。如果它完全不受影响说明观测信息没有进入决策链。我们在数据层面做了两个修正一是保留少量“早期无结果后重试成功”的轨迹让模型看到 observation 为空时正确的动作是改写搜索词二是训练时偶尔把 observation 区域的 token 故意粘到模型的下文里计算一小部分 loss强制它根据观测信息做下一个动作预测。5.2 长上下文的灾难性遗忘Agentic SFT 训练大量几千 token 的轨迹会导致模型在短文本任务上的表现显著下降。不是那种“回复变空”的大崩而是更细碎的——比如总结、分类这类任务变得拖泥带水总是试图把任务拆成多步。这个问题的根源在于训练序列长度分布和真实使用场景的分布不一致。解决思路是做一个“序列长度混合采样”每个 batch 里同时包含短任务128-512 token、中等任务512-2048和长轨迹任务比例可以按 2:3:5 来。只训练长轨迹会让模型适应了超长输入在短输入上注意力分配失衡。另一个补救手段是在 SFT 后做一个短指令的“回声训练”拿几千条纯短指令快速回放一遍恢复短文本能力。这个成本不高但对线上体验帮助很大。5.3 中间步数爆炸模型收不住尾有一版模型训练完后在测试时每一步都正确但永远不肯给出最终答案无限循环地调用工具、查看结果、再调用工具。原因是我们混合数据里“长轨迹”的占比过高模型形成了“只有不停调用工具才算负责”的行为惯性。解决办法分数据层面和算法层面。数据上我们强制要求所有训练轨迹都必须收敛到一个显式的最终回答并且在数据里加入一些“单步就能得出结论”的负样本告诉模型不是所有问题都需要穷举搜索。算法上引入一个“最大步数”的硬性截断辅助 loss——训练时如果模型在若干轮后还没收敛用一个独立的 token 强制它给出决定。这种 token 可以插在指令里比如“你已经搜索了 2 轮现在请基于已有信息给出推荐”让模型把这种约束也学成一种条件行为。5.4 多 Agent 协同场景的 SFT 数据怎么搞上面聊的基本是一个模型独立决策的场景。如果你训练的是多 Agent 协同系统比如一个 planner、一个 executor、一个 validator 配合数据构建复杂一倍。我们尝试过各自独立做 SFT效果很差——planner 生成的计划到了 executor 那里永远是空返回因为两个模型是分开训练的语义空间不匹配。经验做法是用同一个基础模型初始化所有角色模型然后拿“多角色完整轨迹”预先做一轮联合 SFT让各角色的输入输出格式对齐。之后再针对每个角色用各自职责的轨迹数据做增量微调。这个过程类似先“统一语言”再“专业分工”配合 loss mask 把非本角色承担的序列段舍掉。目前我们这套流程跑出来的多 Agent 成功率比完全独立角色微调高十几个百分点。5.5 训练数据覆盖不足冷启动工具调用有些工具在训练轨迹里出现次数极少模型大概率不会主动调用它们。我们发现工具调用频率分布符合严重的长尾现象——80% 的调用集中在 3 个高频工具上剩余 10 多个工具几乎没被触发过。对策是有针对性地合成一批“单工具强制任务”每一个任务只允许使用一个指定工具让模型把低频工具的调用方式背下来。然后再混合一些需要组合多个工具的任务逐步把调用能力串起来。这个过程要有耐心低频工具 SFT 之后要专门评估一次对应工具的调用率确认确实达到阈值再加高难度任务否则最终模型会把多个工具互相调用混乱。6. 持续记录一些还没想清楚的问题写到这里Agentic SFT 的很多细节还谈不上吃透。比如过程奖励到底应该精细到动作级还是保持在 trajectory 级我们尝试过给每一步动作打分再筛选数据但打分器本身的噪声变成了新的瓶颈。又比如“可验证任务”和“开放任务”在 SFT 数据配比上的最优比例目前还只能靠实验试。再比如真正决定模型能否稳定收敛的是增加的轨迹数据本身还是精心维护的观测掩码顺序这些都要通过隔离实验才能有结论。目前我们在持续做的一件事是建立一套从“轨迹数据生成到过拟合报警”的自动化流水线把这篇文章里提到的硬规则落到代码里。后续有新的进展会继续更新这个记录。最后给正在入坑的同学一个真诚的建议不要一上来就搭复杂框架先用 100 条高质量轨迹跑通一个最小闭环观察模型的 loss 曲线、格式稳定性和任务成功率这三件事再决定要不要投入资源扩大数据规模。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑