Agent 每走一步,都让大模型回答一次“该继续,还是停止”,可能有些浪费。但把这个判断交给小模型后,另一个问题很快出现:它每次都返回合法 JSON,也从不输出规定之外的标签,却经常在错误的时机叫停。
输出格式正确,只说明答案装进了正确的容器,不说明判断正确。做分类蒸馏时,这两件事必须分开验收。
10 月 14 日的 AIHOT 精选收录了 LangChain 的 ScaleDown 集成文章。官方正文介绍了专门承担摘要、压缩、提取和分类的模型,也展示了用分类结果识别 Agent 循环、偏离任务的做法。[1] 这提供了一个有用的工程方向:不一定蒸馏整个助手,可以先蒸馏一个高频、边界清楚的决策。
下面以“运行状态分类器”为例,讲清标签定义、教师监督、训练目标和上线验收。这是本文提出的蒸馏设计,不是对 ScaleDown 训练方法的披露;
先把“判断什么”写清,再生成训练数据
假设分类器输入最近几轮对话及工具结果,输出四个业务标签:
| 标签 | 含义 |
|---|---|
| progressing | 有证据表明任务出现新进展 |
| looping | 重复相同操作,且没有增加有效信息 |
| drifting | 正在处理用户没有要求的目标 |
| insufficient_evidence | 当前观察不足以作判断 |
“重复调用两次”不等于 looping。第一次网络超时,第二次请求成功,这是有意义的重试;第一次查不到记录,第二次换了经过核实的编号,也可能是合理恢复。
同样,“工具执行成功”不等于 progressing。如果用户要修改文案,Agent 却成功查询了天气,工具状态码再漂亮也不能证明任务在推进。
因此,标签规范至少应写清:判断所依据的用户目标、允许的恢复行为、观察窗口,以及证据不足时的处理。窗口里没有最初任务说明,却要求判断是否偏离目标,会让教师和学生一起猜。
这里的 insufficient_evidence 是内容标签,表示输入证据不足;后面谈到的“低置信度交给上游”是系统策略。两者可能重合,但不是同一个概念。
图 1:输出通过 JSON 和标签检查后,仍需检验是否符合任务事实。格式合法与语义正确分开统计。作者方法示意,非实测结果。
教师给标签、给概率、给理由,是三种不同的数据
用教师生成数据时,最常见的是硬标签:一个输入,对应一个类别。它适合普通监督微调,也容易人工抽查,但会丢掉类别之间的不确定性。
如果能获得可信的类别分布,可以做软标签蒸馏。例如,教师对某次重试给出如下分布,顺序为四个业务标签:
progressing: 0.55 looping: 0.35 drifting: 0.05 insufficient_evidence: 0.05这组数字是教学示例。它表达“更像推进,但与循环容易混淆”,与只留下 progressing 的信息不同。
需要特别注意:让聊天模型在 JSON 里写"confidence": 0.95,得到的是模型生成的一个数字,不是自动获得了经过校准的类别概率。即使接口提供 token 的 logprobs,也不能直接把它当四个业务类别的分布:一个标签可能由多个 token 组成,输出还受到提示词、格式约束和序列长度影响。
可选做法有三种,按实际条件决定:
- 有分类头及完整类别 logits:直接核对类别顺序和概率定义。
- 只有受控标签序列的评分能力:明确如何计算各个候选序列的分数、归一化及长度影响,再验证它是否适合你的任务。
- 只能取得文本:先采用硬标签蒸馏,把教师理由用于抽查和纠错;不要为了套公式补造概率。
教师理由可以帮助标注员发现错误,例如“因为连续两次调用,所以判循环”暴露了粗糙规则。但理由听起来合理,不等于类别就是对的。必须回看实际目标和工具返回。
软标签损失怎么写,方向别弄反
对固定的 K 个类别,设教师 logits 为 z_T,学生 logits 为 z_S,温度为 τ:
p T ( τ ) = softmax ( z T / τ ) , p S ( τ ) = softmax ( z S / τ ) p_T^{(\tau)}=\operatorname{softmax}(z_T/\tau),\quad p_S^{(\tau)}=\operatorname{softmax}(z_S/\tau)pT(τ)=softmax(zT/τ),pS(τ)=softmax(zS/τ)
一个常见的分类蒸馏目标是:
L = α τ 2 D K L ( p T ( τ ) ∥ p S ( τ ) ) + ( 1 − α ) CE ( y , p S ( 1 ) ) L=\alpha\tau^2D_{KL}(p_T^{(\tau)}\|p_S^{(\tau)}) +(1-\alpha)\operatorname{CE}(y,p_S^{(1)})L=ατ2DKL(pT(τ)∥pS(τ))+(1−α)CE(y,pS(1))
这里 y 是经过核验的硬标签,α 控制两个目标的权重,取值在 0 到 1 之间。KL 的方向是教师到学生;这与另一些同策略蒸馏实现使用的反向 KL 不同,不要因为都叫“蒸馏”就交换方向。
前提要说清:这个式子假定教师和学生都输出同一组 K 个类别的分数,且类别顺序一致。如果学生是生成式模型、只能吐出标签文本,就没有现成的 K 维 logits,要先把它改造成“对候选序列打分”的形式;这与直接读分类头不是同一个训练任务,损失也不能照搬。
这类软目标与硬目标组合可追溯到 Hinton 等人的经典蒸馏论文。[2] 固定教师时,最小化该 KL 与最小化软标签交叉熵,对学生有相同的优化方向,因为两者只差一个与学生无关的教师熵项。τ² 用于补偿温度对软目标梯度尺度的影响——软目标梯度幅度按 1/τ² 缩放,乘上 τ² 才能在改温度时保持硬、软两项的相对贡献大致不变。温度和权重仍需验证,不能机械复制别的任务。
提高温度能让已有分布更平缓,但不能从一个硬标签凭空恢复教师的类别关系。如果硬标签本身也是教师生成的,它仍可能含错;把两种损失混在一起不会自动消除教师偏差。
下面是针对[batch, classes]分类 logits 的 PyTorch 损失片段,不是完整训练项目:
importtorchimporttorch.nn.functionalasFdefkd_loss(student_logits,teacher_logits,verified_labels,tau=2.0,alpha=0.5):iftau<=0ornot0<=alpha<=1:raiseValueError("check tau and alpha")# 教师与学生必须使用同一类别顺序。log_ps=F.log_softmax(student_logits/tau,dim=-1)withtorch.no_grad():pt=F.softmax(teacher_logits/tau,dim=-1)soft_loss=F.kl_div(log_ps,pt,reduction="batchmean")*tau**2hard_loss=F.cross_entropy(student_logits,verified_labels)returnalpha*soft_loss+(1-alpha)*hard_lossPyTorch 这里第一个参数是学生的对数概率,第二个参数是教师概率,计算的仍是 KL(教师‖学生)。reduction必须用batchmean:按官方文档,mean是把总和除以元素个数,并不等于 KL 的数学定义。代码没有包含编码器、数据加载、分布式训练和服务接口。不要直接把生成式模型的整个词表 logits 当作这段代码需要的四类 logits。
图 2:固定标签顺序后,教师软分布与核验硬标签分别监督学生;教师理由仅用于审查,不冒充概率。作者根据经典蒸馏目标绘制。
约束解码解决的是“能输出什么”
分类头天然输出固定数量的类别分数;生成式学生则可以通过约束解码,把候选答案限制为指定标签或结构。
两种实现都可能防止出现拼错的标签,但都不能保证业务判断正确。一个永远输出 progressing 的系统,格式通过率可以达到 100%,同时错过所有真正的循环。
所以验收至少分三层:
- 格式层:能否解析,标签是否属于允许集合,字段是否完整。
- 语义层:各类别的 precision、recall、混淆情况,尤其检查误停正常任务和漏掉循环。
- 系统层:这个判断触发停止或回退后,整项任务的成功率是否改善,有没有新引入的错误终止。
这三层不能用一个“准确率”笼统覆盖。例如数据里正常推进占大多数,总准确率很容易掩盖循环召回不足。
反过来的偏差同样要注意:当 looping 只占少数样本时,即使某一档 precision 看起来不错,触发停止的那批判断里仍可能大部分是误停。两个方向的错误代价通常不对称——把正常任务过早停掉,往往比让无效循环多跑一会儿更贵。所以阈值不该按 F1 之类的对称指标挑,而应按两类错误的实际业务代价选。
分类器只是决策信号,停止 Agent 还应有明确的系统策略。
低置信度回退,要一起报告覆盖率
假设在一个独立测试集上,共有 1000 个判断样本。按开发集上选定的阈值,学生接管其中 700 个,答对 665 个,其余 300 个交给教师或人工。
此时:
- 学生接管覆盖率:700/1000 = 70%。
- 接管部分准确率:665/700 = 95%。
- 学生直接解决且正确的样本,占全部样本的 66.5%。
不能把第二个数写成“整个系统准确率 95%”。回退的 300 个怎样处理、是否正确、花了多少时间,仍要计入完整系统结果。这些均为演示数字,不是本文训练成绩。
阈值也不能先定一个“0.8 看起来很可靠”就上线。先看可靠性:落在高置信度区间的预测,实际正确比例是否相近;再依据误停、漏检、回退的业务代价选阈值。类别分布、输入长度和工具版本发生变化后,原来的阈值可能不再适合。
图 3:1000 个演示样本中,700 个由学生接管、665 个答对,300 个回退;95%只描述接管子集,完整系统结果还需核验回退部分。
第一轮实验,先守住数据边界
从自己有权使用的 Agent 轨迹中抽样,按完整会话或任务分组拆出训练集、开发集和测试集,再生成教师标签。不能把同一会话的相邻窗口分别放进训练和测试,否则模型可能只是认出了近重复内容。
训练集覆盖正常推进、合理重试、无效循环、任务偏离与证据不足。对重要少数类补样,但测试集还应保留自然分布视角;专门构造的困难集合另报,不能混成一个好看的总数。
比较三个版本通常足够启动:简单规则基线、仅硬标签的学生、软标签加核验标签的学生。后两者保持相同架构和训练预算口径;阈值在开发集选好后冻结,再跑测试集。没有概率接口就只做前两者,也比伪造软标签可靠。
本文由 147AI 整理。147AI 是面向开发者与企业技术团队的 AI 模型 API 接入平台。通过 API 采集教师输出时,应记录模型版本、标签规范和调用配置,并核对数据使用条件;普通文本响应不代表提供了分类 logits 或训练服务。
如果你准备蒸馏第一个决策模块,先找出最昂贵的一类误判:是把正常任务过早停止,还是让无效循环一直跑下去?这会直接影响标签定义、采样比例和回退策略,比先选一个更小的模型更有用。
参考资料
- LangChain:Building Long-Running Agents with ScaleDown and Deep Agents。2026-10-14读取官方全文;AIHOT条目日期为10月13日,当前抓取的官方正文未显示独立发布日期。只引用功能与工程方向,不采用厂商速度倍数作蒸馏证据。
- Hinton、Vinyals、Dean:Distilling the Knowledge in a Neural Network,2015。软目标、温度、τ² 梯度补偿与硬标签组合的方法依据,非今日新研究。
- PyTorch:torch.nn.functional.kl_div,2026-10-14核对参数与batchmean定义。本文代码片段未在PyTorch运行环境中执行,不代表已完成训练验证。