告别失忆 AI:LangChain RAG + 对话记忆实战,从 0 到 1 落地
告别失忆 AI:LangChain RAG + 对话记忆实战,从 0 到 1 落地
前言
在大模型应用中,RAG(检索增强生成) 已经成为企业级知识库、智能文档问答的标配。它能让大模型读取你的私有文件(txt、docx、pdf),并基于文件内容精准回答问题,不会编造答案。
而对话记忆能让 AI 记住历史对话,实现连贯的多轮问答。
今天,我用 LangChain 搭建一套:
- 支持本地私有文档(TXT/DOCX/PDF)
- 支持 RAG 知识库检索
- 支持对话历史记忆
- 可直接运行、无环境报错
的完整智能问答系统。
一、核心功能
- 读取本地文档(TXT、DOCX 等)
- RAG 检索:从文档中精准找答案
- 对话记忆:记住你之前说过的话
- 多轮问答:上下文连贯
- 兼容在线大模型(通义千问/Qwen)
二、技术原理
1. RAG 原理
- 加载文档 → 切分文本 → 向量化 → 构建检索库
- 用户提问 → 检索相关文档片段 → 交给大模型回答
2. 对话记忆原理
大模型本身无记忆,LangChain 通过:
- 存储历史对话
- 每次提问自动拼接历史
- 让模型理解上下文
实现“记住对话”的效果。
三、环境安装
pip install langchain langchain-community langchain_openai pip install 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 import create_stuff_documents_chain import warnings from langchain_community.document_loaders import TextLoader warnings.filterwarnings('ignore')# ===================== 加载文档 =====================print("正在加载文档...") loader = TextLoader(DOCX_FILE, encoding="utf-8") documents = loader.load()# 文档切分 text_splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=100) texts = text_splitter.split_documents(documents)# 构建轻量级向量库 embeddings = FakeEmbeddings(size=100) db = DocArrayInMemorySearch.from_documents(texts, embeddings) retriever = db.as_retriever(search_kwargs={"k":2})# ===================== 模型初始化 ===================== llm = ChatOpenAI( model=MODEL, base_url=BASE_URL, api_key=API_KEY, temperature=0.1,)# ===================== 对话记忆模板 =====================# 历史对话理解 prompt1 = ChatPromptTemplate.from_messages([("system","根据对话历史理解用户问题,不要忽略用户刚说过的内容"), MessagesPlaceholder("chat_history"),("human","{input}"),]) retriever_chain = create_history_aware_retriever(llm, retriever, prompt1)# 优先遵守用户指令 + 参考文档 prompt2 = ChatPromptTemplate.from_messages([("system","请遵守用户最新指令!如果用户修改信息,优先使用最新内容,文档仅做参考。文档内容:\n\n{context}"), MessagesPlaceholder("chat_history"),("human","{input}"),]) doc_chain = create_stuff_documents_chain(llm, prompt2) rag_chain = create_retrieval_chain(retriever_chain, doc_chain)# ===================== 记忆存储 =====================from langchain_community.chat_message_histories import ChatMessageHistory from langchain_core.runnables.history import RunnableWithMessageHistory store ={}defget_history(session_id):if session_id notin store: store[session_id]= ChatMessageHistory()return store[session_id]# 最终带记忆的RAG链 chain = RunnableWithMessageHistory( rag_chain, get_history, input_messages_key="input", history_messages_key="chat_history", output_messages_key="answer",)# ===================== 启动对话 =====================print("\n✅ 带记忆的文档问答已启动!输入 exit 退出")print("="*60)whileTrue: q =input("\n你:")if q.lower()in["exit","q"]:print("AI:结束!")break res = chain.invoke({"input": q}, config={"configurable":{"session_id":"test1"}})print("\nAI:", res["answer"])五、运行效果展示
正在加载文档... ✅ 带记忆的文档问答已启动! 你:你是谁 AI: 我是小明,今年25岁,喜欢打篮球和编程。我最喜欢的编程语言是Python。 你:你现在叫做小红,今年30岁,喜欢java AI: 我是小红,今年30岁,喜欢打篮球、编程,最喜欢的编程语言是Java。 你:你现在是谁 AI: 我是小红,今年30岁,喜欢打篮球和编程,最喜欢的编程语言是Java。 你:你现在不喜欢篮球和编程了,你喜欢play piano AI: 我是小红,今年30岁,喜欢弹钢琴,最喜欢的编程语言是Java。 你:告诉我你是谁 AI: 我是小红,今年30岁,喜欢弹钢琴,最喜欢的编程语言是Java。 你:那小明是谁呢 AI: 小明是你最初设定的角色:25岁,喜欢打篮球和编程,最喜欢的编程语言是Python。 但现在你已经将我的身份更新为小红,所以我以小红的身份和你对话。如果你希望切换回小明,也可以告诉我哦! 六、适用场景
- 私有文档智能问答
- 学习资料智能答疑
- 企业知识库
- 报告/论文内容检索
- 带记忆的智能助手