04
向量数据库与 RAG
Qdrant & RAG · 让大模型开卷考试
RAG(检索增强生成)就是让大模型开卷考试——你先从知识库里搜出相关文档,塞进 prompt,再让模型基于这些资料回答。大模型不知道你的私有数据,但 RAG 把数据喂给它。这一章讲向量数据库和 RAG 流水线。
向量数据库:qdrant
qdrant 是 Rust 写的高性能向量数据库。你把文档切成块,每块用 Embedding 模型变成一个向量(比如 512 维),存进 qdrant。查询时把问题也变成向量,算余弦相似度,取出最相近的几块——这就是语义检索。
[dependencies]
qdrant-client = "1"
use qdrant_client::{Qdrant, qdrant::{PointStruct, VectorParams, Distance}};
let client = Qdrant::from_url("http://localhost:6334")?;
// 创建 collection(512 维向量,余弦相似度)
client.create_collection("docs", &VectorParams {
size: 512, distance: Distance::Cosine.into(),
}).await?;
// 插入向量
client.upsert_points("docs", None, vec![
PointStruct::new(1, vec![0.1; 512], vec![])
], None).await?;
// 搜索:用查询向量找最相近的 5 条
let hits = client.search_points("docs", vec![0.1; 512], 5).await?;
for h in hits {
println!("id={} score={:.3}", h.id.unwrap(), h.score);
}
RAG 七步流水线
1. 文档加载 → 读 PDF / Word / Markdown
2. 文档切分 → chunking:切成 200-500 字的块
3. 向量化 → Embedding 模型把每块变成 512 维向量
4. 存入向量库 → qdrant.upsert_points
5. 查询向量化 → 问题也变成向量
6. 检索 → qdrant.search_points,取 top-K 相关块
7. 拼接 prompt → "基于以下资料回答问题:{检索到的块}\n问题:{用户问题}"
→ 送进 LLM 生成答案
论RAG 优化三板斧
一、chunk 大小调优。太大检索不精准,太小上下文不全。中文一般 200-500 字一块,重叠 50-100 字防止切断句子。
二、混合检索。光靠向量相似度不够,加一个 BM25 关键词检索,两路结果融合(RRF),召回率提升明显。
三、重排序(rerank)。向量检索先粗排 top-20,再用 CrossEncoder 精排 top-5。精度提升,但多一次模型推理。
其他向量数据库对比
| 数据库 | 语言 | 人话点评 |
|---|---|---|
| Qdrant | Rust | 单二进制、性能好、Rust 客户端一等公民。本门户首选。 |
| Milvus | Go/C++ | 分布式架构、功能全,但重。适合超大规模。 |
| Weaviate | Go | 模块化、GraphQL API,生态全。 |
| Pinecone | 闭源 SaaS | 全托管,不用运维,但数据在别人云上。 |
| LanceDB | Rust | 嵌入式向量库,文件型,适合本地 Agent。 |
chunk 切分策略
切分质量直接决定 RAG 效果。几种常用策略:
- 固定长度 + 重叠:简单粗暴,200 字一块,重叠 50 字。适合纯文本。
- 按语义切分:按段落/小标题/句子边界切,比固定长度效果好。
- 父子分块:小块检索、大块喂 LLM——检索精度高,上下文又够。
- 结构化文档:Markdown 按标题层级切,PDF 按章节切。
记
本章小结
① qdrant 是 Rust 写的向量库,存文档向量、算相似度、过滤 payload。
② RAG 七步:加载 → 切分 → 向量化 → 入库 → 查询向量化 → 检索 → 拼 prompt 生成。
③ 优化:chunk 大小、混合检索、rerank 重排序。