用例(User Case)
抽取(Extraction)
快速开始(Quickstart)

快速开始

在本快速开始中,我们将使用支持 函数/工具调用 的 聊天模型 从文本中提取信息。

重要:使用 函数/工具调用 进行提取仅适用于 支持 函数/工具调用 的模型。

设置

我们将使用支持 函数/工具调用 的 LLM 上可用的 结构化输出 方法。

选择一个模型,安装其依赖并设置 API 密钥!

!pip install langchain
 
# Install a model capable of tool calling
# pip install langchain-openai
# pip install langchain-mistralai
# pip install langchain-fireworks
 
# Set env vars for the relevant model or load from a .env file:
# import dotenv
# dotenv.load_dotenv()

模式

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

我们将使用 Pydantic 定义一个提取个人信息的示例模式。

from typing import Optional
 
from langchain_core.pydantic_v1 import BaseModel, Field
 
 
class Person(BaseModel):
    """Information about a person."""
 
    # ^ Doc-string for the entity Person.
    # This doc-string is sent to the LLM as the description of the schema Person,
    # and it can help to improve extraction results.
 
    # Note that:
    # 1. Each field is an `optional` -- this allows the model to decline to extract it!
    # 2. Each field has a `description` -- this description is used by the LLM.
    # Having a good description can help improve extraction results.
    name: Optional[str] = Field(default=None, description="The name of the person")
    hair_color: Optional[str] = Field(
        default=None, description="The color of the peron's hair if known"
    )
    height_in_meters: Optional[str] = Field(
        default=None, description="Height measured in meters"
    )

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

  1. 记录 属性 和 模式 本身:该信息会发送给 LLM,并用于提高信息提取的质量。
  2. 不要强迫 LLM 编造信息!上面我们为属性使用了 Optional,允许 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
 
# Define a custom prompt to provide instructions and any additional context.
# 1) You can add examples into the prompt template to improve extraction quality
# 2) Introduce additional parameters to take context into account (e.g., include metadata
#    about the document from which the text was extracted.)
prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "You are an expert extraction algorithm. "
            "Only extract relevant information from the text. "
            "If you do not know the value of an attribute asked to extract, "
            "return null for the attribute's value.",
        ),
        # Please see the how-to about improving performance with
        # reference examples.
        # MessagesPlaceholder('examples'),
        ("human", "{text}"),
    ]
)

我们需要使用一个支持函数/工具调用的模型。

请查看 结构化输出,了解可与该 API 一起使用的一些模型列表。

from langchain_mistralai import ChatMistralAI
 
llm = ChatMistralAI(model="mistral-large-latest", temperature=0)
 
runnable = prompt | llm.with_structured_output(schema=Person)

让我们测试一下

text = "Alan Smith is 6 feet tall and has blond hair."
runnable.invoke({"text": text})
Person(name='Alan Smith', hair_color='blond', height_in_meters='1.8288')

重要:提取是生成式的 🤯

LLM 是生成模型,因此它们可以做一些相当酷的事情,例如即使身高是以英尺提供的,也能正确地以米为单位提取出此人的身高!

多个实体

在 大多数情况下,你应该提取实体列表,而不是单个实体。

这可以通过将模型相互嵌套,使用 pydantic 轻松实现。

from typing import List, Optional
 
from langchain_core.pydantic_v1 import BaseModel, Field
 
 
class Person(BaseModel):
    """Information about a person."""
 
    # ^ Doc-string for the entity Person.
    # This doc-string is sent to the LLM as the description of the schema Person,
    # and it can help to improve extraction results.
 
    # Note that:
    # 1. Each field is an `optional` -- this allows the model to decline to extract it!
    # 2. Each field has a `description` -- this description is used by the LLM.
    # Having a good description can help improve extraction results.
    name: Optional[str] = Field(default=None, description="The name of the person")
    hair_color: Optional[str] = Field(
        default=None, description="The color of the peron's hair if known"
    )
    height_in_meters: Optional[str] = Field(
        default=None, description="Height measured in meters"
    )
 
 
class Data(BaseModel):
    """Extracted data about people."""
 
    # Creates a model so that we can extract multiple entities.
    people: List[Person]

重要:此处的提取可能并不完美。请继续阅读,了解如何使用 参考示例 来提高提取质量,并查看 指南 部分!

runnable = prompt | llm.with_structured_output(schema=Data)
text = "My name is Jeff, my hair is black and i am 6 feet tall. Anna has the same color hair as me."
runnable.invoke({"text": text})
Data(people=[Person(name='Jeff', hair_color=None, height_in_meters=None), Person(name='Anna', hair_color=None, height_in_meters=None)])

提示:当模式支持提取 多个实体 时,如果文本中没有相关信息,它也允许模型通过提供空列表来提取 零个实体。

这通常是 好事!它允许在实体上指定 必需 属性,而不必强迫模型检测到该实体。

下一步

现在你已经了解了使用 LangChain 进行提取的基础知识,可以继续阅读操作指南的其余部分:

  • 添加示例:了解如何使用 参考示例 来提高性能。
  • 处理长文本:如果文本无法放入 LLM 的上下文窗口,该怎么办?
  • 处理文件:使用 LangChain 文档加载器和解析器从 PDF 等文件进行提取的示例。
  • 使用解析方法:使用基于提示的方法,配合不支持 工具/函数调用 的模型进行提取。
  • 指南:在提取任务上获得良好性能的指南。