向量化入门指南
有一组数字,来自一家企业的内部知识库上线第一个月:240 条答错的记录,其中 68% 出在检索环节——分块占 31%,召回占 27%。真正因为模型"胡说"的,反而是少数。
这个比例值得多看一眼。它说明一件很多人不愿意承认的事:当 AI 答不好一个问题时,第一反应往往是"模型不够强,换个更大的",但在这组数据里,绝大多数失败发生在模型开始说话之前。资料没被切对,或者根本没被找出来。
而"找出来"这件事之所以可能,靠的是一个听起来很技术的词:向量化。
如果你最近在看 AI 相关的资料,大概反复撞见过这几个词:向量化、embedding、向量模型、向量库、混合检索、重排。它们经常一起出现,又经常被混着用,看完一圈还是不知道它们各自管什么、先后关系是什么。
这篇是一份入门指南,目标是把这件事一次讲透。全文按一条主线推进:向量化是什么 → 为什么要做 → 具体怎么做 → 做完怎么判断好坏。中间会依次交代清楚四个最容易混淆的概念——向量化、向量模型、向量库、混合检索与重排,并说明它们在这条链路上各自的位置。
读完之后,你应该能回答四个问题:向量化到底把什么变成了什么;为什么这件事非做不可;自己动手要经过哪几步;以及怎么判断自己做得对不对。
一、向量化到底是什么:填的是"语义鸿沟",不是存储格式
先给一句最直白的定义:**向量化,就是把一段文字、一张图、一段音频,转换成一串数字(一个向量),并且让"意思相近的内容,数字也相近"。**这串数字就叫 embedding(嵌入向量)。
先把一个常见的误解拆掉:很多人以为向量化是为了"把数据压缩得更好存"。不是。传统数据库存得好好的,问题出在"问"上。
IBM 在讲向量数据库时用了一张山景日落的照片做例子。这张照片放进关系型数据库,能存的东西其实不少:图片的二进制数据、文件格式、创建时间这些元数据,还可以人工打上"日落""风景""橙色"几个标签。看起来该有的都有了。
但接着问题就来了。如果我想找"色调相似的图片",或者"背景里有山的风景照",用这些字段怎么查?where color = 'orange' 这种查询,抓不住"色调相似"这种连续、多维的概念。标签能表达的是离散的、人工枚举过的特征,而人看图时感受到的东西,往往是连续的、说不清的。
这个断层有个正式的名字,叫语义鸿沟(semantic gap)——计算机存储数据的方式,和人类理解数据的方式,中间隔着一道沟。
向量化做的事,就是把语义搬到沟的另一边。它把一段文字、一张图、一段音频,变成一串数字(一个向量)。这串数字的关键性质是:意思相近的东西,数字也相近。于是"找相似"就从一个说不清的问题,变成了一个可以算的问题——算两个向量之间的距离。
微软的官方文档把这件事说得最简洁:嵌入(embedding)是一个表示文本语义的浮点数向量,相似的文本会产生彼此接近的向量。
这里有个很好用的类比,来自 Ele实验室讲向量数据库时举的例子:怎么区分不同品种的狗?先看体型,一个维度;金毛和拉布拉多体型接近,区分不开,那就再加一个维度看毛长;德国牧羊犬和罗威纳还是接近,再加鼻子长短;还不够,就加腿的粗细、毛发的卷曲,甚至"服从性""攻击性"这种抽象特征。
维度越多,区分能力越强。狗是这样,文字也是这样——只不过文字需要的维度可能是几百、几千甚至上万。
这个做法还带来一个意外收获:向量不只是能算距离,还能做一点"推理"。警察的向量减去小偷的向量,得到的那条"关系向量",和猫减去老鼠得到的关系向量很接近。意思是,"猫和老鼠的关系"类似于"警察和小偷的关系"。这种性质在传统字段里是完全表达不出来的。
语义鸿沟:机器存的和人理解的
所以第一节的结论是:向量化解决的不是"存不下",而是"问不出"。它把人类觉得像、机器看不出像的东西,搬进了一个可以用距离衡量的空间。
用一句话收束:**向量化把"意思"变成了一段可以计算的距离。**后面的模型、向量库、检索、重排,全都是围绕这段距离展开的。
但紧接着的问题就是:这串数字,到底是怎么造出来的?
二、为什么要向量化:因为不这么做,AI 就找不到你的资料
在讲怎么做之前,先把"为什么"说透。因为很多人是被动接受"要做向量化"的,并不清楚它到底解决了什么刚需。
需求来自三个现实约束。
第一,数据大多是非结构化的。 AssemblyAI 在讲向量数据库时提到一个数字:超过 80% 的数据是非结构化的——社交媒体帖子、图片、视频、音频。这些东西没法直接塞进关系型数据库的表格里。
第二,大模型的上下文是有限的。 你不能把几万份文档全塞进 prompt。Computerphile 讲得很直白:把一整篇维基百科塞进去还行,但公司有几千上万份文档时,你根本不知道哪一份该塞。
第三,大模型没有"长期记忆"。 它的知识停在训练完成那一刻,也不知道你公司内部发生了什么。Fireship 在 2023 年那期爆款视频里把向量库的价值概括成一句话:给大模型加长期记忆。
把这三条合起来,需求就很清楚了:**你需要一种办法,从海量非结构化资料里,快速找到"和这个问题最相关的几段",再交给模型去回答。**向量化就是让"找相关"这件事变得可计算的前提。
所以向量化的价值不在存储,而在检索——它是"让 AI 用上你自己的资料"这条路上的第一块地基。
三、具体怎么做:六步流程,翻车点不在模型
这是全文最需要说清楚的一节,因为它最容易被简化成"调个接口"。
在拆步骤之前,先把四个容易混的概念摆到它们各自的位置上:
- 向量化:动作,把内容变成向量的这个过程;
- 向量模型:工具,负责执行这个动作的那个模型(也叫 embedding 模型);
- 向量库:仓库,存向量并提供快速检索的数据库;
- 混合检索与重排:用法,把多路结果合起来并重新排序的策略。
一句话串起来:**用向量模型做向量化,把结果存进向量库,查询时用混合检索加一道重排。**下面这六步,就是这套组合的完整落地流程。
真实的向量化是一条六步流水线。每一步都有官方给的硬参数,也都有各自的坑。
向量化六步流程
第一步,清洗与切块。 长文档不能整篇塞进去,得切成块。这里有个很多人不知道的事实:Pinecone 官方文档明确写着,它不替你切块——你必须在写入之前自己切好,每一块作为一个独立的 document。也就是说,切块这一步的责任在应用侧,不在向量库。
Computerphile 演示过一个完整例子:一份 170 页的 NIST 密钥管理文档,用文本切分器切成约 800 词(或 800 token)一块,块与块之间留一点重叠,最后拆出 800 到 1000 块,再逐块嵌入。留重叠的原因是:你不想让一个关键事实正好被切在中间,一半在前一块、一半在后一块。
官方默认值可以直接参考:LangChain 的文本切分器默认 chunk_size=4000、chunk_overlap=200;LlamaIndex 默认 1024 tokens、重叠 20;代码切分默认 40 行、重叠 15 行。Anthropic 的口径是"通常不超过几百个 token"。而 Azure OpenAI 的单条输入上限 8192 tokens,是块大小的物理天花板。
这一步正是开篇那组数据里占比最高的失败原因(31%)。硬切会把语义切断——比如"合同到期"这段内容被切碎后,检索时反而召回了"离职流程",因为两者都出现了"到期""流程"这类词。
第二步,选模型、定维度与度量。 建索引时必须声明向量维度和距离度量。Pinecone 的官方示例是 dimension=1536, metric="cosine"。Qdrant 支持 Cosine、Dot、Euclid、Manhattan 几种度量,其中 Cosine 是在归一化向量上做点积,上传时会自动归一化。
第三步,批量嵌入。 调用 API 把块转成向量。Azure OpenAI 的官方限制是:单条不超过 8192 tokens,单次请求不超过 2048 条、合计不超过 30 万 tokens,超了直接返回 400。所以批量处理必须自己拆批、加限流重试。
第四步,存储。 存的不只是向量,还有原文和元数据。只存向量不存原文,检索到了却拼不出上下文,等于白找。元数据用于过滤,比如按部门、按时间筛。
第五步,建索引。 Weaviate 官方列了三类:HNSW 构建较慢但查询是对数复杂度,适合大数据集;Flat 轻量,适合小数据集;Dynamic 先按 Flat 跑,规模超过阈值自动切 HNSW。
第六步,查询。 用户的问题也要用同一个模型转成向量,再去检索。这一步有个铁律:换模型等于换了一个向量空间,旧向量全部作废。Pinecone 的 schema 在建索引时声明、建后不可更改,换维度就只能新建索引并全量重灌。
除了这六步,还有两个工程数字值得记住。存储成本:每个稠密向量维度占 4 字节(float32),所以 100 万条 1536 维的向量大约占 5.72 GiB,这还不含 ID、元数据和索引开销。如果嫌大,可以用量化压缩:标量量化 4 倍、二值量化 32 倍、乘积量化最高 64 倍。增量更新则可以按内容指纹比对,内容没变就跳过,变了用相同 ID 覆盖。
把六步串起来,最小可复现的版本其实只有四行逻辑:批量嵌入文档 → 用同一模型嵌入查询 → 逐条算余弦相似度 → 取 top-k。生产环境只是把"存 + 逐个算"换成"向量库 + ANN 检索",前两步不变。
所以这一节的核心判断是:向量化不是"调个模型接口",而是一条六步流水线——真正让人翻车的是切块和一致性,不是模型选得够不够大。
六步里第二步是选模型,那模型到底怎么选?
四、向量模型:决定坐标系的是它,选型看任务不看参数
如果把向量空间想成一个坐标系,那么向量模型就是定义这个坐标系的人。换一个模型,等于换一套坐标——同一个意思,位置完全不同。
两种 embedding 别混为一谈
Weaviate 官方给了一份很实用的选型清单,五个维度:
第一,它是不是在特定领域数据上微调过(法律、医疗、电商),还是通用模型。第二,它擅长什么任务——分类、检索、重排、摘要,不同任务的最优模型不一样。第三,开源还是闭源:闭源要考虑限流和批处理,开源要考虑自己托管和维护。第四,模型大小:小模型快,但可能编码不了那么多细节;大模型准,但对延迟敏感的场景可能撑不住。第五,看榜单,比如 Hugging Face 的 MTEB 排行榜。
这里有个反直觉的点:维度不等于能力。OpenAI 的 text-embedding-3-large 是 3072 维,但它可以截断到 256 维,效果仍然优于上一代 1536 维的 ada-002。维度可以砍,说明"维度高"本身不是目的,只是手段。
还有一个全网最高频的混淆,必须澄清:大模型内部的 token embedding,和 RAG 里用的 embedding,不是一回事。
前者是把每个 token 变成向量,它是模型的一部分,随着训练不断更新;后者是把一整段话压缩成一个概括大意的向量,需要单独训练。训练方式也不同:前者是"文字接龙",预测下一个 token;后者是对比学习——给一对意思相关的句子(正样本)和一对无关的句子(负样本),让正样本的向量靠近、负样本的向量远离。
规模上也有量级差异:GPT-2 XL 的 token embedding 是 1600 维,DeepSeek R1 达到 7168 维。
那榜单分数能直接当业务效果吗?不能。MTEB 覆盖 8 类任务、58 个数据集,论文自己给出的结论是:没有任何一种文本嵌入方法在所有任务上都占优。而且检索任务的英文子集均分区间大约在 8 到 48 之间,跨度极大——说明检索本身就是最难的任务维度。论文还自列了四项局限:长文档数据集不足、任务不平衡、多语言覆盖不足、缺乏其他模态。
所以选模型的正确姿势是:先明确你的任务类型,再看榜单里对应任务的细分分数,最后一定要在自己的数据上跑一遍。
模型定了,向量有了,接下来的问题是:几百万个向量,怎么在毫秒级找出最像的那几个?
五、向量库:核心不是"能存",而是"敢少算"
最直接的办法是暴力搜索:拿查询向量和库里每一个向量都比一遍,挑出最相似的几个。这个方法的搜索质量是完美的——因为它真的比了每一个。
但它的代价是线性增长。几百万条、每条上千维,逐条比对根本来不及。
Ele实验室用了一个很妙的比喻:假设你知道照片上的这个人在 A 城,怎么找他?暴力搜索就是找遍 A 城的每一个人。但你注意到他胸前戴着红领巾——他是个小学生,那就只需要找 A 城的所有小学。搜索范围从千万级降到几十万级。
索引的本质:敢跳过
向量检索也是这个思路:先划一个大致的范围,再在范围里细找。
具体怎么划?最经典的是 K-Means 聚类。先定好要分几类,随机撒几个中心点,让每个向量归到最近的中心;然后用同一类的向量算出平均位置,把中心点挪过去;再重新归类。反复迭代,中心点会收敛,向量就被分成了若干簇。查询时,先找离查询向量最近的簇中心,只在这个簇里搜。
另一种流行做法是基于哈希。随机生成若干条直线(高维情况下是超平面),每个向量在直线正面记 1、反面记 0,几条直线下来就得到一串二进制编码。关键性质是:位置越近的向量,编码越可能相同——于是编码相同的向量被分到同一个"桶"里,查询时只算一下查询向量的编码、找到对应的桶即可。这叫随机超平面(随机投影)哈希。
但这里有个绕不过去的取舍:除了暴力搜索,任何减少计算量的方法都会损失一点准确率。所以这类算法统称"近似最近邻"(ANN)。
这个取舍在工程上是可调的。以 HNSW 为例,它构建较慢,但查询是对数复杂度;Azure AI Search 里有两个旋钮——efSearch 控制候选队列长度、k 控制返回近邻数,调大召回更高、延迟也更高。
而"省下的计算有代价"这件事,在真实事故里看得最清楚。2023 年 3 月 1 日,Pinecone 官方通报过一次事故:一个 SQL bug 误删了 515 个索引,其中 19 个永久丢失了两小时的数据。基础设施的可靠性不是抽象概念,它会在某个下午变成具体的损失。
成本也是同一道理。100 万条 768 维的向量,用托管服务大约 70 美元一个月,自建 Milvus 可以压到 15 美元以下。省下的钱,换来的是运维责任。
所以这一节要记住的是:向量库真正的技术含量不在"能存",而在"敢跳过"。所有索引结构,本质上都是拿一点点准确率,换数量级的速度。
那被跳过的那些,靠什么补回来?
六、混合检索与重排:召回负责别漏,重排负责别乱
答案不是"换一个更大的模型",而是承认一件事:单靠向量检索,在工程上一定会漏。
召回别漏,重排别乱
Anthropic 官方做过一组实测,数字很能说明问题。他们用"检索失败率"(也就是 1 减去 top-20 召回率)来衡量:基线情况下失败率是 5.7%,也就是 top-20 召回率约 94.3%。给每个块加上下文说明后,失败率降到 3.7%;再叠加基于 BM25 的关键词检索,降到 2.9%,也就是召回率约 97.1%。在这之上再加一道重排,失败率又降了 67%。
他们还试了往上下文里塞 5 块、10 块、20 块,结果是 20 块表现最好——但这也得按自己的场景实测。
为什么关键词检索和向量检索要一起用?Elastic 官方的解释很到位:词法检索"过于字面",语义检索"过于模糊",两者的失败方式不一样。一个漏掉同义表达,一个漏掉精确匹配。失败方式不同,才有融合的价值。
但融合有个技术障碍:分数没法直接相加。BM25 的分数可能是 18.5,余弦相似度却在 -1 到 1 之间,量纲完全不同。所以主流做法是用 RRF(倒数排名融合):不看分数,只看名次,公式是 score = Σ 1/(k + rank),k 通常取 60。这样两路结果就能公平合并。
合并之后还需要一道重排。原因是:为了不漏,你得故意多召回一些——比如召回 10 条,但大模型的上下文窗口有限,全塞进去反而稀释注意力。所以让重排模型(通常是 Cross-Encoder)把查询和每个候选逐对打分,重新排序,只把最相关的 5 条送进模型。
vectorize 的演示里有个很直观的例子:搜一首关于咖啡的歌,过度召回拿回来 4 首,正确答案排在最底下。小模型看到这 4 条,很可能被上面几条带偏;加了重排之后,最相关的那条被顶到第一位,模型就不会跑偏。
所以这一节的分工很清楚:召回负责"别漏",重排负责"别乱"。前者要宽,后者要准。
到这里,做法都讲完了。但还有一个问题没解决:你怎么知道自己做得好不好?
七、评判标准:怎么判断向量化做得好不好
这是最容易被跳过的一节,也是最不该跳过的一节。因为没有指标,你连自己错在分块、模型还是排序上都分不清。
指标分三层,从下往上。
三层指标,从下往上
第一层,检索质量。 这一层回答"找得准不准"。
Recall@k(召回率):前 k 个结果里命中的相关文档数,除以全部相关文档数。它回答"该找的有没有漏"。Precision@k(精确率):前 k 个里相关数除以 k,回答"塞进去的是不是都相关"。MRR:每个查询第一个相关结果的排名倒数的平均值,回答"第一个对的排多前"。nDCG@k:DCG@k = Σ(2^rel_i − 1)/log2(i+1),再除以理想值归一化,它支持分级相关性(0/1/2/3 级),是 BEIR 和 MTEB 的主指标。MAP:各查询平均精度的均值。
为什么主指标是 nDCG 而不是 MRR 或 MAP?BEIR 论文说得很明确:MRR 和 MAP 这类二值、rank-aware 的指标,无法评估分级相关性。而现实里的"相关性"往往是有程度的。
第二层,端到端质量。 这一层回答"最终答得好不好"。RAGAS 框架给了四个官方指标:
忠实度(Faithfulness)= 被检索上下文支持的 claim 数 ÷ 回答中 claim 总数。它衡量回答是否忠于资料。答案相关性(Answer Relevancy)= 由回答反推出 N 个问题(默认 N=3),与用户原问题算余弦相似度的均值,衡量回答是否切题。上下文精确率(Context Precision)衡量相关块是否排在前面。上下文召回率(Context Recall)衡量是否漏掉重要信息,它必须有标准答案(reference)才能算。
顺带澄清一个常见说法:RAGAS 里并没有叫"幻觉率"的指标,它的等价物就是 1 减去忠实度,也就是"无法被上下文支持的 claim 占比"。
第三层,模型自身质量。 这一层就是前面说的 MTEB:8 类任务、58 个数据集,论文结论是没有任何方法全任务占优,且自列四项局限。所以榜单分只能作为初筛,不能当业务效果。
除了这三层,还有工程指标:P50/P99 延迟、索引构建时间、单位查询成本(Pinecone 按 read units、write units、storage、egress 四项计量)。
而这一节最关键的判断是:不存在"Recall@10 达到多少就算合格"的通用门槛。
这不是敷衍。BEIR 的实测数据显示,nDCG@10 从 0.228(MS MARCO)到 0.931(FEVER)都可能是好成绩,强依赖数据集本身。唯一能直接引用的官方锚点,是 Anthropic 的 top-20 口径:未优化时召回率约 94.3%,优化后约 97.1%。
所以正确做法是自建一套小规模评测集(golden set)。RAGAS 官方支持基于知识图谱自动生成测试集,区分单跳/多跳、具体/抽象四类查询,保证覆盖面;Anthropic 的做法是跨代码库、小说、ArXiv 论文、科学论文四个知识域各建问答对,统一用 1 减召回率来衡量。业界常见做法是 50 到 200 条人工标注起步——这一条是社区经验,没有官方规定。
结尾:一份入门指南的收束
回到开篇那组数字。240 条 badcase,68% 出在检索链路。如果那家企业当初先去量一下 Recall@k,大概率第一天就能发现分块出了问题,而不是等用户投诉了才回头查。
写到这里,开头那四个问题应该都有答案了:
- 向量化把什么变成了什么? 把文字、图片、音频变成向量,让"意思相近"变成"距离相近"。
- 为什么非做不可? 因为 80% 以上的数据是非结构化的,而大模型上下文有限、又没有长期记忆。
- 自己动手要几步? 六步:切块、定维度度量、批量嵌入、存储、建索引、查询。
- 怎么判断对不对? 三层指标加一套自建评测集,而不是凭感觉。
如果只能记一句话,那就是:向量化把"意思"变成了可计算的距离,但距离只是起点。 一条好的检索链路是"粗召回—精排序—可量化验收"的分层设计,任何一环偷懒,都会在用户那里变成一句"AI 又胡说"。
关于它和 RAG 的关系,可以这样收口:向量化是 RAG 的地基,不是全部。RAG 大致等于"切块与向量化(地基)+ 检索与重排(骨架)+ 生成(屋顶)"。地基歪了,屋顶再漂亮也会塌。
但也别把向量化窄化成"RAG 的配套"。它的应用场景比很多人想的宽:
- 语义搜索:不靠关键词,按意思找文档、找代码、找客服历史;
- 以图搜图与视频推荐:对图片和视频做向量化,找相似的画面;
- 商品推荐:把用户浏览过的商品变成向量,找最近邻;
- 去重与聚类:把相似的文档、工单、评论自动归堆;
- 异常检测:离所有簇都很远的点,往往就是异常;
- Agent 长期记忆:把历史对话向量化,下次自动找回相关的记忆。
这些场景看起来各不相同,本质却是同一件事:把东西变成向量,然后找相似的。
最后留一份自查清单,四个问题:
你的分块,有没有把一句话切成两半?你的查询和文档,是不是用的同一个模型?你的检索,是不是只有向量一路、没有关键词和重排?你有没有一套自己的评测集,能算出 Recall@k?
四个问题都能答上来,这条流水线才算真正跑通了。