Hugging Face Daily Papers 近期收录的 DART-SD 全名是 Diamond-topology Aware Retrieval Tuning with Self-Distillation for Multi-Turn Tool-Calling Agents。论文讨论一个越来越实际的问题:当 agent 不再只调用一次函数,而是需要多轮检索、调用、观察、修正和汇总时,训练数据从哪里来?参考来源:Hugging Face Papers、arXiv 搜索、Model Context Protocol。
过去两年,tool calling 的工程栈成熟很快。OpenAI、Anthropic、Google、Mistral、Qwen、DeepSeek 等模型都支持结构化工具调用,框架层有 LangGraph、LlamaIndex、CrewAI、Mastra、MCP server 和各类 agent harness。但模型训练侧仍有一个硬问题:单轮函数调用样本相对好造,多轮工具轨迹很难造。
原因很简单。一次函数调用只需要判断“应该调用哪个工具,参数是什么”。多轮 agent 轨迹要同时回答更多问题:第一步应该检索还是直接问用户?工具返回空结果后要不要换查询?两个工具结果冲突时信谁?什么时候停止?最后答案如何引用证据?这些能力不是靠一堆孤立 JSON schema 就能学会的。
DART-SD 的价值在于,它把多轮工具调用训练看成数据拓扑问题,而不是 prompt 问题。
为什么多轮工具调用难
我们先看一个企业知识库 agent 的例子。用户问:“过去 30 天高优先级工单里,哪些客户同时临近续约?”一个弱 agent 可能只搜工单,然后直接回答。一个强 agent 会拆成几步:
1. 查询过去 30 天高优先级工单
2. 按客户聚合并筛掉测试租户
3. 查询这些客户的续约日期和 ARR
4. 交叉过滤未来 90 天续约客户
5. 输出客户、风险原因、证据和下一步动作
这里每一步都依赖上一步观察。训练样本如果只记录最终 SQL 或最终答案,模型学不到中间决策。训练样本如果记录所有细节,又可能太长、太嘈杂、难以泛化。
多轮工具调用的样本质量有三个标准:可执行,能恢复错误,有明确停止条件。很多自动生成数据只满足第一条,看起来像轨迹,但没有真实观察和失败分支。
diamond-topology 的直觉
论文标题里的 diamond-topology 可以用工程语言理解:不要只从“问题到答案”建一条线,而是把任务、工具、轨迹和观察连成菱形结构。
task
-> similar tasks
-> relevant tools
-> candidate traces
-> execution observations
-> distilled trace
为什么这比普通检索更好?因为 agent 学工具调用时,真正有用的相似性不只来自文本相似。两个问题表述不同,但都需要先查用户、再查订单、再查工单,它们在工具路径上相似。两个工具名字相似,但权限和返回结构不同,不能混用。一个轨迹看起来合理,但执行观察显示第二步返回空结果,也不能直接当好样本。
所以检索要同时看任务语义、工具 schema、调用历史和执行结果。这就是 DART-SD 对开发者最有启发的地方:训练 agent 不是堆更多 prompt,而是组织更好的经验索引。
自蒸馏为什么适合 agent
自蒸馏在这里的作用,是把复杂轨迹压缩成更干净的训练样本。一个 teacher 模型或强执行器先生成多条候选轨迹,系统执行并观察结果,然后筛选成功轨迹,再把冗余推理、无效尝试和重复调用压缩掉。
一个实用流水线可以这样设计:
type TraceStep = {
thoughtSummary: string;
tool?: string;
args?: Record<string, unknown>;
observation?: unknown;
};
type AgentTrace = {
task: string;
tools: string[];
steps: TraceStep[];
finalAnswer: string;
success: boolean;
};
function keepTrace(trace: AgentTrace) {
if (!trace.success) return false;
if (trace.steps.length === 0) return false;
if (trace.steps.length > 12) return false;
return trace.steps.some((step) => step.tool);
}
真实系统还要加入结果验证。比如查询类任务可以比对数据库结果,代码类任务可以跑测试,客服类任务可以检查是否引用了允许字段。没有执行验证,自蒸馏就容易把模型幻觉变成训练资产。
从训练数据到轨迹库
不是每个团队都要微调模型。DART-SD 的思路同样适合构建“轨迹 RAG”。也就是说,检索的不只是文档,而是过去成功完成任务的工具调用路径。
type TraceCard = {
id: string;
taskEmbeddingText: string;
toolPath: string[];
preconditions: string[];
failureModes: string[];
compactSteps: string[];
};
当新任务进来时,系统先检索相似 TraceCard,把工具路径和失败模式作为上下文给 agent。这样做比把整段历史对话塞进上下文更稳,因为它保留的是可复用结构,而不是聊天噪声。
例如“查客户续约风险”和“查客户流失风险”文本不同,但工具路径可能相近。轨迹库能教模型:先查客户集合,再查事件,再查财务字段,最后汇总证据。
关键风险:污染和过拟合
自动蒸馏最大风险是污染。模型生成错误轨迹,执行器没有发现,下一轮训练又把错误轨迹强化。长期看,agent 会越来越自信地重复错误。
解决办法不是完全不用自蒸馏,而是把蒸馏当数据生产线管理。至少要做四件事。
第一,所有轨迹必须可重放。保存工具版本、输入、输出摘要和验证结果。
第二,失败轨迹不要全删。保留部分失败样本用于教模型何时停止、何时改查、何时向用户澄清。
第三,轨迹要去重。相同工具路径的大量样本会让模型过度偏好某条路线,遇到新任务不愿探索。
第四,敏感数据要脱敏。工具轨迹里常含客户名、邮箱、订单号和内部字段,不能直接进入训练集。
对 MCP 生态的意义
MCP 让工具暴露更标准,但标准化工具并不等于模型会用工具。未来 agent 的差距,很可能来自两层:工具 schema 是否清楚,历史轨迹是否高质量。
DART-SD 提醒我们,MCP server 最好天然产出训练数据。每次工具调用都记录任务、参数、观察、错误、重试和最终结果。这样运行一段时间后,团队会拥有自己的 agent 行为资产。相比通用公开数据,这类私有轨迹更贴近业务流程。
结论
DART-SD 值得关注,因为它把多轮工具调用的核心矛盾说清楚了:agent 缺的不是更多函数名,而是高质量、可执行、可泛化的工具轨迹。
普通团队可以先做低配版:为 agent harness 加 trace 记录,把成功任务压缩成 TraceCard,上线前用检索轨迹做 few-shot,上线后再筛选新轨迹。等数据规模足够,再考虑微调。训练 agent 的第一步,不是买更大的模型,而是把自己的工具经验组织起来。