作者:武卓,AI软件布道师;杨粟,AI软件解决方案工程师
引言
AI 应用正在超越简单的文本生成阶段——开发者如今需要模型能够生成机器可读、结构化的输出,以便代码生成、API 调用或用户界面可以直接使用。这正是 Structured Output(结构化输出,SO) 发挥作用的地方:它在解码过程中对模型进行引导,使每一个生成的 token 都严格遵循预定义的模式或语法规则——无论是 JSON、SQL、XML,还是函数调用参数等。通过在生成阶段就保证结果的正确性,结构化输出消除了脆弱的后处理解析逻辑和“生成错误后重试”的循环,从而带来更安全的自动化、更快的响应时间以及更易集成的工作流程。这一能力在 智能体工作流、MCP 服务器 以及多步 AI 系统中尤为关键,因为这些场景都依赖模型与工具之间可靠的结构化数据交换,以实现实时的协调与决策。
自 OpenVINO™ 2025.3 版本起,OpenVINO™ GenAI 已内置支持结构化输出,可在 AI PC、 边缘设备等各种场景高效运行。
OpenVINO™ GenAI如何实现结构化输出
什么是 Token-Level SO(逐词级结构化输出)?
从本质上讲,Token-Level SO 确保大语言模型(LLM)生成的每一个 token 都严格遵循预定义的结构或约束——例如 JSON Schema、正则表达式或语法规则。其过程非常直观:在每一步解码时,模型会根据整个词表生成概率分布,而系统会屏蔽掉所有违反结构约束的 token,仅允许合法的 token 被采样输出。通过这种方式,模型在生成阶段就能保证语法上的正确性,同时保持极低的运行开销。这种方法高效、确定且与 OpenVINO™ GenAI 的优化流水线高度契合——它将逐词级的掩码机制直接集成到推理过程中,实现实时的、格式完全正确的结构化输出。
OpenVINO™ GenAI 通过使用XGrammar 作为底层引擎来实现这种结构化输出能力。
什么是XGrammar?
XGrammar是一个开源库,用于实现快速且灵活的结构化文本生成。它通过约束解码(constrained decoding)确保输出在结构上 100% 正确,并支持多种结构类型,如JSON、正则表达式(regex) 以及自定义上下文无关语法等。经过精心优化的 XGrammar 在 JSON 生成中实现了几乎为零的性能开销,成为当前最快的结构化生成引擎之一。它已被集成到WebLLM、vLLM 和SGLang 等多个项目中。凭借其出色的速度与可移植性,OpenVINO™ GenAI 采用 XGrammar 作为结构化输出(SO)的底层引擎,帮助开发者轻松生成格式正确、结构清晰的输出结果。
在实际应用中,启用OpenVINO™ GenAI 的结构化输出功能 有一个关键前提:OpenVINO™ 的分词器(tokenizer)必须支持词表暴露(expose vocabulary)。这一能力使解码引擎能够精确地知道哪些 token 可以在下一步出现,从而高效地应用来自 XGrammar 的约束。通过暴露完整的词表,OpenVINO 能在生成过程中执行更细粒度的 token 级掩码控制,实现逐词级的约束与基于模式的验证。
分步教程:用OpenVINO™ GenAI生成结构化输出
以下是有关如何使用 OpenVINO™ GenAI 获取结构化输出的分步指南。
第一步: 安装
首先,克隆openvino.genai GitHub 仓库。这里面包含开始使用 OpenVINO™ GenAI进行 LLM 推理并获得结构化暑促所需的所有代码和示例。
git clone https://github.com/openvinotoolkit/openvino_genai.gitcd openvino_genai
导航到“文本生成”示例:
<your_path>\openvino.genai\samples\python\text_generation
在此文件夹中,您可以找到有关示例的重要 README.md 文件。您也可以直接从 OpenVINO™下载页面获取该文件。
现在需要准备一个 Python 虚拟环境,这是模型推理所必需的。这可以通过以下代码来完成:
python -m venv venv_exportvenv_export\Scripts\activatepip install --upgrade-strategy eager -r ../../deployment-requirements.txt
步骤2: 下载预先优化好及转换为OpenVINO™ IR格式的 LLM
在使用结构化输出解码之前,您的模型需要采用 OpenVINO™ IR 格式。您可以从 魔搭社区 OpenVINO™专区下载预转换的模型,也可以使用 optimum-cli 手动转换您最喜欢的生成式AI模型。以下是将 Qwen3-8B 转换为具有 INT4量化的 OpenVINO™ IR 格式的快速示例:
optimum-cli export openvino \--model qwen\qwen3-8B \--task text-generation-with-past \--weight-format int4 \./qwen3-8B-ov-int4
步骤3: 定义你的结构化模式(来自 Pydantic 的 JSON 模式)
结构化输出解码需要一个模式来定义允许模型生成的内容。在 OpenVINO™ GenAI 中,可以使用 Pydantic 方便地定义此模式,它会自动导出解码器可以遵循的 JSON 模式。
from typing import Literalfrom pydantic import BaseModel, Fieldclass Person(BaseModel):name: str = Field(pattern=r"^[A-Z][a-z]{1,20}$")surname: str = Field(pattern=r"^[A-Z][a-z]{1,20}$")age: intcity: Literal["Dublin", "Dubai", "Munich"]class Car(BaseModel):model: str = Field(pattern=r"^[A-Z][a-z]{1,20} ?[A-Z][a-z]{0,20} ?.?$")year: intengine_type: Literal["diesel", "petrol", "electric", "hybrid"]class Transaction(BaseModel):id: int = Field(ge=1000, le=10_000_000)amount: floatcurrency: Literal["EUR", "PLN", "RUB", "AED", "CHF", "GBP", "USD"]class ItemQuantities(BaseModel):person: int = Field(ge=0, le=100)car: int = Field(ge=0, le=100)transaction: int = Field(ge=0, le=100)items_map = {"person": Person, "car": Car, "transaction": Transaction}sys_message = ("You generate JSON objects based on the user's request. You can generate JSON objects with different types of objects: person, car, transaction.""If the user requested a different type, the JSON fields should remain zero. ""Please note that the words 'individual', 'person', 'people', 'man', 'human', 'woman', 'citizen' are synonyms and can be used interchangeably.""E.g. if the user wants 5 houses, then the JSON must be {\"person\": 0, \"car\": 0, \"transaction\": 0}. ""If the user wants 3 people and 1 house, then the JSON must be {\"person\": 3, \"car\": 0, \"transaction\": 0}. ""Make sure that the JSON contains the numbers that the user requested. If the user asks for specific attributes, like 'surname', 'model', etc., ""ignore this information and generate JSON objects with the same fields as in the schema. ""Please use double quotes for JSON keys and values. ")sys_message_for_items = "Please try to avoid generating the same JSON objects multiple times."
步骤4: 使用结构化输出生成(JSON 模式 + XGrammar)
现在,可以加载 OpenVINO™ 模型并运行 逐词级(token-level)结构化输出解码。
通过在生成配置中附加你的 JSON Schema(即 StructuredOutputConfig),OpenVINO™ GenAI 将在底层自动调用 XGrammar,在每一步解码时强制校验输出的合法性,从而确保生成结果始终是格式正确的 JSON。
from openvino_genai import LLMPipeline, GenerationConfig, StructuredOutputConfigpipe = LLMPipeline(args.model_dir, 'GPU')config = GenerationConfig()config.max_new_tokens = 300while True:prompt = input('> ')pipe.start_chat(sys_message)config.structured_output_config = StructuredOutputConfig(json_schema = json.dumps(ItemQuantities.model_json_schema()))config.do_sample = Falseres = json.loads(pipe.generate(prompt, config))pipe.finish_chat()print(f"Generated JSON with item quantities: {res}")config.do_sample = Trueconfig.temperature = 0.8pipe.start_chat(sys_message_for_items)for item, quantity in res.items():config.structured_output_config = StructuredOutputConfig(json_schema = json.dumps(items_map[item].model_json_schema()))for _ in range(quantity):json_strs = pipe.generate(prompt, config)print(json.loads(json_strs))pipe.finish_chat()
最后,你可以通过以下命令运行结构化输出文本生成的示例代码:
python structured_output_generation.py model_dir
在一台Arrow-lake AI PC上, 使用Qwen3-1.7B-int4-ov 模型运行结构化输出的效果如下所示:
自OpenVINO™ 2025.3 版本起,OpenVINO™模型服务器(OVMS) 也已支持结构化输出。详细说明可参见:https://docs.openvino.ai/2025/model-server/ovms_structured_output.html。
我们将在下一篇博客中分享如何使用OVMS 获取结构化响应,并将其应用于智能体AI的工具调用场景中。敬请期待!
小结
随着 AI 应用从聊天机器人逐步演进到多工具协作的智能体,结构化输出(SO) 已成为不可或缺的能力——开发者需要模型能够直接生成机器可读、符合预定义模式(schema)的结果,以便无缝对接代码和 API。
借助 OpenVINO™ GenAI,你现在可以“开箱即用”地获得可靠的结构化解码能力。自 2025.3 版本起,OpenVINO™ 通过 XGrammar 实现了高效的 SO 支持,确保每一次生成都快速、有效、可直接使用。无论是在 AI PC 本地运行、边缘设备上部署,还是通过 OVMS 提供服务,你都可以用几行代码轻松启用结构化输出——没有格式错误的 JSON,没有重试的麻烦,只有正确与高效,全面释放英特尔平台的潜能。
立即上手,畅享编码吧。
延伸阅读

被折叠的 条评论
为什么被折叠?



