第 10 课 | 向量数据库 ChromaDB 实战存储与检索第 9 课的嵌入向量存在内存里重启就没了。这节课我们把它们存入向量数据库 ChromaDB——持久化、高效检索、元数据过滤一条龙搞定。一、为什么需要向量数据库1.1 第 9 课的遗留问题在第 9 课我们学会了用 BGE 模型把文本变成向量。但有个问题这些向量存在 Python 的内存里程序一关就没了。想象一下你的竞品监控 Agent 处理 100 万条商品数据每次重启都要重新生成 100 万个嵌入向量那得等几个小时。而且 100 万个 1024 维向量存在内存里需要 100 万 × 1024 × 4 字节 ≈ 4GB 内存。这还只是向量不算原始文本。向量数据库就是来解决这个问题的。1.2 向量数据库的三大核心能力能力说明对应传统数据库持久化存储向量存磁盘重启不丢失数据持久化高效检索ANN近似最近邻搜索毫秒级返回 Top-K索引查询元数据过滤按类别、时间、价格等条件过滤WHERE 子句ANNApproximate Nearest Neighbor是向量数据库的核心技术。精确的最近邻搜索需要遍历所有向量O(n)100 万条数据就是 100 万次比较。ANN 通过索引结构如 HNSW将复杂度降到 O(log n)毫秒级返回结果。1.3 向量数据库选型数据库特点适用场景ChromaDB轻量Python 原生零配置开发原型、中小规模100 万Milvus分布式高性能GPU 加速大规模生产100 万pgvectorPostgreSQL 插件已有 PG 基础设施Weaviate全功能GraphQL API企业级应用QdrantRust 实现高性能对延迟敏感的场景对于我们的教程ChromaDB是最佳选择——Python 原生安装简单功能够用和 sentence-transformers 无缝集成。二、ChromaDB 简介与安装2.1 安装uv pip install chromadbChromaDB 的依赖很少安装很快。它自带 SQLite 作为底层存储引擎不需要额外安装数据库。2.2 核心概念ChromaDB Client客户端Collection集合类似表Document文档原始文本Embedding嵌入向量1024维Metadata元数据类别、价格等图 1ChromaDB 核心概念Client客户端管理连接和 CollectionCollection集合类似关系数据库的表存储一组相关文档Document原始文本即你要检索的内容Embedding文档的向量表示由嵌入模型自动生成Metadata文档的附加属性用于过滤2.3 两种模式ChromaDB 支持两种模式# 内存模式数据在内存中重启丢失clientchromadb.Client()# 持久化模式数据存磁盘重启不丢失★ 推荐clientchromadb.PersistentClient(path./chroma_db)生产环境一定要用持久化模式。三、创建 Collection 并导入数据3.1 完整导入流程code/chroma_store.py实现了从第 9 课的products.json到 ChromaDB 的完整导入流程importchromadbfromchromadb.utilsimportembedding_functions# 1. 创建嵌入函数embedding_fnembedding_functions.SentenceTransformerEmbeddingFunction(model_nameBAAI/bge-large-zh-v1.5,)# 2. 创建持久化客户端clientchromadb.PersistentClient(path./chroma_db)# 3. 创建 Collectioncollectionclient.create_collection(nameproduct_knowledge_base,embedding_functionembedding_fn,metadata{description:商品知识库},)# 4. 批量导入collection.add(ids[1,2,3,...],documents[商品描述1,商品描述2,...],metadatas[{name:耳机,category:数码},...],)关键点embedding_function指定了嵌入模型。ChromaDB 会在导入时自动调用 BGE 生成向量不需要手动调用model.encode()ids必须唯一用于后续的更新和删除导入是增量的多次调用add()会追加数据3.2 持久化验证导入完成后检查./chroma_db目录chroma_db/ ├── chroma.sqlite3 ← 元数据和向量索引 └── 索引文件...数据已经在磁盘上了。重启 Python 后只需get_collection()就能恢复所有数据不需要重新导入。四、语义检索4.1 基础检索collectionclient.get_collection(nameproduct_knowledge_base,embedding_functionembedding_fn,)resultscollection.query(query_texts[适合办公的椅子],n_results3,)返回结果结构{ids:[[4,7,16]],documents:[[人体工学办公椅...,升降桌 E5...,双肩电脑包...]],metadatas:[[{name:人体工学办公椅,category:家居办公},...]],distances:[[0.12,0.35,0.72]],}distances是向量距离越小越相似。对于归一化向量距离 ≈ 2 × (1 - 余弦相似度)转换公式similarity 1 - distance / 24.2 与第 9 课手动检索的对比维度第 9 课手动检索ChromaDB代码量~30 行~5 行持久化不支持自动持久化检索速度1000 条~50ms~5ms检索速度100 万条~30s~50ms元数据过滤手动实现内置支持五、元数据过滤5.1 基础过滤元数据过滤让你在语义相似的基础上按业务条件筛选# 只看数码电子类resultscollection.query(query_texts[音质好的设备],n_results3,where{category:数码电子},)效果对比过滤条件结果无过滤智能蓝牙耳机 Pro → 高清降噪耳机 X3 → 便携蓝牙音箱category数码电子智能蓝牙耳机 Pro → 高清降噪耳机 X3 → 智能手表 Ultra加了过滤后第三条从便携蓝牙音箱也是数码电子变成了智能手表 Ultra——因为只返回数码电子类不相关的被排除了。5.2 复合过滤条件ChromaDB 支持丰富的过滤操作符# 多条件where{category:数码电子,price:{$gt:100}}# 范围where{price:{$gte:50,$lte:200}}# 列表where{category:{$in:[数码电子,家用电器]}}这些过滤条件在向量检索之前执行Pre-filtering确保只在与过滤条件匹配的文档中搜索。六、实战构建商品知识库6.1 完整流程数据准备 → 定义嵌入函数 → 创建 Collection → 批量导入 → 语义检索整个流程在code/chroma_store.py和code/chroma_search.py中完整实现。6.2 性能测试在 20 条商品数据上的检索性能操作耗时说明导入 20 条~1.5s含嵌入生成 写入单次检索~5ms含嵌入生成 ANN 搜索带过滤检索~3ms过滤减少了搜索空间50 次检索~250ms平均 5ms/次对于 20 条数据ChromaDB 的 ANN 索引优势还不明显。但当数据量达到 10 万条以上时ANN 索引的优势就体现出来了——检索速度几乎不随数据量线性增长。6.3 扩展到大规模数据当数据量达到 10 万级别时需要注意分批导入每次add()不超过 1000 条避免内存溢出索引构建大量数据导入后ChromaDB 会自动构建 HNSW 索引显存管理嵌入函数在 GPU 上运行注意 batch_size 控制七、小结与预告这节课我们完成了向量数据库 ChromaDB 的部署和使用——从数据导入到语义检索再到元数据过滤。核心收获ChromaDB 解决持久化问题向量存磁盘重启不丢失嵌入函数自动调用不需要手动model.encode()ChromaDB 自动处理元数据过滤语义相似 业务条件双重筛选ANN 索引毫秒级检索随数据量增长几乎不减速下一节课我们将引入Rerank 模型——在向量检索的粗排结果上做一次精排进一步提升检索准确率。这是 RAG 系统中检索质量的关键一环。我们下一课见。系列教程导航上一篇第 09 课 | 嵌入模型 BGE 本地部署让机器理解语义下一篇第 11 课 | Rerank 模型部署粗排 精排双重保险本系列共 50 课持续更新中。关注我不迷路。