RAG编程实践(DashScope+Milvus)

news/2025/11/11 21:35:18/文章来源:https://www.cnblogs.com/LiShengTrip/p/19205549

目录
  • RAG编程实践
    • 一、RAG概述
      • RAG的价值
      • 学习资料
    • 二、系统RAG架构设计
      • 1. 整体架构图
      • 2. 技术选型
    • 三、核心组件
      • 1. 向量生成层:文本到向量的转换
      • 2. 向量存储层:Milvus数据库操作
      • 3. 混合检索实现:RRF排名融合
    • 四、RAG与智能体系统的集成
      • 1. 检索工具封装
      • 2. RAG与智能体的结合
    • 五、RAG完整工作流程
      • 1. 知识库初始化阶段
      • 2. 查询处理阶段
      • 3. 响应处理与优化
    • 六、系统优化
      • 1. 异步架构设计
      • 2. 向量检索优化
      • 3. 知识库维护

RAG编程实践

一、RAG概述

检索增强生成(Retrieval-Augmented Generation,简称RAG)是一种结合了检索系统和生成模型的先进架构,旨在解决大型语言模型(LLM)在知识时效性、准确性和专业性方面的局限性。

RAG的价值

  1. 突破知识截止限制:通过外部知识库提供最新信息,解决LLM知识过时问题
  2. 减少幻觉生成:基于检索到的准确信息回答问题,降低模型生成错误内容的概率
  3. 领域知识专业化:可以导入特定领域的专业知识库,提升回答的专业性
  4. 可追溯性:回答可以溯源到具体的知识来源,增强透明度和可信度

学习资料

Deeptoai RAG系列教程
build-rag-with-milvus文档

二、系统RAG架构设计

本文通过一个电商客服系统进行RAG实践演示。

1. 整体架构图

┌──────────────┐     ┌────────────────┐     ┌───────────────────┐     ┌─────────────────┐
│              │     │                │     │                   │     │                 │
│  用户查询     │────▶│  向量生成层     │────▶│  向量存储与检索层   │────▶│  生成增强层      │
│              │     │                │     │                   │     │                 │
└──────────────┘     └────────────────┘     └───────────────────┘     └─────────────────┘│▼┌─────────────────┐│                 ││   智能回答输出    ││                 │└─────────────────┘

2. 技术选型

  • 向量模型:通过DashScope API生成稀疏向量和密集向量
  • 向量数据库:Milvus,支持混合向量检索
  • 索引技术:FLAT索引(密集向量) + SPARSE_INVERTED_INDEX(稀疏向量)
  • 相似度计算:余弦相似度(COSINE)和内积(IP)
  • 结果融合:RRF(Reciprocal Rank Fusion)排名器

三、核心组件

1. 向量生成层:文本到向量的转换

实现文本到向量的转换功能:

async def query_to_vector(query):"""将用户查询文本转换为稀疏向量与稠密向量,用于后续检索。通过 DashScope 的文本嵌入接口异步调用,避免阻塞事件循环。"""def embedding_sparse(query):# 调用DashScope API获取向量表示resp = dashscope.TextEmbedding.call(api_key=settings.EMBEDDING_API_KEY,model=dashscope.TextEmbedding.Models.text_embedding_v4,input=query,dimension=1024,output_type="dense&sparse",  # 同时获取稀疏和密集向量)if resp.status_code == 200:# 解析稀疏向量:将索引与值映射为字典sparse_vector = {item["index"]: item["value"] for item in resp.output["embeddings"][0]["sparse_embedding"]}# 直接提取稠密向量dense_vector = resp.output["embeddings"][0]["embedding"]return sparse_vector, dense_vectorreturn [], []# 使用asyncio.to_thread将同步调用放到线程池,防止阻塞sparse_vector, dense_vector = await asyncio.to_thread(embedding_sparse, query)return sparse_vector, dense_vector

技术要点

  • 密集向量:捕获语义信息,对同义词、语义相似性表现好
  • 稀疏向量:保留关键词和精确匹配信息,对术语、专有名词识别准确
  • 异步处理:使用asyncio.to_thread避免API调用阻塞事件循环
  • 错误处理:API调用失败时返回空向量,保证系统稳定性

2. 向量存储层:Milvus数据库操作

实现基于Milvus的向量存储和检索功能:

class AsyncMilvusOperator:def __init__(self, collection_name):self.client = client.async_milvus_clientself.collection_name = collection_name# 创建向量数据库schemaasync def create_schema(self):schema = self.client.create_schema(auto_id=True, description="这是通用知识库的参数模型")schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True, description="主键")schema.add_field(field_name="dense_vector", datatype=DataType.FLOAT_VECTOR, dim=1536,description="这是密集向量")schema.add_field(field_name="sparse_vector", datatype=DataType.SPARSE_FLOAT_VECTOR,description="这是稀疏向量")schema.add_field(field_name="text", datatype=DataType.VARCHAR, max_length=4096, description="这是文本内容")return schema# 创建集合和索引async def create_collection(self):await self.client.create_collection(collection_name=self.collection_name,schema=await self.create_schema(),description="这是通用知识库")index_params = self.client.prepare_index_params()# 为密集向量创建FLAT索引,使用余弦相似度index_params.add_index(field_name="dense_vector", index_type="FLAT", metric_type="COSINE")# 为稀疏向量创建SPARSE_INVERTED_INDEX索引,使用内积index_params.add_index(field_name="sparse_vector", index_type="SPARSE_INVERTED_INDEX", metric_type="IP")await self.client.create_index(collection_name=self.collection_name, index_params=index_params)

技术要点

  • schema设计:支持不同类型的向量和元数据存储
  • 索引优化:针对不同类型向量选择最适合的索引类型
  • 异步接口:全面异步实现,提高并发性能

3. 混合检索实现:RRF排名融合

最关键的检索功能通过mix_search_vector方法实现:

async def mix_search_vector(self, dense_vector, sparse_vector):# 加载集合到内存await self.client.load_collection(collection_name=self.collection_name)# 密集向量搜索请求req_dense = AnnSearchRequest(data=[dense_vector],anns_field="dense_vector",param={"metric_type": "COSINE"},limit=10,)# 稀疏向量搜索请求req_sparse = AnnSearchRequest(data=[sparse_vector],anns_field="sparse_vector",param={"metric_type": "IP"},limit=10,)# 合并请求并使用RRF排名器reqs = [req_dense, req_sparse]ranker = RRFRanker(k=10)res = await self.client.hybrid_search(collection_name=self.collection_name, reqs=reqs,output_fields=["text"],ranker=ranker)return res

技术要点

  • 混合检索:同时使用两种向量检索,优势互补
  • RRF排名:使用倒数排名融合算法整合两个检索结果列表
  • 性能优化:加载集合到内存提升检索速度

四、RAG与智能体系统的集成

1. 检索工具封装

将RAG检索功能封装为可重用工具:

class SearchTool(BaseTool):name: str = "search_tool"description: str = "这是通过用户的指令来检索知识库的工具"args_schema: Type[BaseModel] = SearchArgsdef _run(self, query: str) -> str:"""同步执行工具(通过异步包装)"""loop = asyncio.get_event_loop()return loop.run_until_complete(self._arun(query))async def _arun(self, query: str):# 初始化Milvus操作器,指定集合名称milvus_operator = AsyncMilvusOperator(collection_name="general_knowledge")# 生成查询向量sparse_vector, dense_vector = await query_to_vector(query)# 执行混合向量搜索knowledge_info = await milvus_operator.mix_search_vector(dense_vector=dense_vector, sparse_vector=sparse_vector)return knowledge_info

2. RAG与智能体的结合

将检索工具集成到通用智能体中:

class GeneralAgent:def __init__(self):self.prompt = """**# 角色**你是电商平台的**通用客服助手**。你负责处理无法归类到其他专业智能体的一般性问题..."""async def generate_general_agent(self, messages):# 创建智能体,将SearchTool作为可用工具传入order_agent = create_react_agent(model=client.async_openai_chat, tools=[SearchTool()], prompt=self.prompt)# 执行智能体推理result = await order_agent.ainvoke({"messages": messages})return result

五、RAG完整工作流程

1. 知识库初始化阶段

  1. 创建数据库表:基于MySQL创建知识库元数据表
  2. 创建向量集合:应用启动时初始化Milvus集合和索引
  3. 知识导入
    • 收集和整理知识文档
    • 将文档切分为适当大小的文本块
    • 使用query_to_vector生成向量表示
    • 通过insert_vector方法将向量和文本存储到Milvus

2. 查询处理阶段

  1. 用户查询接收:通过FastAPI端点接收用户查询
  2. 智能体路由:RouterAgent将请求路由到相应专业智能体
  3. 向量生成:将用户查询转换为稀疏向量和密集向量
  4. 混合检索:执行混合向量搜索并使用RRF排名器合并结果
  5. 知识增强生成
    • 将检索到的知识作为上下文提供给LLM
    • LLM基于增强上下文生成回答

3. 响应处理与优化

  1. 智能体处理:专业智能体利用检索到的知识生成精准回答
  2. 记忆保存:将交互保存到用户记忆系统
  3. 结果返回:格式化并返回最终回答

六、系统优化

1. 异步架构设计

  • 全面使用异步处理,提高系统并发能力
  • 使用线程池避免API调用阻塞事件循环

2. 向量检索优化

  • 预加载集合到内存提升检索速度
  • 合理设置检索参数(limit、排名策略等)
  • 针对不同类型内容选择合适的向量模型

3. 知识库维护

  • 定期更新知识库内容,确保信息时效性
  • 监控检索效果,优化向量模型和检索参数
  • 建立反馈机制,持续改进知识库质量

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

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

相关文章

使用 Docker 快速部署 MinIO 文件存储服务

使用 Docker 快速部署 MinIO 文件存储服务本文提供了 Docker 快速部署 MinIO 对象存储服务的完整方案,旨在解决传统文件存储分散、安全性低、运维复杂等痛点。核心步骤包括拉取指定稳定版 MinIO 镜像,通过 Docker 命…

2025 年 11 月财税合规服务厂家推荐排行榜,电商/跨境电商/出口退税/公司注销/股权设计/平台报送/亚马逊/Temu/速卖通/高新企业/审计报告全案解决方案

2025年11月财税合规服务厂家推荐排行榜:电商与跨境电商企业全周期财税解决方案深度解析 行业背景与发展趋势 随着数字经济时代的深入发展,财税合规服务行业正经历着前所未有的变革。特别是在电商与跨境电商领域,企业…

AI智能体落地:Agent-Assist vs 全自动化完整决策指南

今年开始LLM驱动的Agentic AI发展速度非常惊人。而我们现在面临一个实际问题:到底是上全自主的AI智能体,还是让人类继续参与决策?从大量实际案例来看Agent-Assist(也就是Human-in-the-Loop系统)既能带来自动化的效…

详细介绍:微服务时代的前后端协作:API契约驱动开发实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

ZROI-NOIP2025做题记录

一些想起来的要做的东西:切距/曼距转化,以及一些常用旋转角度式子背一背,不要在考场上现推了 楼房重建 checkerDP 观察dp状态和值的关系 7连d1t4 纯性质/打表题 7连d1t2 7连d2t1 7连d2t3 启发式 7连d2t4 鸽巢/糖水 …

week1--RE--刷题记录

week1 刷题 目录week1 刷题1. [GXYCTF2019]simple CPP2. [网鼎杯 2020 青龙组]singal3. [buuctf]firmware4. [2019红帽杯]xx 1. [GXYCTF2019]simple CPP ​ IDA载入直接分析,这个程序的主要加密逻辑有几块:第一块是一…

Appium Inspector教程

{ "platformName": "Android", "appium:deviceName": "Android Device", "appium:noReset": true, "appium:automationName": "UiAutomator2"…

Pycharm常用设置

Pycharm常用设置1. 总提示变量名应该全小写 2. 提示参数可以使用外部的变量

pythontip 映射字符串中的字母

编写一个程序,创建一个字典,其中给定单词的每个唯一字母表示一个键,值为字母出现的索引的列表。 定义函数letter_indices(),参数为word(字符串)。 在函数中,创建一个字典,其中键是单词中的唯一字母,值是包含该字…

Python : argument name should be lowercase 警告处理解决方法

Python : argument name should be lowercase 警告处理解决方法From: https://www.cnblogs.com/sunxun001/p/13199786.html 用pyCharm时,常会出现警告信息: function name should be lowercase --函数名应该是小写…

*题解:P5278 算术天才⑨与等差数列

原题链接 解析 要想放到线段树上做,就要考虑如何在不排序的情况下通过一系列可合并的信息判别等差数列。对于一个数列,我们知道它的长度 \(len\),配合上最大值 \(mx\) 最小值 \(mn\) 就可以判断询问给出的 \(k\) 能…

instanceof(类型)

instanceof(类型)instanceof(检测左侧的对象是否为右侧类或接口的实例) public class Main {public static void main(String[] args){//方法的调用只和左边定义的数据类型有关Object object=new teacher();System…

高级程序语言设计第5次

这个作业属于:https://edu.cnblogs.com/campus/fzu/gjyycx 这个作业的要求:https://edu.cnblogs.com/campus/fzu/gjyycx/homework/14581 学号:102500416 姓名:王浩宇 第一部分 1.2. 尽力了,老师3.4.第二部分书本作…

25.11.11 spfa算法

SPFA算法 1.SPFA 是 Bellman-Ford 算法 的一种优化算法,用来求解 带权有向图 中 单源最短路径(可以有负权边,但不能有负权回路)。 2.算法流程: 以源点 s 为起点: (1)初始化 dist[i] = INF,dist[s] = 0; (2)建立…

什么是glTF,与glb的区别,规格和优点,通俗易懂地解释下载获取

​ 近年来,在网站和应用程序上查看 3D 内容的机会迅速增加。 无论是在三维空间中传达产品吸引力的电子商务网站,还是在虚拟空间中交互的元宇宙,还是将信息叠加在现实世界中的增强现实 (AR),3D 技术都在发展我们的…

CF2164E Journey 题解

Hint1 考虑存在欧拉回路的充要条件。Hint2 当我们想在 $(u, v)$ 点间进行传送时,如何计算最小的代价呢?Hint3 相信你已经通过 Hint2 想到建重构树了,那么不妨试试通过贪心算出答案。转化之后题目要求的就是原图的一…

算法训练之BFS解决最短路径难题

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

ASP.NET Core Authorization: 跳过JWT校验

本文记录了如何在asp.net core 9.0上为WebApi配置跳过JWT校验的方法。 项目准备 执行以下命令dotnet new webapi --use-minimal-apis --name MockJwtTestApi --output MockJwtTestApi --auth None dotnet add package …

学习昇腾硬件软件产品名称

应用使能(层级位于MindSpore等框架之上)摘录官网介绍:MindSpeed是一款专为昇腾平台打造的高性能加速库,涵盖了MindSpeed Core亲和加速模块、MindSpeed LLM套件、MindSpeed MM套件以及MindSpeed RL套件这四个重要组…

实用指南:[linux仓库]信号保存[进程信号肆]

实用指南:[linux仓库]信号保存[进程信号肆]2025-11-11 21:08 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: bl…