W
AI-Wiki
CONCEPT

结构化输出兼容性

定义

结构化输出兼容性 在本文语境中,不是泛泛的“模型兼容性”或“API 能不能调用”,而是专指:某个模型通过某个 provider 或部署通道接入 Hyper-Extract Provider System 时,是否支持结构化抽取所需的 JSON 输出能力,尤其是 json_schema、schema 约束、约束解码,以及从首个 token 开始就满足 JSON 语法的输出前提。

这类兼容性直接决定 with_structured_output、AutoGraph 等能力是否可用、是否稳定,以及失败时是报错、输出脏内容,还是悄悄返回不符合 schema 的结果。

在 Hyper-Extract 中的语境

Hyper-Extract Provider System 中,多个云端或本地接入方式表面上共用同一套 create_client() 接口,但“接口一致”不等于“结构化输出能力一致”。

Hyper-Extract 支持通过 OpenAI、阿里云 Bailian 和本地 vLLM 接入模型;然而对于结构化抽取来说,真正关键的不是调用方式统一,而是该渠道下的模型是否支持 json_schema 与受约束的 JSON 生成。

因此,结构化输出兼容性 讨论的不是模型总体能力高低,而是模型 + provider + 部署方式这一组合,在结构化输出场景下是否可靠。

关键机制

1. json_schema 支持是硬条件之一

如果 provider 或模型不支持 json_schema,那么即使普通聊天能工作,依赖 schema 约束的结构化抽取也可能失败。

在 Hyper-Extract 的已验证兼容性说明里,Bailian 渠道下的 qwen-maxdeepseek-v3 被明确指出不支持 json_schema。这类情况下,用户可能遇到两种典型现象:

  • 报错:messages must contain the word 'json'

  • 没有直接报错,但返回的并不是合法 JSON

这说明问题不只是“输出格式不优雅”,而是 provider 侧对结构化输出协议的支持本身不完整,导致 schema 约束无法稳定落地。

2. 约束解码要求首 token 就是 JSON

结构化输出往往依赖 constrained decoding。它要求模型从第一个输出 token 起就进入 JSON 轨道,而不是先输出解释、思考过程或额外标签,再开始 JSON。

如果模型先吐出任何非 JSON 内容,即使后面跟着一个看起来正确的 JSON,对严格的结构化输出链路来说也可能已经算失败。

3. thinking 输出会破坏这个前提

本地部署时,thinking 类模型会输出 <think>...</think>。这会直接破坏“首 token 即 JSON”的前提,因此与 constrained decoding 冲突。

Hyper-Extract 的建议非常明确:本地 vLLM 部署应优先使用非 thinking 模型;如果部署的是 Qwen3.5 的 thinking 模式,需要显式关闭 thinking。

对应部署参数示例是:

--default-chat-template-kwargs '{"enable_thinking": false}'

这不是可有可无的优化,而是为了让结构化输出链路能够成立。

已验证的兼容性事实

Bailian 下已知不兼容组合

在 Bailian 渠道中,以下模型被明确标注为不支持 json_schema

  • qwen-max
  • deepseek-v3

遇到这类组合时,可能出现以下问题:

  • 接口报 messages must contain the word 'json'
  • 返回非 JSON 输出
  • 结构化抽取不稳定,无法可靠用于 with_structured_output

Bailian 下的替代建议

对于上述不兼容情况,Hyper-Extract 给出的替代模型建议是:

  • qwen-plus
  • qwen-turbo
  • deepseek-r1

这几个替代项的意义不是“模型更强”,而是它们在该 provider 语境下更适合承担结构化输出任务。

DeepSeek-R1 通过 Bailian 已验证可用

deepseek-r1 通过 Bailian 已被明确验证可用于 AutoGraph 与 with_structured_output

原因并不只是模型本身,而是 Bailian 会在后端过滤 <think> 标签。这样一来,虽然 DeepSeek-R1 本身属于会产生思维链式输出的模型,但通过 Bailian 接入时,最终交给结构化输出链路的内容仍能满足首 token 进入 JSON 的要求。

这说明同一个 thinking 模型,并非绝对不能做结构化输出;关键在于 provider 是否做了合适的后处理。

本地部署的细节与约束

本地 vLLM 更容易暴露 thinking 冲突

在本地 vLLM 部署中,provider 通常不会替你清洗 thinking 标签,因此 <think>...</think> 会原样进入输出流。

一旦开启 thinking 模式,就很容易破坏 constrained decoding,使结构化抽取失败,或者让 with_structured_output 无法按 schema 正常工作。

所以 Hyper-Extract 明确建议:

  • 本地尽量用 non-thinking 模型
  • 如果是 Qwen3.5 一类支持 thinking 的模型,要显式关闭 thinking 模式
  • 只有在确认首 token 可直接进入 JSON 时,结构化输出才值得信赖

关闭 thinking 的部署示例

在 vLLM 启动 LLM 服务时,Hyper-Extract 给出的示例包含:

vllm serve /path/to/qwen3.5-9b-gptq-marlin \
 --served-model-name Qwen/Qwen3.5-9B \
 --trust-remote-code \
 --quantization gptq_marlin \
 --dtype bfloat16 \
 --max-model-len 8192 \
 --gpu-memory-utilization 0.90 \
 --default-chat-template-kwargs '{"enable_thinking": false}' \
 --port 8000 \
 --api-key dummy

这里的 --default-chat-template-kwargs '{"enable_thinking": false}' 对结构化输出兼容性尤其关键。

相关但不同的问题:量化兼容性

Hyper-Extract 还建议量化时优先用 GPTQ-Marlin 而不是 AWQ,因为 AWQ 与 vLLM 0.21.0 存在兼容性问题。

但这属于部署与推理栈兼容性,不等于本文所说的 结构化输出兼容性。两者可能同时影响结果,但要区分:前者偏运行环境,后者偏 JSON/schema/约束解码行为。

边界与例外

同一个模型,经不同渠道接入,兼容性可能不同

这是 结构化输出兼容性 最容易被误解的地方。问题不一定来自模型本身,也可能来自接入渠道的协议支持、模板设置或后处理行为。

同一个模型在不同 provider 下,可能出现完全不同的结果:

  • 在某个渠道下不支持 json_schema
  • 在某个渠道下会原样输出 <think> 标签
  • 在另一个渠道下,provider 会过滤思维标签,因此结构化输出反而可用

DeepSeek-R1 经 Bailian 可用于 AutoGraph 与 with_structured_output,就是这个边界的典型例子;如果通过其他渠道访问 DeepSeek-R1,thinking 输出仍可能导致问题。

“能输出 JSON”不等于“支持结构化输出”

有些模型偶尔能生成看起来正确的 JSON,但如果不能稳定遵守 schema、不能满足 constrained decoding,或者首 token 前会插入额外文本,那么它在 Hyper-Extract 语境里仍不能算结构化输出兼容。

因此判断标准不是“试了一次像是成功”,而是:

  • 是否支持 json_schema
  • 是否能在受约束模式下稳定工作
  • 是否从首 token 起就是 JSON
  • 是否能可靠支撑 with_structured_output 与 AutoGraph

实务判断方法

在 Hyper-Extract 场景中,遇到结构化抽取失败时,可以优先按以下顺序判断:

  1. 当前 provider 与模型组合是否已知不支持 json_schema
  2. 返回内容是否出现非 JSON 前缀,尤其是 <think>...</think>
  3. 是否使用了 thinking 模型但未关闭 thinking
  4. 问题是否其实来自 provider 的后处理差异,而非模型本体

如果是在 Bailian 下使用 qwen-maxdeepseek-v3,应优先切换到 qwen-plusqwen-turbodeepseek-r1。如果是本地 vLLM,则应先检查是否启用了 thinking 模式。

相关条目