Qwen3x 工具调用:XML 默认,双格式解析才是解法
Qwen3x 会生成工具调用,不等于服务端能稳定解析工具调用。真正决定流式工具是否可用的,是模型格式、chat template 和后端增量 parser 三者是否一致。
qwen3_xml。OpenAI 和 Anthropic 客户端仍发送标准 tools,前端不需要理解模型生成的 XML。
观察到了什么
社区长轮次测试给出的现象很一致:Qwen3x 天然更偏向 XML 工具调用。无论 OpenAI 或 Anthropic 请求外形、流式或非流式,模型都更容易稳定保持 XML。JSON 在非流式下尚有较高成功率,但温度高于 0.3 后,流式调用更容易发生格式漂移、参数截断或无法进入工具执行。
换到 v22 chat template 不能消除这个差异。模板能强化输出格式,却不能替代模型后训练,也不能让一个 XML-only parser 自动理解 JSON。
问题不在前端
客户端看到的应该始终是标准 API 事件。以 OpenAI-compatible API 为例,客户端提交 tools 和消息;chat template 把它渲染成模型熟悉的格式;模型生成 XML;vLLM 再把 XML 增量转换为标准 tool_calls delta。Anthropic 路径同理。
OpenAI / Anthropic tools
↓
chat template 渲染模型提示
↓
Qwen3x 生成 XML
↓
vLLM qwen3_xml 增量解析
↓
标准 tool_calls / tool_use 事件
因此前端助手不应增加 Qwen 专用 XML 逻辑。把模型私有格式泄漏到客户端,只会让每一个前端都重复处理半截标签、转义和重试。
模板支持 JSON,不代表服务支持双格式
30001 固定的 Froggeric 模板已经包含 tool_call_format=json 分支,也能按 XML 或 JSON 重放历史工具调用。但当前启动参数是 --tool-call-parser=qwen3_xml,运行时 parser 只识别 XML 的 <function=...> 和 <parameter=...> 结构。
| 路径 | 模板生成 | 后端增量解析 | 当前结论 |
|---|---|---|---|
| XML | 支持,且为默认 | qwen3_xml 支持 | 生产使用 |
| JSON | 支持 | 当前 parser 不支持 | 不得启用 |
| 网关事后提取 JSON | 无关 | 需要等待完整响应 | 不是真流式 |
如果现在强制 tool_call_format=json,模型可能生成看似正确的 JSON,但服务端可能把它留在普通文本里,或者无法提取为 API 工具调用。这是 parser 能力缺口,不是再加一句提示词就能解决的问题。
真正的双格式方案
后端需要一个按请求维护状态的双格式增量 parser。在每个 <tool_call> 内,看到 <function= 就进入 XML 状态机,看到 { 就进入 JSON 状态机;两条路径都要尽早发出函数名,并持续发送 arguments delta,而不是等整个工具调用闭合以后再解析。
- XML 路径处理跨 chunk 标签、参数内容和多工具调用。
- JSON 路径处理字符串转义、嵌套对象、半截 UTF-8 和未闭合结构。
- 异常输出要区分“尚未收完”和“确定损坏”,不能过早终止 agent loop。
- 重试由后端统一执行,并保留原始失败类型;客户端仍只处理标准协议。
- 模板要覆盖正常和常见错误形态,但格式鲁棒性训练属于模型后训练,不属于部署参数。
温度不是修复开关
降低 temperature 可以减少格式漂移,所以 JSON 在低温下看起来更稳定;它不能弥补 parser 不认识 JSON,也不能保证长参数、write/edit 或多工具流式调用正确。生产指标必须同时覆盖格式提取、参数正确性、工具执行、自动重试和最终回答完成,不能只统计“模型输出过一个 tool_call”。
如何验证生产级
社区结果声称:覆盖长短文本、主要工具类型和 200 轮以上 agent loop,重复五轮后,包含参数错误自动重试的整体成功率不低于 99.6%。这个数字可以作为目标,但不能直接算作我们的结果。复现时必须固定模型 revision、模板、parser、采样参数、工具集合、重试策略和测试语料。
- XML/JSON × 流式/非流式 × OpenAI/Anthropic 四个维度全部覆盖;
- 分别测试 temperature 0、0.3 和 1.0;
- 重点覆盖 write/edit 的长参数、换行、引号、Unicode 和嵌套 JSON;
- 至少 200 轮连续执行,记录格式失败、参数失败、重试恢复和异常停止;
- 重复五轮,按完整工具执行成功率计算,而不是按 parser 命中率计算。
现阶段保留:XML-only、qwen3_xml、标准客户端协议。下一阶段:实现 vLLM 双格式流式 parser 后再开放 JSON,并用上述矩阵独立复现成功率。