基于 LangChain 的 RAG 与对话记忆实现
前言
在大模型应用中,RAG(检索增强生成)已成为企业级知识库和智能文档问答的标配。它能让大模型读取私有文件(txt、docx、pdf),并基于文件内容精准回答问题。
对话记忆则能让 AI 记住历史对话,实现连贯的多轮问答。
本文搭建一套完整智能问答系统,支持本地私有文档读取、RAG 知识库检索及对话历史记忆。
核心功能
- 读取本地文档(TXT、DOCX 等)
- RAG 检索:从文档中精准找答案
- 对话记忆:记住之前说过的话
- 多轮问答:上下文连贯
- 兼容在线大模型(通义千问/Qwen)
技术原理
1. RAG 原理
- 加载文档 → 切分文本 → 向量化 → 构建检索库
- 用户提问 → 检索相关文档片段 → 交给大模型回答
2. 对话记忆原理
大模型本身无记忆,LangChain 通过以下方式实现'记住对话'的效果:
- 存储历史对话
- 每次提问自动拼接历史
- 让模型理解上下文
环境安装
pip install langchain langchain-community langchain_openai docx2txt python-docx pypdf sentence-transformers
完整实战代码
# ===================== 配置 =====================
MODEL = "qwen3-max#######"
BASE_URL = "https://aiapi.#######.com/qwen/v1"
API_KEY = "##########"
DOCX_FILE = "test.txt" # 你的文档(我是小明,今年 25 岁,喜欢打篮球和编程。我最喜欢的编程语言是 Python。)
# ====================================================
from langchain_openai import ChatOpenAI
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.embeddings import FakeEmbeddings
from langchain_community.vectorstores import DocArrayInMemorySearch
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.chains import create_history_aware_retriever, create_retrieval_chain
from langchain.chains.combine_documents create_stuff_documents_chain
warnings
langchain_community.document_loaders TextLoader
langchain_community.chat_message_histories ChatMessageHistory
langchain_core.runnables.history RunnableWithMessageHistory
warnings.filterwarnings()
()
loader = TextLoader(DOCX_FILE, encoding=)
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=, chunk_overlap=)
texts = text_splitter.split_documents(documents)
embeddings = FakeEmbeddings(size=)
db = DocArrayInMemorySearch.from_documents(texts, embeddings)
retriever = db.as_retriever(search_kwargs={: })
llm = ChatOpenAI(
model=MODEL,
base_url=BASE_URL,
api_key=API_KEY,
temperature=,
)
prompt1 = ChatPromptTemplate.from_messages([
(, ),
MessagesPlaceholder(),
(, ),
])
retriever_chain = create_history_aware_retriever(llm, retriever, prompt1)
prompt2 = ChatPromptTemplate.from_messages([
(, ),
MessagesPlaceholder(),
(, ),
])
doc_chain = create_stuff_documents_chain(llm, prompt2)
rag_chain = create_retrieval_chain(retriever_chain, doc_chain)
store = {}
():
session_id store:
store[session_id] = ChatMessageHistory()
store[session_id]
chain = RunnableWithMessageHistory(
rag_chain,
get_history,
input_messages_key=,
history_messages_key=,
output_messages_key=,
)
()
( * )
:
q = ()
q.lower() [, ]:
()
res = chain.invoke({: q}, config={: {: }})
(, res[])

