[Bug]: JSON Schema pattern on string items causes maxLength to be ignored in structured outputs

这个报错发生在 vLLM 结构化输出中,当 JSON Schema 的字符串节点同时包含 pattern 和 maxLength / minLength 时,xgrammar 后端会忽略长度限制。优先排查是否错误地选择了 xgrammar 后端,并检查 has_xgrammar_unsupporte

快速结论:这个报错发生在 vLLM 结构化输出中,当 JSON Schema 的字符串节点同时包含 patternmaxLength/minLength 时,xgrammar 后端会忽略长度限制。优先排查是否错误地选择了 xgrammar 后端,并检查 has_xgrammar_unsupported_json_features 的拦截逻辑。

适用环境:vLLM 结构化输出功能;已确认环境为 Arch Linux、Python 3.12.7、PyTorch 2.11.0+cu130、CUDA 13.0、NVIDIA GeForce RTX 3090。xgrammar 和 guidance 后端的相关代码在 vllm/v1/structured_output/backend_xgrammar.pyvllm/v1/structured_output/backend_guidance.py 中。

最快修复方案:暂无确认的一步修复方案;但可通过修改 has_xgrammar_unsupported_json_features 函数,增加对字符串节点同时包含 patternmaxLengthminLength 的检查,返回 True 以禁用 xgrammar 后端。此修复已包含在 PR #45599 中,升级到包含该 PR 的版本即可解决。

注意事项:该修复只针对 xgrammar 后端。guidance (llguidance) 后端未被确认存在此问题,反而会正确执行长度限制,不应盲目添加相同的拦截检查,否则会错误拒绝本可正常工作的 Schema。

问题场景

用户在使用 vLLM 的 结构化输出(Structured Outputs) 功能时触发该问题。具体场景是向模型提供一个 JSON Schema,其中定义了字符串数组,且数组项既有 pattern(如正则表达式)又有 maxLength 约束。用户期望输出严格遵循 maxLength 限制,但实际生成的输出违反了该限制。

报错原文

[Bug]: JSON Schema pattern on string items causes maxLength to be ignored in structured outputs

问题并非直接抛出异常,而是逻辑层面的错误:xgrammar 后端静默选择了不支持的 Schema。

原因分析

根本原因位于 has_xgrammar_unsupported_json_features 函数(backend_xgrammar.py, L243–249)。该函数的字符串节点检查只拒绝不支持的 format 值,未识别出同时包含 patternmaxLength/minLength 的节点。因此,xgrammar 的 Grammar.from_json_schema() 成功解析此类 Schema,导致 xgrammar 被静默选中作为后端。在生成阶段,xgrammar 将 pattern 编译为正则 DFA,但未将其与字符计数限制(maxLength)取交集,最终导致长度限制被丢弃。

环境排查

  • 确认 vLLM 版本是否包含 PR #45599 的修复。
  • 检查 Python 版本是否符合 vLLM 要求(本 Issue 中为 3.12.7)。
  • 确认使用的后端(xgrammar 或 guidance)及其版本;可临时禁用 xgrammar 或强制使用 guidance 后端进行测试。
  • 验证 xgrammar 是否被正确识别为不支持当前 Schema(可通过直接调用上述函数复现)。

解决步骤

  1. 升级 vLLM 版本:将 vLLM 升级到包含 PR #45599 的版本,该 PR 修复了 xgrammar 后端的此问题。
  2. (可优先尝试)手动修复:若无法升级,可编辑 backend_xgrammar.py 中的 has_xgrammar_unsupported_json_features 函数,在字符串节点检查中增加条件:
    if obj.get("type") == "string" and "pattern" in obj and ("maxLength" in obj or "minLength" in obj):
        return True
  3. 后端切换:临时切换结构化输出后端为 guidance (llguidance)。根据 Issue 评论中的行为验证,guidance 后端能正确执行 maxLength 限制,因此可作为规避方案。
  4. 调整 Schema:若无法修改代码,可尝试调整 Schema,避免在同一个字符串节点上同时使用 patternmaxLength,或将约束拆分到不同结构(若业务允许)。

验证方法

通过运行一段简单 Python 代码验证修复是否生效:

from vllm.v1.structured_output.backend_xgrammar import has_xgrammar_unsupported_json_features
schema = {"type": "array", "items": {"type": "string", "pattern": r"^[\x20-\x7E]+$", "maxLength": 8}}
print(has_xgrammar_unsupported_json_features(schema))  # 修复前为 False,修复后应为 True

若返回 True,说明拦截逻辑已生效,vLLM 将改用其他后端处理该 Schema。之后可重新运行实际生成任务,确认输出不再超过 maxLength 限制。

参考来源

vllm-project/vllm #45592

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 22314

发表回复

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