INTERVIEW · START HERE

把文字,
变成坐标。

向量不是玄学。它只是把文字变成数字,然后用“距离”找相似内容。往下滚,看它怎么变成 RAG。

SCROLL ↓
01 · VECTOR

文字 → 一串数字

Embedding 模型把一句话编码成一串数字。数字本身不重要,重要的是:意思接近,坐标就接近。

国王
[ ]// 这就是"国王"的向量
语义距离:近 · 女王远 · 汽车

向量的结构就是一个数字数组,编程里长这样:[0.85, 0.90, 0.10, ...],方括号括起来、逗号分隔。这些数字不是随机生成的——是 Embedding 模型读完"国王"这个词后算出来的。每个位置叫一个维度,真实模型通常 768 或 1024 维(这里简化为 8 维演示)。

02 · EMBED

文字怎么变向量

不是魔法,是一个叫 Embedding 的模型。把文字喂进去,它吐出一串固定长度的数字。

输入

一段文字

猫是可爱的动物
→
Embedding 模型
例:bge-m3 / text-embedding-3bge-small-zh-v1.5
1024 维
不管输入多长,输出维度固定
→
输出

一串数字

关键事实:文档和问题必须用同一个模型,否则坐标体系不同,没法比距离。换模型 = 全量重灌库。L2 归一化后,cosine 等于内积,检索可以用更快的内积算子。

04 · STORAGE

向量存哪里

三个东西是独立的:pgvector 是 PostgreSQL 插件,Chroma 是独立轻量库,Milvus 是独立分布式库。

pgvector

pgvector = PostgreSQL + 向量插件

CREATE EXTENSION vector; CREATE TABLE chunks ( id serial PRIMARY KEY, text text, embedding vector(1024) ); -- HNSW 索引 CREATE INDEX ON chunks USING hnsw (embedding vector_ip_ops) WITH (m = 16, ef_construction = 64); -- 检索:内积 + 过滤 SELECT text, embedding <#> '[...]' AS score FROM chunks WHERE source = 'wiki' ORDER BY embedding <#> '[...]' LIMIT 5;

向量就是表里一列。事务、join、备份全是现成的。百万级以内 + 需要混合过滤,运维成本最低。

Milvus(独立)

专用分布式向量库

HNSW 索引:多层图,上稀下密。从顶层入口快速跳到底层近邻。

独立分布式服务,etcd 管元数据、MinIO 存数据。上亿级、高 QPS 场景。一致性可设 Strong / Bounded,代价是延迟。

对比
Chroma
独立轻量库
pgvector
PostgreSQL 扩展
Milvus
独立分布式
定位
轻量原型
SQL 即向量库
分布式专用
数据量
万级
< 百万级
> 亿级
运维
几乎为零
已有 PG 就零新增
多一套分布式
适用
demo / POC
生产首选
超大规模

为什么是 PostgreSQL,不是 MySQL?

同样是关系型数据库,为什么向量检索生态先在 PG 上成熟?答案在扩展架构。

PostgreSQL 的扩展接口允许第三方注册新数据类型、新操作符、甚至新索引方法。pgvector 就是通过这个接口把 vector 类型和 HNSW 索引插进 PG,不用改 PG 源码。

PostgreSQL ✅

插件可注册新索引方法
HNSW/IVFFlat 通过插件接入
已有 PG → 一条 CREATE EXTENSION 搞定

MySQL / Oracle ❌

插件层不能注册新索引方法
MySQL 9.0 加了 VECTOR 类型但还没有向量索引
Oracle 没有向量索引插件
要改源码才行,社区没跟上

选型结论:已有 PostgreSQL → 加 pgvector 插件;只有 MySQL → 上 Chroma 或 Milvus 做独立向量服务。

05 · RAG

先找资料,再回答

RAG 就是:把最相关的资料塞进提示词,让模型“照着资料答”。点击步骤,也可以等它自动播放。

宠物与交通.docx
块①
猫是可爱的动物,常被当作宠物。
块②
狗是人类的朋友,也是常见宠物。
块③
汽车需要加油,跑得很快。
块④
火车在铁轨上跑,能拉很多人。
猫块 狗块 汽车块 火车块 问题
模型收到的提示

问题:哪些是宠物?

资料:猫是宠物;狗是常见宠物。

回答:猫和狗都是常见的宠物。
一份大文档,模型一次读不完,也太贵。
06 · SUMMARY & TUNING

一句话总结 + 调优

RAG 的本质就一句:把跟问题最相关的几块资料,塞进提示词,让模型照着答。效果不好,先查切块和检索,别先怪模型。

选型三问

Q1 模型能调参吗? 不能。模型是别人训好的,你只能选型:拿真实语料各跑一遍,比 recall@5,选分数高的。
Q2 换模型会怎样? 全库重灌——不同模型向量空间不同,距离没法比,所以文档和查询必须用同一个模型。
Q3 工程上怎么调优? 下面三个手段 ↓

① 查询前缀

查询时加指令

bge 系列要求查询侧加一段前缀指令,文档侧不加。不加前缀 → 多好几个点召回。只有部分模型需要(bge 系列要,OpenAI 不需要),用之前看文档。

文档侧: "猫是宠物" 查询侧: "为这个句子生成表示 用于检索相关文章: 猫是宠物吗"
② 归一化

让两个向量同量级

向量是一串数字,长度可能不一样大。归一化 = 把每个向量缩成统一长度(长度 = 1)。归一化后,cosine 距离 = 内积,可以用更快的内积算子 <#> 替代 <=>,检索更快。多数现代模型已经内置归一化。

// 归一化前: 长度不等 [0.85, 0.90, 0.10, ...] [0.12, 0.28, 0.85, ...] // 归一化后: 长度都是 1 可直接用 <#> 内积算子
③ 调 top-k

检索取几个结果

k = 检索时取距离最近的几个文档块。k 太小(如 3)→ 可能漏掉正确答案。k 太大(如 50)→ 带回大量噪音,模型被干扰。从 5 开始调,看 recall(召回率)和 precision(精确率)的拐点。

k=3 → 召回高,但可能漏 k=5 → 平衡点(推荐起点) k=10 → 可能带噪音 k=50 → 太多噪音干扰模型