-推荐关注-
为了避免上下文限制、噪声干扰和成本等问题,通过优化查询思路进行文档问答。分段预处理保留关键信息,再利用嵌入模型生成语义向量,结合向量数据库高效检索相关内容。筛选后的精确片段由大语言模型生成答案,该思路显著提升文档查询的效率与准确性。
1. 长文档查询存在的问题 2. 查询的基本思路 2.1 文档预处理 2.2 嵌入与相关性检索 2.3 模型生成与回答 3.代码实现
-- 领取学习资料大礼包,见文末
当下,大语言模型(LLM, Large Language Models)已经成为自然语言处理领域的核心力量。
这些模型拥有处理长文本、理解语义以及生成自然语言的能力,使其成为构建智能问答系统和信息检索工具的理想选择。
然而,当涉及到查询长文档时,我们面临诸多挑战,包括模型的上下文长度限制、噪声干扰对结果的影响以及效率和成本的平衡。
1. 长文档查询存在的问题
大语言模型虽然强大,但目前其输入上下文长度通常有限,例如 GPT-4 的上下文长度虽然可以达到 32k 字符,但仍无法直接处理过长的文档。
此外,直接将整个文档传递给模型处理可能导致信号与噪声比降低,无关信息占据较大比重,增加了模型提取核心信息的难度。
同时,效率与成本也是使用 LLM 查询长文档的关键问题。
长文本的输入不仅会增加推理时间,还会显著提高调用费用。
因此,在实际应用中,我们需要通过优化技术来确保模型在处理文档时能够聚焦于与问题相关的部分,提高回答的准确性和效率。
2. 查询的基本思路
在应对上述问题,一个清晰的基本思路便是:通过分段处理和筛选,先选出与问题最相关的内容,再将其传递给大语言模型进行进一步处理。
大概分为以下几个步骤:文档预处理、嵌入与相关性检索,以及最终的生成与回答。
虽然这些步骤可以根据具体需求进行调整,但它们构成了文档查询的核心流程。
2.1 文档预处理
长文档通常需要被拆分成多个小段,以便于后续的相关性筛选与向量化处理。
拆分的粒度可以是段落、句子甚至固定长度的文本块。
拆分策略的选择应基于具体应用场景,例如,对于结构化文档(如技术文档或报告),可以利用章节或段落作为分割单位。
在拆分的过程中,需要注意保持上下文信息的完整性。过于细化的拆分可能导致信息片段丢失或难以理解,而过于粗糙的拆分则可能增加筛选的难度。
因此,一个好的拆分策略应能在信息完整性和处理效率之间找到平衡。
2.2 嵌入与相关性检索
在完成文档的分段后,接下来的关键步骤是将文本转化为向量表示。
这一过程通常借助嵌入模型(Embedding Model)实现,例如 OpenAI 的 text-embedding-ada-002
或 Hugging Face 提供的 Sentence Transformer 模型。
嵌入模型能够将文本转化为高维向量,这些向量能够捕捉文本的语义信息,从而便于相似性计算。
当用户输入查询问题时,同样需要将查询转化为向量表示。
通过计算查询向量与文档片段向量之间的相似度(例如余弦相似度),我们可以快速筛选出与查询最相关的片段。
向量数据库(如 Chroma)在这一过程中起到了关键作用,它们能够高效地存储和检索嵌入向量。
通过向量检索,文档中的无关部分被有效过滤掉,仅将少量高相关性的片段传递给大语言模型。这种方法不仅显著提高了信号与噪声比,还显著降低了计算成本和模型的负担。
相关阅读:
Sentence Transformer :人工智能小白到高手:Sentence-Transformers
2.3 模型生成与回答
一旦完成相关性筛选,与查询问题高度相关的文档片段便会被传递给大语言模型进行生成与回答。
在这一阶段,大语言模型可以利用上下文信息生成自然语言答案。由于之前的筛选过程已经剔除了大部分干扰信息,模型可以更加专注于核心内容,从而提高回答的准确性和相关性。
在某些情况下,我们还可以对模型的回答进行后处理。例如,通过规则校验确保回答符合特定的格式或约束条件。
3.代码实现
环境:
Python 3.10
LangChain 0.3
加载文档
import os
OPENAI_API_KEY = 'hk-iwte427'# 设置OpenAI API密钥
os.environ['OpenAI_API_KEY'] = OPENAI_API_KEY # 将API密钥设置为环境变量
# 导入文档加载器
from langchain_community.document_loaders import TextLoader
# 导入文本分割器
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 创建文本加载器,加载西游记文本文件,前10回的内容
loader = TextLoader(file_path="../data/西游记1.txt", encoding='utf-8')
# 加载文档内容
data = loader.load()
print(f'一共 {len(data)} 个文档') # 打印加载的文档数量
print(f'一共 {len(data[0].page_content)} 个字符') # 打印第一个文档的字符数
一共 1 个文档
一共 73714 个字符
文档预处理
# 创建文本分割器,设置块大小和重叠
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
# 分割文档
texts = text_splitter.split_documents(data)
print(f'一共 {len(texts)} 个块') # 打印分割后的文本块数量
一共 206 个块
文档嵌入
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
# 创建OpenAI嵌入实例
embeddings = OpenAIEmbeddings(model="text-embedding-3-large", base_url="https://api.openai-hk.com/v1")
# 创建向量存储,将文本块转换为向量
vectorstore = Chroma.from_documents(texts, embeddings)
Chroma 是一款开源、轻量化的向量数据库,专为嵌入向量管理和相似性搜索设计。Chroma 易于集成,可与大语言模型(LLM)配合,实现检索增强生成 (RAG)。相比 Pinecone 和 Weaviate 等,Chroma 更简单、灵活,适合中小规模数据和本地部署需求。
相关性检索
query = "孙悟空的兵器是什么?" # 设置查询问题
# 在向量存储中搜索相似文档
docs = vectorstore.similarity_search(query)
for doc in docs: # 遍历搜索结果
print(f"{doc.page_content}\n") # 打印每个相关文档的内容
三个相关性文档:
好猴王,跳至桥头,使一个闭水法,捻着诀,扑的钻入波中,分开水路,径入东洋海底。正行间,忽见一个巡海的夜叉,挡住问道:“那推水来的,是何神圣?说个明白,好通报迎接。”悟空道:“吾乃花果山天生圣人孙悟空,是你老龙王的紧邻,为何不识?”
...省略一堆字...
好猴王,即拔一把毫毛,入口嚼烂,喷将处去,念动咒语,叫声:“变!”变做千百个小猴,都乱搬乱抢;有力的拿五七件,力小的拿三二件,尽数搬个罄净。径踏云头,弄个摄法,唤转狂风,带领小猴,俱回本处。
龙王心中恐惧,又着□【左“鱼”右“便”】提督、鲤总兵抬出一柄画杆方天戟,那戟有七千二百斤重。悟空见了,跑近前接在手中,丢几个架子,撒两个解数,插在中间道:“也还轻!轻!轻!”老龙王一发怕道:“上仙,我宫中只有这根戟重,再没甚么兵器了。”悟空笑道:“古人云:‘愁海龙王没宝哩!’你再去寻寻看。若有可意的,一一奉价。”龙王道:“委的再无。”
你看这猴王,分开水道,径回铁板桥头,撺将上去,只见四个老猴,领着众猴:都在桥边等待。忽然见悟空跳出波外,身上更无一点水湿,金灿灿的,走上桥来。唬得众猴一齐跪下道:“大王,好华彩耶!好华彩耶!”悟空满面春风,高登宝座,将铁棒竖在当中。那些猴不知好歹,都来拿那宝贝,却便似蜻蜓撼铁树,分毫也不能禁动。
...省略一堆字...
众猴骇然,叫道:“大王!还拿出来耍耍!”猴王真个去耳朵里拿出,托放掌上叫:“大!大!大!”即又大做斗来粗细,二丈长短。他弄到欢喜处,跳上桥,走出洞外,将宝贝攥在手中,使一个法天像地
生成答案
from langchain_openai import ChatOpenAI
from langchain.chains.question_answering import load_qa_chain
llm = ChatOpenAI(
model="gpt-4o-mini", # 使用gpt-4o-mini模型
temperature=0, # 设置温度为0,使输出更确定性
base_url="https://api.openai-hk.com/v1" # 指定API端点
) # 创建OpenAI聊天模型实例
chain = load_qa_chain(llm, chain_type="stuff") # 加载问答链
chain.run(input_documents=docs, question=query) # 运行问答链,获取答案
孙悟空的兵器是如意金箍棒。
RAG(检索增强生成)代表了大语言模型在文档查询任务中的重要演进,它将检索与生成结合,不仅提升了信息查询的效率,还在多样化的实际场景中展现了巨大的潜力。比如企业知识管理、客户服务与技术支持等
文档查询能力作为RAG的基本能力,使得RAG的实际应用和未来发展方向变得更加系统化和高效化。它不仅解决了大语言模型在文档查询中的信息冗余和上下文限制问题,还赋予了系统更强的扩展性和实时性。
有需要的,在公众号「AI取经路」发消息「学习资料」即可获取。
--END--
点亮“赞”和“在看”,“分享”好友一起看