您是否在PDF文件,文档和报告上执行了抹布?许多重要的文档不仅仅是简单的文本。考虑研究论文,财务报告或产品指南。它通常包含段落,表格和其他有组织元素的混合物。这对常规的抹布系统构成了重大挑战。它需要有效的半组织数据,而不仅仅是划分基本文本。本指南通过使用高级知情的智能数据分析(称为RETRIEVER Multi-Vector)提供了一个实用的解决方案,均在Langchain RAG框架内。
在半组织数据上需要抹布
传统的抹布管道经常偶然发现这些混合文档。首先,叛徒可以将简单的文本切成两半,从而摧毁内部有价值的数据。其次,包含大表格的原始文本可以为语义研究创造嘈杂和无效的向量。语言模型可能不会看到正确的上下文来回答用户的问题。
我们将构建一个更聪明的系统,该系统将文本与表分开,并使用不同的策略来存储和恢复每个策略。这种方法可以确保我们的语言模型获得提供准确答案所需的确切和完整的信息。
解决方案:检索中更聪明的方法
我们的解决方案涉及使用两个主要组件面对的基本挑战。此方法围绕准备数据并以保持其原始含义和结构的方式恢复。
- 智能数据分析: 我们使用非结构化库进行第一个繁重的工作。而不是故意划分文本,无组织
partition_pdf
该功能分析文档布局。它可以判断段落和桌子之间的区别,提取每个元素清洁并保持其安全性。 - 多指导恢复: 这是我们先进的抹布技术的本质。多层恢复使我们能够存储数据的多个表示。要检索,我们将使用简短的摘要来切断我们的文本和表格。这些较小的摘要最好包括并寻找相似之处。为了生成答案,我们将将完整,原始或文本表传递给语言模型。这提供了所需的完整背景。
似乎是这样的全面工作流程:
建造破布管道
让我们继续如何逐步构建此系统。我们将使用Llama2搜索表作为我们的示例文档。
步骤1:准备环境
首先,我们需要安装必要的蛇包。我们将使用Langchain为我们的载体进行基本,不规则和色度框架。
! pip install langchain langchain-chroma "unstructured[all-docs]" pydantic lxml langchainhub langchain_openai -q
Unscractive的PDF分析取决于两个用于处理和识别视觉字母(OCR)的外部工具。如果您在Mac上,则可以轻松地使用Homebrew进行安装。
!apt-get install -y tesseract-ocr
!apt-get install -y poppler-utils
步骤2:通过非组织下载数据和分析
我们的第一个任务是治疗PDF。我们使用没有调节器的Partition_PDF,它是为这种非结构性数据分析而设计的。我们将配置它以确定表,并通过其地址和翻译剪切文档。
from typing import Any
from pydantic import BaseModel
from unstructured.partition.pdf import partition_pdf
# Get elements
raw_pdf_elements = partition_pdf(
filename="/content/LLaMA2.pdf",
# Unstructured first finds embedded image blocks
extract_images_in_pdf=False,
# Use layout model (YOLOX) to get bounding boxes (for tables) and find titles
# Titles are any sub-section of the document
infer_table_structure=True,
# Post processing to aggregate text once we have the title
chunking_strategy="by_title",
# Chunking params to aggregate text blocks
# Attempt to create a new chunk 3800 chars
# Attempt to keep chunks > 2000 chars
max_characters=4000,
new_after_n_chars=3800,
combine_text_under_n_chars=2000,
image_output_dir_path=path,
)
扮演分区器后,我们可以看到您发现的元素类型。导演显示两种主要类型: CompositeElement
切断文字和 Table
对于桌子。
# Create a dictionary to store counts of each type
category_counts = {}
for element in raw_pdf_elements:
category = str(type(element))
if category in category_counts:
category_countsBeginner += 1
else:
category_countsBeginner = 1
# Unique_categories will have unique elements
unique_categories = set(category_counts.keys())
category_counts
导演:

如您所见,不规则在确定两个不同的时间表和85个文本方面做得很好。现在,让我们将这些东西分为独特的清单,以促进治疗。
class Element(BaseModel):
type: str
text: Any
# Categorize by type
categorized_elements = []
for element in raw_pdf_elements:
if "unstructured.documents.elements.Table" in str(type(element)):
categorized_elements.append(Element(type="table", text=str(element)))
elif "unstructured.documents.elements.CompositeElement" in str(type(element)):
categorized_elements.append(Element(type="text", text=str(element)))
# Tables
table_elements = [e for e in categorized_elements if e.type == "table"]
print(len(table_elements))
# Text
text_elements = [e for e in categorized_elements if e.type == "text"]
print(len(text_elements))
导演:

步骤3:创建摘要以改善恢复
不要创建大桌子和长文本块,非常有效地用于语义研究。但是,摘要摘要是完美的。这是使用多级恢复的核心思想。我们将创建一个简单的Langchain系列来创建这些摘要。
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from getpass import getpass
OPENAI_KEY = getpass('Enter Open AI API Key: ')
LANGCHAIN_API_KEY = getpass('Enter Langchain API Key: ')
LANGCHAIN_TRACING_V2="true"
# Prompt
prompt_text = """You are an assistant tasked with summarizing tables and text. Give a concise summary of the table or text. Table or text chunk: {element} """
prompt = ChatPromptTemplate.from_template(prompt_text)
# Summary chain
model = ChatOpenAI(temperature=0, model="gpt-4.1-mini")
summarize_chain = {"element": lambda x: x} | prompt | model | StrOutputParser()
现在,我们将该系列应用于提取的表格并剪切文本。付款方法使我们能够同时处理这些问题,从而加快了事情。
# Apply to tables
tables = [i.text for i in table_elements]
table_summaries = summarize_chain.batch(tables, {"max_concurrency": 5})
# Apply to texts
texts = [i.text for i in text_elements]
text_summaries = summarize_chain.batch(texts, {"max_concurrency": 5})
步骤4:在现场建立多次恢复
准备好我们的摘要,是时候建造一个恢复了。存储的两个组成部分:
- 矢量店(Chromadb)存储建造-in 摘要。
- DOCSTORE拥有一个简单的存储器商店) 生的 表和文本内容。
RETRIEVER使用唯一的标识符来在矢量存储中的摘要与原始文档之间创建链接,以换取文档。
import uuid
from langchain.retrievers.multi_vector import MultiVectorRetriever
from langchain.storage import InMemoryStore
from langchain_chroma import Chroma
from langchain_core.documents import Document
from langchain_openai import OpenAIEmbeddings
# The vectorstore to use to index the child chunks
vectorstore = Chroma(collection_name="summaries", embedding_function=OpenAIEmbeddings())
# The storage layer for the parent documents
store = InMemoryStore()
id_key = "doc_id"
# The retriever (empty to start)
retriever = MultiVectorRetriever(
vectorstore=vectorstore,
docstore=store,
id_key=id_key,
)
# Add texts
doc_ids = [str(uuid.uuid4()) for _ in texts]
summary_texts = [
Document(page_content=s, metadata={id_key: doc_ids[i]})
for i, s in enumerate(text_summaries)
]
retriever.vectorstore.add_documents(summary_texts)
retriever.docstore.mset(list(zip(doc_ids, texts)))
# Add tables
table_ids = [str(uuid.uuid4()) for _ in tables]
summary_tables = [
Document(page_content=s, metadata={id_key: table_ids[i]})
for i, s in enumerate(table_summaries)
]
retriever.vectorstore.add_documents(summary_tables)
retriever.docstore.mset(list(zip(table_ids, tables)))
步骤5:运行抹布系列
最后,我们构建了完整的Langchain管道。该系列将提出一个问题,使用恢复来引入相关摘要,撤回相应的原始文档,然后将所有内容传递给语言模型以创建答案。
from langchain_core.runnables import RunnablePassthrough
# Prompt template
template = """Answer the question based only on the following context, which can include text and tables:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
# LLM
model = ChatOpenAI(temperature=0, model="gpt-4")
# RAG pipeline
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| model
| StrOutputParser()
)
Let's test it with a specific question that can only be answered by looking at a table in the paper.
chain.invoke("What is the number of training tokens for LLaMA2?")
导演:

该系统完全工作。通过检查过程,我们可以看到第一次摘要1摘要发现了恢复,该摘要讨论了表单和培训数据的参数。接下来,从文档中恢复完整的表格,并将其呈现给LLM。该模型给出了正确回答问题所需的确切数据,证明了该抹布在几乎有组织的数据方法上的强度。
您可以访问Colab笔记本或GitHub仓库上的完整代码。
结论
用文本和混合表处理文档是现实世界中常见的问题。在大多数情况下,简单的RAG管道还不够。通过将揭露的智能数据的分析与多个掩盖的恢复相结合,我们创建了一个更强大,更准确的系统。这种方法可以确保您的文档的复杂结构变为力量,而不是弱点。它以一种简单的理解方式提供了语言的完整背景,从而导致更好,更可靠的答案。
阅读更多:使用Llama索引创建抹布管道
相关问题
是的,非结构性库支持广泛的文件类型。您只需将Partition_PDF与正确的函数交换,例如Partition_Docx。
答:不,您可以从每件作品中创建虚拟问题,也可以简单地包含原始文本,如果它足够小。摘要通常是复杂表中最有效的。
答:可以创建“嘈杂”的大表格,因为细节中的主要含义丢失了。这使语义研究降低了。摘要摘要概述了表的本质以改善检索。
登录以继续阅读并享受专家内容。