如何让 LLM 稳定输出结构化数据(JSON/Schema)
解决 AI 输出不可控的痛点:通过 API 原生支持的约束解码(Constrained Decoding)技术,让 LLM 严格按照定义的 JSON Schema 输出,彻底告别手动解析文本和处理格式错误。
为什么需要这个技能
在生产环境中,LLM 的输出通常需要喂给下游代码(如写入数据库、调用 API 或渲染 UI)。如果依赖 Prompt 要求 AI “请输出 JSON 格式”,AI 仍可能在 JSON 前后添加解释性文字,或在复杂场景下遗漏字段、写错类型,导致解析崩溃。
本技能教你利用主流模型厂商提供的结构化输出方案(如 OpenAI 的 json_schema、Anthropic 的 tool_use),在 Token 生成层面强制约束格式,确保输出 100% 符合预期 Schema。
适用场景
- 数据提取:从非结构化文本中提取特定字段(如发票金额、会议时间)。
- 自动化管线:LLM 作为工作流的一环,输出结果直接驱动后续代码执行。
- 强类型接口:需要 AI 输出严格的枚举值(Enum)或布尔值以进行逻辑判断。
- 本地模型部署:使用 GBNF 语法或 JSON 模式对本地模型进行输出约束。
核心工作流
- 定义目标 Schema:明确需要提取的字段、类型、是否必填以及枚举值。
- 选择供应商方案:
- OpenAI:使用
response_format: { type: "json_schema", ... }并设置"strict": true。 - Anthropic:定义一个单工具的
input_schema,并通过tool_choice强制调用该工具。 - Google Gemini:在
generationConfig中配置responseSchema并指定responseMimeType: "application/json"。
- OpenAI:使用
- 编写类型定义:
- Python 环境建议使用 Pydantic 建模。
- TypeScript 环境建议使用 Zod 定义 Schema。
- 强化系统提示词:明确告知 AI 此时是“数据提取系统”而非“聊天机器人”,禁止输出 JSON 之外的任何解释。
- 执行语义校验与重试:即便格式正确,值也可能错误。使用
model_validate()或.parse()进行校验,若失败则将错误信息反馈给 AI 进行 1-3 次重试。
代码示例
OpenAI + Pydantic (Python)
from pydantic import BaseModel, Field
from openai import OpenAI
from enum import Enum
class Sentiment(str, Enum):
positive = "positive"
negative = "negative"
neutral = "neutral"
class ReviewAnalysis(BaseModel):
sentiment: Sentiment = Field(description="Overall sentiment of the review")
key_topics: list[str] = Field(description="Main topics mentioned, max 5")
purchase_intent: bool = Field(description="Whether the reviewer would buy again")
client = OpenAI()
response = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "Extract structured review analysis."},
{"role": "user", "content": "This laptop is amazing. Definitely buying the next version."}
],
response_format=ReviewAnalysis,
)
result = response.choices[0].message.parsed
TypeScript + Zod
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";
const EventSchema = z.object({
event_name: z.string().describe("Name of the event"),
date: z.string().describe("ISO 8601 date string"),
attendee_count: z.number().int(),
});
const client = new OpenAI();
const completion = await client.beta.chat.completions.parse({
model: "gpt-4o-2024-08-06",
messages: [
{ role: "system", content: "Extract event details." },
{ role: "user", content: "Tech Summit 2025 in Austin on March 15th. 2000 attendees." },
],
response_format: zodResponseFormat(EventSchema, "event_extraction"),
});
const event = completion.choices[0].message.parsed;
下载和安装
下载 llm-structured-output 中文版 Skill ZIP
解压后将目录放入你的 AI 工具 skills 文件夹,重启工具后即可使用。具体路径参考内附的 USAGE.zh.md。
你可能还需要
暂无推荐