Instructor:给 LLM 一个 Pydantic 结构,让 JSON 输出永不翻车
📖 简介
📝 详细介绍
开篇
这篇教程带你用 Instructor 这个 Python 库,给 LLM 的 JSON 输出加上 Pydantic 结构校验,最终得到一个“输入一句话,返回结构化对象”的可运行 Demo——整个过程 15 分钟搞定。
前置条件
- Python 3.9+:Instructor 依赖 Pydantic v2,版本过低会直接报错
- OpenAI API Key:需要一个可用的 key(支持 OpenAI 兼容接口的本地模型也可以,但教程示例用官方 API)
pip:用于安装依赖包,确保能访问 PyPI- 网络连接:需能访问
api.openai.com(国内环境请提前配置代理)
安装部署
Step 1: 创建虚拟环境并安装依赖
mkdir instructor-demo && cd instructor-demo
python -m venv venv
source venv/bin/activate # Windows 用 venvScriptsactivate
pip install instructor openai pydantic
这里把 instructor、openai、pydantic 一起装上。如果你已有 openai 的旧版本(v0.x),务必修到 v1.x 以上。
Step 2: 设置 API Key
export OPENAI_API_KEY="sk-你的key" # Windows 用 set OPENAI_API_KEY=sk-你的key
建议用环境变量而不是写死在代码里,防止把 key 提交到 Git。
Step 3: 验证安装
python -c "import instructor; print(instructor.__version__)"
能打印出版本号就说明安装成功。下面进入正题。
第一个 Demo
我们的目标:从一段自然语言描述中提取人名和年龄,并强制返回 User 类型的 Pydantic 对象。
Step 1: 定义 Pydantic 结构
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
这是最基础的 Pydantic 模型,声明了字段类型。age 必须是整数,否则后续会抛出校验错误。
Step 2: 创建 Instructor 客户端
import instructor
from openai import OpenAI
client = instructor.from_openai(OpenAI())
instructor.from_openai() 会把标准 OpenAIClient 包装成支持结构化输出的客户端。这是整个库的核心入口。
Step 3: 调用模型并解析
user = client.chat.completions.create(
model="gpt-3.5-turbo",
response_model=User,
messages=[
{"role": "user", "content": "张三今年25岁,是一名程序员"},
],
)
print(type(user)) # <class '__main__.User'>
print(user.name) # 张三
print(user.age) # 25
注意:response_model 是关键参数,它告诉 Instructor 要按哪个模型结构返回。返回值不再是普通的 JSON 字符串,而是直接实例化好的 User 对象。
Step 4: 预期输出验证
<class '__main__.User'>
张三
25
如果你看到这三行,说明 Demo 已经跑通了。LLM 输出的原始字符串已经自动被解析为结构化的 Pydantic 对象。
配置与调优
1. 调整重试次数
client = instructor.from_openai(OpenAI(), max_retries=3)
默认是 1 次重试。当 LLM 返回的字段不符合 Pydantic 校验时,Instructor 会自动把错误信息回传给模型并要求重试。调大 max_retries 能提升成功率高,但会增加延迟。
2. 使用更聪明的模型
user = client.chat.completions.create(
model="gpt-4o-mini",
response_model=User,
messages=[{"role": "user", "content": "张三今年25岁"}],
)
复杂结构建议用 gpt-4o-mini 或更新模型。它们对 JSON Schema 的理解更准确,第一次就能通过校验的概率更高。
3. 让字段变成可选
from typing import Optional
class User(BaseModel):
name: str
age: Optional[int] = None
当原文没提供年龄时,用 Optional 避免校验失败。更适合处理非结构化程度高的文本。
常见坑与排错
| 报错信息 | 原因 | 解决办法 |
|---|---|---|
ModuleNotFoundError: No module named 'openai' |
未安装 openai 依赖 | 执行 pip install openai |
ResponseValidationError: role=value_error |
LLM 返回的字段类型与 Pydantic 模型不匹配(如 "25岁" 被识别为字符串) | 检查模型定义,必要时用更明确的提示词,或给字段加别名 |
APIConnectionError: Error communicating with OpenAI |
网络无法访问 OpenAI 接口 | 配置代理(环境变量 HTTPS_PROXY)或切换网络 |
AttributeError: 'ChatCompletion' object has no attribute 'name' |
直接用了原生 OpenAI 客户端,未经过 Instructor 包装 | 确认调用的是 client.chat.completions.create 而非 openai.chat.completions.create |
下一步
到这里你已经能跑通 Instructor 的核心工作流。进阶方向有三条:
- 数据验证增强:在 Pydantic 模型中加入
@field_validator自定义校验规则,让返回数据自动满足业务约束 - 流式输出:Instructor 支持流式解析(
stream=True),适合处理长文本生成,体验类似 ChatGPT 打字机效果 - 嵌套模型:试试用嵌套 Pydantic 模型表达复杂结构(如订单包含多个商品),Instructor 会自动生成嵌套的 JSON Schema
AI 项目推荐
大模型- 标签
- #结构化输出 #Pydantic #LLM #数据提取
- 浏览
- 👁️ 13
- 发布日期
- 2026-08-30