一架梯子,一头程序猿,仰望星空!
使用LangChain提取结构化数据 > 内容正文

快速开始


快速入门

本教程主要介绍借用大模型的函数/工具调用能力,实现结构化数据提取功能。

以OpenAI的GPT模型为例,模型支持传递一组函数或者工具调用声明(包括函数名、函数说明、参数说明)给大模型,大模型根据用户问题,自动选择调用那个函数/工具,然后从用户的问题中提取相关信息自动填充函数的调用参数。

我们就是利用这个特性实现结构化数据提取。

说明:只有选择支持函数/工具调用的模型才能使用这个方法。

设置

这里选择OpenAI模型,安装它的依赖项,并设置API密钥!

# 安装框架
pip install langchain

# 安装模型依赖
pip install langchain-openai

设置KEY

export OPENAI_API_KEY="..."

或者

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(openai_api_key="...")

定义需要提取的数据结构

首先,我们需要描述我们想要从文本中提取的信息。

我们将使用Pydantic来定义一个数据结构,用来代表,我们需要提取的个人信息。

from typing import Optional

from langchain_core.pydantic_v1 import BaseModel, Field

# 定义一个Person类,类属性就是我们希望提取的字段
# 注意:类的注释、字段的描述都会传给GPT模型,告诉我们我们需要提取什么信息,非常重要。
class Person(BaseModel):
    """个人信息。"""

    name: Optional[str] = Field(..., description="姓名")
    hair_color: Optional[str] = Field(
        ..., description="如果已知,表示人的发色"
    )
    height_in_meters: Optional[str] = Field(
        ..., description="以米为单位的身高"
    )

在上述代码中,我们使用了Pydantic库定义了一个名为Person的模式,用于提取个人信息。这个模式包括了个人的姓名、头发颜色和身高。

在定义模式时有两个最佳实践:

  1. 类注释、字段描述:这些信息要写清楚,这些描述信息会发给大模型,指导大模型提取什么数据。
  2. 不要强迫LLM编造信息!上面我们对属性使用了Optional,如果LLM不知道答案,允许LLM输出None

数据提取

让我们使用上面定义的数据结构,实现一个数据提取逻辑。

from typing import Optional

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI

# 设置提示词
prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "你是一位数据提取专家。"
            "只能从文本中提取相关信息。"
            "如果你不知道要提取的属性的值,"
            "请返回该属性的值为null。",
        ),
        ("human", "{text}"),
    ]
)

初始化OpenAI模型

from langchain_openai import ChatOpenAI

llm = ChatOpenAI()

# 通过LCEL表达式,定一个Chain,把提示词传给模型
# 注意模型使用with_structured_output函数,将我们前面定义的数据结构传递给模型
runnable = prompt | llm.with_structured_output(schema=Person)

让我们来测试一下

text = "Alan Smith身高6英尺,金发。"
runnable.invoke({"text": text})

看下面输出例子,模型返回了一个Person对象,里面包含了我们希望提取的数据

Person(name='Alan Smith', hair_color='金发', height_in_meters='1.8288')

如何提取多条数据

很多时间,我们想提取一个数据列表,而不仅仅是一条数据。

这可以通过在pydantic中嵌套模型来轻松实现。

from typing import List, Optional

from langchain_core.pydantic_v1 import BaseModel, Field


class Person(BaseModel):
    """关于一个人的信息。"""


    name: Optional[str] = Field(..., description="人的姓名")
    hair_color: Optional[str] = Field(
        ..., description="如果已知,人的头发颜色"
    )
    height_in_meters: Optional[str] = Field(
        ..., description="以米为单位的身高"
    )


# 定义了一个Data类,包含了people数组
class Data(BaseModel):
    """有关人的提取数据。"""

    people: List[Person]

下面将Data数据结构传递给模型,进行测试。

runnable = prompt | llm.with_structured_output(schema=Data)
text = "我的名字是杰夫,我的头发是黑色的,我身高6英尺。安娜的头发颜色和我一样。"
runnable.invoke({"text": text})

下面测试输出例子

Data(people=[Person(name='杰夫', hair_color=None, height_in_meters=None), Person(name='安娜', hair_color=None, height_in_meters=None)])

如果文本中没有相关信息,模型也可以提取零个实体,从而允许返回一个空的列表。



关联主题