有效处理长文档提取的策略:分段与RAG方法

249 阅读2分钟
# 引言
在处理PDF等文件时,我们常常会遇到文本长度超出语言模型(LLM)上下文窗口的情况。为了有效地从这样的长文本中提取信息,本文将介绍两种主要策略:分段处理和RAG(Retrieval-Augmented Generation)方法。本文的目的是帮助您理解如何在实用中实施这些策略,并应对潜在的挑战。

# 主要内容

## 1. 分段处理策略
分段处理(Brute Force)是将文档划分为多个小块,每个小块的长度都在LLM的上下文窗口范围内,逐一从每个块中提取内容。这种方法简单直接,但可能会带来信息重复或丢失的问题。

## 2. RAG方法
RAG基于检索的生成方法,将文档分块并构建索引,仅从一小部分看似“相关”的块中提取内容。这种方法可以减少处理不必要信息的机会,但也可能丢失重要信息。

# 代码示例

以下是使用分段处理策略的代码示例:

```python
# 下载示例数据并进行预处理
import requests
import re
from langchain_community.document_loaders import BSHTMLLoader
from langchain_text_splitters import TokenTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

# 下载维基百科关于汽车的文章
response = requests.get("https://en.wikipedia.org/wiki/Car")
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)

# 定义分段器
text_splitter = TokenTextSplitter(chunk_size=2000, chunk_overlap=20)
texts = text_splitter.split_text(document.page_content)

# 提取内容
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "你是历史发展事件的识别专家。只提取重要的历史发展事件。"),
        ("human", "{text}"),
    ]
)

llm = ChatOpenAI(model="gpt-4-0125-preview", temperature=0)  # 使用API代理服务提高访问稳定性
extractor = prompt | llm.with_structured_output()
extractions = extractor.batch([{"text": text} for text in texts[:3]], {"max_concurrency": 5})

# 合并结果
key_developments = []
for extraction in extractions:
    key_developments.extend(extraction.key_developments)

print(key_developments[:10])

常见问题和解决方案

  • 信息丢失:由于分段可能会导致上下文信息的丢失,建议增加块间的重叠。
  • 信息重复:块重叠可能导致信息重复提取,建议在合并结果时进行去重。
  • 数据生成错误:LLMs可能生成不正确的数据,建议对结果进行人工验证。

总结和进一步学习资源

有效处理长文档的关键在于选择合适的策略并处理好由于分段带来的挑战。希望本文的内容为您在设计应用时提供了一些有用的见解。

进一步学习资源:

参考资料

  • LangChain 文档和库
  • OpenAI API 文档

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

---END---