学习如何强制 AI API 仅以严格且有效的 JSON 格式回应

发布: (2026年3月8日 GMT+8 00:28)
5 分钟阅读
原文: Dev.to

Source: Dev.to

结构化输出 :强制 AI 使用 JSON

如果你曾尝试将 AI 的响应直接集成到一个应用(Web 或移动端),一定在服务器日志中看到过这样的错误:

SyntaxError: Unexpected token 'V', "Voici le J"... is not valid JSON

你让 AI 返回一个包含用户姓名和年龄的 JSON 对象,它却回答了:

« Voici le JSON que vous avez demandé :
json { "nom": "Paul", "age": 32 }
J’espère que cela vous aide ! »

后端用 JSON.parse() 解析这段文字时就会崩溃。

开发者不能只满足于 95 % 正确的响应;他们需要确定性。下面介绍如何获得它。

1. Prompt 的局限性

最初,人们会在提示词中加入全大写的指令:

"TU DOIS RÉPONDRE UNIQUEMENT EN JSON. N'AJOUTE AUCUN TEXTE AVANT OU APRÈS."

大多数情况下这能起作用,但在边缘案例中,AI 可能脱离角色,解释为什么不能回答,从而破坏你的代码。
输出格式不能仅仅是文字指令;它必须是 API 级别的技术约束

2. Structured Outputs 与 Pydantic

自 2024 年中期起,主要供应商(OpenAI、Anthropic 等)提供 Structured Outputs
你在 API 请求中直接传入 数据模式,模型会自我约束,只生成符合该模式的字符。

在 Python 中,标准工具是 Pydantic,一个数据验证库。

3. 实践 :永不崩溃的代码

抛弃令人焦虑的提示词。下面是一个完整示例,使用 OpenAI API 以 100 % 确定的方式从文本中提取信息。将其保存为 app.py,使用 uv run app.py 运行(依赖会自动安装)。

# /// script
# requires-python = ">=3.11"
# dependencies = [
#     "openai",
#     "pydantic",
# ]
# ///

import os
from pydantic import BaseModel
from openai import OpenAI

client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key="sk-...",
)

# 1. 定义数据契约(模式)
class ProfilUtilisateur(BaseModel):
    nom: str
    age: int
    tags_hobbies: list[str]
    est_premium: bool

texte_brut = (
    "Hier j'ai discuté avec Marc, il vient d'avoir 28 ans. "
    "Il adore le tennis et la lecture, mais il refuse toujours de payer l'abonnement pro."
)

# 2. 调用 API 并强制响应格式
response = client.beta.chat.completions.parse(
    model="qwen/qwen3-4b:free",
    messages=[
        {"role": "system", "content": "Extrait les informations du profil utilisateur."},
        {"role": "user", "content": texte_brut}
    ],
    response_format=ProfilUtilisateur,  # )
# Premium ? : False (Type: )

有了 response_format,AI 物理上不可能在 JSON 之外生成文字或遗漏 tags_hobbies 键。如果没有找到兴趣爱好,它会返回空列表 [],但键始终存在。这样你的业务代码就不再会因解析错误而崩溃。

4. JSON Mode 与 Structured Output 的区别

API 文档常提到一个简单参数:

{"type": "json_object"}

JSON Mode)。该模式保证响应是合法的 JSON,但不保证包含你期望的键;AI 可能返回 {"utilisateur": "Marc", "annees": 28} 而不是 {"nom": "Marc", "age": 28}

因此应优先使用 Structured Outputs(通过 Pydantic、JavaScript 的 Zod 等),它们强制每个变量的名称和类型必须完全匹配。

核心要点(3 条)

  • 不要恳求:全大写的 “ONLY JSON” 提示并不是技术保证,只是一个祈愿。
  • 强制模式:使用 API 的 Structured Outputs 来数学上约束 AI 的响应。
  • 强类型:通过强类型模型确保返回的数据结构始终符合预期。

* : 使用 Pydantic(Python)或 Zod(JavaScript)直接将 AI 的响应绑定到内部数据模型。

然后呢?

恭喜,你现在已经会正确调用 AI,管理其记忆,降低成本,并将响应以 JSON 类型化。

进一步思考:如何确保在模型更新或提示词修改后,你的 Pydantic 提取仍然可靠?系列的下一篇文章将讨论使用 Test‑Driven Prompting (Evals) 来保障部署的安全。

0 浏览
Back to Blog

相关文章

阅读更多 »