跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

LangChain 中使用 Chroma 检索时无法获取源文档的解决方案

本文详解 langchain 结合 py pdf loader、 openai embeddings 与 chroma 构建 rag 系统时“检索返回空源文档”的常见原因及完整修复流程,涵盖文档加载、分块、向量化与持久化各关键环节。 在 LangChain 中构建基于 PDF 的检索增强生成(RAG)系统时,一个典型痛点是:retriever.get_relevant_documents(query) 能成功返回 Document 对象列表,但 len(docs) 却为 0 —— 表明检索器未实际加载或识别任何源文档。这通常并非模型或 API 问题,而是 数据流水线中的关键步骤被遗漏或错配所致 。 根本原因往往在于: Chroma.from_documents() 必须接收已加载并分块后的 Document 对象(即含 page_content 和 metadata 的 LangChain Document 实例),而不能直接传入原始文本字符串或未经处理的文件路径 。若跳过 loader.load() 或误用 split_documents(),会导致 texts 为空或结构不合法,进而使 Chroma 库无法正确索引元数据(如来源文件路径、页码等),最终 get_relevant_documents() 返回空列表。 ✅ 正确且完整的端到端代码如下: OpenAI Codex 可以生成十多种编程语言的工作代码,基于 OpenAI GPT-3 的自然语言处理模型 下载
from langchain.document_loaders import DirectoryLoader, PyPDFLoader from langchain.text_splitter import CharacterTextSplitter from langchain.embeddings import OpenAIEmbeddings from langchain.vectorstores import Chroma # 1. 加载所有 PDF 文档(必须显式调用 .load()) loader = DirectoryLoader('./files/', glob='*.pdf', loader_cls=PyPDFLoader) documents = loader.load() # ⚠️ 关键:不可省略!返回 Document 列表 # 2. 分块(保持 Document 结构,自动继承 metadata) text_splitter = CharacterTextSplitter( chunk_size=1000, chunk_overlap=200, separator="\n" ) texts = text_splitter.split_documents(documents) # ✅ 输入是 Document,输出仍是 Document # 3. 创建嵌入与向量库(持久化) embeddings = OpenAIEmbeddings() persist_directory = "./chroma_db" docsearch = Chroma.from_documents( texts, embeddings, persist_directory=persist_directory ) # 4. 加载并检索(确保使用同一 embedding_function) docsearch = Chroma(persist_directory=persist_directory, embedding_function=embeddings) retriever = docsearch.as_retriever(search_kwargs={"k": 5}) docs = retriever.get_relevant_documents("你的查询问题") print(f"检索到 {len(docs)} 个相关文档") for i, doc in enumerate(docs): print(f"[{i+1}] 来源: {doc.metadata.get('source', 'unknown')}, 页码: {doc.metadata.get('page', 'N/A')}")
? 关键注意事项 : DirectoryLoader.load() 必须显式调用,否则 documents 为 DirectoryLoader 对象而非文档列表; split_documents()(非 split_text())才能保留 Document 的 metadata(含 source, page 等),这对溯源至关重要; 初始化 Chroma 时,embedding_function 参数 必须与创建时完全一致 (包括模型名称、API key 环境、版本),否则向量维度不匹配将导致静默失败; 若仍返回空,请检查 ./files/ 目录是否存在 PDF 文件,以及 persist_directory 是否被其他进程占用或权限受限; 推荐首次运行后打印 texts[0] 查看其结构,确认 page_content 和 metadata 字段存在且非空。 通过严格遵循上述流程,即可确保源文档被正确加载、分块、嵌入并持久化,从而让 get_relevant_documents() 稳定返回带完整元数据的 Document 对象,真正支撑可解释、可追溯的 RAG 应用。

相关文章