基于 LangChain 和 ChatGPT 构建 PDF 问答机器人
介绍使用 LangChain 结合向量数据库和大模型构建 PDF 问答机器人的方案。通过加载文档、文本分割、嵌入向量化及索引构建,实现基于语义搜索的问答功能。利用 OpenAI API 或私有部署模型,结合多种 Chain 类型处理检索与生成,有效解决大模型幻觉问题,提升对非结构化文档信息的提取与问答准确性。

介绍使用 LangChain 结合向量数据库和大模型构建 PDF 问答机器人的方案。通过加载文档、文本分割、嵌入向量化及索引构建,实现基于语义搜索的问答功能。利用 OpenAI API 或私有部署模型,结合多种 Chain 类型处理检索与生成,有效解决大模型幻觉问题,提升对非结构化文档信息的提取与问答准确性。

在使用 ChatGPT 等通用大模型后,我们常面临一个需求:能否利用它来处理我们自己的私有文档资料,并提供精准的文档问答与摘要?
直接微调模型虽然可行,但成本高且需要大量数据集,且通常只能赋予模型单一技能。另一种方法是使用提示词(Prompt)将文档上下文传入,但受限于 Token 长度和 API 调用成本,处理大量文档时效率较低。
本文介绍一种基于检索增强生成(RAG)的思路,使用 LangChain 结合向量数据库和大模型构建 PDF 聊天机器人原型。该方案证明了从非结构化文档中提取信息并进行问答的可行性,同时避免了大模型在未训练知识上的幻觉问题。
核心流程如下:
注:上图展示源文件经工程化处理存入向量库,用户问题向量化后匹配最近邻数据返回给大模型,并记录聊天历史。
运行本项目需要 Python 版本不低于 3.7。建议创建虚拟环境以隔离依赖。
# 创建虚拟环境
$ python3 -m venv llm_app_env
# 在 MacOS 或 Linux 上激活
$ source llm_app_env/bin/activate
# 在 Windows 上激活
$ llm_app_env\Scripts\activate.bat
openai[embeddings]==0.27.6
langchain==0.0.155
pypdf==3.8.1
tiktoken==0.3.3
faiss-cpu==1.7.4
unstructured==0.6.2
chromadb==0.3.21
llama-index ==0.6.1
jupyterlab
LangChain 是一个功能强大的开源工具,可作为中间层连接应用程序与各种 LLM 提供商(如 OpenAI、Cohere、Huggingface 等)。它提供了处理内存、长文档及令牌限制问题的特性,支持自定义应用构建。
推荐使用 Jupyter Notebook 进行开发,也可使用 Google Colab 在线平台。
在代码中设置环境变量以使用 OpenAI 服务。
import logging
import sys
import os
os.environ["OPENAI_API_KEY"] = "<YOUR_OPENAI_API_KEY>"
获取 API Key 请访问:https://platform.openai.com/account/api-keys
我们需要加载 PDF 文档并将其分割成合适的片段。RecursiveCharacterTextSplitter 是推荐的通用文本分割器,它尝试按字符列表顺序分割,直到块足够小。
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 加载数据
loader = PyPDFLoader('../notebooks/documents/Apple-Financial-Report-Q1-2022.pdf')
data = loader.load()
# 文本分割器配置
# chunk_size: 每个块的最大字符数
# chunk_overlap: 块之间的重叠字符数,有助于保持上下文连贯性
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(data)
# 查看第一个块
print(texts[0])
Chroma 是一种嵌入式数据库,专为 LLM 应用设计。它将文本映射为实数向量(Embedding),使得语义相似的词汇在向量空间中距离更近。
例如,在嵌入空间中,"国王"和"女王"的向量会比"苹果"更接近,因为它们具有语义关联。通过向量数据库,我们可以执行高效的语义搜索,而非简单的关键词匹配。
from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings
# 初始化 OpenAI Embedding 模型
embeddings = OpenAIEmbeddings(model='text-embedding-ada-002')
# 从文档创建内存中的嵌入数据库
# metadatas: 可选的元数据,用于过滤或追踪来源
docsearch = Chroma.from_documents(
texts,
embeddings,
metadatas=[{"source": str(i)} for i in range(len(texts))]
)
# 执行相似性搜索
query = "What is the operating income?"
docs = docsearch.similarity_search(query)
LangChain 提供了多种预建的 Chain 类型来处理问答任务。它们的主要区别在于如何处理检索到的上下文以及是否返回来源引用。
将所有检索到的文档内容作为上下文传递给 LLM。
from langchain.chains.question_answering import load_qa_chain
from langchain.chat_models import ChatOpenAI
chain = load_qa_chain(
ChatOpenAI(temperature=0.2, model_name='gpt-3.5-turbo'),
chain_type="stuff"
)
query = "What is the operating income?"
result = chain.run(input_documents=docs, question=query)
print(result)
类似上述方法,但会尝试识别信息来源。
from langchain.chains.qa_with_sources import load_qa_with_sources_chain
chain = load_qa_with_sources_chain(
ChatOpenAI(temperature=0.2, model_name='gpt-3.5-turbo'),
chain_type="stuff"
)
result = chain({"input_documents": docs, "question": query}, return_only_outputs=True)
print(result)
简化接口,自动处理检索步骤。
from langchain.chains import RetrievalQA
qa = RetrievalQA.from_chain_type(
llm=ChatOpenAI(temperature=0.2, model_name='gpt-3.5-turbo'),
chain_type="stuff",
retriever=docsearch.as_retriever()
)
query = "What is the operating income?"
result = qa.run(query)
print(result)
结合检索与来源引用的简化版。
from langchain.chains import RetrievalQAWithSourcesChain
chain = RetrievalQAWithSourcesChain.from_chain_type(
ChatOpenAI(temperature=0.2, model_name='gpt-3.5-turbo'),
chain_type="stuff",
retriever=docsearch.as_retriever()
)
result = chain({"question": "What is the operating income?"}, return_only_outputs=True)
print(result)
至此,一个基于 PDF 文档的问答聊天机器人原型已完成。该机器人能够读取 PDF 内容并根据文档内容进行交互问答。
通过上述方案,我们可以有效地利用自有数据,构建安全、可控的智能问答系统。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online