做知识库或检索时,最容易犯的错是先去看别人的榜单,再回头硬套自己的场景。结果语料是中文客服问答、却挑了英文语料训练的模型,或者向量库索引已经建好才发现维度对不上要全量重建。这篇按「先约束、再比项、后验证」的顺序,把 RAG 选嵌入模型这件事拆成可执行的几步。
做知识库或 RAG,最容易犯的错是先去看别人的榜单,再回头硬套自己的场景。结果语料是中文客服问答,却挑了英文语料训练的模型;或者向量库索引都建好了,才发现维度对不上,只能全量重建。
这篇按「先约束、再比项、后验证」的顺序,把选嵌入模型这件事拆成可执行的几步。所有比较都对着你自己写下的那行需求来,不要对着榜单来。
先把自己的约束条件写下来,别看榜
约束没写清就去看榜单,等于没有筛选条件。先把下面四类硬约束过一遍,写在文档第一行,后面所有挑模型的讨论都对照这一行。
- 语料语种:纯中文、中英混,还是含小语种;这决定了候选池的大半
- 单条文本长度:切片后最长的一条有没有超过模型能吃的上限,超了要么换模型要么改切片
- 向量库与检索框架支持的维度:维度固定了,可选模型范围就跟着缩小
- 数据能否出内网:能接受把语料发到外部接口,和必须内网部署,是两条完全不同的路
再明确算力形态:本地 CPU 跑、单卡跑,还是直接调托管接口?这决定你能选多大体量的模型。算力口径可以到 /compute/sizing 对照。最后压成一行需求,例如「中文为主 + 单条不超长 + 内网部署 + 现有向量库维度固定」。
比三个维度:效果、成本、可换性
效果别只看榜单分数,要看它在你这块语料上的召回表现。榜单口径差异不小,去 /benchmarks/registry 和 /benchmarks 看清楚它测的是什么任务、什么语料,再决定这个分数对你有多少参考价值。
| 比较项 | 要看什么 | 常见坑 |
|---|---|---|
| 效果 | 在你自己的语料上抽样召回 | 拿通用榜单分数直接换算成业务效果 |
| 一次性成本 | 建索引的算力与时间开销 | 只算在线调用,忽略重建索引的代价 |
| 在线成本 | 每次查询的调用开销 | 短文本高并发场景被低估 |
| 可换性 | 维度是否一致、有无多个托管来源 | 换模型就得全量重建,没提前留退路 |
可换性要提前想:维度不同就必须重建索引,所以优先选接口稳定、有多个托管来源的同族模型。模型规格统一到 /embeddings 看当时的数字。
中文与多语言:什么时候必须换模型
纯中文语料优先选中文语料训练占比高的模型。中英混语料则要验证英文侧不明显掉点,两边都得能过,别只顾一头。
小语种或跨语种检索要看是否做过对齐训练,否则很容易出现中文提问、英文文档检索不到的情况。语种覆盖逐条到 /embeddings 页面核对当时的说明。
- 抽小样本对照抽几十条真实问题,标注好答案,两个候选模型各跑一遍看召回命中,比看任何榜单都可靠
- 分语种看结果把样本按中文、英文、混合分类,分别统计命中情况,避免平均分掩盖某一侧掉点
- 记录失败样例把两个模型都漏掉的查询单独存一份,这类往往不是模型问题,而是切片或字段问题
要不要加重排,以及整条链路的顺序
典型顺序是:切片 → 向量化入库 → 粗排召回 → 重排 → 交给生成模型。重排通常放在召回之后、生成之前,作用是给候选重新排序,而不是扩大候选范围。
召回多、重排少的配置,在中等规模知识库上性价比更高:向量模型稍弱,也能靠重排补回来。维度与多语言的取舍可以对照 /embeddings。
- 先看召回是否漏了:提高召回数量,看漏掉的文档能不能被捞回来
- 再看排序是否乱:召回里有正确答案但排在后面,加一层重排
- 最后才怀疑向量模型本身:前两步都排除了,再考虑换模型
- 延迟敏感场景单独测:加一层重排可能把延迟翻倍,用 /tools/speed-test 量基线
上线前的验证与迁移清单
上线前固定一批真实查询做回归集,换模型前后各跑一次,记录命中率与响应时间。质量口径参考 /tools/quality-check,坚持用同一套样本比较。
- 并行建新索引新模型维度或归一化方式可能不同,旧索引不能复用,先并行建一份新的
- 灰度切流把一小部分查询切到新索引,观察命中率与延迟是否稳定
- 观察与对比用回归集对比新旧结果,确认没有明显回退再继续放量
- 下线旧索引确认稳定运行后再清理,别急着删,留一段回退窗口
把模型选择、切片策略、重排开关写进一页说明,后续换人接手不用重新推一遍。不确定术语含义时先查 /ai-dict 与 /stacks/vector-dbs,别凭印象选。
下一步带着你写好的那行需求,去站内模型库按语种和维度筛一遍候选,再用回归集做小样本对照,比看榜单快得多。→常见问题
中文检索是不是一定要用中文专用嵌入模型?
不一定。纯中文语料选中文训练占比高的模型通常更稳;但如果语料中英混杂,或者以后要跨语种检索,通用多语言模型更省事。判断方法很简单:抽真实问题跑一遍召回,中文专用和多语言各试一次,看谁漏得少就选谁。
嵌入模型换一个,为什么整个库都要重建?
因为不同模型输出的向量空间不一样,同一段文本在两个模型下的向量没有可比性,混用会导致检索结果完全错乱。另外维度变了,向量库的索引结构本身也得重建。所以换模型按新建索引处理,不要试图原地替换。
检索效果差,应该先换嵌入模型还是先加重排?
先分清是「没召回到」还是「召回顺序不对」。如果正确答案压根没进召回列表,加重排没用,得先查切片粒度和召回数量;如果答案在列表里但排在后面,加重排见效最快。排查顺序反了会白花一轮迁移成本。