向量与向量数据库:文字怎么变成可计算的数字
作者:利威尔xu | CSDN 专栏《RAG 保姆级实战:从原理到落地》
前言
在第三篇《RAG文档切分》里,咱把 RAG 的六步流程拆开了讲,重点聊了文档切分这个坑最多的环节。切太大检索不准、切太小上下文碎片化,切分策略没有标准答案,得结合业务场景来定。
那切好的文档块,接下来怎么变成计算机能检索的东西?向量到底是什么?为什么文字能算相似度?
这个专栏一共 6 篇,从 RAG 概念、降幻觉武器库、流程与切分、向量与向量库,到检索重排与引用溯源、落地坑与评估,一路走下来你能完整搞懂 RAG。
这篇,咱把 RAG 的第三步、第四步拆开来讲——向量化是什么,向量数据库怎么选。
一、向量是什么
在讲 Embedding 之前,咱得先搞清楚向量是什么。
你可能还记得中学数学里的坐标系。一个点可以用 x 和 y 两个坐标定位,比如 (3, 4)。这个点不是随便写的,它代表了在平面空间里的一个具体位置。
向量就是这个概念的推广。现实中一个地点用经纬度两个数字定位,一段文字也可以用一串数字定位——这一串数字就是向量。
说白了,向量就是高维空间里的坐标。
你不用被"高维"这个词吓住。平面是二维,咱眼睛能看到;高维只是人脑想象不出来,但数学上是一样的道理——每个维度代表一个方向,无数个方向叠在一起形成一个空间。
Embedding 模型把文字转成向量的时候,每个维度代表某种抽象的语义特征。比如第一个维度可能代表"正式程度",第二个维度代表"技术深度",第三个维度代表"情感正负"……具体每个维度代表什么,不是人工设定的,是模型从海量文本里自己学出来的。
768 维、1536 维、3072 维,这些数字你可能在Embedding模型的介绍里见过。说白了就是:每段文字在这套坐标系里,被标注了上千个维度的坐标。维度越高,模型能表达的语义越细腻,但计算成本也越高。
为什么放这段代码?让你们看看 Embedding 的基本形态,理解输入输出是什么。
// 调用 Embedding 模型,把文字转成向量funcembedText(textstring)([]float32,error){// 调用 Embedding API,把文字转成向量req:=map[string]string{"text":text}body,err:=json.Marshal(req)resp,err:=http.Post(embeddingURL,"application/json",bytes.NewBuffer(body))deferresp.Body.Close()varresultmap[string]interface{}json.NewDecoder(resp.Body).Decode(&result)embedding:=result["embedding"].([]interface{})vector:=make([]float32,len(embedding))fori,v:=rangeembedding{vector[i]=float32(v.(float64))}returnvector,nil}这段代码在干嘛?输入一段文字,调用 Embedding API,输出一串浮点数——那就是这段文字的向量表示。实际生产中会把请求 batch 化、缓存结果、控制并发,这里只展示最基本的数据流。为了代码清晰,这里省略了常规的错误处理和相关逻辑,实际生产代码中务必加if err != nil判断。
二、Embedding 到底在干什么
好,向量说完了,咱再聊 Embedding。
你可能见过这种说法:“Embedding 就是把文字映射成向量”。这话没错,但有点干巴巴的,咱换个更容易记住的比喻。
Embedding 就像给每段文字在地图上标一个位置。
同一个地图上,距离近的地方往往有相似的特点。比如北京市地图里,西单、王府井、国贸都是商业区,它们在地图上挨得近;中关村、上地都是科技区,也挨得近。地理位置近,说明这些地方在某种维度上相似。
Embedding 的地图不是地理地图,是语义地图。语义相近的文字,在这张"地图"上的坐标也相近。
你问"怎么申请退货",系统在地图上找到"退货流程"“退款步骤”"售后服务"这些文字,它们坐标都挨着,所以能检索出来。
这里有个关键点要讲清楚:Embedding 模型不是在"理解"文字,它是在做一种可学习的映射。
模型没有真的懂什么叫"退货",它只是在海量文本里学到了:包含"退货"“退款”"售后"这些词的句子,往往出现在相似的上下文中。所以这些词映射到的坐标就相近。这是一种统计规律,不是真正的语义理解——但在实际效果上,已经足够用了。
再打个"口味"的比方。川菜馆和湘菜馆在地图上往往挨着,因为它们的"口味语义"相近——都是辣的、重口的。川菜馆和日料店可能隔得远,因为一个辣一个清淡,口味差异大。Embedding 映射的道理一样:语义相近的文字,距离近;语义相差大的文字,距离远。
面试官可能追问:Embedding 和 one-hot 编码有什么区别?
答:one-hot 编码是给每个词一个唯一编号,比如"苹果"是第 1 号,“香蕉"是第 2 号。它只管"是不是这个词”,不管语义。Embedding 是把每个词映射到一个稠密向量,语义相近的词向量也相近。one-hot 维度等于词表大小,可能几万维;Embedding 维度是固定的,比如 768 维,更紧凑,也更能表达语义关系。
三、相似度怎么算
地图建好了,位置标好了,接下来要解决一个问题:怎么衡量两个文字"有多像"?
这就涉及到相似度计算:
主流方式有两种:余弦相似度和欧氏距离。
先说余弦相似度。咱把它拆开讲——
余弦,就是两个向量夹角的余弦值。你可以想象两个点从原点出发,指向不同的方向。两个方向越接近,夹角越小,余弦值越接近 1;两个方向越相反,夹角越大,余弦值越接近 -1。
余弦相似度关注的是方向,不是长度。一篇长文章和一篇短文章,向量长度可能差很多,但如果它们讲的是同一个主题,方向应该是接近的。
再说欧氏距离。欧氏距离就是你初中学的两点间直线距离,(3, 4) 到 (0, 0) 的距离是 5。推广到高维空间,道理一样。欧氏距离关注的是绝对距离,两个点靠得近,距离就小。
文本检索里,余弦相似度更常用。原因是向量的长度受文本长度影响。一篇 1000 字的文章和一篇 100 字的文章,向量长度可能差很多,但它们的方向更能反映语义。如果你问"怎么退货",两篇文章都讲退货流程,方向应该接近,长度不重要。
当然这不是绝对的,有些场景欧氏距离效果也好。选哪个取决于具体数据和业务场景。
面试官可能追问:余弦相似度和欧氏距离,该用哪个?
答:看场景。余弦相似度关注方向,不受长度影响,适合文本语义相似度匹配。欧氏距离关注绝对距离,适合需要考虑向量大小的场景,比如推荐系统中用户和物品的向量。一个经验法则:先试余弦相似度,如果效果不好再试欧氏距离。
为什么放这段代码?展示余弦相似度计算的核心思路。
// 余弦相似度计算funccosineSimilarity(a,b[]float32)float32{dot:=float32(0)// 点积normA:=float32(0)// a 的模normB:=float32(0)// b 的模fori:=0;i<len(a);i++{dot+=a[i]*b[i]normA+=a[i]*a[i]normB+=b[i]*b[i]}normA=sqrt(normA)normB=sqrt(normB)ifnormA==0||normB==0{return0}returndot/(normA*normB)// 余弦相似度}这段代码在干嘛?计算两个向量的余弦相似度。核心思路是:点积除以两个向量的模的乘积。如果向量方向完全相同,余弦值是 1;方向完全相反,余弦值是 -1;正交的话是 0。实际向量库通常有 SIMD 加速的向量计算,比循环快得多,这里只是示意。为了代码清晰,这里省略了常规的错误处理和相关逻辑,实际生产代码中务必加if err != nil判断。
四、为什么传统数据库做不了语义检索
讲到这儿,你可能会问:为什么非要用向量数据库?MySQL、PostgreSQL 存文本不行吗?
讲真,还真不太行。咱用一个找书的比喻来解释。
传统数据库是精确匹配,就像按标签找书。
你跟图书馆管理员说"我要找一本关于退货的书",他翻了翻系统,找到了标题包含"退货"的书。但你实际上想问的是"退款流程",书名叫"售后处理指南",标签里没有"退货"两个字。管理员说"没有",你只能空手而归。
这就是传统数据库的局限——字面不匹配,就找不到。你搜"怎么退钱",它找不到"退款流程";你搜"笔记本电脑",它找不到"手提电脑"。中文还有同义词、多义词的问题,"电脑"和"计算机"是一回事,但数据库只会字面匹配。
向量检索是语义匹配,它找的是"意思相近"的内容,不要求字面相同。
你问"怎么退钱",系统找到的"退款流程"可能标题里一个相同的字都没有,但意思相近,向量坐标也相近,所以能被检索出来。
这个差异决定了为什么需要专门的向量数据库。传统数据库是给"人找字",向量数据库是给"意思找意思"。
面试官可能追问:为什么传统数据库做不了语义检索?
答:因为传统数据库是基于精确匹配的,查询条件是"包含某个词"或者"等于某个值"。它不理解语义,不知道"退钱"和"退款"是一回事,"笔记本电脑"和"手提电脑"指的是同一个东西。向量数据库把文字映射成坐标,语义相近的文字坐标也相近,通过计算坐标的距离或夹角来找相似内容,这才是真正的语义检索。
五、向量数据库的作用
好,现在咱知道向量是什么了,也知道相似度怎么算了。但还有一个问题没解决:向量太多了怎么办?
假设你有 100 万条文档,每条文档切 10 块,就是 1000 万个向量。用户来查询,系统要在 1000 万个向量里找最相似的 top-k。如果用遍历算法,每个查询都要做 1000 万次相似度计算,延迟高到没法用。
向量数据库就是来解决这个问题的——如何在海量向量里快速找到最相似的几条。
这就像图书馆的索引系统。图书馆的书有几百万册,你不可能一本一本翻目录找。索引系统把书按类别、作者、出版社分好类,你要找某一类的书,直接去那个区域翻,几秒钟就找到。向量数据库的索引也是这个作用——把海量向量按某种结构组织好,查询的时候不用全量遍历,直接在索引里定位最可能的区域。
常见的索引结构有 HNSW、IVF、PQ 等等,这些名字你可能见过。不用记住算法的细节,你只需要知道它们解决的是同一个问题:在大规模向量库里快速检索。HNSW 是图索引,检索快但内存占用大;IVF 是聚类索引,先定位到某个簇再细找;PQ 是量化索引,用近似计算换存储和速度。每种都有取舍,实际选型看你的数据规模和延迟要求。
这里要特别提一句:向量数据库不是替代传统数据库,它是补充。
元数据还在传统数据库里存——文档 ID、标题、更新时间、作者信息。向量在向量数据库里存。两边配合用,检索用向量库,找详情用传统库。
打个比方:向量数据库是图书馆的分类索引系统,告诉你"你要的书在 A-7 区的第 3 排第 5 本"。但索引不告诉你书里写了什么,具体内容你还是得去书架上拿书来看。索引和书架,各司其职。
面试官可能追问:向量数据库和传统数据库是什么关系?
答:补充关系,不是替代关系。向量数据库擅长语义检索,但不适合存结构化的元数据——文档标题、更新时间、作者信息,这些存在传统数据库里更合适。向量数据库存向量、计算相似度,两边通过文档 ID 关联。实际系统通常是向量库 + 传统库组合使用,各取所长。
六、RAG 里向量库怎么配合检索
把之前的内容串一下,你就明白 RAG 里向量库是怎么工作的了。
用户上传一批文档,系统先加载、切成小块。第三篇咱讲过这些。
切好的每一块,经过 Embedding 模型变成一个向量。这就是向量化这一步。
向量和原始文本块一一对应,存进向量数据库。这就是存储这一步。存的时候,向量和文本块是关联的——向量用于检索,文本块用于最终生成。
用户提问:“怎么申请退款”。问题本身也经过 Embedding 模型,变成一个查询向量。
系统拿着这个查询向量,在向量数据库里做相似度检索,找到最相似的 top-k 个文档块。这就是检索这一步。
检索出来的文档块,连同用户的问题,一起拼进 Prompt,交给大模型生成回答。这就是生成这一步。
所以 RAG 的向量化、存储、检索三步,就是这么串起来的。切分好的块 → Embedding 成向量 → 存进向量库 → 用户提问 → 查向量库 → 拿文档块 → 生成回答。六步环环相扣,向量库是中间的关键枢纽。
七、落地常见坑,先提一嘴
趁这块地盘,先给你们打几剂预防针,后面第六篇会专门展开。
最常见的坑是向量模型选错。Embedding 模型有很多种,效果差很多。通用模型在你垂直领域可能表现一般,专业领域的模型效果可能更好。选错了模型,后面调参都是在坑里打转。
还有个坑是维度太高成本爆炸。维度越高越精细,但存储成本、计算成本也越高。你 3072 维的向量和 768 维的向量,存储空间差 4 倍,检索速度也慢很多。不是越高越好,够用就行。
第三个坑是不归一化导致相似度算错。有些向量在入库前没有做归一化处理,导致长度差异大,相似度计算结果不准。这个坑很隐蔽,容易被忽略。
最后一个坑是只靠向量不考虑关键词。向量检索是语义匹配,但不是万能的。有些场景关键词匹配更重要,比如查订单号、查人名,你不能指望语义检索能准确找到。向量检索和关键词检索,往往要组合着用。
💡 本章面试要点
向量是什么?Embedding 在干什么?
向量是高维空间里的坐标,每个维度代表某种抽象语义特征。Embedding 是把文字映射成向量的过程,语义相近的文字在向量空间里距离近。Embedding 模型不是真的"理解"文字,它是在做一种可学习的映射,让语义相近的文本映射到相近的坐标——这是统计规律,不是真正的语义理解,但在实际效果上已经够用。余弦相似度和欧氏距离有什么区别?该用哪个?
余弦相似度关注方向,不受长度影响,适合文本语义匹配;欧氏距离关注绝对距离,适合需要考虑向量大小的场景。文本检索里余弦相似度更常用,因为向量的长度受文本长度影响,方向更能反映语义。一个经验法则:先试余弦相似度,效果不好再试欧氏距离。为什么传统数据库做不了语义检索?
传统数据库是基于精确匹配的,查询"退钱"找不到"退款",因为字面不匹配。它不理解语义,不知道同义词、多义词的关系。向量数据库把文字映射成坐标,语义相近的文字坐标也相近,通过计算坐标的距离或夹角来找相似内容,这是真正的语义检索。向量数据库的作用是什么?和传统数据库什么关系?
向量数据库解决的是海量向量快速检索的问题——用索引结构(如 HNSW、IVF)组织向量,查询时不用全量遍历。向量数据库不是替代传统数据库,是补充——元数据存在传统库,向量存在向量库,通过文档 ID 关联。索引告诉你书在哪个区域,具体内容还是得去书架上拿。向量检索和关键词检索的区别是什么?
关键词检索是精确匹配,字面不符就找不到,比如搜"退钱"找不到"退款";向量检索是语义匹配,搜"怎么退钱"能找到"退款流程",即使一个字都不重合。两者各有适用场景:查订单号、查人名用关键词,搜知识、找相关内容用向量。实际系统往往是两种组合用,取长补短。
下篇预告
第五篇《检索、重排与引用溯源:怎么找到真正有用的资料》,咱会深入讲 RAG 的第五步——检索。重点聊向量检索怎么调优、Multi-Vector 和 Hybrid Search 是什么、重排模型怎么把检索结果再排一遍、怎么让模型回答时引用原文而不是胡编。
如果这篇文章帮你搞懂了向量和向量数据库,欢迎点赞、收藏、关注利威尔xu,咱们下篇见。
你们项目里向量模型用的什么?向量数据库选型踩过什么坑?评论区聊聊。