#CSDN博客-智能客服RAG实战

news2026/4/9 15:23:24
基于 Milvus Ollama(BGE-M3) DeepSeek 的智能客服 RAG 实战一、项目背景在社保、医保、就业等公共服务领域每天都有大量群众拨打热线咨询相似问题。传统人工客服成本高、效率低而基于关键词匹配的机器人又难以理解用户的真实意图。本项目基于RAGRetrieval-Augmented Generation检索增强生成架构搭建了一套智能客服系统实现用户问题语义理解非关键词匹配从知识库中精准检索相关问答基于 LLM 生成自然语言回答自动推荐相关问题引导用户继续咨询支持语音输入和语音播报二、整体架构用户(语音/文本输入) │ ▼ ┌─────────────┐ │ Flask服务 │ ← HTTPS部署 │ (后端API) │ └──────┬──────┘ │ ▼ ┌──────────────────┐ ┌──────────────────┐ │ Ollama本地服务 │ │ Milvus向量数据库 │ │ (bge-m3 向量化) │────▶│ (知识库语义检索) │ └──────────────────┘ └────────┬─────────┘ │ Top-20 相似问答 ▼ ┌──────────────────┐ │ DeepSeek API │ │ (LLM推理生成回答) │ └────────┬─────────┘ │ ▼ 回答 推荐问题 (SSE流式 / 普通返回)三、技术栈组件技术选型说明Embedding模型Ollama bge-m3本地部署免费支持中英文混合向量数据库Milvus开源高性能支持COSINE相似度大语言模型DeepSeek API (deepseek-chat)推理能力强性价比高后端服务Flask flask_cors轻量级支持HTTPS前端HTML JS jQuery支持语音输入(讯飞) Markdown渲染四、环境准备4.1 安装 Ollama 并拉取模型# 安装Ollama参考官方文档 https://ollama.com# 拉取中文Embedding模型ollama pull bge-m3验证模型是否可用curlhttp://localhost:11434/api/embeddings-d{ model: bge-m3:latest, prompt: 社保缴费年限不够怎么办 }返回结果中包含embedding字段即为成功。4.2 部署 Milvus推荐使用 Docker 部署# 下载docker-compose.ymlwgethttps://github.com/milvus-io/milvus/releases/download/v2.4.0/milvus-standalone-docker-compose.yml-Odocker-compose.yml# 启动dockercompose up-d4.3 安装Python依赖pipinstallflask flask-cors pymilvus requests chardet五、知识库构建5.1 创建Milvus集合frompymilvusimport(MilvusClient,FieldSchema,CollectionSchema,DataType)clientMilvusClient(urihttp://your_milvus_host:19530,tokenyour_token,db_namedefault)fields[FieldSchema(nameuid,dtypeDataType.INT64,is_primaryTrue,auto_idFalse,max_length100),FieldSchema(nameQuestion,dtypeDataType.VARCHAR,max_length5000),FieldSchema(nameAnswer,dtypeDataType.VARCHAR,max_length5000),FieldSchema(nameVector,dtypeDataType.FLOAT_VECTOR,dim1024),]schemaCollectionSchema(fields,社保知识库向量存储)client.create_collection(collection_nameSI_knowledge,schemaschema,dimension1024)注意bge-m3 模型输出的向量维度为1024创建集合时dim必须一致。5.2 创建向量索引defcreate_index(client:MilvusClient,collection_name:str):index_paraclient.prepare_index_params()index_para.add_index(field_nameVector,index_typeIVF_FLAT,metric_typeCOSINE,params{nlist:1024})client.create_index(collection_namecollection_name,index_paramsindex_para)5.3 导入知识库数据将业务问答数据向量化并存入Milvus。核心逻辑先检索是否已存在语义相似的问答去重再插入新数据。defvectorize_text(text):urlhttp://localhost:11434/api/embeddingsheaders{Content-Type:application/json,Accept:application/json}data{model:bge-m3:latest,prompt:text}responserequests.post(url,jsondata,headersheaders)ifresponse.status_code200:returnresponse.json().get(embedding,[])returnNonedefimport_knowledge(client,question,answer,uid):vectorvectorize_text(question)# 去重先检索是否存在语义高度相似的问题search_params{metric_type:COSINE,params:{radius:0.87}}resclient.search(collection_nameSI_knowledge,data[vector],limit10,output_fields[uid,Question],search_paramssearch_params)iflen(res[0])0:print(f已存在相似问题:{res[0][0][entity][Question]})return# 插入新数据data{uid:uid,Question:question,Answer:answer,Vector:vector}client.insert(collection_nameSI_knowledge,datadata)print(f插入成功: uid{uid})六、核心服务实现6.1 Flask服务主框架fromflaskimportFlask,request,render_template,Response,stream_with_contextfrompymilvusimportMilvusClientfromflask_corsimportCORSimportrequests,json,time appFlask(__name__)CORS(app)# Milvus连接配置clientMilvusClient(uriyour_milvus_host:19530,tokenyour_token,db_namedefault)# DeepSeek API配置DEEPSEEK_URLhttps://api.deepseek.com/chat/completionsDEEPSEEK_API_KEYos.environ.get(DEEPSEEK_API_KEY)# 建议使用环境变量headers{Content-Type:application/json,Accept:application/json,Authorization:fBearer{DEEPSEEK_API_KEY}}# 向量检索参数search_params{metric_type:COSINE,params:{radius:0.5}}6.2 本地Embedding向量化defvectorize_text(text):调用本地Ollama的bge-m3模型进行文本向量化urlhttp://localhost:11434/api/embeddingsheaders{Content-Type:application/json,Accept:application/json}data{model:bge-m3:latest,prompt:text}responserequests.post(url,jsondata,headersheaders)ifresponse.status_code200:returnresponse.json().get(embedding,[])returnNone为什么用本地Ollama做Embedding免费调用无API费用数据不出内网安全可控bge-m3 对中文语义理解效果优秀6.3 普通问答接口同步返回app.route(/getAnser,methods[GET])defget_answer():questionrequest.args.get(q)# 1. 问题向量化vectorvectorize_text(question)# 2. Milvus语义检索获取Top-20相关问答resclient.search(collection_nameSI_knowledge,data[vector],limit20,output_fields[uid,Question,Answer],search_paramssearch_params)# 3. 构建DeepSeek的请求data{model:deepseek-chat,messages:[],stream:False,temperature:0.3,max_tokens:8192}# 用户问题带Prompt约束data[messages].append({role:user,content:(question只能使用提供的上下文进行逻辑推理不要提示根据提供的上下文。回答问题后推荐相关的3个问题且不含回答及序号且答案与推荐的问题之间用separate分开且问题的答案在前面)})# 将检索到的知识库答案作为System上下文注入foriteminres[0]:data[messages].append({role:system,content:item[entity][Answer]})# 4. 调用DeepSeek生成回答start_timetime.time()responserequests.post(DEEPSEEK_URL,jsondata,headersheaders)print(f耗时:{time.time()-start_time:.2f}s)ifresponse.status_code200:resultresponse.json()contentresult[choices][0][message][content]# 5. 解析回答和推荐问题answer,recommendparse_answer_and_recommend(content)returnanswerseparaterecommendreturn6.4 流式问答接口SSE实时返回defsafe_decode(byte_data:bytes,encodingutf-8)-str:兼容多种编码格式的字节解码try:encodingrequests.compat.chardet.detect(byte_data)[encoding]returnbyte_data.decode(encoding)exceptUnicodeDecodeError:returnbyte_data.decode(encoding,errorsreplace)app.route(/getAnserStream,methods[GET])defget_answer_stream():questionrequest.args.get(q)# 1. 向量化 检索同上vectorvectorize_text(question)resclient.search(collection_nameSI_knowledge,data[vector],limit20,output_fields[uid,Question,Answer],search_paramssearch_params)# 2. 构建请求streamTruedata{model:deepseek-chat,messages:[],stream:True,temperature:0.3,max_tokens:8192}data[messages].append({role:user,content:(question只能使用提供的上下文进行逻辑推理不要提示根据提供的上下文如果发现是问了多个问题拆分问题。回答问题后从上下文中推荐相关的3个问题且不含回答及序号且答案与推荐的问题之间用separate分开且问题的答案在前面)})foriteminres[0]:data[messages].append({role:system,content:f问:{item[entity][Question]}?答:{item[entity][Answer]}})# 3. 流式调用DeepSeekresponserequests.post(DEEPSEEK_URL,jsondata,headersheaders,streamTrue)ifresponse.status_code200:defgenerate():forlineinresponse.iter_lines():ifline:textsafe_decode(line).replace(data: ,)try:chunkjson.loads(text)contentchunk[choices][0][delta][content]yieldcontentexceptException:passreturnResponse(stream_with_context(generate()),mimetypetext/plain)return6.5 解析回答和推荐问题defparse_answer_and_recommend(raw_content:str):从LLM输出中分离答案和推荐问题# 处理DeepSeek-R1的思考标记char_think\u25b8positionraw_content.find(char_think)startposition8ifposition0else0contentraw_content[start:]# 分离答案和推荐问题sepseparatesep_poscontent.find(sep)ifsep_pos0:answercontent[:sep_pos]recommend_textcontent[sep_poslen(sep):]# 清洗推荐问题文本linesrecommend_text.split(\n)cleaned[]forlineinlines:fornoisein[相关推荐问题,相关问题推荐,推荐相关问题,*,:,]:lineline.replace(noise,)iflen(line)4:cleaned.append(line)recommendseparate.join(cleaned)returnanswer,recommendreturncontent,七、前端集成7.1 流式请求与Markdown渲染functionaskllm(question){varallResult;fetch(/getAnserStream?qencodeURIComponent(question)).then(response{constreaderresponse.body.getReader();constdecodernewTextDecoder();functionreadChunk(){returnreader.read().then(({done,value}){if(done){// 流结束解析推荐问题constsepIndexallResult.indexOf(separate);constanswerallResult.slice(0,sepIndex);// 使用marked.js渲染Markdowndocument.getElementById(result).innerHTMLmarked(allResult.substring(0,sepIndex));// 解析并渲染推荐问题...return;}consttextdecoder.decode(value);allResulttext;document.getElementById(result).innerHTMLtext;readChunk();});}readChunk();});}7.2 语音输入讯飞语音识别前端集成了讯飞实时语音转写iat用户可以通过点击麦克风按钮直接语音提问语音识别结果自动发送给后端进行问答。7.3 语音播报讯飞TTS回答生成完成后自动调用讯飞TTS进行语音播报实现完整的语音交互闭环。八、HTTPS部署if__name____main__:app.run(host0.0.0.0,port443,ssl_context(path/to/server.crt,path/to/server.key))生产环境建议使用 Nginx 反向代理 Let’s Encrypt 证书而非直接在Flask中启用HTTPS。九、关键技术细节9.1 Prompt工程本项目的Prompt设计核心思路用户问题 约束条件 → 要求LLM 1. 只能使用提供的上下文推理防止幻觉 2. 不提示根据提供的上下文更自然 3. 拆分多问题场景 4. 输出答案 推荐问题用特殊分隔符分隔将检索到的知识库答案以system角色注入格式为问:xxx?答:xxx让LLM理解上下文结构。9.2 相似度阈值调优参数值说明radius0.5检索阈值越高越严格limit20检索返回条数metric_typeCOSINE余弦相似度temperature0.3LLM温度值偏低以保持准确知识库去重时使用radius0.87确保高语义相似的问题不会重复入库。9.3 选择bge-m3的原因中英文混合支持bge-m3 多语言效果好维度适中1024维Milvus检索效率高本地部署零成本通过Ollama本地运行无需API调用十、效果展示用户提问示例用户: “职工缴费年限不够怎么办”系统回答:从知识库检索到Top-20相关问题及答案DeepSeek基于上下文生成结构化回答自动推荐3个相关问题如养老保险缴费标准是什么、灵活就业人员如何参保等十一、优化方向Prompt输出结构化当前使用separate分隔符解析推荐问题可改为JSON格式输出更稳定Rerank重排序在Milvus检索后增加Rerank模型如bge-reranker提升Top-K准确率对话历史管理当前为单轮对话可增加session管理实现多轮上下文缓存层高频问题可加Redis缓存减少重复的Embedding和LLM调用知识库更新机制定时从业务系统同步最新问答数据十二、总结本项目通过Ollama本地Embedding Milvus向量检索 DeepSeek推理的RAG架构实现了零Embedding API成本的语义检索基于知识库的准确回答减少幻觉流式输出 语音交互的良好用户体验整套方案技术栈开源、部署简单适合政府、企业等有私有知识库的智能客服场景。相关技术文档Milvus官方文档https://milvus.io/docsOllama官方文档https://ollama.comDeepSeek API文档https://platform.deepseek.com/api-docsbge-m3模型https://huggingface.co/BAAI/bge-m3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2499826.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…