每个 RAG 系统、语义搜索框、许多推荐引擎,背后都有同一套基础设施:Embedding 存在 向量数据库 里。这篇把两者讲透——够入门,也够你开始做架构选型。
核心直觉(一段话)
Embedding 把文本(或图片、音频)变成一串数字——向量。意思相近的内容,向量在高维空间里距离更近。向量数据库存百万级向量,并在毫秒内找出与查询向量最近邻。这就是语义搜索:按意思匹配,而不是按关键词。
"年假政策" → [0.12, -0.34, 0.56, …] (1536 维)
"PTO 规定" → [0.11, -0.33, 0.55, …] ← 很近
"停车位申请" → [-0.42, 0.18, 0.09, …] ← 很远
Embedding 怎么来的
Embedding 模型(OpenAI text-embedding-3-small、Cohere、开源 bge-large 等)在训练时被优化成:相关文本的向量靠近、不相关的远离。
训练直觉:
"狗" 和 "小狗" → 拉近
"狗" 和 "飞机" → 推远
推理时:
任意文本 → 固定长度向量(常见 384–3072 维)
关键属性:
| 属性 | 为什么重要 |
|---|---|
| 固定维度 | 决定表结构和索引类型 |
| 索引与查询用同一模型 | 混用模型会破坏相似度 |
| 语言/领域匹配 | 法律、医疗、代码宜选对口模型 |
| 向量归一化 | 许多库默认用余弦相似度 |
距离度量:什么叫「近」
| 度量 | 直觉 | 常见场景 |
|---|---|---|
| 余弦相似度 | 向量夹角 | 文本 Embedding(默认) |
| 欧氏距离 L2 | 直线距离 | 部分图像向量 |
| 点积 | 方向 + 模长 | 归一化后 ≈ 余弦 |
文本 RAG 多数用 余弦 或归一化后的点积。
向量库 vs 普通数据库
PostgreSQL 关键词:
WHERE content LIKE '%年假%'
→ 搜不到只写 "annual leave" 的段落
向量库:
embed("休假几天") → 最近邻
→ 找到 "年假政策" 相关 chunk
向量库额外提供:
- ANN 近似最近邻索引(HNSW、IVF)——用极小精度换极快速度
- Metadata 过滤——
department = HR AND score > 0.8 - 批量 upsert——大规模重建索引
- 混合检索——向量 + 关键词(生产必备)
架构:向量库在哪一层
离线入库 在线查询
┌─────────────────────────┐ ┌─────────────────────────┐
│ 文档 → 分块 → Embedding │ │ 用户问题 │
│ → 写入向量库 │ │ → 问题 Embedding │
└─────────────────────────┘ │ → ANN 检索 + 过滤 │
│ → Top-K → LLM 生成 │
└─────────────────────────┘
RAG、企业搜索、内容推荐都是这个模式。
三款主流向量库对比
Pinecone — 托管、偏规模
类型: 全托管 SaaS
优势: 零运维、高 QPS、内置混合检索
劣势: 规模大时成本、数据在云端(企业版可 VPC)
适合: 想快速上线 RAG/搜索、不想自建基础设施的团队
真实用法:SaaS 创业公司将 50 万篇帮助文档写入 Pinecone,p95 检索 < 50ms,按产品线和语言做 metadata 过滤。
pgvector — Postgres 扩展,一个库搞定
类型: 现有 PostgreSQL 上的扩展
优势: ACID、与业务表 JOIN、运维团队熟悉 Postgres
劣势: 十亿级向量需调优;非专用向量引擎
适合: 千万级以下向量、要强一致、已有 SQL 工作流
真实用法:电商把商品 Embedding 存在 products.embedding vector(1536),推荐查询在同一事务里 JOIN 库存和价格。
CREATE EXTENSION vector;
CREATE TABLE docs (id serial, content text, embedding vector(1536));
CREATE INDEX ON docs USING hnsw (embedding vector_cosine_ops);
SELECT content FROM docs
ORDER BY embedding <=> $query_embedding
LIMIT 5;
Chroma — 开发者友好,嵌入式或服务端
类型: 开源;可嵌入进程或 client/server
优势: 本地开发快、Python 生态、配 LangChain/LlamaIndex 方便
劣势: 生产 HA/扩展需自己运维
适合: 原型、单租户、内网试点
真实用法:内部工具团队把 Chroma 嵌进 FastAPI;Slack 机器人查内部 Runbook;流量上来后迁 Pinecone 或 pgvector。
应用 1:RAG
基础系列第 04 篇讲过流程——向量库是 检索引擎:
类似 Shopify Sidekick:
帮助中心 → 分块 → Embedding → 索引
商家提问 → 检索 Top chunk → LLM 回答 + 引用
生产级增强:
- 混合检索(Shopify 从纯向量改为向量 + BM25)
- Reranker(Cross-encoder 从 Top-20 重排到 Top-3)
- 文档更新 webhook 触发重新 Embedding
应用 2:语义搜索
Notion / Confluence 式「智能搜索」:
用户: "怎么重置 MFA"
关键词搜不到 "双因素认证恢复"
语义搜索能找到正确页面
工程建议:
- 标题、小标题、正文可分开索引并加权
- 展示相似度分数和摘要,方便调试
- 记录零结果查询,补内容或换模型
应用 3:推荐
「相似商品 / 相关文章」:
物品向量 = embed(标题 + 描述 + 标签)
用户向量 = 最近点击物品向量的平均
推荐 = 最近邻,排除已看过
Spotify 音频、新闻推荐等在更大规模上用同一套 向量近邻 思路(常是专用模型,而非通用文本 Embedding)。
选型决策树
要托管、快上线、少运维?
是 → Pinecone(或 Weaviate Cloud、Qdrant Cloud)
否 ↓
已在 Postgres、向量 < 约千万、需要 SQL JOIN?
是 → pgvector
否 ↓
原型 / 本地 / 嵌入式?
是 → Chroma 或 LanceDB
否 ↓
自建大规模?
→ Qdrant、Milvus、Weaviate(评估运维能力)
常见翻车点
| 现象 | 原因 | 解法 |
|---|---|---|
| 结果不相关 | 模型不对 / chunk 太大 | 换领域模型;调 chunk |
| 搜不到 SKU/错误码 | 纯语义对精确词弱 | 混合 BM25 |
| 查询慢 | 没建 ANN、暴力算 | HNSW/IVF;降维 |
| 答案过时 | 索引未更新 | 文档变更 → 自动 re-embed |
| Top-K 重复 | chunk 重叠 | 去重、MMR 多样化 |
成本粗算
Embedding 一次: 100 万 token × $0.02/1M ≈ $0.02
存储: 100 万向量 × 1536 维 × 4 字节 ≈ 6 GB 原始数据
Pinecone: 按 pod/存储计费;pgvector: 算 Postgres 账单
查询: RAG 场景 LLM 往往更贵;检索本身通常每千次几分钱量级
缓存 Embedding——原文不变就不重新算。
最小闭环(概念代码)
# 1. 分块并 Embedding
chunks = split(document, size=512, overlap=64)
vectors = embed_model.encode(chunks)
# 2. 写入(Chroma / pgvector / Pinecone API 类似)
store.upsert(ids=ids, embeddings=vectors, metadatas={"source": doc_id})
# 3. 查询
q_vec = embed_model.encode(user_question)
hits = store.query(q_vec, top_k=5, filter={"source": allowed_docs})
# 4. RAG
prompt = format_context(hits) + user_question
answer = llm.generate(prompt)
小结
| 组件 | 作用 |
|---|---|
| Embedding 模型 | 文本 → 语义向量 |
| 向量数据库 | 存储 + 快速相似度检索 |
| RAG | 为 LLM 检索上下文 |
| 语义搜索 | 按意图找内容 |
| 推荐 | 向量近邻 = 相似物品 |
Pinecone 适合托管快启,pgvector 适合已有 Postgres 的一体化栈,Chroma 适合开发与轻量部署。库选对一半——另一半在 分块、混合检索和 Eval;再好的向量库,检索不到对的段落,RAG 照样幻觉。
模型系列下一篇可回顾文本/视觉/多模态,或跳到案例篇看 Shopify 如何把 RAG 做到 82% 自动解决率。