OpenAI公司于8月6日宣布,在其API中新增了结构化输出功能,这标志着OpenAI现在能够根据开发者提供的JSON模式,准确生成符合要求的输出结果。官方还宣布,借助这一功能,新推出的gpt-4o-2024-08-06模型在评估中达到了100%的准确率,完美匹配了预期的输出模式。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于被人阅读和编写,同时也易于被机器解析和生成。去年在DevDay上,OpenAI引入了JSON模式助开发者构建应用,本次新的结构化输出功能将进一步改善模型与JSON冲突的情况,从而减少“幻觉”现象和降低输出成本。
一、结构化输出功能API上线,JSON准确率100%
由非结构化输入得到结构化输出数据是当今应用中AI的核心用例之一。开发人员使用OpenAI API构建了功能强大的助手,这些助手能够通过函数调用获取数据、回答问题、提取结构化数据并构建多步骤的智能工作流程,从而使大型语言模型(LLM)能够有效行动。长期以来,开发者通过开源工具、提示工程和反复请求来解决LLM在此方面的限制,以确保模型输出符合系统的要求。结构化输出通过训练模型更好地理解复杂模式,并让OpenAI模型遵循开发者提供的模式,很好地解决了这一难题。
OpenAI公司跟踪评估了复杂JSON模式,带有结构化输出的新模型gpt-4o-2024-08-06获得了100%的满分成绩;相比之下,gpt-4-0613得分不到40%。
▲gpt-4o-2024-08-06实现了100%的可靠性(图源:OpenAI)
OpenAI公司宣布,结构化输出功能现已在API中正式上线。所有支持函数调用的模型均可实现此功能,包括最新的gpt-4o和gpt-4o-mini模型,以及gpt-4-0613和gpt-3.5-turbo-0613等微调模型。该功能可在Chat Completions API、Assistants API和Batch API中使用,并兼容视觉输入。
二、双形式创新:结构化输出携手原生SDK
OpenAI公司在API中以两种新形式引入了结构化输出功能:
1.函数调用:通过在函数定义中设置“strict: true”即可通过工具获得结构化输出。此功能适用于所有支持工具的模型,包括gpt-4-0613和gpt-3.5-turbo-0613及更高版本。启用结构化输出后,模型输出将与提供的工具定义匹配。
▲(图源:OpenAI)
2.“response_format”参数的新选项:开发人员现在可以通过结构化输入提供JSON模式,这是“response_format”参数的新选项。当模型不调用工具而是以结构化方式响应用户时,这将更加高效。此功能适用于OpenAI最新的GPT-4o模型:今天发布的gpt-4o-2024-08-06和gpt-4o-mini-2024-07-18.当“response_format”提供 “strict: true”参数时,模型输出将与提供的模式匹配。
▲(图源:OpenAI)
OpenAI的Python和Node SDK已更新,提供对原生结构化输出的支持。通过将架构作为工具或响应格式提供,开发者可以轻松地使用 “Pydantic”或“Zod”对象,OpenAI的SDK将处理数据类型转换为受支持的JSON架构,自动将JSON响应反序列化为类型化的数据结构,并在出现拒绝时进行分析。
以下示例展示了使用函数调用对结构化输出的本机支持:
▲(图源:OpenAI)
开发人员经常使用OpenAI的模型为各种用例生成结构化数据。
一些其他示例包括:
1、根据用户意图动态生成用户界面
2、将最终答案与支持推理或附加评论分开
3、从非结构化数据中提取结构化数据
新的结构化输出功能将严格遵守OpenAI的安全政策,同时仍允许模型拒绝不安全的请求。API响应中新增了一个拒绝字符串值,开发人员可以通过编程方式检测模型是否生成了拒绝指令。
当响应不包含拒绝且模型的响应没有被过早中断时,模型将可靠地生成与提供的架构匹配的有效JSON模式。
三、技术揭秘:结构化输出的双重约束机制
OpenAI采用了双重方法来提高模型输出与JSON模式匹配的可靠性。首先,OpenAI对其最新的模型GPT-4o-2024-08-06进行了训练,使其能够理解复杂的模式,并生成最适配的输出。
其次,OpenAI采用了受限解码技术。尽管模型的性能显著提升,在基准测试中达到93%的准确性,但模型的固有不确定性仍然存在。为确保开发者构建应用的稳健性,OpenAI提供了一种确定性方法来约束模型输出,实现100%的可靠性。
默认情况下,模型在生成输出时没有约束,可能从词汇表中选择任何标记。这种灵活性可能导致模型生成无效的JSON字符。为了避免这种错误,OpenAI使用动态受限解码方法,强制模型仅选择符合提供模式的有效标记。在每次生成标记后,推理引擎根据前一个标记和模式规则确定下一个有效标记。这一方法通过屏蔽无效标记的可能性,确保生成的输出始终符合提供的模式。
实现这种约束可能具有挑战性,因为有效标记在整个模型输出中是动态变化的。例如,初始有效标记包括 {、{” 和 {\n等,但一旦模型生成了 {“val,那么 { 就不再是有效标记。因此,OpenAI需要在生成每个标记后动态确定哪些标记有效,而不是在响应开始时预先确定。
为此,OpenAI将提供的JSON模式转换为上下文无关语法(CFG)。CFG是一组定义语言的有效规则,开发者可以将JSON和JSON模式视为具有规则的特定语言。类似于英语中没有动词的句子是无效的,JSON中带有尾随逗号也是无效的。
因此,对于每个JSON模式,OpenAI计算出代表该模式的语法,并在采样过程中高效地访问预处理组件。这就是为什么首次使用新模式可能需要额外处理时间的原因——OpenAI必须对模式进行预处理,以生成可以在采样中有效使用的组件。
在采样时,OpenAI的推理引擎将根据先前生成的标记和语法规则(指示下一个标记是否有效)确定下一个生成的标记。OpenAI使用标记列表来屏蔽无效标记,将无效标记的概率降至0.由于模式已被预处理,OpenAI可以使用缓存的数据结构高效地完成此操作,同时将延迟开销降至最低。
除了CFG方法,有限状态机(FSM)或正则表达式也可以用于受限解码。它们的功能类似,都会在生成每个标记后动态更新哪些标记是有效的。但值得注意的是,CFG方法能够表达比FSM更广泛的语言类别。对于简单模式,这种差别可能不明显。然而,OpenAI发现对于涉及嵌套或递归数据结构的复杂模式,CFG方法表现更为出色。例如,FSM通常无法表达递归类型,因此可能难以匹配深度嵌套JSON中的括号,而支持递归模式的JSON模式在OpenAI API上已得到实现,但FSM方法难以处理。
▲(图源:OpenAI)
请注意,每个UI元素都可以有任意子元素,这些子元素以递归方式引用根模式,这种灵活性是CFG方法所能提供的。
四、边界探索:结构化输出的部分限制
在享受结构化输出带来的高效与精准的同时,我们也需要清楚地认识到其存在的限制,以便更好地指导开发和应用。使用结构化输出时,开发者需注意以下限制:
支持的JSON模式子集:结构化输出仅支持JSON模式的子集,以确保最佳性能。具体限制可参考OpenAI的官方文档。
首次请求延迟:新模式的首次请求可能带来额外延迟,但后续响应将很快,不会有延迟损失。第一次请求期间,OpenAI会处理并缓存模式以供后续使用。通常模式在首次请求时可在10秒内处理完毕,但更复杂的模式可能需要长达一分钟。
拒绝不安全请求:如果模型选择拒绝不安全请求,则模型可能无法遵循模式。当选择拒绝时,返回消息将包含一个拒绝布尔值以指示这一点。
停止条件限制:如果生成过程中达到最大令牌数或其他停止条件,模型可能无法遵循模式。
模型错误:结构化输出不能完全防止所有模型错误。例如,模型在JSON对象的值中仍可能犯错(如数学计算错误)。开发者可以通过提供系统指令中的示例或将任务拆分为更简单的子任务来减少错误。
与并行函数调用不兼容:生成并行函数调用时,可能不符合提供的模式。开发者可以禁用并行函数调用,使用“parallel_tool_calls: false”设置。
不符合零数据保留(ZDR)资格:结构化输出与JSON模式不符合零数据保留(ZDR)资格。
结语:新增结构化输出,助力降本增效
与gpt-4o-2024-05-13版本相比,gpt-4o-2024-08-06版本在成本上更具优势。开发者可以节省50%的输入成本,每百万输入令牌相当于2.50美元(约合人民币17.95元);输出成本节省33%,每百万输出令牌相当于10.00美元(约合人民币71.81元)。