想象你是某个蓬勃发展的组织的知识中心,管理着一个充斥着各种复杂文档的数字图书馆,比如冗长的PDF文档、详尽的报告和复杂的手册,这些手册中充满了宝贵的信息。每天,同事们都会来找你询问急切的问题:“我该如何配置这个新系统呢?”“最新的政策更新情况如何?”“我是否能在一处查看这个项目的所有细节?”
乍一看,提供答案似乎很简单。但这里有件事需要注意:这些文件远非用户友好。许多文件长达数百页,充斥着密集的表格、复杂的图表以及大量的技术文本。快速找到正确答案感觉就像大海捞针一样。你可能会花费数小时翻阅页面寻找,希望能准确找到每个人所需的信息,但这既不高效也不实际,浪费时间。
现在,如果你有一个聪明的助手能轻松处理每份文档,提取最相关的部分,并在几秒内提供确切的信息会怎么样? 我们正在探索的正是这种解决方案——一个能解析大型复杂文档并使其易于搜索的系统,让使用者能够瞬间找到所需信息。
如今,组织面临着海量未结构化数据的挑战,这些数据散落在各种文档之中。关键信息往往被锁定在难以访问或搜索的格式中。传统方法在深入文档内容以找到特定答案时显得力不从心。
常见的问题:- 低效搜索:翻阅大量文件耗时耗力。
- 信息过载:海量信息使得找到相关内容变得困难。
- 非结构化格式:各种文档类型和格式使数据检索复杂化。
- 响应延迟:无法迅速回答问题会妨碍决策进程。
为了解决这些问题,我们正在构建一个高效的文档处理流程。它就像是一个智能助手,帮助处理您的所有数据。这个系统能为您做以下几件事:
1. 轻松搞定大文档该系统处理巨大的PDF、图像和其他文件类型时毫不费力,不会出现卡顿。它利用高效的解析器来处理任意大小的文档。
2. 按关键部分整理利用目录功能,它会自动将文档分解成逻辑部分,这样让导航变得一目了然,也符合用户查找信息的习惯。
3. 标记并结构化内容它能够识别各种内容类型——文本、表格、图片——并将其组织起来,便于访问。通过分类,用户可以快速找到特定类型的信息。
4. 存下所有东西,以便快速查找每个部分都通过向量嵌入丰富了语义,使其能够基于概念相关性,而不是仅仅基于关键词,进行快速且准确的检索。
5. 即时问答用户只需用自然语言提问,系统就会检索他们需要的准确信息,无需手动搜索,。这不仅加快了回复时间,还提高了工作效率。
推动解决方案的技术力量为了让这个系统运作起来,我们正在用一系列尖端的技术。
将其视为系统的“数字剪刀”,根据目录把大的 PDF 文件切成几部分。这让我们可以把文档分割成容易管理的部分,从而提高处理效率,更加方便。
Unstructured.io一个多功能的工具包,帮助识别并标注文档中的各种元素,从文本、表格到图像。它能够从非结构化文件中解析并提取结构化的信息。
OpenAI的嵌入式API充当“记忆”,捕捉每一部分的意义,使我们能够通过概念而不是仅仅通过关键词进行搜索。它将文本转换为高维的向量,编码语义信息,使我们能够通过概念搜索。
MongoDB(一种NoSQL数据库)一个快速灵活的存储方案,其中每一块数据都被索引并随时可检索。它充当可扩展的向量资料库,用于存储嵌入和元数据。
LangChain(语言链)具备解读用户问题并连接到相关内容的智能。它还能帮助创建这些高级的应用,比如做摘要或回答问题等任务。
启程:将文档转换为可搜索的知识通过一系列步骤处理文档,该解决方案以Unstructured.io为核心功能,从而创建一个结构化、可搜索的知识库系统。
- 文档导入
我们首先加载并准备大型PDF文件以进行处理。使用PyMuPDF,文档根据目录或逻辑部分分割成可管理的片段,使解析更加顺畅。 - 使用PyMuPDF动态拆分
利用PyMuPDF根据目录部分动态拆分文档。如果目录列出诸如“第一章”、“介绍”或“附录”等部分,PyMuPDF会检测相关的页面边界,生成易于处理的段。 - 使用Unstructured.io解析和拆分
接下来,Unstructured.io解析每个文档部分。分区策略将内容分解成核心元素——段落、表格、标题、图片——而拆分则进一步将这些元素分解为更小的、适合模型的片段。
from unstructured.partition.pdf import 分割PDF # 分割PDF文件的函数
元素 = 分割PDF( # 获取分割后的元素
文件名="document_section.pdf", # 指定要分割的PDF文件名
策略="hi_res", # 设置分割策略为高分辨率
PDF 表格结构检测=True, # 开启PDF表格结构检测
分块策略="by_title", # 设置分块策略为按标题
最大字符数=1500, # 设置每个分块的最大字符数
重叠=100 # 设置分块之间的字符重叠数
)
- 嵌入和存储在MongoDB中
每个解析的部分都被转换为嵌入,使用的是OpenAI的嵌入API,并与元数据一起存储在MongoDB中,以便快速、语义化的检索和访问。 - 构建问答系统的过程:利用LangChain和OpenAI实现自然语言查询功能。
Unstructured.io 拥有一系列功能,使其非常适合将复杂文档转换为结构化、易于搜索的数据。以下简要概述了其核心功能及其最佳应用场景:
1. 拆分:将文档分解为独立的部分。拆分是将文档拆分成其核心元素的过程,例如段落、表格、图片和标题等。这一步骤对于分离文档中的各个部分至关重要,使其更容易组织、搜索和分析其中的数据。在处理大型或复杂的文档时,拆分是必不可少的,因为它以细致的层次组织内容,使您可以更方便地处理文档中的特定部分。
1.1 常见分区选项及其应用场景自动分区
自动分区是默认选项,Unstructured.io 会根据文档类型和结构自动选择最佳的分区策略。这非常适合处理各种通用提取任务,并能很好地处理各种文档类型。
使用场景:混合内容文档(例如文本为主的报告、简单的PDF文件),无需特别的文档划分策略。
代码片段:
from unstructured.partition.pdf import partition_pdf
# 根据内容自动划分文件
elements = partition_pdf(
filename="general_document.pdf",
strategy="auto"
)
二. 快速划分
快速分段策略利用传统NLP技术快速提取文本。此策略适用于文本密集型的文档,其中布局识别不是关键。它跳过复杂的基于模型的检测,这使得它更快,但对结构化数据的准确性较低。
使用场景:大型以文本为主的PDF,比如电子书或报告,速度优先,不需要复杂的结构。
代码片段:
from unstructured.partition.pdf import partition_pdf
# 使用快速提取策略进行快速提取
elements = partition_pdf(
filename="text_heavy_document.pdf",
strategy="fast"
)
解释:fast
策略(或快速策略)采用传统的文本提取方法,跳过了基于模型的布局分析。这非常适合文本密集型文件,可以在不处理表格或图片的情况下实现更快的提取速度。
3.: 高分辨率分割
高分辨率分区策略采用基于模型的方法来检测复杂的文档结构。它准确地分类和提取不同的元素,例如表格和图片,非常适合包含各种格式化内容的文档。
使用场景:财务报告、技术手册,或者任何需要保留表格、图片和文本布局的文档。
一段代码:
from unstructured.partition.pdf import partition_pdf
# 在这种复杂布局的PDF文档中,使用高分辨率策略来处理表格和图片
元素 = partition_pdf(
filename="complex_report.pdf",
strategy="hi_res",
pdf_infer_table_structure=True,
extract_images_in_pdf=True
)
说明:hi_res
策略使用基于模型的提取来保留文档的布局,准确捕捉表格和图片等。pdf_infer_table_structure=True
选项启用了结构化抽取表格,而extract_images_in_pdf=True
则将图片保存到指定目录。这种设置非常适合那些视觉结构和文本内容一样重要的文档。
_4. OCR 分区:**
仅使用OCR的方法通过OCR技术从图像文档中提取文本。它适用于扫描的文档、图像密集的PDF文件或不可选择的多语言文档。
案例:扫描的合约、图像文档或多种语言的内容。
代码片段:
from unstructured.partition.pdf import partition_pdf
# 使用OCR从图像文档中提取文本
elements = partition_pdf(
filename="scanned_document.pdf",
strategy="ocr_only", # 方法设置为仅使用OCR
ocr_languages="eng, spa" # OCR语言设置,支持英文和西班牙文
)
解释:使用ocr_only
策略通过OCR从扫描或图像文档中提取文本。指定ocr_languages="eng, spa"
支持英语和西班牙语文本,适用于多语言文档处理。这种方法常用于文档数字化流程中。
当文档分割时,Unstructured.io 会自动捕获每个元素的元数据信息,提供关于其位置和类型的上下文信息。这在跟踪大型文档中的部分,或保持数据的完整来源(溯源)方面特别有用。
例子:
for element in elements:
print(element.metadata.to_dict()) # 打印每个元素的元数据
解释:Unstructured.io 会自动为每个提取的元素添加元数据,提供包括页码、文件名以及元素类型等相关信息。
2. 分块:将元素分成可管理的小块分块是指将已划分的元素进一步细分为更小、更易管理的部分或块。这一步特别有用,尤其是在处理语言模型或嵌入模型时。这样可以确保每个块都在模型的最大上下文限制之内。分块还能逻辑地组织内容,比如按部分或主题来划分。这样一来,处理或查询特定部分就更加方便了。
2.1 常见分块选项及应用场景1. 第一步:基本分段
基础分块将连续元素组合成块,每个块的长度限制在指定字符数内。这种方法简单且直接,并且提供了固定大小的块,这对于使用有最大输入长度限制的模型非常重要。
用例:通用分段,用于等大小的块,非常适合输入长度有限的模型。
代码片段 :如下所示
from unstructured.partition.pdf import partition_pdf
# 将文档分割成等大小的段落
elements = partition_pdf(
filename="document.pdf",
chunking_strategy="basic",
max_characters=1500
)
for chunk in elements:
print(chunk.text) # 打印分段文本内容
2: 按标题分段
按标题分块确保每个部分都从一个新的标题开始,保留文档内部的逻辑结构。这种方法特别适合于有明确部分划分的文档,在这些文档中每个标题代表一个独立话题。
使用场景:结构化的章节,如研究论文、教科书或其他报告。
代码片段 如下所示:
from unstructured.partition.pdf import partition_pdf
# 使用基于标题的分块来分离逻辑上分开的部分
elements = partition_pdf(
filename="sectioned_document.pdf",
chunking_strategy="by_title",
max_characters=1500,
overlap=100 # 添加重叠以保持上下文的连贯性
)
解释:by_title
分块策略会在每个标题处创建分块,保持逻辑上的分节。设置 max_characters=1500
来限制每个分块的长度,并设置 overlap=100
来保持分块间的上下文联系。这种设置对于结构明显的文档特别有用,便于查询特定部分的内容。
3. 按页分块
按页分块是根据页面边界划分内容,对于每页信息独立的文档(如幻灯片或手册)特别有用。这种方法简单明了,但保留了页面特定的信息,这对某些类型的文档来说非常有用。
用例:演示幻灯片、手册或每页内容不同的文档或文件。
这里是一个代码段:
从unstructured.partition.pdf导入partition_pdf()
# 将内容按页面分割
elements = partition_pdf(
filename="paged_document.pdf",
chunking_strategy="by_page"
)
4. 根据相似性分组
这种方法将相似内容分成组,适用于相关主题分散在各页的文档。通过分组语义相似的内容,这种方法非常适合用于基于主题的检索,如问答和内容摘要。
使用场景:文档存档、包含不同章节相关主题的大报告以及问答应用。
代码段 :
from unstructured.partition.pdf import partition_pdf
# 根据语义相似性分割文档
elements = partition_pdf(
filename="thematic_document.pdf",
chunking_strategy="基于相似度"
)
Unstructured.io (一些选项)
一旦文档内容被分割成块之后,下一步是将每个块转换为一个“嵌入向量”。嵌入向量是一种高维向量表示,用于编码文本的语义,使得比较各块之间的相似度变得容易。使用OpenAI的嵌入API,每个块会被转换成一个向量,这种转换使得基于概念的检索成为可能,而不仅仅是简单的关键词匹配。
以下代码片段:
from langchain_openai import OpenAIEmbeddings as OpenAIEmbeddings
# 为每个分块文本生成嵌入向量
embedding_model = OpenAIEmbeddings()
documents = [{"text": chunk.text, "embedding": embedding_model.embed(chunk.text)} for chunk in elements]
在这个设置里,嵌入捕捉了每个文档部分中的细微含义。当它们被存入向量数据库时,这使得通过概念相关性进行基于相似性的高级检索变得简单。
持久性:将嵌入向量和元数据存储在MongoDB中生成嵌入数据后,接下来需要将这些数据存储在可扩展且高效的数据库中,以实现快速检索。MongoDB非常适合这里,它是一个快速且灵活的存储解决方案,不仅可以存储嵌入向量,还可以存储每个文档片段的元数据。元数据包括比如页面编号、元素类型或源文件名等重要信息,这些信息对索引和检索非常重要。
这是一个代码片段 :
from Python import MongoClient
client = MongoClient("mongodb://localhost:27017")
db = client['知识库']
collection = db['文档片段']
# 将每个文档片段及其嵌入和元数据存储到MongoDB中
for document in documents:
collection.insert_one({
"text": document["text"],
"embedding": document["embedding"],
"metadata": document["metadata"]
})
存储每个块的嵌入和元数据信息,让用户能根据概念搜索,并找到内容丰富的信息,从而使文档检索更互动和动态。
智能问答系统:基于LangChain和OpenAI的智能查询最终的目标是创建一个无缝的问题与回答(Q&A)系统,让用户可以用自然语言提问,系统则检索相关的文档片段。LangChain通过整合自然语言查询和基于嵌入的搜索技术,实现了这个目标。当用户提出问题时,LangChain将其转换为嵌入向量,并在MongoDB中基于向量相似性搜索最相关的片段。
问答系统分为两个步骤
- 嵌入用户问题:LangChain 使用 OpenAI 的嵌入模型将用户的问题转换成向量。
- 查找相关的文档部分:MongoDB 使用该向量执行相似度搜索,返回最相关的文档片段来匹配查询。
一段代码:
从langchain和langchain_openai中导入LLMChain和ChatOpenAI
# 使用LangChain构建问答链
llm = ChatOpenAI(model="gpt-4", openai_api_key="YOUR_API_KEY")
qa_chain = LLMChain(llm=llm, prompt_template="回答用户的查询。")
def answer_question(question):
question_embedding = embedding_model.embed_text(question)
# 在MongoDB中搜索最接近问题嵌入的文档
relevant_docs = collection.find({"embedding": {"$near": question_embedding}})
return qa_chain.run(relevant_docs)
通过这种设置,系统可以检索与用户查询相关的具体段落,而问答界面简化了访问复杂文档的过程,直接提取用户所需答案,大大节省了用户的时间和精力。
结论部分Unstructured.io 提供了一个强大的解决方案,帮助组织将复杂的文档库转变为易于访问的知识密集型资产。通过将文档拆分为逻辑部分,通过语义嵌入丰富内容,并支持自然语言查询,这套工具包不仅超越了简单的文档存储功能。它将非结构化数据转化为结构化且可操作的洞察,助力决策制定,加快信息检索速度,并提高工作效率。
这条管道—依托Unstructured.io的解析和分块功能、PyMuPDF的文档分割、OpenAI的嵌入式模型、LangChain的NLP能力以及MongoDB的可扩展的存储—提供了一种创新的方式来管理和存储信息。结果是一个动态智能助手,能快速访问重要信息,而无需进行繁琐的手动查找。
无论您的组织管理的是公司知识库、研究资料还是客户支持文件,Unstructured.io 都能提高文档数据的价值,将其转化为一个强大的、即时可搜索的知识资源。通过这种方式,任何人都可以瞬间从复杂的文档中提取有价值的信息,让知识管理不仅变得可能,而且更加直观高效。
共同學習,寫下你的評論
評論加載中...
作者其他優質文章