为什么需要结构化输出

在实际应用中,AI的文本输出需要被下游系统解析和使用。结构化输出(如JSON、XML)让机器的自动化处理成为可能。无论是构建API、填充数据库,还是触发自动化工作流,结构化输出都是连接AI与业务系统的桥梁。

JSON模式提示词

通过精心设计的提示词,可以让模型输出格式化的JSON数据:

你是一个信息提取助手。请从以下用户消息中提取关键信息,并以JSON格式输出。

输出格式:
{
  "intent": "用户意图",
  "entities": [
    {"name": "实体名称", "type": "实体类型"}
  ],
  "sentiment": "positive/negative/neutral",
  "summary": "一句话总结"
}

用户消息:我想预订明天从北京到上海的机票,经济舱,靠窗位置。

JSON Schema约束

更深层的控制是使用JSON Schema来定义输出结构:

请按照以下JSON Schema输出你的分析结果:

{
  "type": "object",
  "properties": {
    "analysis": {
      "type": "object",
      "properties": {
        "overall_score": {"type": "number", "minimum": 0, "maximum": 100},
        "strengths": {"type": "array", "items": {"type": "string"}},
        "weaknesses": {"type": "array", "items": {"type": "string"}},
        "recommendations": {"type": "array", "items": {
          "type": "object",
          "properties": {
            "action": {"type": "string"},
            "priority": {"type": "string", "enum": ["high", "medium", "low"]},
            "expected_impact": {"type": "string"}
          },
          "required": ["action", "priority"]
        }}
      },
      "required": ["overall_score", "strengths", "weaknesses"]
    }
  },
  "required": ["analysis"]
}

使用Function Calling实现结构化输出

现代LLM API(如OpenAI、DeepSeek)提供了Function Calling能力,这是实现结构化输出的最佳方式:

import json
from openai import OpenAI

client = OpenAI()

response = client.chat.completions.create(
    model="deepseek-chat",
    messages=[
        {"role": "system", "content": "你是一个数据分析助手"},
        {"role": "user", "content": "分析Q3销售数据:总营收500万,同比增长15%"}
    ],
    functions=[{
        "name": "generate_report",
        "description": "生成销售数据分析报告",
        "parameters": {
            "type": "object",
            "properties": {
                "total_revenue": {"type": "number"},
                "growth_rate": {"type": "number"},
                "analysis": {"type": "string"},
                "recommendations": {
                    "type": "array",
                    "items": {"type": "string"}
                }
            },
            "required": ["total_revenue", "growth_rate", "analysis"]
        }
    }],
    function_call={"name": "generate_report"}
)

result = json.loads(
    response.choices[0].message.function_call.arguments
)
print(json.dumps(result, indent=2, ensure_ascii=False))

结构化输出的最佳实践

  • 优先使用Function Calling:这是最可靠的结构化输出方式
  • 添加fallback处理:模型输出可能不符合格式,需要JSON解析异常处理
  • 使用枚举约束:对于有限选项的字段,使用enum限制取值范围
  • 添加验证层:使用Pydantic或JSON Schema在后端验证输出
  • 提供输出示例:在提示词中提供期望的输出格式示例

常见问题与解决方案

问题1:输出不是有效JSON。解决:使用正则提取JSON块,或使用Function Calling。问题2:输出字段缺失。解决:设置required字段,并在代码中提供默认值。问题3:模型「创造性」添加额外字段。解决:明确说明「只输出指定的字段,不要添加额外内容」。