RAG 检索增强,彻底解决文档问答幻觉
一、RAG 核心原理
RAG 全称 Retrieval-Augmented Generation,检索增强生成。执行流程:加载文档 → 分割文本 → 向量化存入向量库 → 用户提问 → 检索相似片段 → 把片段+问题一起喂给LLM → 模型基于真实素材回答
核心逻辑:不让模型凭空回忆知识,强制它基于检索到的真实文档作答,从根源杜绝幻觉。
pip install langchain langchain-openai langchain-community faiss-cpu
from langchain_openai import ChatOpenAI, OpenAIEmbeddingsfrom langchain_community.document_loaders import TextLoaderfrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain_community.vectorstores import FAISSfrom langchain_core.prompts import ChatPromptTemplatefrom langchain_core.output_parsers import StrOutputParserfrom langchain_core.runnables import RunnablePassthrough# 1. 初始化模型&嵌入模型llm = ChatOpenAI(model="deepseek-chat",api_key="你的Key",base_url="https://api.deepseek.com/v1",temperature=0.2 # 低温度抑制幻觉)embeddings = OpenAIEmbeddings(api_key="你的Key",base_url="https://api.deepseek.com/v1")# 2. 加载本地文档loader = TextLoader("test.txt", encoding="utf-8")docs = loader.load()# 3. 文本分割:避免单段文本过长,提升检索精度text_splitter = RecursiveCharacterTextSplitter(chunk_size=300,chunk_overlap=50 # 片段重叠,防止语义断裂)split_docs = text_splitter.split_documents(docs)# 4. 构建向量数据库vector_store = FAISS.from_documents(split_docs, embeddings)retriever = vector_store.as_retriever(k=3) # 检索Top3相关片段# 5. 自定义提示词:强约束,禁止幻觉prompt = ChatPromptTemplate.from_template("""请**严格根据下方参考文档**回答用户问题,禁止编造任何内容。如果参考文档中没有对应答案,请直接回复:暂无相关信息。参考文档:{context}用户问题:{question}""")# 6. 构建RAG链式调用rag_chain = ({"context": retriever, "question": RunnablePassthrough()}| prompt| llm| StrOutputParser())# 7. 执行问答测试if __name__ == "__main__":question = "文档中介绍了什么内容?"result = rag_chain.invoke(question)print("回答:", result)
-
合理文本分割
chunk_size和chunk_overlap是核心参数:片段太大检索不准,太小丢失语义;重叠区保证上下文连贯。 -
检索数量 k 值
k=3/5为宜,检索过多无关片段会干扰模型,反而引发新的理解错误。 -
强约束提示词明确要求模型 “只参考文档、不懂就直说”,双重兜底防幻觉。
多轮场景下,需要结合历史对话优化检索:
-
先用历史对话 + 当前问题,重构检索 Query; -
再检索文档片段,最后拼接上下文一起问答。该方案同时解决上下文丢失和文档幻觉两大问题,是企业知识库主流架构。
夜雨聆风