快速结论:在 vLLM 上通过 OpenAI 兼容接口为 Qwen3.5 提供 structured output 时,thinking 模式下返回的 JSON 可能被 markdown 代码块包裹(如 “`json … “`),或在启用 MTP 投机解码时违反 response_format 约束。优先排查是否同时开启了 thinking 模式与 MTP 投机解码。
适用环境:vLLM nightly 镜像(Issue 中确认复现的镜像为 vllm/vllm-openai:nightly-af1c01499b289be555c475669ba50a88e96d846e,版本字符串 0.29.1rc1.dev187+gaf1c01499),OpenAI Python SDK;涉及模型 Qwen3.5 27B FP8、Qwen3.5-122B-A10B-GPTQ-Int4、Qwen3.5-35B-A3B-MXFP4。确认测试环境包括 1x B200(最后无法复现的测试);其余环境细节未在讨论中完整给出。
最快修复方案:暂无确认的一步修复方案。社区验证过的规避手段是关闭 MTP 投机解码(不传 –speculative-config,或移除 method 为 mtp / qwen3_next_mtp 的配置),并确认已设置正确的 reasoning parser(如 –reasoning-parser qwen3)。
注意事项:关闭 MTP 属于规避而非根治,代价是失去投机解码带来的吞吐收益;有用户反馈在非 thinking 模式下即使开启 MTP 也正常,说明触发条件与 thinking 模式相关。社区提出的模型无关根因是:启用投机解码时,在 尚未被接受之前,draft tokens 未受约束。对应的修复 PR(#36138)是否已在正式版本合入,Issue 中未明确说明。Issue 关闭前的最新测试(2026-09-16 nightly)未能在 thinking 模式(含/不含 MTP)下复现,说明问题可能已在较新版本中修复,或仅在特定配置组合下出现。
问题场景
用户将 Qwen3.5 27B FP8 以 OpenAI 兼容服务方式部署在 vLLM 上,并通过 openai-python-sdk 的 response_format(structured output)功能请求结构化输出。结果模型返回的内容不符合 response_format 指定的 schema,输出被 markdown 代码块包裹,形如 “`json xxx “`。有用户指出同一段代码在 vLLM 服务 Qwen3-VL 时工作正常。进一步讨论确认:在 thinking 模式下失败概率较高,在非 thinking 模式下正常;启用 MTP 投机解码(speculative decoding)是另一个关键触发因素。
报错原文
[Bug]: Qwen3.5 structured output doesn't work
The result is warpped with markdown code block, looks like ```json xxx ```
I can confirm Qwen3.5 fails most of the time in thinking mode but works in non-thinking mode.
From my testing, It failed in thinking mode when mtp is enabled. Other condition works fine,
Sometimes outputs
\n\n'''json
in the beginning of the response.
There is a model-independent bug when speculative token is enabled that draft tokens are unconstrained unless reasoning end (</think>) has already been accepted in a previous step.
原因分析
根据讨论中给出的结论,最可能的原因是:当启用投机解码(MTP)且模型处于 thinking 模式时,draft tokens 在 尚未被接受之前不受 structured output 约束,因此生成的 content 可能违反 response_format 的 schema,或被额外包裹 markdown 代码块。有用户认为该问题与模型无关,属于投机解码路径的约束逻辑缺陷(对应修复 PR #36138)。另有参与者提示,服务端可能缺少 –reasoning-parser qwen3 设置,导致 reasoning 内容与 content 的边界处理不正确,这属于可能原因之一。需要说明的是,Issue 关闭前的最新测试未能在 thinking 模式下复现该问题,因此该缺陷可能已在较新版本中修复,或只在特定模型/量化/并行配置下触发。
环境排查
- 确认 vLLM 版本与镜像:是否使用 nightly 或 latest 镜像,具体 commit/版本字符串是什么(复现测试使用 nightly-af1c01499b289be555c475669ba50a88e96d846e / 0.29.1rc1.dev187+gaf1c01499)。
- 确认是否配置了 –reasoning-parser qwen3(或对应模型的 reasoning parser),以及是否使用了 –language-model-only。
- 确认是否启用了投机解码:–speculative-config 中 method 是否为 mtp 或 qwen3_next_mtp,num_speculative_tokens 是否为 1。
- 确认请求是否处于 thinking 模式(未显式设置 enable_thinking: false)。
- 确认模型与量化格式:Qwen3.5 27B FP8 / 122B-A10B-GPTQ-Int4 / 35B-A3B-MXFP4 等。
- 确认并行与显存配置:tensor-parallel-size、enable-expert-parallel、gpu_memory_utilization、max-model-len、kv-cache-dtype。
- 确认 max_tokens 是否过小:测试中发现部分请求在 reasoning 阶段耗尽 token 预算,导致 content 为 null,容易被误判为结构化输出失败。
解决步骤
- 先关闭投机解码进行对照测试:不传 –speculative-config(或移除 MTP 相关配置),确认在 thinking 模式下 structured output 是否恢复正常。多名用户反馈关闭 MTP 后问题消失。
- 确认服务端已正确设置 reasoning parser,例如启动参数中加入 –reasoning-parser qwen3,避免 reasoning 内容与最终 content 混淆。
- 在请求中显式关闭 thinking 模式(例如 enable_thinking: false),验证非 thinking 模式下是否稳定符合 schema,用于区分是 thinking 模式问题还是 structured output 本身问题。
- 可优先尝试使用较新的 nightly 或正式镜像重新验证,因为 2026-09-16 的 nightly 测试已无法复现该问题,可能已包含相关修复。
- 可优先尝试确认 PR #36138 中提出的修复是否已合入当前所用版本;如仍未合入,可参考该 PR 的改动方向评估是否等待官方修复。
- 测试时适当增大 max_tokens(例如 4096),避免请求在 reasoning 阶段因预算耗尽而 content 为 null,造成误判。
验证方法
使用与失败时相同的 response_format schema 发起请求,在 thinking 模式下检查返回的 content 是否为干净、符合 schema 的 JSON,且不包含 markdown 代码块包裹。同时确认 finish_reason 为 stop 而非 length,json.loads(content) 能正常解析。建议在关闭 MTP、开启 reasoning parser 的配置下重复多次请求,因为该问题据反馈为间歇性出现(“fails most of the time”)。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。

![[Model Support] DeepSeek-V4.1 Tracking Issue](https://www.chat-gpts.plus/wp-content/uploads/2026/09/56400-8f0f3572-768x403.jpg)
