OpenAI结构化输出功能
一、核心概念
OpenAI于2024年8月推出的结构化输出功能,通过结合Pydantic模型和API参数校验,显著提升了大模型生成函数调用参数的准确性。该功能支持以下核心特性:
- 强制类型校验:基于Pydantic模型定义参数结构,确保生成的JSON严格符合预期。
- 自然语言解析:可直接从自然语言中提取结构化数据(如事件信息)。
- 简化开发流程:减少手动数据校验代码,提升开发效率。
二、Pydantic模型构建
(一)Pydantic作用
Pydantic通过基于Python类型标注的模型来确保数据类型正确,其内置实现了一个强大的系统,用于数据解析、校验和文档生成。
(二)模型定义示例
from pydantic import BaseModel
class GetProductName(BaseModel):
product_name: str
- 类定义:定义名为
GetProductName的类,继承自BaseModel,可利用 Pydantic 的自动数据验证、序列化和反序列化等功能。 - 属性标注:
product_name: str表明该模型有一个属性product_name,且必须是字符串类型。任何为product_name提供非字符串类型值的操作,都将引发类型错误。
三、基础实现示例
from openai import OpenAI
from pydantic import BaseModel
# 定义结构化模型
class GetProductName(BaseModel):
product_name: str
# 初始化客户端
client = OpenAI()
# 定义工具(使用Pydantic模型)
tools = [
{
"type": "function",
"function": {
"name": "query_by_product_name",
"description": "根据产品名称查询商品信息",
"parameters": GetProductName.model_json_schema()
}
}
]
# 调用示例
messages = [
{"role": "user", "content": "你好,你们家有什么适合户外运动的鞋子吗?"}
]
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=tools
)
# 解析工具调用
tool_calls = response.choices[0].message.tool_calls
if tool_calls:
args = GetProductName.model_validate_json(tool_calls[0].function.arguments)
print(f"查询参数: {args.product_name}")
四、自然语言结构化解析
(一)普通对话中的结构化输出
结构化输出不仅用于函数调用,还可在普通对话中实现结构化模型的输出响应。通过定义Pydantic模型,利用OpenAI的beta接口进行解析。
(二)beta接口讲解
OpenAI的 beta 接口用于测试新功能,如结构化解析。这类接口处于测试阶段,功能可能调整。使用时通过 client.beta.chat.completions.parse 调用,需传递模型、消息、响应格式等参数,以获取结构化输出结果。
(三)实现代码示例
from pydantic import BaseModel
from openai import OpenAI
client = OpenAI()
class CalendarEvent(BaseModel):
name: str
date: str
participants: list[str]
completion = client.beta.chat.completions.parse(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "提取事件信息"},
{"role": "user", "content": "李华和张明星期五要去参加科学博览会"}
],
response_format=CalendarEvent
)
# 获取结构化结果
event = completion.choices[0].message.parsed
print(f"事件名称: {event.name}")
print(f"事件日期: {event.date}")
print(f"参与者: {event.participants}")
输出结果:
事件名称: 科学博览会
事件日期: 星期五
参与者: [‘李华’, ‘张明’]
五、功能特性
- 模型支持:GPT-4o系列(2024-08-06版本及以上)、GPT-4o-mini(2024-07-18版本及以上)。
- 优势场景:数据提取类任务(如事件抽取、实体识别)、表单填写类应用、需要严格参数校验的函数调用。
- 注意事项:需使用
client.beta.chat.completions.parse接口;模型可能返回不完整数据,需添加异常处理;结构化输出与函数调用不可同时使用。
六、典型应用场景
- 电商客服:
class ProductQuery(BaseModel):
category: str
price_range: tuple[float, float]
brand: str | None = None
response = client.beta.chat.completions.parse(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "推荐一款500-800元的知名品牌篮球鞋"}
],
response_format=ProductQuery
)
解析结果示例:
假设输入符合逻辑,可能解析出 ProductQuery(category="篮球鞋", price_range=(500.0, 800.0), brand="某知名品牌")(实际结果依模型和数据而定)。
- 行程管理:
class TravelPlan(BaseModel):
destination: str
start_date: str
duration: int
companions: list[str]
completion = client.beta.chat.completions.parse(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "我和朋友计划下周一去三亚玩5天"}
],
response_format=TravelPlan
)
解析结果示例:
可能解析出 TravelPlan(destination="三亚", start_date="下周一", duration=5, companions=["我", "朋友"])(实际结果依模型和数据而定)。
七、技术演进方向
- 增强语义理解:通过持续训练提升复杂场景的结构化解析能力。
- 多模态支持:未来可能扩展至图像、语音等非文本输入。
- 与Agent框架整合:深度集成于OpenAI的Assistant API中。
建议在实际项目中结合以下策略使用:优先在简单场景验证;结合传统数据校验作为补充;密切关注OpenAI官方更新日志。
八、补充
20250401:OpenAI 的结构化输出功能目前已正式发布,不再处于测试阶段 。无需通过beta接口,直接使用常规chat.completions.create接口实现。
import json
from openai import OpenAI
from pydantic import BaseModel, ValidationError
# 初始化OpenAI客户端
client = OpenAI()
# 定义结构化数据模型
class WeatherInfo(BaseModel):
location: str
temperature: float
weather_condition: str
def get_weather_structure(prompt):
# 调用OpenAI API,指定结构化输出格式
response = client.chat.completions.create(
model="gpt-4o", # 选择支持结构化输出的模型,如gpt-4o系列
messages=[
{"role": "user", "content": prompt}
],
response_format={
"type": "json_object",
"schema": WeatherInfo.model_json_schema() # 关联Pydantic模型的JSON Schema
}
)
try:
# 解析并验证模型输出
result_json = json.loads(response.choices[0].message.content)
return WeatherInfo(**result_json) # 使用Pydantic模型验证数据
except (json.JSONDecodeError, ValidationError) as e:
print(f"解析或验证错误: {e}")
return None
# 示例使用:获取北京天气的结构化输出
weather_prompt = "用JSON输出北京的天气信息,包含地点、温度(假设值)、天气状况"
weather_result = get_weather_structure(weather_prompt)
if weather_result:
print(f"地点: {weather_result.location}")
print(f"温度: {weather_result.temperature}")
print(f"天气状况: {weather_result.weather_condition}")
786

被折叠的 条评论
为什么被折叠?



