从关键词搜索到语义搜索,理解AI应用的数据基础设施
检索技术四代演进: ┌─────────────────────────────────────────────────────┐ │ 第一代: 精确匹配 (1990s) │ │ │ │ 原理: 字符串完全匹配 │ │ 搜索"年假政策" → 只能找到包含"年假政策"的文档 │ │ 问题: "带薪休假"就搜不到"年假" │ │ 代表: grep, SQL LIKE │ ├─────────────────────────────────────────────────────┤ │ 第二代: 全文索引 (2000s) │ │ │ │ 原理: 分词 + 倒排索引 + TF-IDF/BM25 │ │ "年假政策" → 分词为["年假","政策"] → 各自索引 │ │ 改进: 能匹配部分关键词,支持相关性排序 │ │ 问题: 仍然不理解"年假"="带薪休假" │ │ 代表: Elasticsearch, Lucene │ │ 本项目: MySQL FULLTEXT索引 │ ├─────────────────────────────────────────────────────┤ │ 第三代: 语义搜索 (2020s) │ │ │ │ 原理: 文本 → Embedding向量 → 余弦相似度匹配 │ │ "年假政策" → [0.23, -0.45, 0.78, ...] │ │ "带薪休假" → [0.21, -0.43, 0.75, ...] ← 相似! │ │ 突破: 理解语义,"年假"≈"带薪休假"≈"annual leave" │ │ 代表: Milvus, Pinecone, Weaviate │ │ 本项目: Milvus 2.6 + Embedding模型 │ ├─────────────────────────────────────────────────────┤ │ 第四代: 混合搜索 (2024+) │ │ │ │ 原理: 语义搜索 + 关键词搜索 + RRF融合 │ │ 向量搜索找到语义相关的 │ │ 全文搜索找到关键词精确匹配的 │ │ RRF融合两者的优势 │ │ 代表: 本项目的HybridSearchService │ └─────────────────────────────────────────────────────┘
Embedding是将文字转化为数字数组(向量)的技术,让AI能理解语义关系:
Embedding 原理: 文本 → Embedding模型 → 向量 (高维数字数组) "苹果" → [0.82, -0.15, 0.93, 0.12, ...] (1536维) "iPhone" → [0.78, -0.12, 0.89, 0.15, ...] ← 与"苹果"相似 "香蕉" → [0.65, -0.22, 0.71, 0.18, ...] ← 水果类,较相似 "汽车" → [0.10, 0.85, -0.30, 0.92, ...] ← 不相似 相似度计算: 余弦相似度 (Cosine Similarity) ┌─────────────────────────────────────────┐ │ │ │ cos(A, B) = (A·B) / (|A| × |B|) │ │ │ │ 值域: -1 到 1 │ │ 1 = 完全相同 │ │ 0 = 无关 │ │ -1 = 完全相反 │ │ │ │ "苹果" vs "iPhone" → 0.92 ✅ 相似 │ │ "苹果" vs "汽车" → 0.15 ❌ 不相似 │ └─────────────────────────────────────────┘
传统数据库 vs 向量数据库: 传统数据库 (MySQL): 向量数据库 (Milvus): ┌──────────────────┐ ┌──────────────────┐ │ 精确查询 │ │ 相似度查询 │ │ │ │ │ │ SELECT * FROM │ │ search( │ │ docs │ │ vector=[0.8..], │ │ WHERE title = │ │ top_k=10, │ │ '年假政策' │ │ threshold=0.7 │ │ │ │ ) │ │ 精确匹配 "年假" │ │ 语义匹配 "年假" │ │ 找不到 "带薪休假" │ │ 也能找到 "带薪休假"│ └──────────────────┘ └──────────────────┘ 本项目双写架构: ┌──────────────────────────────────────┐ │ │ │ 文档内容 → 分块 → Embedding │ │ │ │ │ ┌───────┴───────┐ │ │ ▼ ▼ │ │ Milvus MySQL │ │ (向量+语义) (元数据+关键词) │ │ │ │ │ │ └───────┬───────┘ │ │ ▼ │ │ 混合搜索 │ │ 语义 + 关键词 + RRF │ └──────────────────────────────────────┘
| 数据库 | 类型 | 优势 | 劣势 |
|---|---|---|---|
| Milvus | 开源 | 分布式、高性能、GPU加速 | 部署复杂 |
| Pinecone | 托管服务 | 零运维、易上手 | 数据出境、费用高 |
| FAISS | 库 | Meta开源、极快 | 单机、无持久化 |
| Weaviate | 开源 | 内置多模态 | 社区较小 |
| Chroma | 开源 | Python友好 | 性能弱、不适合生产 |
| Qdrant | 开源 | Rust实现、高效 | 生态不如Milvus |
向量搜索的挑战与优化:
挑战: 100万条文档 × 1536维向量 = 15亿个数字
暴力搜索 = 与每个向量计算相似度 = 太慢!
解决方案: 近似最近邻 (ANN) 索引
┌─────────────────────────────────────────────────┐
│ IVF_FLAT (倒排文件索引) │
│ · 将向量空间划分为N个区域(clusters) │
│ · 搜索时只计算目标区域内的向量 │
│ · 精度: 90%+ 速度: 比暴力快10-100x │
├─────────────────────────────────────────────────┤
│ HNSW (层级可导航小世界图) │
│ · 构建多层图结构,类似"六度分隔" │
│ · 从顶层粗搜索,逐层精细化 │
│ · 精度: 99% 速度: 比暴力快100-1000x │
│ · 本项目推荐的索引类型 │
└─────────────────────────────────────────────────┘