Langchain+RAG基于Llama检索FAQ PDF内容出错问题排查
问题描述
我用Langchain、RAG结合Llama,基于带编号问答列表的PDF格式FAQ文档实现问答功能,代码能正常运行,但检索存在问题——即便提问文档里已有的相同问题,Langchain也匹配不到正确的问答对,仅返回相似但无法解答问题的文档片段。
代码如下:
from langchain.document_loaders import PyPDFLoader loader = PyPDFLoader("doc.pdf") data = loader.load_and_split() from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter(chunk_size=1500, chunk_overlap=100) all_splits = text_splitter.split_documents(data) # Embed and store from langchain.embeddings import ( GPT4AllEmbeddings, OllamaEmbeddings, # We can also try Ollama embeddings ) from langchain.vectorstores import Chroma vectorstore = Chroma.from_documents(documents=all_splits, embedding=GPT4AllEmbeddings()) from langchain.prompts import PromptTemplate template = "..." QA_CHAIN_PROMPT = PromptTemplate.from_template(template)# Run chain # LLM from langchain.callbacks.manager import CallbackManager from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler import requests import json # QA chain from langchain.chains import RetrievalQA qa_chain = RetrievalQA.from_chain_type( llm, retriever=vectorstore.as_retriever(), return_source_documents=True, chain_type_kwargs={"prompt": QA_CHAIN_PROMPT} ) question = "..." print(qa_chain({"query": question}))
问题原因及优化方案
一、核心问题定位
- 文档拆分不合理:使用固定字符数的
RecursiveCharacterTextSplitter会破坏FAQ的问答对完整性,把一个完整的Q&A拆成多个片段,导致检索时无法获取完整上下文,自然匹配不到正确结果。 - 嵌入模型适配性不足:
GPT4AllEmbeddings对中文FAQ的语义匹配精度有限,或与Llama的适配性不佳,导致相同问题的向量相似度计算偏差,无法召回正确片段。 - 检索器参数未优化:默认检索器未设置相似度阈值、召回数量等参数,可能返回低相关度片段;且未采用FAQ场景适配的混合检索策略。
- Prompt缺失关键引导:空模板未明确要求LLM优先匹配检索到的FAQ问答对,导致模型忽略正确内容,自行生成或选取无关片段。
二、具体优化措施
1. 按问答对拆分文档
替换文本拆分器,基于FAQ的编号格式(如1. 问题:XXX\n回答:XXX)自定义拆分逻辑,确保每个片段是完整的Q&A:
from langchain.text_splitter import CharacterTextSplitter # 以编号(如"1. "、"2. ")作为拆分边界,保留完整问答对 text_splitter = CharacterTextSplitter( separator=r"\n\d+\. ", chunk_size=1, chunk_overlap=0, is_separator_regex=True ) all_splits = text_splitter.split_documents(data) # 拆分后补回编号,确保每个片段的完整性 processed_splits = [] for i, doc in enumerate(all_splits): if i == 0: processed_splits.append(doc) else: doc.page_content = f"{i+1}. {doc.page_content}" processed_splits.append(doc) all_splits = processed_splits
2. 更换适配的嵌入模型
改用Ollama嵌入模型(与Llama适配性更好)或中文专用嵌入模型:
# 使用Ollama的Llama2嵌入 vectorstore = Chroma.from_documents( documents=all_splits, embedding=OllamaEmbeddings(model="llama2") ) # 中文场景可选BGE中文嵌入 from langchain.embeddings import HuggingFaceEmbeddings embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-base-zh-v1.5") vectorstore = Chroma.from_documents(documents=all_splits, embedding=embeddings)
3. 优化检索器配置
调整检索器参数,或使用多查询检索提升召回率:
# 基础优化:设置相似度阈值和召回数量 retriever = vectorstore.as_retriever( search_type="similarity_score_threshold", search_kwargs={"k": 5, "score_threshold": 0.7} ) # 进阶:用MultiQueryRetriever生成多个相关查询,提升召回精度 from langchain.retrievers.multi_query import MultiQueryRetriever retriever = MultiQueryRetriever.from_llm( retriever=vectorstore.as_retriever(), llm=llm )
4. 完善Prompt模板
给LLM明确指令,要求优先匹配检索到的FAQ内容:
template = """你是FAQ专属问答助手,必须严格遵循以下规则回答: 1. 优先在提供的FAQ片段中查找完全匹配或高度相似的问题 2. 找到匹配问题后,直接使用对应的回答内容,不得自行创作 3. 若未找到匹配问题,直接告知用户"暂无相关解答" FAQ片段: {context} 用户问题:{question} 你的回答:""" QA_CHAIN_PROMPT = PromptTemplate.from_template(template)
5. 改用结构化FAQ检索方案
针对结构化FAQ,可先做精确/模糊匹配,向量检索作为兜底:
# 预处理FAQ为字典:{问题: 回答} faq_dict = {} for doc in all_splits: content = doc.page_content # 假设格式为"X. 问题:XXX\n回答:XXX" q_part, a_part = content.split("\n回答:", 1) question = q_part.split("问题:", 1)[1].strip() faq_dict[question] = a_part.strip() # 优先精确匹配,再模糊匹配,最后向量检索兜底 def get_faq_answer(question): # 精确匹配 if question in faq_dict: return faq_dict[question] # 模糊匹配 from difflib import get_close_matches close_matches = get_close_matches(question, faq_dict.keys(), n=1, cutoff=0.8) if close_matches: return faq_dict[close_matches[0]] # 向量检索兜底 result = qa_chain({"query": question}) return result["result"]
三、无法匹配正确问答对的核心原因
- 拆分破坏了问答对的完整性,向量存储的是不完整语义,无法匹配完整的Q&A上下文;
- 嵌入模型对FAQ场景的语义捕捉精度不足,导致相同问题的向量相似度偏低,被其他片段覆盖;
- 检索策略和Prompt缺乏针对性,未优先匹配精确问题,也未引导LLM使用正确的FAQ内容。
内容的提问来源于stack exchange,提问作者ABinx
相关产品推荐
相关产品推荐

