[Bug]: JSON schema with multiple allOf branches is silently ignored by the xgrammar structured-output backend

当你在 vLLM 中使用 xgrammar 结构化输出后端(structured-output backend),并且 JSON schema 里存在多个 allOf 分支(或 anyOf / oneOf 与约束关键字相邻)时,xgrammar 可能会静默忽略这些约束,生成不受限制的 JSON,而

快速结论:当你在 vLLM 中使用 xgrammar 结构化输出后端(structured-output backend),并且 JSON schema 里存在多个 allOf 分支(或 anyOf/oneOf 与约束关键字相邻)时,xgrammar 可能会静默忽略这些约束,生成不受限制的 JSON,而 vLLM 的 has_xgrammar_unsupported_json_features 检查却返回 False,不会自动回退到 llguidance。优先排查 schema 是否包含多分支 allOf 或带兄弟约束关键字的组合器。

适用环境:Issue 中确认的环境为:Ubuntu 26.04 LTS (x86_64)、WSL2、Python 3.12.14、PyTorch 2.13.0+cpu、AMD Ryzen 7 4800H、无 CUDA/ROCm/XPU;vLLM 版本相关行为在 main 与 v0.31.0 上均复现,xgrammar 0.2.8 与 0.2.7 均存在该问题,llguidance 1.7.6 不受影响。

最快修复方案:Issue 中没有确认的一步修复方案,但已合并的修复 PR #56557(以及 #59061)通过扩展 has_xgrammar_unsupported_json_features 检查,将多分支 allOf 标记为 xgrammar 不支持,从而让 auto 回退到 llguidance。可优先尝试升级到包含该修复的 vLLM 版本,或显式指定 guided_decoding_backend="llguidance" 绕过 xgrammar。

注意事项:修复 PR 仅覆盖多分支 allOf;对于 anyOf/oneOf/单分支 allOf 与 type、properties、required 等约束关键字相邻的情况,检查仍返回 False,问题依旧存在。显式切换到 llguidance 可能带来性能差异,且需确认后端已安装。

问题场景

用户在 vLLM 中使用结构化输出(structured output / guided decoding),并且 guided_decoding_backend 为默认的 auto 或显式设置为 xgrammar。当请求中的 JSON schema 包含多个 allOf 分支时,xgrammar 后端不会正确编译这些约束,而是静默生成一个接受任意 JSON 值的语法,导致输出不符合 schema 要求。相关场景还包括 anyOf、oneOf 或 allOf 与 type、properties、required 等约束关键字出现在同一节点上(xgrammar 会丢弃这些兄弟关键字)。Issue 中给出的复现 schema 包括:

{"type": "object", "properties": {"modifier": {"enum": ["", "dark"]}}, "anyOf": [{"required": ["modifier"]}], "additionalProperties": false}
{"type": "object", "properties": {"a": {"type": "integer"}}, "required": ["a"], "additionalProperties": false, "allOf": [{"required": ["a"]}]}

报错原文

[Bug]: JSON schema with multiple allOf branches is silently ignored by the xgrammar structured-output backend

该 Issue 属于静默失败类型,没有抛出异常或错误堆栈;表现为 xgrammar 编译出的根规则接受任意 JSON 值,无效实例(如 [1]、{}、{"a": 1}、{"a": "x"}、{"zzz": [1, 2, 3]} 等)全部被接受。

原因分析

最可能的原因是 xgrammar 的结构化输出后端在遇到多分支 allOf(以及组合器旁边带有约束关键字的 anyOf/oneOf/单分支 allOf)时,没有正确地将这些约束编译进语法,而是将其丢弃,最终生成一个接受任意 JSON 值的根规则。与此同时,vLLM 的 has_xgrammar_unsupported_json_features 检查未能识别这类 schema 为不支持,返回 False,导致 auto 模式继续选择 xgrammar 而不是回退到 llguidance。Issue 评论指出该检查遗漏了“组合器与约束关键字相邻”的情况,xgrammar 会丢弃这些兄弟关键字(参考 mlc-ai/xgrammar#858,修复 mlc-ai/xgrammar#859 仍未合并)。

环境排查

  • 确认 vLLM 版本:Issue 中在 main 和 v0.31.0 上均复现。
  • 确认 xgrammar 版本:Issue 中验证 xgrammar 0.2.8(main 的 pin)和 0.2.7(v0.31.0)行为相同。
  • 确认 llguidance 版本:Issue 中使用 llguidance 1.7.6,该后端能正确拒绝无效实例,可作为回退比对。
  • 确认 guided_decoding_backend 设置:默认 auto 会优先选择 xgrammar,可能不会自动回退。
  • 确认请求中的 JSON schema 是否包含多分支 allOf,或 anyOf/oneOf/allOf 与 type、properties、required 等约束关键字位于同一节点。
  • 确认 Python 版本:Issue 环境为 Python 3.12.14。
  • 确认操作系统:Issue 环境为 Ubuntu 26.04 LTS (x86_64)、WSL2、内核 6.18.33.2-microsoft-standard-WSL2。
  • CUDA/ROCm/XPU:Issue 环境中 PyTorch 为 2.13.0+cpu,未使用 GPU 加速,相关项目无法收集。

解决步骤

  1. 先判断当前 schema 是否命中已知问题模式:检查是否包含多个 allOf 分支;或检查 anyOf/oneOf/allOf 节点旁是否同时存在 type、properties、required 等约束关键字。
  2. 可优先尝试将 vLLM 升级到包含 PR #56557 修复的版本;该 PR 扩展了 has_xgrammar_unsupported_json_features 检查,使多分支 allOf 被判定为 xgrammar 不支持,从而让 auto 回退到 llguidance。
  3. 如果暂时无法升级,可显式设置 guided_decoding_backend="llguidance"(或对应的后端选择参数),绕过 xgrammar,避免静默忽略约束。
  4. 如果使用的是 auto 且无法升级,可在应用层对 schema 做预处理:将多分支 allOf 合并展开,或移除与组合器相邻的冗余约束关键字,减少触发条件。
  5. 若问题涉及 anyOf/oneOf/单分支 allOf 与约束关键字相邻的情况,注意 #56557 和 #59061 均未覆盖该场景,需要关注 xgrammar 侧修复 mlc-ai/xgrammar#859 或 vLLM 后续检查的扩展。

验证方法

使用 xgrammar.testing._is_grammar_accept_string 对编译后的语法进行测试(Issue 中采用该方法),确认无效实例不再被接受。例如,对于第一个复现 schema,检查 [1]、{}、{"a": 1}、{"a": "x"}、{"zzz": [1, 2, 3]} 是否被拒绝;对于第二个 schema,检查 [1]、{}、{"a": "x"}、{"zzz": [1, 2, 3]} 是否被拒绝。也可以对比切换到 llguidance 后端时的行为,确认无效实例被正确拒绝。若升级后 has_xgrammar_unsupported_json_features 对多分支 allOf 返回 True 并回退到 llguidance,则说明修复生效。

参考来源

vllm-project/vllm #56556

vllm-project/vllm PR #56557

vllm-project/vllm PR #59061

mlc-ai/xgrammar #858

mlc-ai/xgrammar PR #859

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 27606

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注