关于 instructor
此技能介绍如何用 Instructor 将大模型响应转为类型明确、经过验证的结构化数据。开发者可定义 Pydantic 模式、重试无效输出、流式接收部分结果,并通过统一 API 使用不同提供方。
主要功能
- 01Pydantic 模式验证
- 02无效输出自动重试
- 03部分结果流式传输
- 04嵌套及可选字段类型支持
- 05跨提供方统一 API
适用场景
- 01从文本中提取记录
- 02按模式验证生成的 JSON
- 03实时流式接收结构化结果
- 04处理无效的提取响应
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ kalarislabs/ research-agent-skills --skill instructor安装后在 Claude Code 中输入/instructor确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/advanced-features.mdcommon-patterns.mderror-handling.mdexamples.mdprovider-configuration.mdproviders.mdvalidation.md详细介绍
Instructor:结构化 LLM 输出
何时使用此技能
在以下情况下使用 Instructor:
- 从 LLM 响应中可靠地提取结构化数据
- 根据 Pydantic schema 自动验证输出
- 自动处理错误并重试提取失败的操作
- 以类型安全和验证机制解析复杂 JSON
- 流式传输部分结果,以便实时处理
- 通过一致的 API 支持多个 LLM 提供商
安装
# Base installation
pip install instructor
# With specific providers
pip install "instructor[anthropic]" # Anthropic Claude
pip install "instructor[openai]" # OpenAI
pip install "instructor[all]" # All providers
快速入门
基本示例:提取用户数据
import instructor
from pydantic import BaseModel
from anthropic import Anthropic
# Define output structure
class User(BaseModel):
name: str
age: int
email: str
# Create instructor client
client = instructor.from_anthropic(Anthropic())
# Extract structured data
user = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "John Doe is 30 years old. His email is [email protected]"
}],
response_model=User
)
print(user.name) # "John Doe"
print(user.age) # 30
print(user.email) # "[email protected]"
使用 OpenAI
from openai import OpenAI
client = instructor.from_openai(OpenAI())
user = client.chat.completions.create(
model="gpt-4o-mini",
response_model=User,
messages=[{"role": "user", "content": "Extract: Alice, 25, [email protected]"}]
)
核心概念
1. 响应模型(Pydantic)
响应模型定义 LLM 输出的结构和验证规则。
基本模型
from pydantic import BaseModel, Field
class Article(BaseModel):
title: str = Field(description="Article title")
author: str = Field(description="Author name")
word_count: int = Field(description="Number of words", gt=0)
tags: list[str] = Field(description="List of relevant tags")
article = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "Analyze this article: [article text]"
}],
response_model=Article
)
优点:
- 使用 Python 类型提示确保类型安全
- 自动验证(word_count > 0)
- 使用 Field 描述实现自文档化
- 支持 IDE 自动补全
嵌套模型
class Address(BaseModel):
street: str
city: str
country: str
class Person(BaseModel):
name: str
age: int
address: Address # Nested model
person = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "John lives at 123 Main St, Boston, USA"
}],
response_model=Person
)
print(person.address.city) # "Boston"
可选字段
from typing import Optional
class Product(BaseModel):
name: str
price: float
discount: Optional[float] = None # Optional
description: str = Field(default="No description") # Default value
# LLM doesn't need to provide discount or description
使用枚举设置约束
from enum import Enum
class Sentiment(str, Enum):
POSITIVE = "positive"
NEGATIVE = "negative"
NEUTRAL = "neutral"
class Review(BaseModel):
text: str
sentiment: Sentiment # Only these 3 values allowed
review = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "This product is amazing!"
}],
response_model=Review
)
print(review.sentiment) # Sentiment.POSITIVE
2. 验证
Pydantic 会自动验证 LLM 输出。如果验证失败,Instructor 会重试。
内置验证器
from pydantic import Field, EmailStr, HttpUrl
class Contact(BaseModel):
name: str = Field(min_length=2, max_length=100)
age: int = Field(ge=0, le=120) # 0 <= age <= 120
email: EmailStr # Validates email format
website: HttpUrl # Validates URL format
# If LLM provides invalid data, Instructor retries automatically
自定义验证器
from pydantic import field_validator
class Event(BaseModel):
name: str
date: str
attendees: int
@field_validator('date')
def validate_date(cls, v):
"""Ensure date is in YYYY-MM-DD format."""
import re
if not re.match(r'\d{4}-\d{2}-\d{2}', v):
raise ValueError('Date must be YYYY-MM-DD format')
return v
@field_validator('attendees')
def validate_attendees(cls, v):
"""Ensure positive attendees."""
if v < 1:
raise ValueError('Must have at least 1 attendee')
return v
模型级验证
from pydantic import model_validator
class DateRange(BaseModel):
start_date: str
end_date: str
@model_validator(mode='after')
def check_dates(self):
"""Ensure end_date is after start_date."""
from datetime import datetime
start = datetime.strptime(self.start_date, '%Y-%m-%d')
end = datetime.strptime(self.end_date, '%Y-%m-%d')
if end < start:
raise ValueError('end_date must be after start_date')
return self
3. 自动重试
验证失败时,Instructor 会自动重试,并向 LLM 提供错误反馈。
# Retries up to 3 times if validation fails
user = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "Extract user from: John, age unknown"
}],
response_model=User,
max_retries=3 # Default is 3
)
# If age can't be extracted, Instructor tells the LLM:
# "Validation error: age - field required"
# LLM tries again with better extraction
工作原理:
- LLM 生成输出
- Pydantic 执行验证
- 如果无效:将错误消息发送回 LLM
- LLM 根据错误反馈重试
- 重复上述过程,最多达到 max_retries
4. 流式传输
流式传输部分结果,以便实时处理。
流式传输部分对象
from instructor import Partial
class Story(BaseModel):
title: str
content: str
tags: list[str]
# Stream partial updates as LLM generates
for partial_story in client.messages.create_partial(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "Write a short sci-fi story"
}],
response_model=Story
):
print(f"Title: {partial_story.title}")
print(f"Content so far: {partial_story.content[:100]}...")
# Update UI in real-time
流式传输可迭代对象
class Task(BaseModel):
title: str
priority: str
# Stream list items as they're generated
tasks = client.messages.create_iterable(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{
"role": "user",
"content": "Generate 10 project tasks"
}],
response_model=Task
)
for task in tasks:
print(f"- {task.title} ({task.priority})")
# Process each task as it arrives
提供商配置
详细信息、代码示例和参数表:references/provider-configuration.md。适用此步骤时请阅读。
常见模式
详细信息、代码示例和参数表:references/common-patterns.md。适用此步骤时请阅读。
高级功能
详细信息、代码示例和参数表:references/advanced-features.md。适用此步骤时请阅读。
错误处理
详细信息、代码示例和参数表:references/error-handling.md。适用此步骤时请阅读。
最佳实践
1. 清晰的字段描述
# ❌ Bad: Vague
class Product(BaseModel):
name: str
price: float
# ✅ Good: Descriptive
class Product(BaseModel):
name: str = Field(description="Product name from the text")
price: float = Field(description="Price in USD, without currency symbol")
2. 使用恰当的验证
# ✅ Good: Constrain values
class Rating(BaseModel):
score: int = Field(ge=1, le=5, description="Rating from 1 to 5 stars")
review: str = Field(min_length=10, description="Review text, at least 10 chars")
3. 在提示词中提供示例
messages = [{
"role": "user",
"content": """Extract person info from: "John, 30, engineer"
Example format:
{
"name": "John Doe",
"age": 30,
"occupation": "engineer"
}"""
}]
4. 对固定类别使用枚举
# ✅ Good: Enum ensures valid values
class Status(str, Enum):
PENDING = "pending"
APPROVED = "approved"
REJECTED = "rejected"
class Application(BaseModel):
status: Status # LLM must choose from enum
5. 妥善处理缺失数据
class PartialData(BaseModel):
required_field: str
optional_field: Optional[str] = None
default_field: str = "default_value"
# LLM only needs to provide required_field
与其他方案的比较
| 功能 | Instructor | 手动 JSON | LangChain | DSPy |
|---|---|---|---|---|
| 类型安全 | ✅ 是 | ❌ 否 | ⚠️ 部分支持 | ✅ 是 |
| 自动验证 | ✅ 是 | ❌ 否 | ❌ 否 | ⚠️ 有限支持 |
| 自动重试 | ✅ 是 | ❌ 否 | ❌ 否 | ✅ 是 |
| 流式传输 | ✅ 是 | ❌ 否 | ✅ 是 | ❌ 否 |
| 多提供商支持 | ✅ 是 | ⚠️ 手动处理 | ✅ 是 | ✅ 是 |
| 学习曲线 | 低 | 低 | 中 | 高 |
适合选择 Instructor 的情况:
- 需要结构化且经过验证的输出
- 希望获得类型安全和 IDE 支持
- 需要自动重试
- 正在构建数据提取系统
适合选择其他方案的情况:
- DSPy:需要优化提示词
- LangChain:正在构建复杂链
- 手动处理:简单的一次性提取
资源
- 文档:https://python.useinstructor.com
- GitHub:https://github.com/jxnl/instructor
- 示例集:https://python.useinstructor.com/examples
- Discord:可获取社区支持
另请参阅
references/validation.md- 高级验证模式references/providers.md- 提供商专属配置references/examples.md- 实际应用案例
Agent 操作流程
- 检查环境。 确认框架版本、模型提供商、API 密钥和速率限制。
- 明确输入。 根据数据或用户确认格式、标识符和参数。任何会影响结果的值都不要猜测,应先询问。
- 先运行小规模版本。 使用已知输入测试单次调用或调用链,并检查原始输出。
- 使用以上说明和参考资料执行完整任务。
- 验证结果。 在小型标注数据集上评估;根据架构检查结构化输出;记录提示词和响应。
- 报告。 说明运行了什么(版本、命令、参数)、检查了什么,以及还有哪些不确定之处。
| 如果发生这种情况 | 请这样做 |
|---|---|
| 输出与预期架构不符 | 添加验证和重试机制,收紧架构,或简化提示词。 |
| 已安装版本中缺少这些说明提到的函数、标志或端点 | 查阅已安装版本的文档(help()、--help、官方文档),进行调整并告知用户。切勿臆造 API。 |
| 必需的输入、标识符或参数含义不明确 | 询问用户,或在运行前明确说明所采用的假设。 |
诚信守则
- 切勿伪造结果、参数、标识符、引用或统计数据。若无法运行或验证某项内容,请如实说明。
- 未经用户同意,切勿将私人或敏感数据发送到外部 API。
- 此处与版本相关的细节可能已经过时:请根据已安装版本的官方文档进行确认。
- 对于需要付费、消耗共享 GPU 或云配额、涉及个人或患者数据,或无法撤销的操作,请先征求同意。
评论
支持 Markdown