一、通用步骤
1、切片
2、生成 embedding
把每个 chunk 送入 embedding 模型,得到向量。
- query 的向量和文档向量必须来自同一个模型
- 维度必须一致
"用户输入账号密码后进行验证码校验"
-> [0.12, -0.33, 0.91, ...]
3、保存 chunk + 元数据
每个 chunk 不只是存一个向量,通常还要保存:
- doc_id
- chunk_id
- content
- section_title
- file_name
- path
- tags
- permission
- 其他业务字段
4、建立向量索引
向量索引是一种专门为“相似度检索”设计的数据结构。它的作用不是存向量本身,而是:
- 帮你更快找到“和 query 最像的向量”
- 避免每次都把全库向量挨个比一遍
常见的向量索引有:
- HNSW
- IVF
- Flat(严格说是无索引或暴力搜索)
- Annoy
- PQ / OPQ 等压缩索引
其中最常见的是 HNSW,因为它适合做近似最近邻搜索,速度快,召回效果也不错。
5、持久化
最后把这些数据和索引结构落盘。
6、用户查询
(1)把问题也向量化
用同一个 embedding 模型把 query 编成向量。
(2)到向量索引里检索
拿 query vector 去找最近的 TopK chunk。
这里通常有两种模式:
- 近似检索:用 HNSW 等 ANN 结构,速度快,适合生产
- 精确检索:扫描所有候选,算精确距离,适合小数据或精确评分
(3)【可选】过滤
可以先按元数据过滤,例如:
- 只查某个知识库
- 只查某个租户
- 只查某个权限范围
- 只查某个时间范围
(4)【可选】重排序
向量召回通常是“先找近”,但不一定“最适合回答”。
所以生产里经常会再接一层 rerank。
(5)返回 chunk 内容给大模型
最后把最相关的 chunk 原文回填给 LLM。
二、主流向量数据库
| 名称 | 类型 | 特点 | 许可证/免费情况 |
|---|---|---|---|
| FAISS | 向量索引库 | 经典、快、功能全,适合做 ANN | MIT,免费开源 |
| hnswlib | 向量索引库 | 轻量,主打 HNSW | Apache-2.0,免费开源 |
| Annoy | 向量索引库 | 轻量、支持 mmap,适合只读索引 | Apache-2.0,免费开源 |
| ScaNN | 向量索引库 | Google 的高性能 ANN 库 | Google Research 开源仓库,Apache-2.0 |
| pgvector | Postgres 扩展 | 直接把向量存在 PostgreSQL 里 | PostgreSQL license,免费开源 |
| Milvus | 向量数据库 | 生产级、可扩展 | Apache-2.0,免费开源 |
| Qdrant | 向量数据库 | 轻量、好用、工程体验好 | Apache-2.0,免费开源 |
| Weaviate | 向量数据库 | 支持混合检索、结构化过滤 | BSD-3-Clause,免费开源 |
| OpenSearch k-NN | 搜索引擎 / 向量检索 | 同时适合关键词+向量混合检索 | Apache-2.0,免费开源 |
1. Qdrant
Qdrant 明确支持 payload,而且 payload 可以是 JSON 结构。
这意味着你可以把:
- 原文文本
- 标题
- 来源
- 标签
- 任何结构化信息
一起存进去。
Qdrant 还区分:
- InMemory payload storage
- OnDisk payload storage
官方也提到,payload 很大时,放 on-disk 更合适。
2. Weaviate
Weaviate 的 property 支持多种数据类型,包括:
- text
- blob
- int
- number
- boolean
- object
所以它也可以把原文或文本字段直接存为对象属性。
如果是文本类原文,通常用 text;如果是 Base64 编码数据,也可以用 blob。
3. Milvus
Milvus 支持 scalar fields,比如:
- VarChar
- Boolean
- Int
- Float
- Double
它官方文档里也明确说了,scalar fields 可以存 metadata。
对于文本字段,可以用 VARCHAR。
但要注意:VARCHAR 有长度上限,最大可到 65535 字节,超大的原文一般不建议硬塞进去。
4. Pinecone
Pinecone 支持:
- 向量
- metadata
- 集成 embedding 下的 raw text
官方文档里也写得很清楚,文本字段可以转成向量,而其他字段会作为 metadata 存储。
也就是说,它也支持“向量 + 文本/元数据”的组合。