magentic结构化输出完全指南:使用Pydantic模型和Python类型

【免费下载链接】magentic Seamlessly integrate LLMs as Python functions 【免费下载链接】magentic 项目地址: https://gitcode.com/gh_mirrors/ma/magentic

magentic是一个能将大型语言模型(LLM)无缝集成为Python函数的强大工具,其结构化输出功能允许开发者通过Pydantic模型和Python类型系统获得可靠、类型安全的AI响应。本文将全面介绍如何利用magentic实现结构化输出,帮助开发者轻松构建可信赖的AI应用。

为什么选择magentic结构化输出?

在AI应用开发中,处理非结构化的文本响应往往需要复杂的解析逻辑,容易出错且难以维护。magentic的结构化输出功能通过Pydantic模型和Python类型注解,让LLM直接返回符合预期格式的数据,大幅降低开发难度并提高系统可靠性。

无论是构建聊天机器人、数据分析工具还是自动化工作流,结构化输出都能确保AI响应的一致性和可用性,是提升开发效率的关键技术。

Pydantic模型:定义结构化数据

基础模型定义

magentic的@prompt装饰器会尊重函数的返回类型注解,支持任何Pydantic支持的类型,包括自定义的Pydantic模型。这使得我们可以精确定义AI应该返回的数据结构。

from magentic import prompt
from pydantic import BaseModel

class Superhero(BaseModel):
    name: str
    age: int
    power: str
    enemies: list[str]

@prompt("Create a Superhero named {name}.")
def create_superhero(name: str) -> Superhero: ...

create_superhero("Garden Man")
# Superhero(name='Garden Man', age=30, power='Control over plants', enemies=['Pollution Man', 'Concrete Woman'])

使用Field增强模型

通过Pydantic的Field类,我们可以为模型字段提供额外信息,如描述、示例等,帮助LLM更准确地生成符合预期的数据。

from magentic import prompt
from pydantic import BaseModel, Field

class Superhero(BaseModel):
    name: str
    age: int = Field(
        description="The age of the hero, which could be much older than humans."
    )
    power: str = Field(examples=["Runs really fast"])
    enemies: list[str]

@prompt("Create a Superhero named {name}.")
def create_superhero(name: str) -> Superhero: ...

模型配置与严格模式

Pydantic模型支持通过model_config属性进行配置,magentic扩展了Pydantic的ConfigDict类,增加了openai_strict选项,用于启用OpenAI的结构化输出特性。

from magentic import prompt, ConfigDict
from pydantic import BaseModel

class Superhero(BaseModel):
    model_config = ConfigDict(openai_strict=True)
    
    name: str
    age: int
    power: str
    enemies: list[str]

@prompt("Create a Superhero named {name}.")
def create_superhero(name: str) -> Superhero: ...

启用严格模式后,LLM将更严格地遵循指定的JSON模式,减少格式错误。你可以通过模型的.model_json_schema()方法查看生成的JSON模式:

{
    "properties": {
        "name": {"title": "Name", "type": "string"},
        "age": {
            "description": "The age of the hero, which could be much older than humans.",
            "title": "Age",
            "type": "integer",
        },
        "power": {
            "examples": ["Runs really fast"],
            "title": "Power",
            "type": "string",
        },
        "enemies": {"items": {"type": "string"}, "title": "Enemies", "type": "array"},
    },
    "required": ["name", "age", "power", "enemies"],
    "title": "Superhero",
    "type": "object",
}

Python类型:简化的结构化输出

除了Pydantic模型,magentic还支持使用常规Python类型作为函数返回类型,实现更简洁的结构化输出。

from magentic import prompt
from pydantic import BaseModel

class Superhero(BaseModel):
    name: str
    age: int
    power: str
    enemies: list[str]

garden_man = Superhero(
    name="Garden Man",
    age=30,
    power="Control over plants",
    enemies=["Pollution Man", "Concrete Woman"],
)

@prompt("Return True if {hero.name} will be defeated by enemies {hero.enemies}")
def will_be_defeated(hero: Superhero) -> bool: ...

hero_defeated = will_be_defeated(garden_man)
print(hero_defeated)
# > True

链式思考提示:提升输出质量

有时,直接要求LLM返回简单类型可能导致结果质量不高。通过定义包含解释字段的Pydantic模型,可以引导LLM进行"链式思考",先解释推理过程再给出最终结果。

from magentic import prompt
from pydantic import BaseModel, Field

class ExplainedDefeated(BaseModel):
    explanation: str = Field(
        description="Describe the battle between the hero and their enemy."
    )
    defeated: bool = Field(description="True if the hero was defeated.")

class Superhero(BaseModel):
    name: str
    age: int
    power: str
    enemies: list[str]

@prompt("Return True if {hero.name} will be defeated by enemies {hero.enemies}")
def will_be_defeated(hero: Superhero) -> ExplainedDefeated: ...

garden_man = Superhero(
    name="Garden Man",
    age=30,
    power="Control over plants",
    enemies=["Pollution Man", "Concrete Woman"],
)

hero_defeated = will_be_defeated(garden_man)
print(hero_defeated.defeated)
# > True
print(hero_defeated.explanation)
# > 'Garden Man is an environmental hero who fights against Pollution Man ...'

通用解释模型

为了方便复用链式思考模式,可以定义一个通用的Explained模型:

from typing import Generic, TypeVar
from magentic import prompt
from pydantic import BaseModel, Field

T = TypeVar("T")

class Explained(BaseModel, Generic[T]):
    explanation: str = Field(description="Explanation of how the value was determined.")
    value: T

@prompt("Return True if {hero.name} will be defeated by enemies {hero.enemies}")
def will_be_defeated(hero: Superhero) -> Explained[bool]: ...

结构化输出的实际应用与监控

结构化输出不仅使数据处理更简单,还提高了AI应用的可观测性。通过日志和追踪工具,我们可以清晰地看到函数调用过程和结果。

magentic结构化输出追踪示例

上图展示了magentic在Jaeger UI中的追踪信息,清晰显示了函数调用get_current_weather的执行过程和耗时。这种可视化监控对于调试和优化AI应用至关重要。

magentic结构化输出日志示例

Logfire提供的实时监控界面则展示了函数调用的参数和详细信息,包括位置参数"Boston"和代码执行的具体位置,帮助开发者深入了解AI应用的运行状态。

解决结构化输出常见问题

如果经常遇到StructuredOutputError,说明LLM难以匹配预期的 schema。解决此问题的方法包括:

  1. 为字段添加更详细的描述或示例
  2. 简化输出 schema,使用更灵活的类型(如str代替datetime
  3. 允许字段为 nullable(使用| None
  4. 切换到更智能的LLM模型(参见Configuration

通过这些方法,可以显著提高结构化输出的成功率和可靠性。

总结

magentic的结构化输出功能通过Pydantic模型和Python类型系统,为AI应用开发提供了强大的类型安全保障。无论是构建简单的工具函数还是复杂的AI工作流,结构化输出都能帮助开发者获得更可靠、更易维护的AI响应。

通过本文介绍的方法,你可以轻松开始使用magentic构建结构化的AI应用,提升开发效率并确保系统质量。如需了解更多细节,请参考官方文档docs/structured-outputs.md

要开始使用magentic,只需克隆仓库并按照文档进行安装配置:

git clone https://gitcode.com/gh_mirrors/ma/magentic
cd magentic
# 按照安装说明进行配置

现在,你已经掌握了magentic结构化输出的核心技术,开始构建你的AI应用吧!

【免费下载链接】magentic Seamlessly integrate LLMs as Python functions 【免费下载链接】magentic 项目地址: https://gitcode.com/gh_mirrors/ma/magentic

更多推荐