跳到内容

从LLM生成结构化输出/JSON

语言模型取得了显著发展。有效地使用它们通常需要复杂的框架。本文讨论了 Instructor 如何利用 Pydantic 简化这一过程。

现有LLM框架的问题

当前的语言学习模型 (LLM) 框架设置复杂。开发者发现难以控制与语言模型的交互。有些框架需要复杂的 JSON Schema 设置。

OpenAI 函数调用:改变游戏规则的功能

OpenAI 的函数调用功能提供了一种受限的交互模型。然而,它也有其自身的复杂性,主要体现在 JSON Schema 方面。

为什么选择 Pydantic?

Instructor 使用 Pydantic 来简化程序员与语言模型之间的交互。

  • 广泛采用:Pydantic 是 Python 开发者中广泛使用的工具。
  • 简洁性:Pydantic 允许在 Python 中定义模型。
  • 框架兼容性:许多 Python 框架已经在使用 Pydantic。
import pydantic
import instructor
from openai import OpenAI

# Enables the response_model
client = instructor.from_openai(OpenAI())


class UserDetail(pydantic.BaseModel):
    name: str
    age: int

    def introduce(self):
        return f"Hello I'm {self.name} and I'm {self.age} years old"


user: UserDetail = client.chat.completions.create(
    model="gpt-3.5-turbo",
    response_model=UserDetail,
    messages=[
        {"role": "user", "content": "Extract Jason is 25 years old"},
    ],
)

使用 Pydantic 简化验证流程

Pydantic 验证器简化了诸如重新提问或自我批评等功能。这使得这些任务比其他框架更加不复杂。

from typing_extensions import Annotated
from pydantic import BaseModel, BeforeValidator
from instructor import llm_validator


class QuestionAnswerNoEvil(BaseModel):
    question: str
    answer: Annotated[
        str,
        BeforeValidator(llm_validator("don't say objectionable things")),
    ]

模块化方法

Pydantic 允许模块化的输出模式。这使得代码更加有条理。

模式组合

class UserDetails(BaseModel):
    name: str
    age: int


class UserWithAddress(UserDetails):
    address: str

定义关系

class UserDetail(BaseModel):
    id: int
    age: int
    name: str
    friends: List[int]


class UserRelationships(BaseModel):
    users: List[UserDetail]

使用枚举

from enum import Enum, auto


class Role(Enum):
    PRINCIPAL = auto()
    TEACHER = auto()
    STUDENT = auto()
    OTHER = auto()


class UserDetail(BaseModel):
    age: int
    name: str
    role: Role

灵活的模式

from typing import List


class Property(BaseModel):
    key: str
    value: str


class UserDetail(BaseModel):
    age: int
    name: str
    properties: List[Property]

思维链

class TimeRange(BaseModel):
    chain_of_thought: str
    start_time: int
    end_time: int


class UserDetail(BaseModel):
    id: int
    age: int
    name: str
    work_time: TimeRange
    leisure_time: TimeRange

作为微服务的语言模型

其架构类似于 FastAPI。大多数代码可以编写为使用 Pydantic 对象的 Python 函数。这消除了对提示链的需求。

FastAPI 存根

import fastapi
from pydantic import BaseModel

class UserDetails(BaseModel):
    name: str
    age: int

app = fastapi.FastAPI()

@app.get("/user/{user_id}", response_model=UserDetails)
async def get_user(user_id: int) -> UserDetails:
    return ...

将 Instructor 用作函数

def extract_user(str) -> UserDetails:
    return client.chat.completions(
           response_model=UserDetails,
           messages=[]
    )

响应建模

class MaybeUser(BaseModel):
    result: Optional[UserDetail]
    error: bool
    message: Optional[str]

结论

Instructor 结合 Pydantic,简化了与语言模型的交互。它适用于有经验和新手开发者。

如果您喜欢这些内容或想尝试使用 instructor,请查看 github 并给我们一个星!