使用 Instructor 和 OpenAI 实现结构化输出,完整指南¶
OpenAI 是 Instructor 的主要集成,为 GPT-3.5、GPT-4 及未来的模型提供强大的结构化输出支持。本指南涵盖了使用 Instructor 与 OpenAI 实现类型安全、经过验证的响应所需的一切信息。
快速开始¶
Instructor 开箱即用支持 OpenAI,您无需额外安装任何东西。
⚠️ 重要:在使用客户端之前,必须设置您的 OpenAI API 密钥。您可以通过两种方式进行设置:
- 设置环境变量
- 或者直接提供给客户端
简单用户示例 (同步)¶
import os
from openai import OpenAI
import instructor
from pydantic import BaseModel
# Initialize with API key
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
# Enable instructor patches for OpenAI client
client = instructor.from_openai(client)
class User(BaseModel):
name: str
age: int
# Create structured output
user = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "Extract: Jason is 25 years old"},
],
response_model=User,
)
print(user)
#> User(name='Jason', age=25)
简单用户示例 (异步)¶
import os
from openai import AsyncOpenAI
import instructor
from pydantic import BaseModel
import asyncio
# Initialize with API key
client = AsyncOpenAI(api_key=os.getenv('OPENAI_API_KEY'))
# Enable instructor patches for async OpenAI client
client = instructor.from_openai(client)
class User(BaseModel):
name: str
age: int
async def extract_user():
user = await client.chat.completions.create(
model="gpt-4-turbo-preview",
messages=[
{"role": "user", "content": "Extract: Jason is 25 years old"},
],
response_model=User,
)
return user
# Run async function
user = asyncio.run(extract_user())
print(user)
#> User(name='Jason', age=25)
嵌套示例¶
from pydantic import BaseModel
from typing import List
import os
from openai import OpenAI
import instructor
from pydantic import BaseModel
class Address(BaseModel):
street: str
city: str
country: str
class User(BaseModel):
name: str
age: int
addresses: List[Address]
# Initialize with API key
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
# Enable instructor patches for OpenAI client
client = instructor.from_openai(client)
# Create structured output with nested objects
user = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": """
Extract: Jason is 25 years old.
He lives at 123 Main St, New York, USA
and has a summer house at 456 Beach Rd, Miami, USA
"""},
],
response_model=User,
)
print(user)
#> {
#> 'name': 'Jason',
#> 'age': 25,
#> 'addresses': [
#> {
#> 'street': '123 Main St',
#> 'city': 'New York',
#> 'country': 'USA'
#> },
#> {
#> 'street': '456 Beach Rd',
#> 'city': 'Miami',
#> 'country': 'USA'
#> }
#> ]
#> }
多模态¶
我们提供了一些不同的示例文件供您测试这些新功能。以下所有示例均使用这些文件。
- (音频) : 林肯葛底斯堡演说录音 : gettysburg.wav
- (图片) : 一张蓝莓植物的图片 image.jpg
- (PDF) : 一个包含虚假发票的示例 PDF 文件 invoice.pdf
Instructor 提供了一个统一的、与提供商无关的接口,用于处理图像、PDF 和音频文件等多模态输入。使用 Instructor 的多模态对象,您可以使用一致的 API 从 URL、本地文件或 base64 字符串轻松加载媒体,该 API 适用于不同的 AI 提供商(OpenAI、Anthropic、Mistral 等)。
Instructor 在幕后处理所有提供商特定的格式要求,确保您的代码随着提供商 API 的演进保持整洁和面向未来。
让我们看看如何使用 Image、Audio 和 PDF 类。
图像¶
有关 Image 组件更深入的介绍,请查看此处的文档
Instructor 使使用 OpenAI 的 GPT-4o 模型分析和提取图像中的语义信息变得容易。点击此处查看您想使用的模型是否具有视觉能力。
让我们看一个使用上面示例图像的例子,我们将使用 from_url
方法加载它。
请注意,我们也支持使用 from_path
和 from_base64
类方法加载本地文件和 base64 字符串。
from instructor.multimodal import Image
from pydantic import BaseModel, Field
import instructor
from openai import OpenAI
class ImageDescription(BaseModel):
objects: list[str] = Field(..., description="The objects in the image")
scene: str = Field(..., description="The scene of the image")
colors: list[str] = Field(..., description="The colors in the image")
client = instructor.from_openai(OpenAI())
url = "https://raw.githubusercontent.com/instructor-ai/instructor/main/tests/assets/image.jpg"
# Multiple ways to load an image:
response = client.chat.completions.create(
model="gpt-4o-mini",
response_model=ImageDescription,
messages=[
{
"role": "user",
"content": [
"What is in this image?",
# Option 1: Direct URL with autodetection
Image.from_url(url),
# Option 2: Local file
# Image.from_path("path/to/local/image.jpg")
# Option 3: Base64 string
# Image.from_base64("base64_encoded_string_here")
# Option 4: Autodetect
# Image.autodetect(<url|path|base64>)
],
},
],
)
print(response)
# Example output:
# ImageDescription(
# objects=['blueberries', 'leaves'],
# scene='A blueberry bush with clusters of ripe blueberries and some unripe ones against a cloudy sky',
# colors=['green', 'blue', 'purple', 'white']
# )
PDF¶
Instructor 使使用 OpenAI 的 GPT-4o 模型分析和提取 PDF 中的语义信息变得容易。
让我们看一个使用上面示例 PDF 的例子,我们将使用 from_url
方法加载它。
请注意,我们也支持使用 from_path
和 from_base64
类方法加载本地文件和 base64 字符串。
from instructor.multimodal import PDF
from pydantic import BaseModel, Field
import instructor
from openai import OpenAI
class Receipt(BaseModel):
total: int
items: list[str]
client = instructor.from_openai(OpenAI())
url = "https://raw.githubusercontent.com/instructor-ai/instructor/main/tests/assets/invoice.pdf"
# Multiple ways to load an PDF:
response = client.chat.completions.create(
model="gpt-4o-mini",
response_model=Receipt,
messages=[
{
"role": "user",
"content": [
"Extract out the total and line items from the invoice",
# Option 1: Direct URL
PDF.from_url(url),
# Option 2: Local file
# PDF.from_path("path/to/local/invoice.pdf"),
# Option 3: Base64 string
# PDF.from_base64("base64_encoded_string_here")
# Option 4: Autodetect
# PDF.autodetect(<url|path|base64>)
],
},
],
)
print(response)
# > Receipt(total=220, items=['English Tea', 'Tofu'])
音频¶
Instructor 使使用 OpenAI 的 GPT-4o 模型分析和提取音频文件中的语义信息变得容易。让我们看一个使用上面示例音频文件的例子,我们将使用 from_url
方法加载它。
请注意,我们也支持使用 from_path
加载本地文件和 base64 字符串。
from instructor.multimodal import Audio
from pydantic import BaseModel
import instructor
from openai import OpenAI
class AudioDescription(BaseModel):
transcript: str
summary: str
speakers: list[str]
key_points: list[str]
url = "https://raw.githubusercontent.com/instructor-ai/instructor/main/tests/assets/gettysburg.wav"
client = instructor.from_openai(OpenAI())
response = client.chat.completions.create(
model="gpt-4o-audio-preview",
response_model=AudioDescription,
modalities=["text"],
audio={"voice": "alloy", "format": "wav"},
messages=[
{
"role": "user",
"content": [
"Please transcribe and analyze this audio:",
# Multiple loading options:
Audio.from_url(url),
# Option 2: Local file
# Audio.from_path("path/to/local/audio.mp3")
],
},
],
)
print(response)
# > transcript='Four score and seven years ago our fathers..."]
流式支持¶
Instructor 提供两种主要方式来流式输出响应
- 可迭代对象 (Iterables):当您想流式传输同一类型的对象列表时,这些对象非常有用(例如,使用结构化输出提取多个用户)
- 局部流式传输 (Partial Streaming):当您想流式传输单个对象并希望在响应传入时立即开始处理时,这非常有用。
局部解析¶
from instructor import from_openai
import openai
from pydantic import BaseModel
client = from_openai(openai.OpenAI())
class User(BaseModel):
name: str
age: int
bio: str
user = client.chat.completions.create_partial(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "Create a user profile for Jason, age 25"},
],
response_model=User,
)
for user_partial in user:
print(user_partial)
# > name='Jason' age=None bio='None'
# > name='Jason' age=25 bio='A tech'
# > name='Jason' age=25 bio='A tech enthusiast'
# > name='Jason' age=25 bio='A tech enthusiast who loves coding, gaming, and exploring new'
# > name='Jason' age=25 bio='A tech enthusiast who loves coding, gaming, and exploring new technologies'
可迭代示例¶
import os
from openai import OpenAI
import instructor
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
# Extract multiple users from text
users = client.chat.completions.create_iterable(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": """
Extract users:
1. Jason is 25 years old
2. Sarah is 30 years old
3. Mike is 28 years old
"""},
],
response_model=User,
)
for user in users:
print(user)
#> name='Jason' age=25
#> name='Sarah' age=30
#> name='Mike' age=28
Instructor 模式¶
我们提供了几种模式,以便轻松使用 OpenAI 支持的不同响应模型
instructor.Mode.TOOLS
: 这使用工具调用 API 向客户端返回结构化输出instructor.Mode.JSON
: 这通过使用OpenAI 的 JSON 模式强制模型返回 JSON。instructor.Mode.FUNCTIONS
: 这使用 OpenAI 的函数调用 API 返回结构化输出,将来将被弃用。instructor.Mode.PARALLEL_TOOLS
: 这使用并行工具调用 API 向客户端返回结构化输出。这允许模型在单个响应中生成多个调用。instructor.Mode.MD_JSON
: 这对 OpenAI 聊天完成 API 进行简单调用,并将原始响应解析为 JSON。instructor.Mode.TOOLS_STRICT
: 这使用新的 OpenAI 结构化输出 API,通过受限语法采样向客户端返回结构化输出。这限制用户只能使用 JSON schema 的一个子集。instructor.Mode.JSON_O1
: 这是O1
模型的一种模式。我们创建了一个新模式,因为O1
不支持任何系统消息、工具调用或流式传输,因此您需要使用此模式才能将 Instructor 与O1
一起使用。
总的来说,我们建议使用 Mode.Tools
,因为它最灵活且面向未来。它拥有一组最大的特性集,您可以在其中指定 schema,并且使工作变得显著容易。
批量 API¶
我们也支持使用 create_batch
方法批量处理请求。如果您的请求对时间不敏感,这很有帮助,因为您可以获得 50% 的 token 成本折扣。
最佳实践¶
-
模型选择 : 对于更简单的用例,我们建议使用 gpt-4o-mini,因为它便宜且非常适合结构化输出的明确目标。当任务更模糊时,请考虑根据您的需求升级到
4o
甚至O1
-
性能优化 : 流式处理响应模型更快,应该从一开始就这样做。如果您使用简单的响应模型,尤其如此。
常见用例¶
- 数据提取
- 表单解析
- API 响应结构化
- 文档分析
- 配置生成
相关资源¶
更新与兼容性¶
Instructor 与最新的 OpenAI API 版本和模型保持兼容。查看变更日志以获取更新。