LangChain 检索配置:让向量库返回相关文档的关键步骤
检索配置没做好时,向量库往往返回无关片段,后面接大模型也答不对。
LangChain 的检索链路由文档加载、文本切分、嵌入模型、向量存储和检索器五个环节组成,任何一环参数不匹配都会影响召回质量。
下面按实际配置顺序说明关键步骤和验证方法。
先确认嵌入模型与向量库可用
配置检索前需要准备两样东西:一个可调用的嵌入模型,以及一个能存向量的存储后端。
本地测试可以用 sentence-transformers 加载开源嵌入模型,向量存储用内存版 Chroma,避免依赖外部服务。
安装最小依赖:
pip install langchain langchain-community chromadb sentence-transformers
检查嵌入模型能否正常输出向量,这是后续所有检索的基础:
from langchain_community.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
vector = embeddings.embed_query("测试文本")
print(len(vector)) # 正常应输出 384
如果这里报错,先解决模型下载或网络问题,不要继续往下配置。
嵌入维度必须和向量库中已有数据一致,换模型后旧索引不能直接混用。
文档切分参数怎么定
切分粒度直接决定检索能否命中。
块太大,一个片段混入多个主题,相似度被稀释;
块太小,上下文不完整,大模型拿到的信息不足。
用 RecursiveCharacterTextSplitter 按段落和句子边界切分,中文场景建议把分隔符显式列出来:
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=80,
separators=["\n\n", "\n", "。", "!", "?", " ", ""]
)
chunks = splitter.split_documents(docs)
print(f"切分后片段数:{len(chunks)}")
chunk_size 控制单块字符数,chunk_overlap 保留相邻块的重叠内容,避免关键句被切断。
先用 300 到 800 之间的值测试,观察检索结果再调整。
构建向量库并配置检索器
把切分后的片段写入向量库,然后创建检索器。
检索器参数决定返回多少条、按什么方式排序:
from langchain_community.vectorstores import Chroma
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
collection_name="demo"
)
retriever = vectorstore.as_retriever(
search_type="similarity",
search_kwargs={"k": 4}
)
k 是返回片段数量,通常设 3 到 6 条。
设得太大容易把低相关内容也塞进上下文,反而干扰回答。search_type 默认是相似度检索,如果文档量大且需要兼顾关键词匹配,可以换成 mmr 减少结果重复。
验证检索结果是否相关
配置完成后不要直接接大模型,先单独检查检索输出。
用一句和文档主题相关的问题调用检索器:
results = retriever.invoke("文档中提到的配置步骤是什么")
for i, doc in enumerate(results):
print(f"--- 片段 {i+1} ---")
print(doc.page_content[:200])
判断标准很简单:返回片段里是否包含问题相关的关键词或语义相近的句子。
如果全是无关内容,按以下顺序排查:
- 嵌入模型是否和向量库构建时使用的是同一个,换过模型必须重建索引。
- 切分块是否过大,导致单个片段主题混杂,尝试调小
chunk_size。 - 查询语句是否太短或太模糊,换成更具体的问法再测。
- 向量库中是否真的有数据,检查
vectorstore._collection.count()返回的数量。
容易忽略的配置细节
检索配置不是一次调参就结束。
文档更新后需要重新切分和写入向量库,否则检索到的还是旧内容。
生产环境建议把嵌入模型版本、切分参数和向量库集合名记录在配置文件中,换环境时保持一致。
如果使用外部向量数据库,注意连接超时和批量写入大小,一次性写入过多文档可能触发限制。
先小批量验证写入和检索都正常,再扩大数据量。
常见疑问
检索返回空结果怎么办?
先确认向量库非空,再检查查询语句是否为空字符串。空查询或只有标点符号的查询通常无法生成有效向量。
相似度分数在哪里看?
similarity_search_with_score 可以返回片段和分数,分数含义取决于具体向量库实现,不同后端之间不能直接比较绝对值,只适合在同一库内排序参考。
改了切分参数需要重建索引吗?
需要。切分结果变了,向量库中的片段内容也变了,必须删除旧集合并重新写入。
LangChain 检索配置的核心是让切分粒度、嵌入模型和检索参数围绕同一批文档保持一致。
先用小数据量跑通检索验证,再逐步扩大文档规模,比一次性导入大量数据再排查更容易定位问题。