LangChain 核心组件
PyPDFLoader:PDF 文件读取解析
RecursiveCharacterTextSplitter:递归智能文本切片(解决段落断裂、语义割裂问题)
OpenAIEmbeddings/HuggingFaceEmbeddings:文本向量化(兼顾付费 API 与本地开源模型)
Chroma:轻量本地向量库(无需额外部署,新手首选)
拓展生产方案:Milvus、FAISS、PGVector、Pinecone,底层调用逻辑完全通用,仅替换向量库实例即可
分步拆解全流程
步骤 1:加载 PDF 文档
使用 LangChain 内置 PDF 加载器,自动提取 PDF 全部文字,支持多页、图文型 PDF(纯文字 PDF 效果最优)
from langchain_community.document_loaders import PyPDFLoader# 初始化加载器,替换为你的PDF文件路径loader = PyPDFLoader("./企业技术手册.pdf")# 读取文档,每页生成一个Document对象pages = loader.load()print(f"PDF总页数:{len(pages)}")print("第一页文本预览:")print(pages[0].page_content[:300])
步骤 2:智能文本切片(关键优化点)
直接整页存入向量库会出现语义混杂、检索精度暴跌,采用递归字符分割器,设置块大小 + 重叠区,保证上下文不丢失
from langchain.text_splitter import RecursiveCharacterTextSplitter# 切片参数配置,可根据文档类型调整text_splitter = RecursiveCharacterTextSplitter(chunk_size=800, # 单块文本长度chunk_overlap=150, # 块之间重叠文本,保留上下文关联length_function=len,separators=["\n\n", "\n", "。", ",", " ", ""] # 优先按段落、分句切割)# 对PDF所有页面文本进行切分split_docs = text_splitter.split_documents(pages)print(f"切片后总文本块数量:{len(split_docs)}")print("单块切片示例:")print(split_docs[0].page_content)
步骤 3:初始化 Embedding 向量模型
云端模型
1、OpenAI 接口---国内无法连接(废弃)
from langchain_openai import OpenAIEmbeddingsimport os# 配置OpenAI密钥os.environ["OPENAI_API_KEY"] = "你的OpenAI Key"embedding = OpenAIEmbeddings(model="text-embedding-ada-002")
2、国内合规大模型厂商 Embedding API
百度千帆、阿里通义、腾讯混元、智谱 AI、MiniMax 等,全部国内服务器,备案合规,LangChain 均有对应封装,举智谱示例
from langchain_zhipuai import ZhipuAIEmbeddingsimport osos.environ["ZHIPUAI_API_KEY"] = "国内厂商申请的key"embedding = ZhipuAIEmbeddings(model="embedding-2")
本地模型
1、shibing624/text2vec-base-chinese,完全离线 ---经典开源 maxKBfrom langchain_community.embeddings import HuggingFaceEmbeddingsembedding = HuggingFaceEmbeddings(model_name="shibing624/text2vec-base-chinese",model_kwargs={"device": "cpu"},encode_kwargs={"normalize_embeddings": True})
2、bge-base-zh-v1.5,部署在内网服务器,所有业务机器内网调用from langchain_community.embeddings import OllamaEmbeddings# Ollama部署在内网服务器 192.168.1.100embedding = OllamaEmbeddings(model="bge-base-zh-v1.5",base_url="http://192.168.1.100:11434")
关于模型这快,会写一个专题专门介绍
步骤 4:向量存入 Chroma 本地向量库
Chroma 零部署,自动持久化存储到本地文件夹,重启程序向量不丢失
from langchain_community.vectorstores import Chroma# 持久化向量库文件夹persist_dir = "./chroma_vector_db"# 构建向量库,自动完成文本向量化+入库vector_db = Chroma.from_documents(documents=split_docs,embedding=embedding,persist_directory=persist_dir)# 持久化落地磁盘vector_db.persist()print("PDF向量数据入库完成!")# 加载已存在的向量库(下次启动直接调用,无需重新解析PDF)load_vector_db = Chroma(persist_directory=persist_dir, embedding_function=embedding)
步骤 5:向量相似度检索验证
测试检索功能,输入问题召回 PDF 中匹配的文本块,验证 RAG 基础能力
# 创建检索器,设置返回top3最相似文本retriever = vector_db.as_retriever(search_kwargs={"k": 3})# 测试查询query = "文档中关于产品售后流程的说明"result_docs = retriever.get_relevant_documents(query)print(f"检索到匹配文本块数量:{len(result_docs)}")for idx, doc in enumerate(result_docs):print(f"\n=====匹配片段{idx+1}=====")print(doc.page_content)
完整可运行整合代码
# langchain完整RAG:PDF读取-切片-向量入库 全流程代码import osfrom langchain_community.document_loaders import PyPDFLoaderfrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain_community.vectorstores import Chromafrom langchain_community.embeddings import HuggingFaceEmbeddings# ===================== 配置区(自行修改)=====================PDF_FILE_PATH = "./企业技术手册.pdf" # 你的PDF路径VECTOR_STORE_PATH = "./chroma_vector_db" # 向量库存储目录USE_LOCAL_EMBEDDING = True # True本地模型,False OpenAI接口# ==========================================================def init_embedding():"""初始化向量模型"""if USE_LOCAL_EMBEDDING:return HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2",model_kwargs={"device": "cpu"})else:from langchain_openai import OpenAIEmbeddingsreturn OpenAIEmbeddings(model="text-embedding-ada-002")def load_and_split_pdf(pdf_path):"""加载PDF并文本切片"""# 1. 读取PDFloader = PyPDFLoader(pdf_path)pages = loader.load()print(f"成功读取PDF,总页数:{len(pages)}")# 2. 文本分割splitter = RecursiveCharacterTextSplitter(chunk_size=800,chunk_overlap=150,separators=["\n\n", "\n", "。", ",", " ", ""])split_docs = splitter.split_documents(pages)print(f"文本切片完成,共生成{len(split_docs)}个文本块")return split_docsdef save_to_vector_db(docs, embedding, persist_path):"""文本向量化并存入向量库"""vector_db = Chroma.from_documents(documents=docs,embedding=embedding,persist_directory=persist_path)vector_db.persist()print(f"向量数据持久化至 {persist_path},入库完成")return vector_dbdef test_retrieve(vector_db, query):"""测试相似度检索"""retriever = vector_db.as_retriever(search_kwargs={"k": 3})match_docs = retriever.get_relevant_documents(query)print(f"\n查询问题:{query}")print(f"检索匹配片段数:{len(match_docs)}")for i, doc in enumerate(match_docs):print(f"\n【匹配片段{i+1}】\n{doc.page_content[:400]}...")if __name__ == "__main__":# 初始化向量模型emb_model = init_embedding()# 加载并切分PDFdoc_chunks = load_and_split_pdf(PDF_FILE_PATH)# 存入向量库db = save_to_vector_db(doc_chunks, emb_model, VECTOR_STORE_PATH)# 检索测试test_retrieve(db, "文档中产品售后流程说明")
关于向量数据库的选择,我会在下一篇中输出一篇详细的RAG向量数据库选型介绍!而针对向量库怎么部署也会单独整理一篇供大家参考!
大家在本地调试、企业私有化部署过程中,有任何疑问、踩坑经历或是不同选型观点,都欢迎在留言区交流探讨,一起互相学习、共同落地 RAG 项目!#LangChain #RAG #本地知识库问答 #Agent
夜雨聆风