2026/10/17 11:36:08

Agentic SFT实战踩坑:从轨迹数据到智能体策略学习的进阶指南

Agentic SFT实战踩坑:从轨迹数据到智能体策略学习的进阶指南 我做过很长时间的普通SFT监督微调训练基本套路很熟收集问答数据、清洗、格式化、跑几个epoch、看loss、上线下线。可真把训练目标从“让模型会答题”换成“让模型能当智能体Agent去调用工具、看中间结果、决定下一步”之后我发现自己过去的经验一下失效了大半。这篇文章不是什么标准教程而是把我持续记录“Agentic SFT”的思考、踩坑和一些隐约成立的经验留下来。标题里“浅薄认知”几个字不是客气话是这个方向更新太快、我大多数结论都只能算是阶段性的。写出来是给同样在搭智能体训练流程的人做参照。1. Agentic SFT和传统SFT看似同源本质却是两个物种1.1 我最开始的失误把轨迹数据当成多轮对话喂进去第一次做Agent训练我犯了个很典型的错。当时拿了一批工具调用轨迹把“用户提问、模型调工具、工具返回结果、模型再调工具、最后给答复”整条链路当成一种变长的多轮对话直接套用了之前做对话SFT的模板和训练流。结果验证集上loss很不错但真实跑Agent任务的时候模型非常热衷调用第一个工具之后就开始胡来有的直接无视工具返回值开始编总结有的反复调用同一个工具不推进任务只有极少数样本能完整走完一条正确链路。这个问题追踪到最后我意识到根源在于“数据形态看起来一样但学习的对象变了”。对话SFT学的核心是语言风格和内容质量模型要预测的是“一段合理的人类回复”。而Agentic SFT里大量预测位置是“一个动作”——调用哪个工具、带什么参数、要不要停止调用开始总结。动作的合理与否不仅取决于上下文和用户意图还取决于外部工具实际返回了什么。模型必须学会读取返回值里的关键信息来修正下一步。如果用一句话概括我当时的教训普通SFT教的是“怎么把话说好”Agentic SFT教的是“怎么把事情做对”。话好与事对有时候一致有时候完全不一致。1.2 同样的交叉熵损失为什么训练目标已经变了表面看损失函数还是那一个交叉熵但拆开看内部标签的语义一切都不一样了。传统SFT的标签是“人类认为更合适的文本”。智能体轨迹里的标签在动作位置上是“当时环境下最合理的动作选择”。这个“环境”很重要它意味着如果工具返回了异常内容下一步的最佳动作可能是“换一个工具”或者“向用户澄清”而不是沿着正常流程继续走如果工具调用的参数填错了最佳动作可能是“修正参数重试一次”如果已经能总结答案最佳动作可能是“停止调用”哪怕上下文里还能继续调。这一层如果没想清楚很容易直接用“成功轨迹”堆训练数据并且把数据里每一步都当成唯一的黄金答案。模型学到的东西会趋向“复现成功路径的惯性”却学不会“根据环境变化切换策略”。1.3 我给自己重新下的定义在持续记录里我暂时把Agentic SFT的定位写成这样在固定动作空间和观察反馈的条件下从轨迹数据中学习“状态到动作”的行为策略。它保留了SFT的高效和稳定但它本质是在模仿策略而不是模仿文风。这个认知帮我避掉了后面很多弯路。比如后文会提到既然是在学策略数据里就必须覆盖足够多的“状态”特别是那些失败和异常状态而不是覆盖足够多的“语气”。2. 轨迹数据构造我踩过且目前还在踩的坑2.1 数据来源配比人工、环境采样、大模型蒸馏各有各的用Agent训练轨迹数据最常见的三个来源我分别试过各有明显的脾气。数据来源主要优点主要缺点我的建议占比人工标注完整轨迹质量最高、策略意图清晰贵、慢、规模上不去起步阶段必须有一批三百到一千条就足够发现问题环境自动采样后筛选量大、覆盖真实环境状态噪声高、大量轨迹是失败的中期的扩充主力用更强模型蒸馏轨迹速度快、能覆盖边缘场景可能带入模型自身偏见适合冷启动和规则之外的兜底我反复翻过车的地方是一开始光顾着大模型蒸馏轨迹因为量大又便宜。后面两个问题冒出来一是蒸馏来的轨迹里“应急处理”特别少。因为强模型本身能力强很多在普通模型看来会导致失败的中间状态它天然避开了。投给模型的数据全是“顺风顺水”型模型根本没看过错误返回值长什么样真正上线时一旦工具开始报错动作链立刻断掉。二是蒸馏轨迹里存在“假动作”比如输入一个完全重复的工具参数或者在根本无需调工具时调用工具刷存在感。这些噪声在蒸馏阶段不明显但作为标签时会被模型当成一种风格去学习形成很难改掉的坏习惯。2.2 失败轨迹一开始我全扔了后来发现亏大了之前做文本SFT接收过一条约定成俗的说法尽量别拿坏样本训练不然模型会学坏。这条在Agent轨迹上只对一半。我后来把一组失败轨迹拆开做对比试验。同一批工具调用任务基础模型主要用成功轨迹训练在模拟环境的完成率仅35%。另一组我在成功轨迹里掺了15%左右的失败轨迹但做了处理在失败发生的位置之后修正或拼接出“如何从失败中恢复”的动作。效果提升非常大对异常返回值的后续处理能力肉眼可见地变好了。现在的做法是保留轨迹里导致失败的那个步骤和返回结果把后面恢复过程的动作留下组成半失败半恢复的轨迹。用个类比你不该让消防员只看“顺利救火”的视频也应该让他看几百次“进屋发现门是锁的、破拆工具没带、对讲机信号断了”该怎么办。动作空间能不能用好很大程度上取决于模型见过多少种异常状态。2.3 格式与动作耦合工具Schema不是装饰品又踩了一个不起眼但很折腾的坑数据里的工具Schema和系统Prompt必须当“动作约束”来看而不是当说明文档。Agent动作空间某种意义上就是能调用工具的集合和规则训练时如果工具Schema描述不够准确模型会把参数名、参数类型、值域要求一起学错。比如有个工具参数叫“target_date”格式是YYYY-MM-DD。结果我有一部分蒸馏数据里填的是“明天”这类自然语言。模型立刻学会在参数位置输出“明天”然后在运行时被工具解析直接拒绝更闹心的是这种错误很难靠推理修正因为训练分布里已经存在了。后来我把所有工具字段全量做了强制校验标注工具自动规范化非法值。凡是参数值不符合Schema的数据要么改写、要么丢弃绝不能让格式错误进入标签。3. 训练过程中我认为Agentic SFT必须单独处理的细节3.1 掩码处理工具观察结果到底该不该算损失Loss掩码是Agentic SFT里最容易被忽略、影响却很大的设计点。普通对话SFT里标签全算Loss没有太大问题因为所有内容都是模型应该生成的文本。但Agent轨迹不一样整体结构通常是这样用户提问 助手调用工具这条要学 函数返回结果这条不能学 助手再调用工具这条要学 函数返回结果这条不能学 助手生成最终答案这条要学工具返回结果凭什么不能学因为它不是模型生成的文本而是外部环境写入的模型在训练位点上根本不可能预测出来。如果不mask掉模型会去背一些工具返回的随机报错信息、时间戳、编号之类既浪费训练容量也会干扰关键动作Token的梯度占比。我见过一次很典型的案例LossMask没做细工具返回内容很长导致整条样本里绝大部分Token都被外部内容占据。训练下来模型确实记住了某个工具返回的固定字段格式但对“何时调用工具”这件事学得稀烂因为动作Token数量少、梯度被稀释了。3.2 截断策略滚动截断很容易切断“观察-动作”对应Agent轨迹天然是长文本上下文窗口有限的条件下必须做截断。一开始用了一个通用做法从开头开始超长就丢弃前面的历史只保留最后一段。结果训练完发现模型在中间的决策点经常“忘记”用户最初的指令是什么尤其是工具调用比较多的时候。后来把截断逻辑改成了以回合为单位的滚动截断并且强行保证只要进入样本最后一条一定是一个完整的“观察-动作”对前面可以丢但这个不能断。这里有个细节值得单独记录截断时保留的窗口里应该有最近一次工具返回和随后的动作因为这是模型最容易学习的“基于当前状态行动”的最小语义单元。如果窗口把工具返回截掉、只留动作模型看到的动作就是“无源之水”学出来的策略会变成瞎猜。3.3 “假收敛”Loss低到一定程度后Agent能力反而下降我还撞上过一种非常迷惑的现象到现在想起来还觉得值得继续深挖。跑一个中期训练任务时Loss掉到很低继续训练后Loss继续缓慢下降但Agent完成率反而开始跌。一开始以为是过拟合提前停掉以后发现完成率也没回来多少。分析下来原因是这样的当Loss很低时模型对训练轨迹里的高频路径已经形成极强的先验。在评估集和训练集分布一致的场景下表现很好一旦评估环境出现训练集里少见的返回状态模型更倾向于按训练高频路径惯性行动而不是根据当前观察去调整。这和传统SFT的“过拟合”表现不同更像是策略在动作空间上变得更尖、更窄。后来我给自己定下一个规矩只看Loss还不够每个训练阶段的Agent轨迹里必须抽一批人工观察——看模型是不是会在不同环境下做出不同动作。如果动作模式越来越少、越来越僵硬就该考虑做数据扩增或者提前停了。4. 只靠 Agentic SFT模型会卡在哪几道门槛既然标题是“浅薄认知”我也想把SFT这条路的边界如实写下来。以下四道门槛是我目前观察下来纯SFT自身难以跨过的。4.1 面对从未见过的状态模型倾向于“照着最像的路径走”SFT的本质是模仿模仿决定了对已覆盖状态会有不错表现但对覆盖之外的状态模型会给一个“看起来最顺”的动作而不是一个真正有规划的下一步。比如工具突然返回一个超出预期的权限错误做过类似处理的模型可能会尝试换参数重试但如果错误原因完全没进训练分布它就站在原地打转。4.2 连续失败时很少能主动改变整套策略智能体失败一次不可怕可怕的是连续失败后不换策略。SFT模型容易在轨迹层面学习到一种“执着”当前动作失败它会微调参数再试试两三次之后依然不调用另一个完全不同的工具也不转向用户求助。这很像在没有监督信号的情况下模型缺少对策略的整体评估能力。它知道每个局部步骤的“平均正确做法”却缺少“这个方案已经僵死了需要换方案”的高层判断。4.3 “快速应答”和“多调几步”之间的平衡不容易学清楚智能体动作空间里有一个重要的隐形参数什么时候该停止调用工具输出答案。很多轨迹里正确答案已经出现模型依然多调好几个无关工具也有些情况是信息不足模型却提前开始总结。这两个极端在纯SFT数据里很难靠标签数量去压制本质是因为SFT阶段没有交互式价值反馈模型分不清“多探索”和“少动作”哪个更符合当前场景。4.4 对动作空间的利用存在局部性还有一个现象是训练数据里某个工具出现得频繁模型就很会用某个工具出现得少即使其它地方触发了调用条件模型也想不起来用。模型学到的“工具偏好”很容易被数据频次带偏而真实的智能体任务往往要求按需均匀调度工具。我目前唯一有效的缓解方式是长期维护一套工具调用频次统计定期给低频工具补充合成轨迹把分布拉平整一些。5. 我对“浅薄认知”的自洽理解以及持续记录的方法5.1 SFT在Agent训练链路里更适合当“地基校准器”被这几次实验教育之后我对Agentic SFT的定位变成它主要解决的是“让模型会用动作空间、能读懂观察结果、能按基本协议执行多步任务”。更高级的试错、规划、策略调整更适合交给基于环境反馈的强化阶段去解决。换句话说先靠SFT把动作格式和基本策略学到足够好再进入强化阶段效率更高如果SFT阶段动作协议都没成型强化阶段会花大量时间在“补格式”而不是“优化决策”。SFT阶段应该贪的是对动作准确率的要求至于在多变环境中的长期规划我不再寄希望于单靠堆数据解决。5.2 我维护训练笔记的方式笔记最终会汇成数据集需求“持续记录”对我而言不是写日记。我的实际做法是失败案例、反常行为、模型能力突变的观察全部记进同一个待办池然后每周把笔记归类一次转化成明确的数据需求或训练改动项。举个例子某次我发现模型非常喜欢在单步就能完成的任务里调用三个工具。记录下来之后我去统计训练数据发现确实有大量多步调用样本主动单步完成的样本偏少。于是后续数据收集就开始大幅补充“一步到位”的样本把这个偏差纠正过来。小技巧是记录时不要只写现象要多写一句话这说明训练数据主要缺了哪一块。这样笔记才不会停留在描述层。说白了笔记就是数据集的“缺口清单”。5.3 持续记录本身的三条小经验坚持记这类训练笔记一阵子之后我留了三条经验给自己第一记录要快失败现场尤其不能隔夜再补。当场记下模型输出里最畸形的动作比事后看训练日志有效得多。第二定期用记录反向审计训练集。如果某个现象反复出现通常意味着训练分布里有系统性的偏差只是之前没察觉。第三阶段性地推翻自己也不敢偷懒。标题里的“浅薄认知”很重要我定期回看旧记录会发现自己当时的结论很粗糙甚至是错的这一般都是因为对Agent训练的理解又往前推了一小步。写在记录中间的一个补充如果这时有人问我Agentic SFT到底怎么看我会把这个思路留着他更像一面地基把模型的“动作语法”校准好但真正的策略智能需要环境交互反馈来完成。数据面注定要长期维护只是不要一次性把所有希望都压在SFT这一步上。“持续记录”最在意的不是某个时点认知有多完善而是你有没有在每次实验后攒下新的观测。下一次再看这份记录我大概率能对着某个段落笑出声——这和模型训练一样只能先出一个版本再靠迭代把它推好。