微信扫码
添加专属顾问
我要投稿
在今天,OpenAI 的 CEO 山姆·奥特曼宣布推出了一项新的特性:支持 JSON 格式化输出。这一功能的引入将大大提升在实际业务场景中使用模型输出结构化数据的能力。
去年 DevDay 上,OpenAI 推出了 JSON 模式。这是一种对希望通过模型构建可靠应用程序的开发者非常有用的工具。虽然 JSON 模式提高了模型生成有效 JSON 输出的可靠性,但它不能保证响应完全符合特定的 schema。为了解决这个问题,OpenAI 推出了 API 的结构化输出功能,确保模型输出完全匹配开发者提供的 JSON Schema。
从非结构化输入生成结构化数据是当今应用程序中 AI 的核心应用场景之一。开发者利用 OpenAI API 构建强大的助手,这些助手能够通过函数调用获取数据并回答问题,提取结构化数据以进行数据录入,并构建多步骤的代理工作流程,使LLMs能够采取行动。长期以来,开发者通过开源工具、提示工程和反复重试请求来克服LLMs在这一领域的局限性,以确保模型输出符合与其系统互操作所需的格式。结构化输出通过约束 OpenAI 模型匹配开发者提供的模式,并通过训练我们的模型更好地理解复杂的模式,解决了这一问题。
在最近的评估中,新模型 gpt-4o-2024-08-06 凭借结构化输出获得了完美的 100%评分。相比之下,gpt-4-0613 的得分不足 40%。
示例请求
POST /v1/chat/completions{"model": "gpt-4o-2024-08-06","messages": [{"role": "system","content": "You are a helpful assistant. The current date is August 6, 2024. You help users query for the data they are looking for by calling the query function."},{"role": "user","content": "look up all my orders in may of last year that were fulfilled but not delivered on time"}],"tools": [{"type": "function","function": {"name": "query","description": "Execute a query.","strict": true,"parameters": {"type": "object","properties": {"table_name": {"type": "string","enum": ["orders"]},"columns": {"type": "array","items": {"type": "string","enum": ["id","status","expected_delivery_date","delivered_at","shipped_at","ordered_at","canceled_at"]}},"conditions": {"type": "array","items": {"type": "object","properties": {"column": {"type": "string"},"operator": {"type": "string","enum": ["=", ">", "<", ">=", "<=", "!="]},"value": {"anyOf": [{"type": "string"},{"type": "number"},{"type": "object","properties": {"column_name": {"type": "string"}},"required": ["column_name"],"additionalProperties": false}]}},"required": ["column", "operator", "value"],"additionalProperties": false}},"order_by": {"type": "string","enum": ["asc", "desc"]}},"required": ["table_name", "columns", "conditions", "order_by"],"additionalProperties": false}}}]}
示例输出 JSON
{
"table_name": "orders",
"columns": ["id", "status", "expected_delivery_date", "delivered_at"],
"conditions": [
{
"column": "status",
"operator": "=",
"value": "fulfilled"
},
{
"column": "ordered_at",
"operator": ">=",
"value": "2023-05-01"
},
{
"column": "ordered_at",
"operator": "<",
"value": "2023-06-01"
},
{
"column": "delivered_at",
"operator": ">",
"value": {
"column_name": "expected_delivery_date"
}
}
],
"order_by": "asc"
}
开发者现在可以通过 `json_schema` 为 `response_format` 参数提供一个 JSON Schema。当模型不调用工具,而是以结构化方式响应用户时,这一功能尤为有用。此功能适用于我们最新的 gpt-4o 系列模型:今日发布的 gpt-4o-2024-08-06 和 gpt-4o-mini-2024-07-18。当 `response_format` 设置为 `strict: true` 时,模型输出将匹配提供的 Schema。
示例请求
POST /v1/chat/completions{"model": "gpt-4o-2024-08-06","messages": [{"role": "system","content": "You are a helpful math tutor."},{"role": "user","content": "solve 8x + 31 = 2"}],"response_format": {"type": "json_schema","json_schema": {"name": "math_response","strict": true,"schema": {"type": "object","properties": {"steps": {"type": "array","items": {"type": "object","properties": {"explanation": {"type": "string"},"output": {"type": "string"}},"required": ["explanation", "output"],"additionalProperties": false}},"final_answer": {"type": "string"}},"required": ["steps", "final_answer"],"additionalProperties": false}}}}
示例输出 JSON
{"steps": [{"explanation": "Subtract 31 from both sides to isolate the term with x.","output": "8x + 31 - 31 = 2 - 31"},{"explanation": "This simplifies to 8x = -29.","output": "8x = -29"},{"explanation": "Divide both sides by 8 to solve for x.","output": "x = -29 / 8"}],"final_answer": "x = -29 / 8"}
安全性始终是 OpenAI 的首要任务。新推出的结构化输出功能严格遵循现有的安全政策,并允许模型在遇到不安全请求时进行拒绝。为了方便开发者检测模型是否生成了拒绝而非与 schema 匹配的输出,API 响应中新增了一个拒绝字符串值。
当模型的响应不包含拒绝,并且响应没有因任何原因被过早中断(如通过 finish_reason 指示),则模型的响应将可靠地产生与提供的 schema 完全匹配的有效 JSON。这一功能使得开发者可以以编程方式确保模型响应的准确性和安全性。
示例拒绝响应
{
"id": "chatcmpl-9nYAG9LPNonX8DAyrkwYfemr3C8HC",
"object": "chat.completion",
"created": 1721596428,
"model": "gpt-4o-2024-08-06",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"refusal": "I'm sorry, I cannot assist with that request."
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 81,
"completion_tokens": 11,
"total_tokens": 92
},
"system_fingerprint": "fp_3407719c7f"
}
OpenAI 的 Python 和 Node SDK 已更新以原生支持结构化输出。通过将 schema 作为工具或响应格式提供,开发者可以轻松地使用 Pydantic 或 Zod 对象。这使得 SDK 能够自动将数据类型转换为支持的 JSON schema,并将 JSON 响应反序列化为类型化的数据结构。
以下是如何通过函数调用实现结构化输出的示例:
from enum import Enum
from typing import Union
from pydantic import BaseModel
import openai
from openai import OpenAI
class Table(str, Enum):
orders = "orders"
customers = "customers"
products = "products"
class Column(str, Enum):
id = "id"
status = "status"
expected_delivery_date = "expected_delivery_date"
delivered_at = "delivered_at"
shipped_at = "shipped_at"
ordered_at = "ordered_at"
canceled_at = "canceled_at"
class Operator(str, Enum):
eq = "="
gt = ">"
lt = "<"
le = "<="
ge = ">="
ne = "!="
class OrderBy(str, Enum):
asc = "asc"
desc = "desc"
class DynamicValue(BaseModel):
column_name: str
class Condition(BaseModel):
column: str
operator: Operator
value: Union[str, int, DynamicValue]
class Query(BaseModel):
table_name: Table
columns: list[Column]
conditions: list[Condition]
order_by: OrderBy
client = OpenAI()
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{
"role": "system",
"content": "You are a helpful assistant. The current date is August 6, 2024. You help users query for the data they are looking for by calling the query function.",
},
{
"role": "user",
"content": "look up all my orders in may of last year that were fulfilled but not delivered on time",
},
],
tools=[
openai.pydantic_function_tool(Query),
],
)
print(completion.choices[0].message.tool_calls[0].function.parsed_arguments)
原生结构化输出支持也可用于 `response_format`。
from pydantic import BaseModel
from openai import OpenAI
class Step(BaseModel):
explanation: str
output: str
class MathResponse(BaseModel):
steps: list[Step]
final_answer: str
client = OpenAI()
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "You are a helpful math tutor."},
{"role": "user", "content": "solve 8x + 31 = 2"},
],
response_format=MathResponse,
)
message = completion.choices[0].message
if message.parsed:
print(message.parsed.steps)
print(message.parsed.final_answer)
else:
print(message.refusal)
为模型提供一个单独的“思考链”字段,有助于提升最终回复的质量。
{"model": "gpt-4o-2024-08-06","messages": [{"role": "system","content": "You are a helpful assistant"},{"role": "user","content": "9.11 and 9.9 -- which is bigger?"}],"response_format": {"type": "json_schema","json_schema": {"name": "reasoning_schema","strict": true,"schema": {"type": "object","properties": {"reasoning_steps": {"type": "array","items": {"type": "string"},"description": "The reasoning steps leading to the final conclusion."},"answer": {"type": "string","description": "The final answer, taking into account the reasoning steps."}},"required": ["reasoning_steps", "answer"],"additionalProperties": false}}}}
输出
{"reasoning_steps": ["First step is to compare the numbers 9.11 and 9.9.","Both numbers have the same whole number part, which is 9.","To compare the decimal parts, convert them to the same number of decimal places.","9.11 has two decimal places: it is 9.11.","9.9 has one decimal place: it can be rewritten as 9.90.","Now, compare 9.11 and 9.90 by looking at the decimal parts.","Compare 11 with 90.","90 is greater than 11, so 9.90 is greater than 9.11."],"answer": "9.9 is bigger than 9.11."}
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2024-08-13
2024-06-13
2024-09-23
2024-08-21
2024-05-28
2024-07-31
2024-08-04
2024-04-26
2024-07-09
2024-09-17
2025-03-08
2025-03-08
2025-03-07
2025-03-07
2025-03-05
2025-03-05
2025-03-05
2025-03-04