结构化输出(Structured Output):如何让 LLM 返回 JSON/XML?
难度:基础 分类:Prompt Engineering
简短回答
结构化输出是让 LLM 返回机器可解析格式(JSON、XML 等)而非自由文本的技术,是 Agent 系统和数据管道的基础能力。主要实现方法有四种:(1) Prompt 指令——在 Prompt 中描述期望格式,最简单但不保证合规;(2) JSON Mode——API 级别强制输出合法 JSON,保证语法正确但不保证 Schema 匹配;(3) Function Calling / Tool Use——定义函数签名让 LLM 填参数,最适合 Agent 工具调用;(4) Constrained Decoding——在解码层面约束 token 生成,100% 保证格式合规(如 Outlines、Guidance)。生产环境推荐 Function Calling + Pydantic 验证:Function Calling 处理格式,Pydantic 验证语义。OpenAI 自 openai-python 1.92 起 client.chat.completions.parse 已 GA,Responses API 提供 client.responses.parse 作为新项目首选;Anthropic 也已于 2025-11-14 公开 Beta 原生 Structured Outputs(anthropic-beta: structured-outputs-2025-11-13 + client.messages.parse),底层 constrained decoding 100% Schema 合规——这是 2026 面试的核心新原语。
详细解析
方法 1:Prompt 指令(最简单)
代码块
Bash
# 通过 Prompt 要求输出 JSON
prompt = """
从以下文本中提取实体信息,以 JSON 格式输出。
文本:张三是 ABC 公司的技术总监,他在北京工作了 5 年。
输出格式:
{
"name": "人名",
"company": "公司名",
"title": "职位",
"location": "工作地点",
"years": 数字
}
请只输出 JSON,不要添加任何其他文本。
"""
# 问题:
# - LLM 可能添加 "```json" 标记或解释文字
# - 可能输出不合法的 JSON(缺少引号、多余逗号)
# - 需要后处理和错误处理
方法 2:JSON Mode(API 级别)
代码块
JavaScript
# OpenAI JSON Mode
from openai import OpenAI
client = OpenAI()
方法 3:Function Calling / Structured Outputs
代码块
Python
from pydantic import BaseModel
方法 4:Constrained Decoding(底层约束)
代码块
Python
# Outlines 框架:在 token 级别约束输出
# 新版 API(outlines >= 1.0):from_transformers / from_vllm 等装载器
import outlines
from transformers import AutoModelForCausalLM, AutoTokenizer
base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-7B-Instruct")
tok = AutoTokenizer.from_pretrained("Qwen/Qwen3-7B-Instruct")
model = outlines.from_transformers(base, tok)
# 用 Pydantic / JSON Schema 约束生成
class Person(BaseModel):
name: str
age: int
skills: list[str]
result = model("提取信息:张三,25岁,会Python和Java", Person)
# 100% 保证输出符合 Schema
# 原理:在每步 token 采样时,只允许合法的下一个 token
方法对比
生产环境最佳实践
代码块
Python
from pydantic import BaseModel, Field, field_validator
Agent 系统中的结构化输出
代码块
JSON
# Agent 的工具调用就是结构化输出的典型应用
tools = [
{
"name": "search_web",
"description": "搜索网页信息",
"parameters": {
"type": "object",
"properties": {
常见误区 / 面试追问
误区:"在 Prompt 里说'输出 JSON'就够了" — Prompt 指令无法保证输出是合法 JSON。LLM 可能添加 markdown 标记、额外解释、或生成语法错误的 JSON。生产环境必须用 JSON Mode 或 Function Calling。
误区:"JSON Mode 能保证字段完整" — JSON Mode 只保证输出是合法 JSON,不保证包含你需要的字段。需要用 Structured Outputs(传入 JSON Schema 或 Pydantic 模型)来保证 Schema 合规。
追问:"Structured Output 会影响模型的生成质量吗?" — 会有轻微影响。格式约束限制了模型的自由度,在某些创意任务上可能降低质量。但对于数据提取、工具调用等结构化任务,约束反而提升了准确率。
追问:"如何处理嵌套和复杂的输出结构?" — Pydantic 支持嵌套模型、列表、可选字段、枚举等复杂结构。关键是 Schema 设计要清晰——字段名用语义化命名,description 写清楚每个字段的含义,帮助 LLM 理解期望。