探索长文本提取技术:如何处理超出上下文窗口的长文本

引言

在处理像PDF这样的文件时,我们常常会遇到超出语言模型上下文窗口的长文本。本文将探讨如何应对长文本提取的挑战,重点介绍两种方法:分块处理和检索增强生成(RAG)。这些策略有各自的优缺点,选择合适的方法需要根据具体应用情境来定。

主要内容

方法选择

  1. 更换LLM:选择支持更大上下文窗口的语言模型。
  2. 分块处理:将文档分块并从每个块中提取内容。
  3. RAG:将文档分块并索引,仅从看似相关的子集块中提取内容。

分块处理方法

数据准备

我们将从Wikipedia下载一篇关于汽车的文章,并将其加载为LangChain文档。

import re
import requests
from langchain_community.document_loaders import BSHTMLLoader

# 下载内容
response = requests.get("https://en.wikipedia.org/wiki/Car")  # 使用API代理服务提高访问稳定性
# 写入文件
with open("car.html", "w", encoding="utf-8") as f:
    f.write(response.text)
# 加载为HTML解析器
loader = BSHTMLLoader("car.html")
document = loader.load()[0]
# 清理代码
# 替换连续的换行符
document.page_content = re.sub("\n\n+", "\n", document.page_content)

print(len(document.page_content))  # 输出文本长度

定义模式

我们将使用Pydantic定义我们要提取的信息结构。在这个例子中,我们将提取“关键发展”,包括年份和描述。

from typing import List
from langchain_core.pydantic_v1 import BaseModel, Field

class KeyDevelopment(BaseModel):
    year: int = Field(..., description="历史发展的年份")
    description: str = Field(..., description="该年发生了什么?")
    evidence: str = Field(..., description="从中提取信息的句子")

class ExtractionData(BaseModel):
    key_developments: List[KeyDevelopment]

分块处理实现

使用TokenTextSplitter将文档分块,以便每个块适合语言模型的上下文窗口。

from langchain_text_splitters import TokenTextSplitter

text_splitter = TokenTextSplitter(chunk_size=2000, chunk_overlap=20)
texts = text_splitter.split_text(document.page_content)

# 提取第一个几个块
first_few = texts[:3]

# 进行并行提取
extractions = extractor.batch(
    [{"text": text} for text in first_few],
    {"max_concurrency": 5}
)

RAG方法

通过RAG方法,文本被分块,但只关注最相关的块。

from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings

texts = text_splitter.split_text(document.page_content)
vectorstore = FAISS.from_texts(texts, embedding=OpenAIEmbeddings())
retriever = vectorstore.as_retriever(search_kwargs={"k": 1})
rag_extractor = {"text": retriever | (lambda docs: docs[0].page_content)} | extractor
results = rag_extractor.invoke("汽车相关的关键发展")

常见问题和解决方案

  • 信息分散问题:分块可能导致信息分散,LLM无法提取跨多个块的信息。
  • 重复问题:较大的块重叠可能会导致重复信息,需要去重。
  • 虚假信息:在处理长文本时,可能会获得虚假数据。

总结和进一步学习资源

通过本文,我们探讨了在处理长文本时可采取的不同策略及其实现方法。若要深入学习,请参考以下资源:

参考资料

  • LangChain相关库
  • Wikipedia

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
—END—

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值