用序列蒸馏降低 Agent 工具循环成本
教程在 SageMaker AI 上使用序列级知识蒸馏,将前沿教师模型的 Agent 行为迁移到成本更低的小模型。目标是减少多步工具调用流程中每一步都使用昂贵模型的开销。
AI 深度解读
一个购物 Agent 完成一次推荐,背后可能要反复搜索、读取结果、核对约束,每一步都在消耗模型调用费用。AWS 这篇文章给出的办法是:让大模型先跑任务,再用成功轨迹训练小模型,把持续发生的推理成本,部分转成前期的数据和训练投入。
实验里,Qwen3.5-4B 经过蒸馏,在购物基准上的平均成功率达到 0.541,与教师模型接近。但这个结果依赖成功筛选、完整轨迹和特定评测环境,不能直接理解成「4B 可以普遍替代大模型」。
小模型要学的,是完成任务的过程
文章使用序列级知识蒸馏(SeqKD):教师生成文本,学生通过监督微调(SFT)学习这些文本。它不需要教师的权重、梯度或 logits,也就是模型对候选 token 的原始打分,因此可以使用只能通过 API 调用的教师。
普通问答可以只学最终答案,Agent 则需要学习轨迹:看到什么信息,选择哪个工具,工具返回后怎样继续,何时推荐和结束。最终推荐正确,并不能单独告诉学生下一步该做什么。
这里的教师是 Amazon Bedrock 上的 GLM-5.3,学生是 Qwen3.5-4B。教师打开推理,以 temperature 1.0 在约 270 万件商品中搜索,再由 ShoppingBench 的程序评分器保留成功记录。
ShoppingBench 有 750 道合成题,product、shop、voucher 三种意图各 250 道。作者固定划出 426 道训练题和 324 道评测题,评测题分别为 103、105、116 道。每道训练题采样两次,原文报告得到 850 条轨迹;但 426×2 应为 852,差额原因没有交代。
采样温度设为 1.0,是为了探索不同搜索路径,而非重复最可能的答案。随后用拒绝采样(rejection sampling)过滤失败记录。
学生学习的是教师成功完成任务的那部分行为,而不是教师所有尝试的平均表现。
这个设计适合「有输入、缺高质量答案,而且能自动判断成败」的任务。评分器不是附属工具,它决定哪些行为值得复制。
怎样把工具调用记录变成训练数据
训练期间不会真的搜索商品。所有工具结果都已经写进轨迹,学生只学习根据已有上下文生成下一步。
作者把一条轨迹拆成多个训练行:user 放任务与历史观察,assistant 放当前步骤的推理和工具调用。下面这行数据展示了第一次搜索如何成为学习目标:
{
"messages": [
{"role": "user", "content": "You are a shopping assistant. ...\n# Task\nFind a black waist bag under $20 from a shop rated 4.5 or higher.\n# Observations so far\n(none yet)"},
{"role": "assistant", "content": "<think>Start with a broad search and let the price filter work before I narrow by shop rating.</think>\n<tool_call>[{\"name\": \"find_product\", \"parameters\": {\"q\": \"black waist bag\", \"price\": \"0-20\"}}]</tool_call>"}
]
}
要看 assistant 那一行:训练损失只计算这部分,让模型学习「接下来怎么行动」,而非预测环境返回什么。后续步骤不断追加观察,直到 recommend_product 和 terminate。所有数据必须用学生模型自己的 chat template 渲染,保证训练与推理格式一致。
过滤后,轨迹展开为约 2,600 行训练数据、130 行验证数据。验证集按完整问题划分,约占 5%,不能随机拆行。同一道题的多个步骤和两次尝试高度相似,拆行会让验证集提前见到近似上下文。
逐步展开还有代价:历史反复出现,工具返回越长,token 越多。作者优先压缩搜索结果,只保留 id、price、rating 和待检查约束,并限制结果数量,必要时再限制轨迹步数。否则超过 dataset_max_len 的部分会被截断,关键条件也可能一起丢失。
托管训练省了运维,工具循环仍要自己接
环境要求包括 Python 3.12 或以上、SageMaker Python SDK v3、boto3,以及至少 ml.m5.4xlarge 的 notebook 实例。这里的 CPU 负责数据准备和本地评分,serverless 指训练计算由托管服务提供,不是整条流程没有资源成本。
JSONL 上传 S3 后,用 DataSet.create 注册数据,通过 ModelPackageGroup.create 创建模型版本组。SFTTrainer 选择模型标识 huggingface-vlm-qwen3-5-4b,使用 TrainingType.LORA;TrainingType.FULL 则对应全量微调,指标送入 MLflow 实验 seqkd-shopping-exp。
以下配置用于容纳多步轨迹,并在小数据集上训练三个 epoch:
sft_trainer.hyperparameters.dataset_max_len = 16384
sft_trainer.hyperparameters.max_epochs = 3
sft_trainer.hyperparameters.global_batch_size = 64
sft_trainer.hyperparameters.learning_rate = 0.0001
sft_trainer.hyperparameters.lora_rank = 64
sft_trainer.hyperparameters.lora_alpha = 256 # alpha / rank = 4
sft_trainer.hyperparameters.lr_warmup_steps_ratio = 0.1
sft_trainer.hyperparameters.train_val_split_ratio = 0.95
重点是 dataset_max_len = 16384:增加长度预算仍不能替代观察压缩。默认参数可通过 sft_trainer.hyperparameters.to_dict() 检查,先运行 train(dry_run=True) 验证配置,再用 train(wait=True) 启动,通过 TrainingJob.get 读取 output_model_package_arn。
部署时,LoRA 适配器挂在基础模型上,两者作为 inference component 共用一个实时端点和基础权重。示例采用包含 vLLM 的 DJL LMI 容器,固定 version="0.36.0",基础模型为 Qwen/Qwen3.5-4B。配置是 max_lora_rank=64、max_loras=4、max_model_len=131072;推理长度不能与训练的 16384 混为一谈。
实例依次尝试 ml.g5.2xlarge、ml.g6.2xlarge、ml.g6e.2xlarge。示例中的 kd_serve 负责部署基础组件、解析适配器地址并挂载学生,它是配套辅助代码。
应用还需要一个确定性的工具循环:调用模型、解析工具文本、执行工具、追加观察,再调用模型。模型学会输出工具调用,不等于它拥有执行能力。
成功率追平教师,证据覆盖到哪里
作者先做低成本预检:通过 Evaluator.create() 注册 Custom Scorer,再调用 evaluate(),比较学生与基础模型能否按正确顺序选中教师使用的工具。
这个检查宽松解析工具名,不要求参数格式完全匹配。因此它只能确认工具选择有所改善,不能证明价格、评分等参数正确,更不能代替任务评测。
完整评测让所有模型运行相同的 ShoppingBench 循环,以绝对成功率(ASR)衡量推荐是否满足全部约束,缺失轨迹算失败,再对三类意图取平均。
| 对照方式 | 平均 ASR |
|---|---|
| GLM-5.3,temperature 1.0 | 0.511 |
| GLM-5.3,temperature 0 | 0.540 |
| 学生保留推理与工具调用 | 0.541 |
| 学生只保留工具调用 | 0.415 |
蒸馏学生比基础模型平均提高约 24 个百分点;保留推理比只学工具调用高 12.6 个百分点,约为 13 个百分点。这项消融支持一个具体结论:在这套任务和训练设置下,推理文本对行为迁移有帮助。
但结果来自单次 LoRA 实验,作者也提示不同运行可能相差几个百分点。0.541 与 0.540 的差距,不足以证明学生超过教师。原文还提到一个中等规模商业模型作为参照,却没有在所给文本中提供名称和具体分数。
我的判断
这篇最有价值的地方,是把蒸馏拆成了可执行的数据工程:生成轨迹、判断成败、保留成功记录、按步骤编码,再做完整任务验证。相比直接拿教师输出全部微调,这条路线有明确的质量关口。
能否可靠判断任务成功,可能比选哪一个学生模型更早决定项目能否成立。
局限也很清楚。ShoppingBench 是合成购物任务,训练和评测共享工具与环境;成绩接近教师,不代表换成陌生工具、真实用户表达或变化中的商品库后仍然成立。
文章以降本为动机,却没有给出教师采样费用、训练费用、端点开销、延迟和每任务成本的对照。质量收益有实验数字,经济收益仍需业务测算。低请求量应用,直接调用教师 API 可能更省维护投入。
所给原文还在「Keeping general ability」开头截断,无法判断学生是否保住通用能力。它也没有比较蒸馏与提示词优化、规则校验、模型路由的效果,不能替这些方案排出胜负。
能拿来做什么
- 如果正在做购物或检索推荐 Agent,先把用户约束整理成可程序检查的条件,再积累成功轨迹;没有可靠评分器时,先解决数据验收。
- 在 Node 工具循环中记录每步输入、模型输出、工具参数和返回观察,并让训练与线上使用相同格式,方便后续复现与蒸馏。
- 工具返回包含大量商品文案时,先保留下一步真正需要的字段,同时按完整任务划分验证集,避免上下文膨胀和数据泄漏。
- 替换线上教师模型前,同时测完整任务成功率、调用轮数、延迟与总成本;工具名匹配只能作为预检,不能作为上线依据。