LangChain实现RAG历史会话:构建上下文感知AI问答系统
1. 项目概述基于LangChain的RAG应用开发在当今AI技术快速发展的背景下检索增强生成Retrieval-Augmented Generation简称RAG已成为构建智能问答系统的核心技术之一。RAG通过结合信息检索和大型语言模型的生成能力能够提供更准确、更有上下文的回答。而LangChain作为当前最流行的AI应用开发框架之一为RAG系统的实现提供了强大的工具链支持。这个项目专注于在RAG应用中添加历史会话消息功能这是构建真正对话式AI系统的关键一步。想象一下当你与ChatGPT进行多轮对话时它能记住之前的交流内容这种记忆能力正是通过chat_history机制实现的。在商业客服、教育辅导、技术支持等场景中这种上下文感知能力尤为重要。2. 核心组件解析2.1 LangChain框架基础LangChain是一个用于开发由语言模型驱动的应用程序的框架。它提供了一套标准化的接口和组件使得开发者能够轻松构建复杂的AI应用链。在RAG场景中LangChain主要处理以下几个核心环节文档加载与处理从各种来源网页、PDF、数据库等加载文档文本分割将大文档切分为适合处理的片段向量化存储将文本转换为向量并存入向量数据库检索与生成根据查询检索相关内容并生成回答2.2 RAG架构详解RAG系统通常由三个主要部分组成检索器(Retriever)负责从知识库中查找与问题相关的文档片段生成器(Generator)基于检索到的内容和问题生成回答对话管理器处理多轮对话的上下文和历史传统RAG系统的一个主要局限是它们通常将每个查询视为独立的缺乏对话上下文的理解能力。这正是本项目要解决的核心问题。3. 历史会话消息的实现3.1 会话感知检索器LangChain提供了create_history_aware_retriever构造函数来创建能够理解对话上下文的检索器。这个检索器会接收两个输入用户当前的问题(input)之前的对话历史(chat_history)其工作原理是将对话历史与当前问题结合重新构造一个独立的、包含完整上下文的问题。例如原始对话历史 用户什么是任务分解 AI任务分解是将复杂任务拆分为更小步骤的技术...用户新问题常见的方法有哪些重构后的问题 任务分解的常见方法有哪些上下文任务分解是将复杂任务拆分为更小步骤的技术这种重构使得检索器能够找到更相关的文档片段。3.2 实现步骤详解3.2.1 构建基础检索器首先需要建立一个标准的RAG检索系统from langchain_chroma import Chroma from langchain_community.document_loaders import WebBaseLoader from langchain_openai import OpenAIEmbeddings from langchain_text_splitters import RecursiveCharacterTextSplitter # 加载文档 loader WebBaseLoader( web_paths(https://example.com/your-knowledge-source,), bs_kwargsdict( parse_onlybs4.SoupStrainer( class_(content-class, title-class) ) ), ) docs loader.load() # 分割文档 text_splitter RecursiveCharacterTextSplitter( chunk_size1000, chunk_overlap200 ) splits text_splitter.split_documents(docs) # 创建向量存储 vectorstore Chroma.from_documents( documentssplits, embeddingOpenAIEmbeddings() ) retriever vectorstore.as_retriever()3.2.2 添加历史感知能力接下来我们创建能够理解对话历史的检索器from langchain.chains import create_history_aware_retriever from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder contextualize_q_system_prompt ( Given a chat history and the latest user question which might reference context in the chat history, formulate a standalone question which can be understood without the chat history. Do NOT answer the question, just reformulate it if needed and otherwise return it as is. ) contextualize_q_prompt ChatPromptTemplate.from_messages( [ (system, contextualize_q_system_prompt), MessagesPlaceholder(chat_history), (human, {input}), ] ) history_aware_retriever create_history_aware_retriever( llm, retriever, contextualize_q_prompt )3.2.3 构建完整问答链将检索器与生成器结合创建完整的问答链from langchain.chains import create_retrieval_chain from langchain.chains.combine_documents import create_stuff_documents_chain system_prompt ( You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you dont know the answer, say that you dont know. Use three sentences maximum and keep the answer concise.\n\n {context} ) qa_prompt ChatPromptTemplate.from_messages( [ (system, system_prompt), MessagesPlaceholder(chat_history), (human, {input}), ] ) question_answer_chain create_stuff_documents_chain(llm, qa_prompt) rag_chain create_retrieval_chain(history_aware_retriever, question_answer_chain)4. 对话状态管理4.1 会话历史存储为了实现真正的多轮对话我们需要存储和管理对话历史。LangChain提供了ChatMessageHistory类来帮助管理from langchain_community.chat_message_histories import ChatMessageHistory from langchain_core.chat_history import BaseChatMessageHistory store {} def get_session_history(session_id: str) - BaseChatMessageHistory: if session_id not in store: store[session_id] ChatMessageHistory() return store[session_id]4.2 集成历史管理的对话链使用RunnableWithMessageHistory将历史管理集成到问答链中from langchain_core.runnables.history import RunnableWithMessageHistory conversational_rag_chain RunnableWithMessageHistory( rag_chain, get_session_history, input_messages_keyinput, history_messages_keychat_history, output_messages_keyanswer, )4.3 使用示例现在可以这样使用对话系统# 第一轮对话 result conversational_rag_chain.invoke( {input: 什么是任务分解}, config{configurable: {session_id: user123}}, ) print(result[answer]) # 第二轮对话会记住之前的上下文 result conversational_rag_chain.invoke( {input: 有哪些常见方法}, config{configurable: {session_id: user123}}, ) print(result[answer])5. 高级功能与优化5.1 使用代理(Agent)模式对于更复杂的场景可以使用LangChain的代理模式让LLM自主决定何时使用检索器from langchain.tools.retriever import create_retriever_tool from langgraph.prebuilt import create_react_agent # 将检索器转换为工具 tool create_retriever_tool( retriever, knowledge_retriever, Searches and returns information from knowledge base., ) tools [tool] # 创建代理 agent_executor create_react_agent(llm, tools) # 使用代理进行对话 for s in agent_executor.stream( {messages: [HumanMessage(content什么是任务分解)]}, config{configurable: {thread_id: user123}}, ): print(s)5.2 持久化存储方案在生产环境中应该使用更可靠的存储方案替代内存存储# 使用Redis存储对话历史 from langchain_community.chat_message_histories import RedisChatMessageHistory def get_redis_history(session_id: str) - BaseChatMessageHistory: return RedisChatMessageHistory( session_idsession_id, urlredis://localhost:6379/0, )5.3 性能优化技巧分块策略优化根据文档类型调整chunk_size和chunk_overlap检索优化使用混合检索(结合关键词和向量检索)缓存机制对常见问题答案进行缓存异步处理对耗时操作使用异步实现6. 常见问题与解决方案6.1 上下文窗口限制问题长对话历史可能超出模型的上下文窗口限制。解决方案实现对话历史摘要功能只保留最近N轮对话使用向量检索从历史中选择最相关的部分6.2 信息不一致问题模型可能生成与检索内容不一致的回答。解决方案在提示中强制要求引用来源实现一致性检查机制使用RAG-Fusion等技术改进检索6.3 会话隔离问题不同用户的会话需要隔离。解决方案确保每个用户/会话有唯一的session_id使用数据库或缓存系统存储历史实现会话过期机制7. 实际应用案例7.1 技术文档助手为开发团队构建的技术文档问答系统能够理解开发者的问题上下文比如用户如何配置数据库连接 系统回答... 用户连接池参数有哪些 系统能理解这是前一个问题的延伸7.2 教育辅导系统智能辅导系统可以记住学生的知识水平和使用习惯提供个性化的学习建议学生请解释一下牛顿第一定律 系统回答... 学生能举个例子吗 系统能提供与力学相关的例子7.3 商业客服机器人电商客服机器人能够记住用户的订单信息和之前的咨询内容用户我上周买的手机什么时候到货 系统查询订单... 用户能改送到公司地址吗 系统理解这是关于同一订单的请求8. 部署与扩展8.1 部署方案本地开发使用FastAPI或Flask构建简单的API服务云服务部署AWS Lambda、Google Cloud Functions等无服务方案容器化使用Docker打包部署到Kubernetes集群8.2 监控与日志使用LangSmith跟踪链的执行情况记录用户查询和系统响应用于后续分析实现反馈机制收集用户满意度8.3 扩展方向多模态支持处理图像、表格等非文本内容个性化适配基于用户画像调整回答风格实时学习允许用户纠正错误并更新知识库9. 性能评估与调优9.1 评估指标检索相关性命中文档与问题的匹配程度回答质量准确性、完整性和流畅性响应时间从提问到获得回答的延迟上下文保持在多轮对话中保持主题一致性的能力9.2 A/B测试策略对比有无历史会话功能的用户体验测试不同检索策略的效果评估不同LLM模型的性能差异9.3 持续改进流程收集真实用户交互数据识别常见问题和失败模式调整提示词和检索策略部署更新并监控改进效果10. 安全与隐私考虑10.1 数据安全对话历史加密存储实现数据访问控制定期清理过期数据10.2 隐私保护匿名化处理用户数据提供数据删除接口遵守相关数据保护法规10.3 内容过滤实现输入输出过滤机制检测并阻止不当内容记录审核日志在实际开发中我发现历史会话管理是RAG系统中最容易被低估的复杂部分。一个常见的陷阱是过度依赖对话历史导致系统在长对话中性能下降。最佳实践是动态调整历史上下文的长度和相关性而不是简单地保留所有历史消息。另一个实用技巧是在检索前对历史消息进行轻量级摘要既能保留关键信息又能节省上下文窗口的空间。

相关新闻

鸿蒙 ArkTS 实战:Product Photo Checklist 从商品拍摄清单到店铺经营工具完整解析

鸿蒙 ArkTS 实战:Product Photo Checklist 从商品拍摄清单到店铺经营工具完整解析

鸿蒙 ArkTS 实战:Product Photo Checklist 从商品拍摄清单到店铺经营工具完整解析 前言 Product Photo Checklist 是一个基于鸿蒙 ArkTS 与 ArkUI 声明式 UI 实现的店铺经营类单页应用,核心场景是 商品素材拍摄管理。 它把 维护拍摄任务、角度要求、素…

2026/7/20 23:57:45阅读更多 →
AI Agent项目预算大揭秘:中小企业与大企业的成本差异与收藏攻略

AI Agent项目预算大揭秘:中小企业与大企业的成本差异与收藏攻略

本文深入剖析了企业实施AI Agent项目的成本构成,对比了中小企业与大企业在实施成本上的差异。文章指出,除了模型调用和平台授权费用外,还包括场景梳理、数据准备、系统连接、模型与基础设施、安全治理及持续运营等成本。中小企业需关注人力成…

2026/7/20 23:57:45阅读更多 →
鸿蒙 ArkTS 实战:Calligraphy Club Review 从书法社点评到兴趣社群工具完整解析

鸿蒙 ArkTS 实战:Calligraphy Club Review 从书法社点评到兴趣社群工具完整解析

鸿蒙 ArkTS 实战:Calligraphy Club Review 从书法社点评到兴趣社群工具完整解析 前言 Calligraphy Club Review 是一个围绕 书法作品点评 设计的鸿蒙 ArkTS 单页应用。 它把 上传作品、记录点评、生成练习任务,并累计进步相册照片 这类真实活动需求&a…

2026/7/20 23:55:45阅读更多 →
金融对账系统架构:从文件对账到实时逐笔对账的技术演进

金融对账系统架构:从文件对账到实时逐笔对账的技术演进

金融对账系统架构:从文件对账到实时逐笔对账的技术演进 一、背景与问题 对账是金融系统风险控制的最后一道闸门——所有前端系统的数据正确性最终都要通过对账来验证。传统对账依赖渠道方提供的对账文件(通常是T1的CSV/ZIP文件),存…

2026/7/22 2:10:08阅读更多 →
半参数随机基本图建模:结合交通流理论与高斯过程的混合方法

半参数随机基本图建模:结合交通流理论与高斯过程的混合方法

在交通工程和智能交通系统研究中,交通流基本图是描述流量、密度和速度之间关系的核心理论工具。传统的基本图模型多为确定性模型,但在实际道路环境中,交通流具有显著的随机性和不确定性,例如不同天气条件、驾驶员行为差异、突发事…

2026/7/22 2:10:08阅读更多 →
企业AI开发中的数据孤岛问题与解决方案

企业AI开发中的数据孤岛问题与解决方案

1. 企业AI开发的困境与机遇在制造业数字化转型浪潮中,AI技术正成为企业降本增效的关键抓手。但现实情况是,超过70%的企业AI项目在实施过程中遭遇"数据孤岛"问题,导致项目延期甚至失败。某汽车零部件企业的CIO曾向我透露&#xff1a…

2026/7/22 2:10:08阅读更多 →
基于Transformer的多语言滥用检测:语码混合场景下的工程实践

基于Transformer的多语言滥用检测:语码混合场景下的工程实践

在自然语言处理的实际应用中,多语言和语码混合场景下的滥用内容检测一直是个棘手问题。传统方法往往依赖单一语言的毒性信号,但真实网络环境里用户可能在同一句话中切换语言,或者使用非母语表达攻击性内容,这导致检测准确率大幅下…

2026/7/22 2:10:08阅读更多 →
Mamba-3架构:动态权重调整与高效序列建模实践

Mamba-3架构:动态权重调整与高效序列建模实践

1. Mamba-3架构实验设计方法论在序列建模领域,Mamba-3作为新一代选择性状态空间模型(Selective State Space Model),其核心创新在于动态权重调整机制。与传统Transformer的固定注意力模式不同,Mamba-3通过时变参数系统实现了输入自适应的状态…

2026/7/22 2:10:08阅读更多 →
Zen Browser完整配置指南:5分钟打造高效隐私浏览器

Zen Browser完整配置指南:5分钟打造高效隐私浏览器

Zen Browser完整配置指南:5分钟打造高效隐私浏览器 【免费下载链接】desktop Welcome to a calmer internet 项目地址: https://gitcode.com/GitHub_Trending/desktop70/desktop 想要体验一款既注重隐私保护又能显著提升工作效率的浏览器吗?Zen B…

2026/7/22 2:08:08阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 0:53:59阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 0:53:59阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 0:53:59阅读更多 →
中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业做小程序,最常见的矛盾是预算有限,但又不希望功能太单薄;没有技术团队,但又希望后续能自己运营;想快速上线,又担心隐性收费和售后失联。选型时如果只看“低价套餐”或“案例数量”,很容…

2026/7/22 0:01:17阅读更多 →
GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

企业做营销,最怕钱花完了,资产没有留下。 效果广告能带来一段时间的曝光,但预算停止后,流量往往也随之停止。短视频内容可能在几天内冲高,也可能很快沉下去。AI搜索时代,企业需要重新思考一个问题&#xff…

2026/7/22 0:01:17阅读更多 →
Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复 一、你的 Agent 在"再想想"的循环里绕了 12 轮,用户已经关窗口了 Agent 与人最大的区别是:人知道什么时候该停下来给答案,Agent 会一直"想"下去。你给 Agent 接…

2026/7/22 0:01:17阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/21 22:53:50阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/21 18:53:30阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/21 18:53:30阅读更多 →