当前位置: 首页 > news >正文

简单学习 --> Rag

一、 RAG 的本质:为大模型外接“动态内存”

在计算机架构中,CPU 的算力再强,也受限于 L1/L2 缓存和内存的大小。LLM(大语言模型)同理:它的权重矩阵(模型本身)相当于只读存储器(ROM),而它的上下文窗口(Context Window)相当于极其昂贵的运行内存(RAM)

RAG(检索增强生成)的核心思想是:绝不修改 ROM(不微调大模型),而是通过外部系统实时将最相关的数据加载到 RAM 中,供 LLM 进行即时计算与推理。

例子:

大模型(LLM)是一个智商高达 150 但“没背过你们公司业务手册”的学霸。 用户提问时,如果直接让他裸考(直接问 LLM),他可能会胡编乱造(幻觉)。

RAG 就是学霸的场外书童

书童飞速去图书馆(向量数据库)翻出相关的 3 页资料,复印下来连同考卷一起递给学霸。学霸看着这 3 页资料总结出完美答案。

RAG 工作流:

  1. 意图捕获:拦截用户的查询请求。

  2. 知识寻址:借助向量引擎,在庞大知识库中定位到最相关的“知识块”。

  3. 上下文组装:将找到的“知识块”拼接到系统提示词(Prompt)中。

  4. 推理输出:LLM 基于刚刚被注入的背景知识生成回复。

二、 主流技术架构与选型

在实际工程落地中,架构选型主要考虑运维成本掌控力的平衡。

方案类型技术栈示例适用场景与优缺点
全云服务 (主流)OpenAI API + Pinecone/Zilliz + 纯 Python / LangChain推荐。开发快,无需关心底层扩容。缺点是数据出境或依赖第三方厂商。
半云服务 (企业常用)LLM API + LlamaIndex + 私有部署向量数据库 (如 Milvus/Qdrant)平衡之选。模型用云端保证智商,数据留在本地库保证隐私。
全本地化 (研究向)本地部署 Llama 3 + 本地向量数据库 + LangChain门槛高。适合对数据安全极度敏感或做底层研究的团队,对硬件算力要求极高。

为什么向量数据库推荐用云服务?和传统 MySQL 一样,一旦数据量变大,向量数据库也需要面对分布式架构、主从同步、读写分离、高可用等问题。向量检索极耗内存和 CPU,云服务能有效转嫁高昂的运维和机器成本。

三、 向量数据库的三部曲

向量数据库的本质可以概括为:将万物映射为坐标(Embedding),用数学计算距离(Similarity),并修筑高速公路(Indexing)以实现海量秒查。

1. 核心灵魂:万物皆坐标 (Embeddings)

计算机无法理解人类语言中的“相似”,但能理解空间中坐标点的距离。Embedding 就是把文本压缩成一个固定维度的数组。

代码解析:文本转向量

from langchain_community.embeddings import HuggingFaceBgeEmbeddings # 初始化 BGE 模型 (目前开源界语义理解极强的轻量级模型) model_name = "BAAI/bge-small-zh-v1.5" embeddings = HuggingFaceBgeEmbeddings(model_name=model_name) # 定义要处理的文本 text_a = "Java Spring Boot的AOP拦截器怎么写?" text_b = "Python中如何使用装饰器实现切面编程?" text_c = "今天晚上的夜宵打算吃小龙虾。" # 将文本转化为高维向量 (执行 Embedding 过程) vec_a = embeddings.embed_query(text_a) # 打印结果:你会看到一个拥有多个浮点数的列表,这就是它的GPS坐标 print(f"文本A的向量维度: {len(vec_a)} 维") print(f"截取前三维: {vec_a[:3]}")
2. 检索原理:计算相似度 (Similarity Search)

找到相关内容的本质,是在高维空间中找寻距离最近的两个点。最常用的尺子是余弦相似度(Cosine Similarity),它关注向量夹角的大小;另一把常用的尺子是点乘(Dot Product)

补充概念:什么是点乘?点乘是两个向量对应维度相乘后再相加的数学过程。公式为:A⋅B=∑i=1naibi。

  • 物理意义:它衡量了两个向量在相同方向上的“协同程度”。

  • 在向量库中的应用:如果向量在存入前已经做过归一化(长度都变为 1),那么点乘的值就完全等于余弦相似度。计算点乘的硬件资源消耗通常低于计算夹角,因此被广泛使用。

代码解析:手写点乘计算相似度

from scipy.spatial import distance import numpy as np # 假设我们将刚刚生成的三个文本向量化为了 numpy 数组 # vec_a ("Java AOP") 和 vec_b ("Python 装饰器") 都在讲编程范式 # vec_c ("吃小龙虾") 完全无关 # 计算余弦相似度 (1 - 余弦距离) # 值越接近 1,表示极其相似;越接近 0,表示毫无关联 sim_ab = 1 - distance.cosine(vec_a, vec_b) sim_ac = 1 - distance.cosine(vec_a, vec_c) print(f"Java编程 vs Python编程 的语义相似度: {sim_ab:.4f}") # 得分很高 print(f"Java编程 vs 吃小龙虾 的语义相似度: {sim_ac:.4f}") # 得分极低
3. 性能关键:建立索引 (Indexing / ANN)

全量对比计算(暴力搜索)太慢。现代向量库使用ANN(近似最近邻)算法,其中最主流的是HNSW算法。它构建了一个多层的图结构,类似于“先坐高铁到大城市,再坐公交到具体街道”,从而实现毫秒级检索。

四、 维度、模型与兼容性

  • 模型兼容性铁律:写入和查询必须使用同一个 Embedding 模型。不同模型提取特征的逻辑完全不同,跨模型对比就像拿美元面值直接对比日元面值,毫无意义。

  • 维度选择:常见的维度有 384、768、1536 等。维度越高,能表达的语义细节越丰富,但存储和计算成本呈线性增加。目前通用 RAG 任务中,768 到 1536 维是平衡性能与成本的最优解。

五、 文本切片 (Chunking):操作系统的“内存分页”逻辑

这是 RAG 系统工程落地中最容易翻车的环节。大模型的上下文窗口有限,我们必须把知识库切分为标准的“块”(Chunk)再喂给它,这类似于操作系统的内存分页(Paging)

场景 A:长文档的智能切片 (递归切分)

如果是整本书或长篇论文,我们不能粗暴地按固定字数一刀切,这会切断上下文的逻辑。业界主流做法是递归切分,并保留重叠区(Overlap)

例子:

怎么切战斧牛排?你不能把一整块战斧牛排一口吞下(Token 超限),你得切块。 如果你闭着眼睛按重量乱砍,可能会直接把骨头和肉的连接处剁碎(把一句话从中间截断)。 递归切分就是有技巧地沿着筋络切(优先按段落切,段落太大再按句子切)。而**重叠区(Overlap)**就是保证每一块肉上都连着一点上一块的肉筋,这样吃的时候(LLM理解时),才知道这两块肉原本是连在一起的。

代码示例:LangChain 递归字符切分器

from langchain.text_splitter import RecursiveCharacterTextSplitter long_document = "这里是长达十万字的技术文档原文..." # 实例化高级文本切分器 splitter = RecursiveCharacterTextSplitter( chunk_size=500, # 每个块的最大容量限制 (牛排块大小) chunk_overlap=50, # 设置 50 个字符的冗余重叠区 (连带的肉筋) separators=["\n\n", "\n", "。", "!", "?"] # 切分优先级,优先保证段落完整 ) chunks = splitter.create_documents([long_document])
场景 B:离散短文本 (FAQ) 的精准映射

针对类似["华为手机好不好?", "苹果手机好不好?"]这种已经具有高度独立语义的短句。

工程铁律:绝不合并!一定要确保“一个语义单元 = 一个 Chunk”。

例子:

不要把 M&M 豆融化成巧克力砖FAQ 问答对本身就是一颗颗完整的 M&M 豆,有着独立的颜色和味道。如果你因为觉得单颗太小,非要把 100 颗不同的 M&M 豆加热融化成一个 500g 的巧克力大砖块(大 Chunk),等你想吃红色的豆子时,拿出来的全都是一堆大杂烩,这就是严重的注意力污染(Noise)

代码示例:针对 FAQ 数据的精准切分

from langchain.text_splitter import CharacterTextSplitter faq_text = """ 华为手机好不好?答:信号好,拍照强。 苹果手机好不好?答:生态好,录像强。 今天下雨吗?答:不下。 """ # 针对离散数据的强硬切分策略 faq_splitter = CharacterTextSplitter( separator="\n", # 仅以换行符作为唯一物理边界 chunk_size=10, # 设积极小值,逼迫切分器在每一个换行符处都必须切断 chunk_overlap=0 # 独立数据,绝对不允许重叠污染 ) faq_chunks = faq_splitter.create_documents([faq_text.strip()]) # 输出结果将是绝对干净的三条独立记录,彼此互不干扰。

六、 LlamaIndex 的底层逻辑:List Index 🆚 Vector Index

在框架层面,针对不同的数据量,索引方式也有区别:

索引类型原理是否需要 Embedding 模型适用场景
Vector Index计算所有文本的向量坐标,通过空间距离进行检索,只提取 Top-K 给 LLM。海量文档、长文本、常规 RAG 场景。
List Index直接将所有文本按顺序拼接成一个列表。查询时,把整个列表内容直接塞进 Prompt 交给 LLM 处理。数据量极小(总 Token 小于大模型上下文窗口上限)、或者要求严格按顺序总结的场景。

总结来说,RAG 系统的上限由检索的精准度(Embedding 质量 + Chunking 策略)决定,而下限由LLM 自身的逻辑推理能力决定。您的这套笔记已经非常清晰地覆盖了这一闭环。

http://www.jsqmd.com/news/895405/

相关文章:

  • 2026年亲测免费去AI痕迹工具+3大方法,降低论文AI率30%! - 降AI实验室
  • BroadcastChannel 深度解析
  • Hugging Face分词报错怎么办?教你一招避坑
  • 告别命令行!ESP32-S3安全三件套(Flash加密+Secure Boot V2+NVS加密)的图形化工具配置避坑指南
  • 从1600次周下载看开源工具包设计:聚焦高频开发痛点
  • 2026年Python学习指南:从零基础到实战项目,掌握核心语法与工具
  • Windows窗口置顶终极指南:5分钟掌握AlwaysOnTop提升工作效率
  • RTX内核栈溢出检测机制与配置指南
  • 免费QQ音乐格式转换终极指南:如何用QMCDecode解锁加密音频文件
  • 番茄小说下载器:从网络小说到个人图书馆的一站式解决方案
  • RC振荡器和LC振荡器,是包含在单片机内部,还是作为单独的元件?
  • 基于ssm的大学校医院信息管理系统(10112)
  • 5步彻底解决TranslucentTB安装错误:Windows任务栏透明化工具安装指南
  • 新手避坑指南:在RHEL 6.10上安装Cadence IC618和Verdi 2018.09的完整流程(含依赖库检查)
  • EhViewer开源漫画阅读器:打造你的专属Android漫画图书馆
  • 基于STCO框架构建类型安全提示工程,降低LLM幻觉率30%
  • 为AI编码助手集成运行时日志:从日志采集到智能诊断的工程实践
  • 基于Agora与AssemblyAI构建高精度实时语音转录机器人
  • 面向AI智能体的API设计:从人类可读到机器可理解的技术演进
  • Unity游戏配置表管理新思路:不写编辑器扩展,用ExcelDataReader+ScriptableObject实现数据热更新
  • 基于异步并发与复古终端的Claude API健康检查工具开发实践
  • AI搜索优化:揭秘Schema标记44%提升神话与实证策略
  • 开发者如何克服完美主义陷阱,构建内在交付体系实现项目上线
  • 构建本地语音控制AI智能体:从语音识别到安全文件操作的全栈实践
  • 2026年5月北京十大装修公司排行榜推荐:十大专业公司评测夜间施工防噪音 - 品牌推荐
  • 基于Quarkus与MCP协议构建Java多智能体LLM Web前端实践
  • 8天构建AI自动生成PR描述工具:从零到一的技术实战复盘
  • LeetCode 438:找到字符串中所有字母异位词 | 滑动窗口
  • Numeca在Linux下的两种安装路径选择:/usr/ 还是 /home/?权限管理与后续使用对比
  • 从37欧元账单到3.5欧元:Serverless架构重构实战与云成本优化指南