markdown
# 构建信息提取链:从非结构化文本中提取结构化数据的实践
## 引言
在大多数自然语言处理工作中,提取非结构化文本中的结构化信息是一个重要的需求。例如,识别一段文章中的人名、身高、发色等关键信息。得益于大语言模型(LLM)的强大泛化能力,这项任务变得更加高效。本教程将带你一步步构建一个信息提取链,用于从非结构化文本中提取特定的数据。
**目标**:通过 `LangChain`,结合工具调用(Tool Calling)和自定义模式,构建一个灵活的信息提取系统。
---
## 主要内容
### 1. 环境准备
#### 安装所需依赖
我们将使用 `LangChain` 来搭建信息提取链。可以通过以下命令来安装:
```bash
# 使用 pip 安装
pip install langchain
# 使用 conda 安装
conda install langchain -c conda-forge
配置 LangSmith(可选)
为了更好地追踪和调试链条的执行,可以使用 LangSmith
。注册账户后,设置以下环境变量:
python
import getpass
import os
# 启用 LangChain 跟踪
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = getpass.getpass("Enter your LangChain API Key: ")
2. 定义模式
我们将使用 Pydantic
定义信息提取模式。以下是示例架构,将提取的结构化数据描述为一个 Person
对象:
python
from typing import Optional
from langchain_core.pydantic_v1 import BaseModel, Field
class Person(BaseModel):
"""关于某人的信息."""
name: Optional[str] = Field(default=None, description="该人的名字")
hair_color: Optional[str] = Field(default=None, description="该人的头发颜色")
height_in_meters: Optional[str] = Field(default=None, description="以米为单位的身高")
最佳实践:
- 文档化字段和模式:每个字段应附带描述,以便提升提取的准确性。
- 使用可选字段 :避免强制模型返回结果。如果信息不存在,允许其返回
None
。
3. 构建信息提取链
核心逻辑是定义一个提示(Prompt)模板,引导模型从文本中提取数据。
python
from langchain_core.prompts import ChatPromptTemplate
from langchain_mistralai import ChatMistralAI
# 定义自定义提示模板
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"你是一个专业的信息提取算法。"
"仅从提供的文本中提取相关信息。"
"如果无法提取某个属性,则返回 null。",
),
("human", "{text}"),
]
)
# 使用支持工具调用的模型
llm = ChatMistralAI(model="mistral-large-latest", temperature=0)
# 构建可运行的提取链
runnable = prompt | llm.with_structured_output(schema=Person)
4. 测试单实体提取
我们来测试提取功能,输入一段描述人的文本,并观察模型的输出。
python
text = "Alan Smith is 6 feet tall and has blond hair."
result = runnable.invoke({"text": text})
print(result)
# 输出示例:
# Person(name='Alan Smith', hair_color='blond', height_in_meters='1.83')
解析:注意,虽然身高以英尺单位提供,模型成功将其转换为米单位。这是生成式模型的强大之处!
5. 多实体提取
在实际应用中,往往需要提取多个实体。这可以通过嵌套模型实现。
python
from typing import List
class Data(BaseModel):
"""关于多人的提取数据."""
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."
result = runnable.invoke({"text": text})
print(result)
# 输出示例:
# Data(people=[Person(name='Jeff', hair_color='black', height_in_meters='1.83'),
# Person(name='Anna', hair_color='black', height_in_meters=None)])
常见问题和解决方案
-
提取结果不准确怎么办?
- 提高模式(Schema)的描述完整性。
- 为模型提供参考示例,优化模型性能。
- 检查输入文本是否清晰简洁。
-
长文本处理的瓶颈?
- 使用分块策略,将长文本分成多个小段逐步处理。
- 优化模型的上下文窗口。
-
模型不支持工具调用?
- 可切换到支持工具调用的模型,例如 OpenAI (部分型号)或 Mistral。
- 如果模型不支持工具调用,可使用基于提示的解析方法。
总结和进一步学习资源
本教程介绍了如何使用 LangChain
构建信息提取链,并通过示例展示了如何从非结构化文本中提取结构化信息。以下是推荐的学习资源:
参考资料
- LangChain 提取链官方示例
- Pydantic 模式建模最佳实践
- 如何优化提示设计
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!