收藏这篇就够了!LangChain+ RAG从0到1搭建 智能客服系统

张开发
2026/6/12 4:00:50 15 分钟阅读

分享文章

收藏这篇就够了!LangChain+ RAG从0到1搭建 智能客服系统
概要全文干货纯手写架构拆解、原理讲解、细节优化全部逐一打磨。项目从零手写开发调试排错、逻辑优化、功能迭代耗费大量时间与精力。深知大家自学踩坑多、拼接代码难运行、资料零散难落地因此整理了完整可直接运行的全套源码。学会本文你将完整掌握 RAG 项目全链路开发独立实现私有知识库构建、向量检索、多轮会话、流式问答与混合回答模式。对比维度直接使用通用大模型豆包 / Deepseek等LangChain RAG 检索增强方案私有业务适配无本地知识库无法读取企业内部、行业专属资料只能依靠训练通识数据支持私有文档向量化入库定制专属知识库精准匹配业务场景回答真实性易产生AI 幻觉无依据编造内容答案不可控、不可溯源回答依赖检索到的真实文档内容有据可依从源头抑制幻觉内容精准度回答泛化笼统无法贴合细分业务规则、产品资料定向检索关联片段答案针对性强贴合实际业务需求知识时效性模型训练数据固定无法同步最新业务文件、更新资料支持文档随时新增、替换、更新知识库可动态迭代开发落地成本仅能单轮简单问答无法私有化部署无定制化能力模块化全流程编排易私有化部署、二次开发与功能拓展上下文与工程化缺少定制会话管理、文档处理、向量存储等配套能力集成文本切割、MD5 去重、会话记忆、流式输出等完整工程能力系统实现两大核心流程离线流程文档上传 → MD5 去重 → 文本分块 → 向量化 → 存入向量库在线流程用户提问 → 向量检索 → 提示词组装 → 大模型生成 → 流式输出系统支持混合问答知识库内外自动切换、流式打字机效果、会话历史保存可直接用于企业级私有知识库、智能客服等场景。整体架构流程总架构离线流程知识库构建在线流程智能问答技术名词解释LangChainRAG 全流程编排工具负责文档加载、分块、检索、Prompt 组装、大模型调用等全链路管理。RAG检索增强生成项目核心架构通过 “检索私有知识库 大模型生成”解决大模型幻觉问题。Chroma轻量级向量数据库用于存储文档向量化后的向量数据支持快速相似度检索。StreamlitWeb 交互界面框架用于快速搭建项目可视化界面实现文档上传、问答交互等功能。Embedding 模型负责将文本转化为向量为向量检索提供支撑。大模型Qwen/Deepseek/GPT 等本章所使用大模型为Qwen3-max,相关的 API_KEY 已配置环境变量代码中不体现。MD5用于文档内容去重避免重复文档多次存入向量数据库提升数据库效率。流式输出实现 “打字机效果”让大模型回答逐字逐句显示优化用户交互体验。技术细节文件名核心作用app_file_upload.py知识库更新主程序Streamlit 界面负责文档上传与入库流程app_qa.py项目对话主程序Streamlit 界面启动问答 Web 页面处理用户交互config_data.py全局配置文件统一管理项目参数file_history_store.py长期会话记忆存储服务负责用户对话历史的读写knowledge_base.py知识库更新服务实现文档去重、分块、元数据处理rag.pyRAG 核心服务负责检索、提示词组装与大模型调用vector_stores.py向量存储服务封装向量数据库的写入、检索等底层操作MD5 去重为什么要去重?防止相同 / 重复的文档多次存入向量数据库造成数据库冗余、检索效率降低核心原理只要文档内容一致其 MD5 字符串就完全相同def check_md5(md5_str: str): 检查传入的md5字符串是否已经被处理过了 :param md5_str: :return: False:未处理过 True:处理过 if not os.path.exists(config.md5_path): #if进入,表示文件不存在,那肯定没有处理过这个Md5 open(config.md5_path,w,encodingutf-8).close() return False else: for line in open(config.md5_path,r,encodingutf-8).readlines(): line line.strip() #处理字符串前后的空格和回车 if line md5_str: return True #已处理过 return FalseMD5去重代码实现st.session_statest.session_state 是 Streamlit 框架专用的会话状态存储器可理解为每个用户打开网页后独有的一块 “临时内存 / 小仓库”。其核心作用是保存页面数据、避免刷新丢失、实现跨模块数据共享是保证 RAG 系统正常运行、不重复初始化、不丢失对话数据的核心机制。if message not in st.session_state: st.session_state[message] [ { role:assistant,context:你好,有什么可以帮助你? } ] if rag not in st.session_state: st.session_state[rag] RagService() #页面刷新时显示聊天记录 for message in st.session_state[message]: st.chat_message(message[role]).write(message[context])session_state代码实现文档分割作用:将长文档按规则切分成短文本片段Chunk让向量检索更精准、大模型理解更高效。基础用法:固定长度分块self.spliter RecursiveCharacterTextSplitter( chunk_sizeconfig.chunk_size, #分割后的文本段最大长度 chunk_overlapconfig.chunk_overlap, #分割后的文本段之间允许重叠的长度 separatorsconfig.separators, #文本自然段落分隔的依据符号 length_functionlen, #使用Python自带的len函数统计长度 ) #文本分割器的对象# spliter chunk_size 1000 chunk_overlap 100 separators [\n\n, \n, ., !, ?, 。, , , , ] max_split_char_number 1000 # 文本分割的阈值文本分割以及配置项进阶用法:语义分块推荐进阶方案按语义完整性切割不破坏句子、段落逻辑检索更准。优先保证一个块 一个完整意思适用商品说明、合同、文章、知识库结构分块按文档自身结构切割标题 → 段落 → 子段落目录层级切割适用PDF、说明书、论文、多章节文档递归分块RecursiveCharacterTextSplitterLangChain 标准高级用法先按大分隔符换行、段落分再按小分隔符句子切最后保证块不超限最均衡、最常用。按专业场景优化电商商品按 SKU、属性、规格分块客服知识库按问题 - 答案分块代码文档按函数、类、注释分块会话历史保存实现多轮对话系统能记住上一轮对话内容回答更连贯、更贴合上下文。提升用户体验用户无需重复描述问题交互更自然。便于追溯与优化保存对话记录可用于后续客服质检、问题分析、模型优化。业务闭环支持对话导出、复盘、用户行为分析。def get_history(session_id): return FileChatMessageHistory(session_id, ./chat_history) # 创建一个新的链对原有链增强功能自动附加历史消息 conversation_chain RunnableWithMessageHistory( base_chain, # 被增强的原有chain get_history, # 通过会话id获取InMemoryChatMessageHistory类对象 input_messages_keyinput, # 表示用户输入在模板中的占位符 history_messages_keychat_history # 表示用户输入在模板中的占位符 )会话历史保存功能实现session_config { configurable: { session_id: user_001, } }session_id可在配置项中配置流式输出什么是流式输出:write_stream是 Streamlit 框架提供的流式输出方法配合大模型的流式返回实现逐字、逐词、逐句的 “打字机效果”让回答像真人一样逐步显示。核心作用:提升交互体验不用等大模型全部生成完才显示用户看到文字逐字输出等待感更低。降低感知延迟大模型一返回内容就立刻展示响应更快、更流畅。贴近商用产品抖音、GPT、文心一言等产品都用这种流式输出。配合会话保存一边流式输出一边完整保存回答内容。关键点:必须使用yield关键字注:以上问题与答案的模式就是类似流式输出,包括日常使用的豆包,deepseek等,默认都是采用流式输出def capture(generator,cache_list): for chunk in generator: cache_list.append(chunk) yield chunk st.chat_message(assistant).write_stream(capture(res_stream,ai_res_list))流式输出代码如果不加yiled呢?def capture(generator, cache_list): for chunk in generator: cache_list.append(chunk) # 没有 yield这个函数就变成了普通函数 # 它会把所有 chunk 都收完最后返回 None你可能会问“我直接把res_strem传给write_stream不就行了吗为什么要包一层capture”这是因为有两个需求同时存在需求 A给用户看需要实时流式显示由write_stream处理。需求 B给自己存需要把完整的回答存进st.session_state做历史记录由cache_list处理。capture函数的作用就是通过yield chunk满足需求 A把数据吐给页面显示。通过cache_list.append(chunk)满足需求 B把数据悄悄存进列表。混合模式什么是混合模式?私有知识库回答大模型通用回答 自动切换系统自动判断问题是否在知识库范围内有答案 → 按私有资料专业回答无答案 → 用大模型自身知识正常聊天self.prompt_template ChatPromptTemplate.from_messages( [ (system, 你是一个智能助手。请根据以下【参考资料】回答用户问题。\n 如果【参考资料】中包含相关信息请严格依据资料进行简洁、专业的回答。\n 如果【参考资料】为空或与问题无关请利用你自身的通用知识来回答用户的问题。\n 参考资料: {context}), (user, 用户提问: {input}) ] )def format_document(docs:list[Document]): if not docs: return # 如果没有资料直接给空字符串模型会自然切换到通用模式 formatted_str for doc in docs : formatted_str f文档片段:{doc.page_content}\n文档元数据:{doc.metadata}\n\n return formatted_str混合模式代码实现效果展示文件上传知识库基于知识库回答问题(流式输出)保留历史对话混合模式(langchainrag知识不在知识库里,根据模型自己回答)小结本文围绕LangChainRAG企业级知识库问答系统展开完整讲解依托检索增强技术有效解决大模型幻觉、私有知识无法适配等问题。结合文档去重、文本切割、会话记忆、流式输出、混合问答等工程优化提升检索精度与交互体验。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

更多文章