通过结构化输出和Pydantic来增强AI集成

16-bit style illustration by OpenAI’s DALL-E, depicting the integration of AI with structured outputs and Pydantic for enhanced application reliability

我已经将大型语言模型(LLMs)整合到许多项目中,极大地增强了我的应用程序的功能。然而,我一直面临一个重大挑战:LLM输出的不可预测性。这种不稳定性使得在我的应用程序中可靠地解析和利用它们的响应变得困难。我花费了无数个小时,甚至是周,尝试创建可以处理JSON或其他格式化的LLM响应中的变化性的解析器,但我未能实现重要的可靠性。结果是?功能失效和无数小时的故障排除。

当我发现将OpenAI的结构化输出功能与Pydantic模型相结合的力量时,一切都发生了变化。这种方法彻底改变了我将人工智能整合到应用程序中的方式,我很高兴与您分享它如何为您做同样的事情。

改变游戏规则的元素:GPT-4o中的结构化输出

OpenAI的GPT-4o-2024-08-06模型,预计将于十月成为默认的GPT-4o模型,引入了一个关键的功能:结构化输出。这一功能允许我为LLM响应定义特定的模式,确保模型以精确、预定义的格式返回数据。这对我的开发过程产生了重大影响。

Pydantic:完美的搭档

为了补充结构化的输出,我使用Pydantic,这是一个强大的用于Python的数据验证库。Pydantic利用Python类型注解来定义数据模型,提供了几个关键优点:

1. 我可以为我预期的数据结构创建清晰,类型安全的模型定义。 2. 它会自动验证和解析LLM响应为我定义的模型。 3. 它高效地处理嵌套结构,这对复杂数据非常关键。

这个组合的力量

通过将结构化输出与Pydantic模型整合,我获得了重大好处:

  1. 可靠性:现在我每次都能获得一致且格式良好的数据。这消除了我在代码中复杂错误处理和回退逻辑的需要。
  2. 效率:我过去用于解析和错误处理的时间现在用于功能开发和创新。以前花费我数天的工作现在只需数小时。
  3. 可扩展性:随着我的项目日益复杂,这种结构化方法使得可以轻松扩展和修改数据模型,而不会破坏现有功能。

真实世界应用:动物分类学

让我向您展示我如何将这种方法应用于实践中。以下是一个使用动物分类法的例子,这是一个经典的嵌套结构,展示了这种方法的强大之处。

首先,我定义我的Pydantic模型:

from pydantic import BaseModel
from typing import List

class Species(BaseModel):
name: str
scientific_name: str

class Genus(BaseModel):
name: str
species: List[Species]

class Family(BaseModel):
name: str
genera: List[Genus]

class Order(BaseModel):
name: str
families: List[Family]

class AnimalTaxonomy(BaseModel):
kingdom: str
phylum: str
class_name: str
orders: List[Order]

然后,我将这些模型与OpenAI的结构化输出结合使用:

import openai
from pydantic import parse_raw_as

def get_animal_taxonomy(animal: str):
response = openai.ChatCompletion.create(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "You are a helpful assistant that provides animal taxonomy information."},
{"role": "user", "content": f"Provide the taxonomy for {animal} in a structured format."}
],
functions=[
{
"name": "provide_taxonomy",
"description": "Provide the taxonomy for a given animal",
"parameters": AnimalTaxonomy.schema()
}
],
function_call={"name": "provide_taxonomy"}
)

taxonomy_data = response.choices[0].function_call.arguments
taxonomy = parse_raw_as(AnimalTaxonomy, taxonomy_data)
return taxonomy

# Usage
lion_taxonomy = get_animal_taxonomy("lion")
print(f"The lion belongs to the {lion_taxonomy.orders[0].name} order.")

当我运行这段代码时,我会得到一个结构化的JSON响应,与我的Pydantic模型完全匹配。

{
"kingdom": "Animalia",
"phylum": "Chordata",
"class_name": "Mammalia",
"orders": [
{
"name": "Carnivora",
"families": [
{
"name": "Felidae",
"genera": [
{
"name": "Panthera",
"species": [
{
"name": "Lion",
"scientific_name": "Panthera leo"
}
]
}
]
}
]
}
]
}

这个结构化输出正是我所需的。它干净整洁,嵌套方式与我在Pydantic模型中定义的完全一致,可以轻松解析。再也不用担心与不一致的JSON结构打交道或编写复杂的解析逻辑了。使用Pydantic的`parse_raw_as`函数,我只需一行代码就可以获得一个完全验证过的`AnimalTaxonomy`对象。

結論

GPT-4o的结构化输出与Pydantic模型的结合,彻底改变了我的AI整合方法。它让我能够充分利用LLMs的全部功能,同时保持坚固的应用程序开发所需的可靠性和结构。通过消除AI响应中的不确定性,我得以专注于创新和功能开发,极大地提高了我的工作效率。

如果您正在开发人工智能功能或希望简化开发流程,我强烈推荐探索这种方法。这可能会彻底改变您的人工智能集成工作流程,就像它改变了我的一样。

2024-09-13 04:14:15 AI中文站翻译自原文