跳到内容

处理缺失数据

`Maybe` 模式是函数式编程中用于错误处理的一个概念。您可以使用 `Maybe` 类型来封装结果和潜在的错误,而不是抛出异常或返回 `None`。

这种模式在进行 LLM 调用时特别有用,因为为语言模型提供一个“逃生舱”可以有效减少幻觉。

定义模型

使用 Pydantic,我们将首先定义 `UserDetail` 和 `MaybeUser` 类。

from pydantic import BaseModel, Field
from typing import Optional


class UserDetail(BaseModel):
    age: int
    name: str
    role: Optional[str] = Field(default=None)


class MaybeUser(BaseModel):
    result: Optional[UserDetail] = Field(default=None)
    error: bool = Field(default=False)
    message: Optional[str] = Field(default=None)

    def __bool__(self):
        return self.result is not None

注意 `MaybeUser` 有一个 `result` 字段,它是一个可选的 `UserDetail` 实例,用于存储提取的数据。`error` 字段是一个布尔值,指示是否发生了错误,而 `message` 字段是一个可选字符串,包含错误消息。

定义函数

定义好模型后,我们可以创建一个使用 `Maybe` 模式提取数据的函数。

import instructor
import openai
from pydantic import BaseModel, Field
from typing import Optional

# This enables the `response_model` keyword
client = instructor.from_openai(openai.OpenAI())


class UserDetail(BaseModel):
    age: int
    name: str
    role: Optional[str] = Field(default=None)


class MaybeUser(BaseModel):
    result: Optional[UserDetail] = Field(default=None)
    error: bool = Field(default=False)
    message: Optional[str] = Field(default=None)

    def __bool__(self):
        return self.result is not None


def extract(content: str) -> MaybeUser:
    return client.chat.completions.create(
        model="gpt-3.5-turbo",
        response_model=MaybeUser,
        messages=[
            {"role": "user", "content": f"Extract `{content}`"},
        ],
    )


user1 = extract("Jason is a 25-year-old scientist")
print(user1.model_dump_json(indent=2))
"""
{
  "result": null,
  "error": false,
  "message": null
}
"""

user2 = extract("Unknown user")
print(user2.model_dump_json(indent=2))
"""
{
  "result": null,
  "error": true,
  "message": "Unknown user"
}
"""

如您所见,当数据成功提取时,`result` 字段包含 `UserDetail` 实例。发生错误时,`error` 字段被设置为 `True`,而 `message` 字段包含错误消息。

如果您想了解更多关于模式匹配的信息,请查看 Pydantic 关于结构化模式匹配的文档。