Python RAG 实战手册——基础模型

0 阅读23分钟

基础模型,包括 LLMs 和多模态模型,构成了现代 RAG 系统的骨干。这些模型既用于为用户生成答案,也用于在内容被存储和检索之前对其进行准备。

在生成步骤中,基础模型会分析检索到的上下文和用户问题,生成 grounded responses。在准备步骤中,基础模型会从图像中提取文本、转录音频、总结长文档,并用 metadata 丰富内容,从而提升检索质量。

本章聚焦于准备步骤和生成步骤中使用的语言模型与多模态模型。准备步骤也称 ingestion phase,在这个阶段,内容会被处理、转换并准备存储;生成步骤则是模型分析检索信息并为用户生成答案的阶段。

图 2-1 展示了一个处理视频内容的典型多模态工作流:

  1. 使用 vision model 分析视频帧。
  2. 使用 speech-to-text 转录音频。
  3. 使用 embedding model 对生成文本进行 embedding。
  4. 当用户提问时,检索相关上下文。
  5. 使用 language model 生成答案。

image.png

图 2-1:多模态模型可以解释和生成文本、图像、音频和视频

每个 RAG 系统都需要一个 generation model,用于解释检索到的内容并生成所需输出——无论是回答用户问题、生成报告,还是完成其他特定任务。下面的 recipes 将展示如何设计有效 prompts、选择合适模型,并生成结构化输出。

你可以在本书 GitHub repository 中找到本章所有代码示例。

2.1 定义合适的 Prompt Template

Problem

你需要为 RAG 应用的生成步骤定义一个有效的 prompt template。

Solution

对于 RAG 应用,prompts 遵循一种结构化模式。一个合适的 prompt template 包含四个关键组件:

  • 一个 role,用于定义 assistant 应该如何表现
  • 一个 instruction,用于描述任务
  • 模型必须依赖的 retrieved context
  • output requirements,用于定义答案应当呈现成什么样

这种结构会引导模型生成 grounded responses。通过明确指示模型只使用检索到的上下文,用户之后可以审查 sources,并验证答案是基于真实信息,而不是 hallucinated facts。

图 2-2 展示了这类 prompt 的高层结构。

image.png

图 2-2:RAG 应用中的 Prompt 结构

为了让这个概念更具体,设想一个支持内部采购团队的 AI assistant。该 assistant 可以访问内部政策文档、合同条款和供应商 notes。所有这些信息都存储在 vector database 中,并在 query time 被检索出来,用 grounded 的方式回答问题。

下面是该 use case 的一个简单 prompt template。Context 部分包含一个 placeholder,因为在真实 RAG 系统中,retrieved passages 会在运行时动态插入:

[Role]
You are a procurement analyst who explains internal policies in a
simple and reliable way.

[Instruction]
Read the retrieved context and answer the user's question using
only the information from the retrieved context.

If the answer is not covered in the context, say that the
information is not available in the provided context.

[Context]
<<context>>

[User Question]
"Do our standard supplier contracts include a minimum warranty period?"

[Output Requirements]
Short answer. Clear wording. Up to 120 words.

这个 prompt 指示模型分析 retrieved context,并仅基于该信息生成合适答案。这是一个经典 chatbot 设置,assistant 连接到一个包含领域知识的 vector store。由于模型被明确要求遵循 context,每个答案都可以追溯到真实 source material。

Discussion

Prompt templates 的作用,是创建一致结构来约束模型行为。role 字段会预设模型对专业水平和沟通风格的预期。instructions 会明确成功标准,而不是依赖隐式模型假设。context 提供基于检索事实的 grounding。output requirements 则防止格式错误破坏下游处理。

你需要在灵活性和控制之间取得平衡。Templates 太宽松时,模型会注入训练数据并捏造引用。Templates 太严格时,模型会拒绝回答那些部分超出 retrieved context 的边缘问题。应使用真实 queries 测试,并根据 failure patterns 调整。

当下游系统需要解析模型输出,或一致性比创造性更重要时,使用 structured templates。对于探索性对话,不要使用它们,因为僵硬结构会限制有用回答。Templates 会增加 token overhead;每次 retrieval call 都会增加这个成本,因此应保持 templates 简洁。

See Also

DAIR.AI Prompt Engineering Guide 提供了一个全面、由社区维护的 prompt engineering 技术、论文和实践示例集合,适用于 RAG 和 AI agents。

Anthropic’s Prompt Engineering Interactive Tutorial 通过动手练习教授核心 prompt engineering 技术,适用于大多数 LLMs。

2.2 为任务选择合适的语言模型

Problem

你需要为 RAG 系统选择合适的 generation model。选择太弱的模型会导致答案不可靠;选择太强的模型则会让系统变慢且昂贵。

Solution

所有主要提供商都会提供多个尺寸的 model families。这些模型从 ultra-efficient models,到可靠的日常模型,再到用于高难任务的强大 flagship 和 reasoning models。

表 2-1 总结了每个层级的优势和短板,以及通常属于该类别的模型。

表 2-1:语言模型选择框架(截至 2026 年 1 月)

TierAccuracy / typical use casesExamples
Ultra-efficient• 简单任务、轻量 workload• 高吞吐、实时响应• 分类、快速 Q&A• Edge 或 embedded applicationsGemini 3 Flash、Claude Haiku 4.5、GPT-5 nano
Efficient / everyday• 通用生产力• 文本生成、总结• Chatbots 和 support assistantsGemini 2.5 Flash、GPT-5 mini、GPT-4.1
Flagship• 复杂或创造性任务• 深度分析和结构化推理• 高级代码生成• 面向客户的自动化Gemini 3 Pro、GPT-5、Claude Sonnet 4.5
Reasoning / frontier• 多步推理和逻辑问题求解• 科学与数学任务• 长上下文规划或证明• 自主 agentic workflowsGPT-5、Claude Opus 4.5

使用 LLMs 时,成本是一个重要因素。商业 LLMs 会分别对 input 和 output tokens 收费。Output tokens 通常显著更贵,因为模型必须在考虑所有先前 tokens 的情况下,一个 token 一个 token 地生成。Input tokens 则是在一次 forward pass 中并行处理的。

选择提供商时,应比较不同供应商中相似 model tiers 的模型。例如,GPT-5 和 Gemini 3 Pro 都属于 flagship tier,而 GPT-5 mini 和 Gemini 3 Flash 则在 efficient tier 中竞争。同一 tier 内的价格差异通常是边际性的,而不同 tiers 之间的成本差异则非常显著。

图 2-3 展示了截至 2026 年 1 月,各 model tiers 的典型 input token price ranges:

Ultra-efficient

约每 100 万(1M)input tokens 0.05–0.20 美元

Efficient

约每 1M input tokens 0.25–0.60 美元

Flagship

约每 1M input tokens 1–5 美元

Reasoning / frontier

约每 1M input tokens 2–30 美元

image.png

图 2-3:LLM model pricing comparison——各模型层级的 input token costs(2026 年 1 月)

Discussion

Model selection 需要在 cost、latency 和 accuracy 之间取得平衡。你的目标是为每个 pipeline step 选择仍能满足需求的最小模型。

先从 latency constraints 开始。实时 chatbots 需要在数秒内响应。除非答案提供特别高的价值,否则用户很少愿意等待超过 10 秒。对于标准 chatbot 交互,如果问题直接、context 可控,通常是三到四个 retrieved chunks,ultra-efficient 或 efficient models 往往可以提供足够质量,同时响应速度比强大模型更快。在这些场景中,大模型提供的额外价值不足以证明增加的延迟是合理的。

Batch jobs 可以容忍更长 latency,可以运行数分钟或数小时,因此更高准确率可能 justify 使用更慢、更昂贵的模型。一个审查复杂合同的 pipeline,如果稍微更好的 extraction quality 能避免昂贵错误,就可以节省大量资金,因此 reasoning models 值得额外成本。像提取合同双方或到期日期这样的简单任务,则适合使用 cost-efficient models。

不要把大型 reasoning models 用在 efficient models 已经能可靠处理的简单分类或抽取任务上。应在每个 tier 上测试;你可能会发现 ultra-efficient models 可以处理 80% 的 queries,只把昂贵模型保留给模糊案例。

TIP

对于复杂 workflows,把任务拆成更小步骤,并为每一步选择合适模型。这样可以用 efficient models 解决多步问题,因为每次调用只处理一个定义清晰的任务,而不是要求模型跨整个 workflow 推理。

See Also

OpenAI model selection guide 根据任务复杂度和成本,为选择 GPT models 提供结构化标准。

Arena leaderboard 根据 side-by-side 比较中的 blind user preference votes 对语言模型排序。

2.3 使用 OpenAI API 生成内容

Problem

你想使用 OpenAI 远程托管的 LLMs 来分析和生成内容,而不想自己部署和运维模型。

Solution

OpenAI 在托管基础设施上托管模型,并通过 API endpoints 暴露它们。这使你可以用最少设置使用强大的语言模型。

OpenAI 为不同任务画像提供 model families。GPT-5 等旗舰模型适合复杂推理任务,同时也有更小、更快的变体支持,例如 GPT-5 mini 和 GPT-5 nano。所有这些模型都可以处理文本和图像来生成 responses。

图 2-4 展示了主要 GPT model series 的发布情况。

image.png

图 2-4:OpenAI GPT model series

你可以在 OpenAI 账户设置中找到 API key。搜索 “OpenAI API key” 创建新的 key。

将 key 存储在名为 OPENAI_API_KEY 的 environment variable 中。这是 OpenAI SDK 默认加载 API key 的位置。按如下方式安装 dependencies:

pip install openai httpx

NOTE

如果你在一家 Microsoft Azure 使用很深的大公司工作,你可能不会直接使用 OpenAI public API。相反,你可以通过 Microsoft 的 Azure OpenAI service 访问相同的 OpenAI models。Azure 在 Azure 生态内托管 GPT-5、GPT-5 mini、GPT-5 nano 和 text-embedding-3-small 等模型。

与 OpenAI models 通信遵循一个简单模式。首先,你创建一个连接 OpenAI servers 的 client。然后发送带有 prompt 的 messages,并接收包含生成文本的 response。

每条 message 包含两个 required fields。role 字段表示谁在说话,例如 system、user 或 assistant。content 字段包含实际消息文本。

下面的代码片段展示了 message dictionary 的样子。你可以添加额外 key-value pairs,但 rolecontent 是必需的:

{
  "role": "user",
  "content": "What is RAG?"
}

现在可以看一个完整示例。你会把 messages 作为 dictionary list 发送。第一项通常是 system message,随后是第一个 user message。Prompt 发送后,模型生成 response,该 response 会追加到 message list 中:

from openai import OpenAI

def ask_with_context(context, question):
    client = OpenAI()

    messages = [
        {
            "role": "system",
            "content": "Answer based only on the provided context."
        },
        {
            "role": "user",
            "content": f"Context:\n{context}\n\nQuestion:\n{question}"
        },
    ]

    response = client.chat.completions.create(
        model="gpt-5.2",
        messages=messages
    )

    return response.choices[0].message.content


# Usage
context = "RAG stands for Retrieval-Augmented Generation."
question = "What does RAG stand for?"
answer = ask_with_context(context, question)
print(answer)

除了 GPT models,OpenAI 还提供 speech-to-text 和 video generation models。当你需要在 indexing 前转录音频录音、会议记录或客服电话时,speech-to-text 与 RAG 很相关。

要转录音频,你上传一个 audio file,并获得 transcript 作为返回结果。你可以使用 LJ Speech Dataset 中任意文件作为示例。LJ Speech 是一个包含单个说话人朗读各种句子的音频录音集合。这个示例使用 gpt-4o-transcribe endpoint 转录音频:

import httpx
from openai import OpenAI

client = OpenAI()

with open(
    "..\datasets\audio_files\LJ037-0171.wav",
    "rb",
) as audio_file:
    transcript = client.audio.transcriptions.create(
        model="gpt-4o-transcribe",
        file=audio_file,
    )

print(transcript.text)

Discussion

使用托管 foundation models 所需设置很少:设置 API key 和 HTTP client,就可以生成文本。当你对 cost、context windows 或 regulatory requirements 有特定约束时,provider 的选择会很重要。

OpenAI 的 rate limits 和 throughput 通常高于竞争对手,适合高吞吐生产部署。当你需要更长 context windows、更便宜的高吞吐推理,或特定 multimodal capabilities 时,可以切换到 Google 或 Anthropic。

GPT-5 可以处理复杂推理、structured outputs 和 tool use。对于 latency-sensitive workloads,如果速度比最大推理深度更重要,可以考虑 GPT-4.1 或 GPT-5 mini 等更小变体。GPT-4.1 针对低延迟和高吞吐优化,因此更适合实时聊天和客户支持。

如果你所在公司有严格 cybersecurity requirements,并且已经使用 Azure,那么可以使用 Azure OpenAI services 在 Azure context 中处理数据,而不让 OpenAI 捕获数据用于其自身平台。

TIP

选择 provider 时,应关注 model capabilities 和 context window requirements,而不是 pricing。虽然不同 model tiers 之间的成本差异可能很大,从 ultra-efficient 到 reasoning models,每 1M input tokens 的价格可从 0.05 到 30 美元不等,但同一 tier 内不同 providers 之间的价格差异通常是边际性的。为 use case 选择正确 model tier 的影响,远大于基于小幅价格差异在 OpenAI、Google 或 Anthropic 之间选择。

See Also

OpenAI Chat API reference 记录了 request 和 response format,包括 streaming、function calling 和 parameter options。

OpenAI embeddings guide 解释了如何在 RAG systems 中使用 embedding models 进行 similarity search 和 retrieval。

2.4 使用 Google Gemini Models 生成内容

Problem

你想使用 Google 的 Gemini models 来生成和分析文本与图像。

Solution

Google 已经让自己的 API 与 OpenAI client library conventions 对齐,因此你可以复用同一个 SDK。你只需要修改 base URL,使 client 将 requests 发送到 Google 的 generative language endpoint,而不是 OpenAI 的 endpoint。

图 2-5 展示了迄今为止主要 Gemini model releases。

image.png

图 2-5:Google Gemini model timeline

安装 OpenAI client library:

pip install openai

要使用 Gemini,你需要从 Google AI Studio 获取 API key。点击几下即可创建 key,并将其存储在名为 GOOGLE_API_KEY 的 environment variable 中。下面示例会从该变量读取 key。

接下来,创建一个连接 Google 而非 OpenAI 的 OpenAI client。其结构与使用 OpenAI model 完全相同。唯一差异是创建 client 时定义的 base URL:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("GOOGLE_API_KEY"),
    base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
)

resp = client.chat.completions.create(
    model="gemini-3-flash",
    messages=[
        {"role": "user", "content": "What is the capital of France?"}
    ],
)

print(resp.choices[0].message.content)

一旦这个例子运行成功,你可以通过替换 model name 切换到其他 Gemini models。

Discussion

截至 2026 年初,Gemini models 是可用模型中最强的选择之一,尤其适合多模态任务。它们可以在同一条 reasoning chain 中解释文本、图像、图表和截图,并处理非常大的文档。Gemini 2.5 Pro 支持约 100 万 tokens 的 context windows,并被设计用于跨文本、音频、图像、视频,甚至 source code repositories 的长上下文推理。

对于日常 workloads,Gemini 2.5 Flash 和 Gemini 2.5 Flash-Lite 等较小模型提供类似多模态能力,但成本更低、速度更快,因此对许多 RAG pipelines 来说是很强选择。

实践中,Gemini 可以作为 OpenAI models 的 drop-in replacement。今天选择 Gemini,尤其是 Gemini 2.5 Pro,的主要理由,是它强大的多模态表现和稳健的 long-context handling。当处理超过 100,000 tokens 的文档,或需要在单次 request 中组合图像、音频和文本时,可以选择 Gemini 而不是 OpenAI。

对于 low-latency、short-context interactions,例如 chat、RAG retrieval steps 和 agent loops,OpenAI models 通常比 Gemini 更快给出 time-to-first-token。Gemini 的架构针对 long-context 和 multimodal workloads 优化,这可能为小 requests 带来额外 overhead。

TIP

使用 Gemini 2.5 Pro 处理强多模态推理或超长上下文;使用 Gemini 2.5 Flash 或 Flash-Lite 处理成本敏感、高吞吐 RAG pipelines。

See Also

Gemini API Quickstart guide 展示了如何直接使用 Google 的 Gemini SDK,包括 model selection、text generation 和 multimodal inputs。

Gemini model documentation 列出了可用模型、能力、context windows 和各变体 pricing。

2.5 使用 Anthropic API 生成内容

Problem

你想使用 Anthropic 的 Claude models 来分析内容并生成文本。

Solution

Anthropic 提供了 OpenAI 和 Google 之外的强大替代方案,尤其适合你需要精确推理、可靠编码支持或数学上准确输出的场景。

图 2-6 展示了已经发布的主要 Claude models。

image.png

图 2-6:Anthropic Claude model release timeline

要使用 Anthropic API,需要在 Anthropic 网站创建账户并生成 API key。你可以在 Claude Console 的 API section 中生成 key。需要购买少量 credits。通常 5 美元就足以运行本书中的示例。将 key 存储为名为 ANTHROPIC_API_KEY 的 environment variable,这样 Anthropic SDK 就可以找到它。

Google 提供 OpenAI-compatible endpoint,而 Anthropic 使用自己的 protocol,并不匹配 OpenAI SDK 预期。因此,你需要使用 Anthropic SDK,可以按如下方式安装:

pip install anthropic

使用官方 Anthropic Python SDK 与 Claude models 交互。在这个示例中,你会使用简单 request-response flow 发送 prompt 并取回生成文本。在 RAG 设置中,这个调用通常位于 retrieval step 之后,也就是 retrieved documents 被注入 user message 的位置。

我们使用 messages.create 方法,这是与 Claude models 通信的标准接口。模型会在 content 字段中返回 response:

from anthropic import Anthropic
import os

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

response = client.messages.create(
    model="claude-sonnet-4.5",
    max_tokens=200,
    messages=[
        {
            "role": "user",
            "content": "Explain how vector databases work in "
                       "simple terms.",
        }
    ],
)

print(response.content[0].text)

Discussion

Claude models 强调 explicit reasoning 和 edge-case handling。实践中,Claude 倾向于生成更长解释,并明确指出 ambiguities,而不是直接选择一个看似合理的答案。这种行为使 Claude 适合那些 conservative reasoning 比速度更重要的任务。

当 explicit edge-case handling 很重要时,可以选择 Claude;legal document review、compliance analysis 和 code generation 都能从这种方法中受益。Claude 的 extended thinking capability 也有助于处理复杂数学推理和多步逻辑问题。

不要把 Claude 用于用户期待对简单 queries 立即响应的高吞吐 chatbots,或需要尽可能快 inference 的 batch jobs。Claude 的审慎推理是在用速度换取彻底性。

Anthropic 提供不同尺寸的模型。Claude Haiku 能高效处理高容量 workloads。Claude Sonnet 提供强 all-around performance。Claude Opus 为复杂任务提供深度推理。这种结构与 OpenAI 和 Google 的 model families 类似。

See Also

Anthropic Messages API reference 提供 request / response format、streaming、tool use 和 system prompts 的完整文档。

Anthropic quickstart guide 是使用 Python SDK 实现 Claude API calls 的分步教程。

Anthropic prompt engineering guide 给出了为 Claude models 编写有效 prompts 的最佳实践。

2.6 使用 Ollama 在本地运行开源模型

Problem

你需要在本地运行语言模型,因为你的数据过于敏感,不能发送给外部 providers,或者因为在你的 API call volume 下 self-hosting 更具成本效益。

Solution

一种简单的私有运行模型方式是 Ollama。这个免费开源工具允许你直接在自己的机器上运行开源 LLMs。安装后,Ollama 会启动一个本地服务,其行为类似 OpenAI 和 Google 的远程 API endpoints。

在 Python 代码调用 Ollama 前,你需要两样东西:

  • 机器上已安装 Ollama runtime
  • 至少一个本地模型已下载并可用

Ollama 不是 Python package。它是一个系统工具,会在后台运行一个小型本地服务器。该服务器加载模型、执行 inference,并在 localhost:11434 暴露 API,供 Python 代码调用。

要安装 Ollama,请按照 Download Ollama 页面说明执行。macOS、Windows 和 Linux 都有安装程序。

安装 Ollama 后,你仍然需要下载想运行的模型。使用简单的 ollama pull 命令即可完成。这些命令会获取模型权重并存储到本地,使模型准备就绪。

在这个例子中,你会 pull 三个流行模型:Llama 2、Mistral 和 Code Llama。你也可以选择其他模型。完整列表可在 Ollama Models 网页中找到。代码如下:

# Pull models (run in terminal)
ollama pull llama2
ollama pull mistral
ollama pull codellama

一旦 Ollama 运行起来,就可以像调用其他 API 一样调用它。最简单的方法是复用前面用于 OpenAI 和 Gemini APIs 的 OpenAI SDK。Ollama 在 http://localhost:11434/v1 暴露一个 OpenAI-compatible endpoint,因此已有代码几乎不需要变化。

接下来,你会使用 OpenAI client 调用本地 Ollama 模型。创建一个指向本地 endpoint 而非 OpenAI servers 的 client,然后像之前一样发送 prompt。唯一不同的是 base_url 和 model name:

from openai import OpenAI

# Point the client to your local Ollama server
client = OpenAI(
    base_url="http://localhost:11434/v1",
    api_key="ollama",  # Ollama does not require a real key,
                       # but the SDK expects one
)

response = client.chat.completions.create(
    model="qwen3:4b",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {
            "role": "user",
            "content": "What is retrieval augmented generation?"
        },
    ],
)

print(response.choices[0].message.content)

这可以让你在不同 providers 之间保持代码结构一致。如果之后从 Ollama 切换到 OpenAI 或 Gemini,只需要修改 base_urlapi_key 值。

TIP

如果你不想使用 SDK,也可以用 curlrequests library 直接调用 Ollama:

curl http://localhost:11434/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama2",
    "messages": [
      {
        "role": "user",
        "content": "What is RAG?"
      }
    ]
  }'

当基础设置正常后,你可以尝试不同模型,比较它们的表现和行为。

下一个例子中,你会一次评估多个本地模型。代码遍历已安装 Ollama models 列表,向它们发送同一个 prompt,并收集答案。这能让你比较不同模型的质量、速度和一致性:

from openai import OpenAI

models = ["llama2", "mistral", "codellama"]
client = OpenAI(
    base_url="http://localhost:11434/v1",
    api_key="ollama"
)

for model in models:
    print(f"\n--- Testing {model} ---")
    response = client.chat.completions.create(
        model=model,
        messages=[
            {"role": "user", "content": "Explain RAG in one sentence."}
        ]
    )
    print(response.choices[0].message.content)

表 2-2 中列出了一些更流行的开源模型。

表 2-2:流行开源语言模型

Model(Developer)ReleaseParameter countPerformancePopularity
Llama 2(Meta AI)July 20237B、13B、70B70B chat model 的 MMLU 约 68.9%Very high
GPT OSS(OpenAI)August 202520B、120B接近 GPT-3.5 性能High
Mistral 7B(Mistral AI)September 20237B最强 7B 级开源模型Very high
Qwen 7B and 14B(Alibaba Cloud)September 20237B、14B多语言表现强High
Falcon 40B(TII)May 202340B早期开源 benchmark leaderStrong community interest

Discussion

Ollama 会处理模型下载,并在你的 CPU 或 GPU 上运行模型。本地运行模型有局限:如果没有强 GPU 或专用 inference hardware,你的笔记本只能处理较小模型,即使这些模型响应速度也会明显慢于 API calls。对于 privacy-sensitive workflows,这种取舍通常可以接受。

70 billion(70B)参数级别的大模型,例如 Llama 3.1 70B,对大多数笔记本来说通常太大。更现实的选择是 Llama 3.1 8B 或类似 midsize models。它们质量不错,同时硬件要求可控。预计 8B 模型至少需要 8 GB virtual random access memory(VRAM);13B 模型需要 16 GB 或更多。

当你处理不能离开网络的受监管健康或金融数据,或者每月有数百万 API calls,且 hosting costs 低于 API fees 时,可以在自己硬件上运行模型。

如果 use case 需要最新推理能力,或者开发速度比成本更重要,不要使用本地模型。本地模型设置、fine-tuning 和维护会消耗工程时间,而这些时间本可以投入到应用功能上。

See Also

Ollama documentation 覆盖 installation、model management 和用于运行 open-weight models 的 local API。

Ollama model library 列出了支持模型,以及每个模型变体的 pull commands 和 hardware requirements。

Open LLM Leaderboard 提供标准化 benchmark scores,用于比较 open-weight language models。

WARNING

应把 public leaderboards 当作筛选工具,而不是最终决策标准。常见限制包括:

Benchmark leakage or data contamination

一些 benchmark 问题和答案是公开可用的,可能已经直接或间接被包含在训练数据中,从而夸大分数。

Goodhart’s law or over-optimization

一旦 benchmark 成为目标,模型开发者可能专门针对该 benchmark 调优,提高分数,但不提高通用实用性。

Mismatch with real-world usage

你的生产设置,包括 prompt templates、retrieval quality、tool use、long context、多语言内容、quantization 和 latency constraints,都可能实质性改变结果。某个模型在 leaderboard 上“赢了”,仍然可能在你的 RAG queries 上表现更差。

2.7 使用 OpenAI SDK 和 Pydantic 创建结构化输出

Problem

你想从文本和图像中提取洞察,同时确保 LLM 和多模态模型输出符合预定义 schema,并拥有正确数据类型。

Solution

OpenAI SDK 允许你使用 Pydantic model 定义 response schema。这个 schema 描述模型应返回的字段及其数据类型。你不需要处理 raw JSON,SDK 会验证模型输出,并返回一个 typed Python object。

图 2-7 展示了一个简单的多模态发票分析流程。模型会提取 invoice date、supplier、receiver、line items、currency 和 total value。Pydantic model 描述这些字段,并强制执行预期数据类型。

image.png

图 2-7:使用 Pydantic models 的结构化输出

要使用 structured outputs,需要安装 OpenAI SDK 和 Pydantic:

pip install openai pydantic

首先定义你希望模型填充的结构。在这个示例中,你使用 Pydantic 的 BaseModel 类定义用于 invoice extraction 的 Python objects,并包含 nested structures。这个类创建一个 LineItem 来表示发票上的单个条目,以及一个 Invoice 来表示包含多个 line items 的完整发票。每个 Pydantic model 都必须继承 BaseModel,因为它提供 automatic type validation 和 parsing methods,可以将 raw model output 转换为干净的 Python objects。代码如下:

# pip install openai pydantic

from openai import OpenAI
from pydantic import BaseModel
from datetime import date
from typing import List

class LineItem(BaseModel):
    description: str
    quantity: int
    total: float

class Invoice(BaseModel):
    invoice_number: str
    invoice_date: date
    supplier: str
    items: List[LineItem]
    total_due: float

结构定义完成后,下一步是要求模型填充它。你把 invoice image 和 instructions 一起发送给 OpenAI endpoint,OpenAI SDK 会返回一个已解析的 Invoice object,并且已经通过 type validation:

result = client.responses.parse(
    model="gpt-5-mini",
    input=[{
        "role": "user",
        "content": [
            {"type": "input_text", "text": "Extract the invoice data."},
            {"type": "input_image", "image_url": "invoice.png"},
        ],
    }],
    response_format=Invoice,
)

invoice: Invoice = result.output_parsed
print(invoice)

结果是一个经过验证的 Invoice object。因为数据已经具有正确类型,你可以直接将其存入数据库,或传递给下游 workflow steps,而无需额外 parsing 或手工检查。

Discussion

Structured outputs 会在 inference time 强制 schema,确保模型返回经过验证的字段,而不是非结构化文本。之所以能做到,是因为 API 会约束模型生成,使其只生成符合 Pydantic schema 的有效 JSON。典型 use cases 包括:

  • 从 sales system 的 emails 中提取 contract details
  • 自动解析 invoices 或 order confirmations
  • 从 technical drawings 中读取 metadata,以一致方式标注它们
  • 在 automated workflows 中做决策,并要求输出被限制在特定 value ranges 中

Pydantic validation 会在 type mismatches 或 missing fields 传播到下游前捕获它们,使失败立即可见,而不是让错误值悄悄流入系统。

当 downstream systems 依赖这些数据时,应使用 structured outputs。Database inserts、API calls、decision logic 和 multistep agent workflows 都会从有保证的字段类型中受益。对于 exploratory chat、creative writing,或当你希望模型自行选择输出格式时,不要使用 structured outputs。

Structured outputs 会增加 latency,因为模型必须生成符合 schema 的有效 JSON。当 schema 与模型想解释的内容不匹配时,它也可能限制有用答案。强制 binary answer,而正确响应其实是 “it depends”,会损失细微差别。应测试你的 use case 是更受益于结构,还是更受益于灵活性。

See Also

Anthropic tool use documentation 解释了如何使用 Claude models 强制 JSON schemas,以生成 structured outputs。

Google Gemini JSON mode guide 描述了如何在 Gemini models 中启用 structured output support。