掘金 人工智能 07月17日 15:50
RAG 每日一技(六):别再手动管理了!认识你的第一个向量数据库
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文深入探讨了在RAG(检索增强生成)系统中,FAISS索引在持久化、元数据管理和数据更新方面的工程挑战。为解决这些问题,文章引入了向量数据库的概念,并重点介绍了轻量级且友好的ChromaDB。通过实例演示,展示了ChromaDB如何通过简单的API(如add和query)高效地存储、索引、管理向量及其关联元数据,并支持元数据过滤等高级功能,极大地简化了RAG系统的开发和维护。文章最后预告了下一阶段将聚焦于结果的重排优化。

🧰 **向量数据库解决FAISS索引的痛点**:FAISS虽然能加速向量检索,但存在数据易丢失(内存存储)、元数据管理繁琐(需单独存储和关联)以及数据更新删除复杂等问题。向量数据库如ChromaDB提供了统一的解决方案,内置高效索引,支持向量与元数据(如文本原文、来源、类型等)的绑定存储,具备数据持久化能力,并提供简单的增删改查API,同时支持可扩展性,能有效解决手动管理FAISS带来的工程难题。

✨ **ChromaDB的便捷使用与核心功能**:ChromaDB被誉为向量数据库界的“SQLite”,对新手极其友好。文章通过四个步骤展示了其核心功能:1. 初始化持久化客户端和创建“集合”(类似SQL表);2. 使用`add`命令一次性添加文档、元数据和ID,ChromaDB自动完成Embedding和存储;3. 通过`query`命令高效检索,返回包含ID、距离、元数据和原文的结构化结果;4. 利用`where`子句实现带元数据的过滤查询,实现更精准的检索。

💡 **元数据过滤提升检索精度**:ChromaDB的元数据过滤功能是一项杀手级特性,允许用户根据预设的条件(如文档类型为“tech”)来限定搜索范围。这对于构建需要复杂检索策略的应用场景至关重要,能够显著提高检索结果的相关性和用户满意度,是向量数据库相比纯向量索引库的关键优势之一。

🚀 **RAG系统检索环节的完整解决方案**:通过介绍FAISS的局限性和向量数据库的优势,文章为RAG系统的“R”(Retrieval)部分构建了从文本分块、向量嵌入到高效存储与检索的全链路基础。ChromaDB的引入使得这一过程更加顺畅和易于管理,为后续的生成环节提供了坚实的基础。

前情回顾

上一篇文章 中,我们化身效率大师,使用FAISS成功地为海量向量构建了高速索引,解决了RAG系统中的“检索慢”问题。那一刻,我们仿佛掌控了从百万数据中大海捞针的神力。

然而,兴奋劲还没过,几个头疼的工程问题就冒了出来:

    持久化之痛:我们用FAISS辛辛苦苦构建的索引,它只存在于内存里。程序一重启,一切归零,我们又得重新加载全部数据、重新训练、重新构建索引。这谁受得了?元数据之殇:FAISS只关心向量本身。它返回给我们的是向量的ID和距离。但那个ID对应的原始文本块是什么?它来自哪个文档的第几页?这些信息(我们称之为元数据 Metadata)我们得自己另找地方存(比如另一个SQL数据库),然后小心翼翼地做关联。太繁琐了!管理之烦:如果我想删除或更新某一个文本块和它对应的向量呢?在FAISS这类底层库里操作起来非常复杂。

总而言之,我们造出了一台性能强劲的“发动机”(FAISS),但我们还得自己手动焊车架、装轮子、连电路。是时候让专业的“汽车制造商”出场了。

这个制造商,就是向量数据库 (Vector Database)

什么是向量数据库?

向量数据库是一种专门为了高效存储、索引、管理和查询海量向量及其关联元数据而设计的数据库系统。

它就像一个全能管家,把我们昨天头疼的所有问题都打包解决了:

今天,我们来认识一位向量数据库领域的“小而美”的明星选手:ChromaDB。它非常轻量,对新手极其友好,堪称向量数据库界的“SQLite”。

上手实战:ChromaDB 四步走

我们将用ChromaDB重新实现一遍存储和检索的流程,感受一下它到底有多方便。

首先,安装必要的库:

pip install chromadb sentence-transformers
第1步:初始化客户端,创建集合

ChromaDB可以纯内存运行,也可以持久化到本地。我们当然选择后者。一个“集合(Collection)”就类似于SQL数据库中的一张“表”。

import chromadb# 初始化一个持久化的客户端,数据将存储在'my_chroma_db'目录下client = chromadb.PersistentClient(path="my_chroma_db")# 创建一个名为"rag_series_demo"的集合# 如果该集合已存在,get_or_create_collection会直接获取它collection = client.get_or_create_collection(name="rag_series_demo")

就这么简单,我们的“数据库”和“表”就建好了。

第2步:添加数据(见证奇迹的时刻)

这是ChromaDB最能体现其便利性的地方。我们不再需要自己去手动做Embedding,再把向量和ID分开添加。我们可以把所有信息一股脑地扔给它!

# 准备要添加的数据,注意,这次我们有丰富的元数据documents_to_add = [    "RAG的核心思想是检索增强生成。",    "FAISS是Facebook开源的向量检索库。",    "ChromaDB是一个对开发者友好的向量数据库。",    "今天天气真不错,适合出去玩。",]metadatas_to_add = [    {"source": "doc1", "type": "tech"},    {"source": "doc2", "type": "tech"},    {"source": "doc3", "type": "tech"},    {"source": "doc4", "type": "daily"},]ids_to_add = ["id1", "id2", "id3", "id4"]# 只需一个add命令,ChromaDB会自动处理:# 1. 调用默认的Embedding模型将documents转换为向量 (我们也可以指定自己的模型)# 2. 存储向量、文档原文、元数据和IDcollection.add(    documents=documents_to_add,    metadatas=metadatas_to_add,    ids=ids_to_add)

看到了吗?文本、元数据、ID,一步到位! 这背后繁琐的Embedding、存储、索引过程,ChromaDB已经默默为我们全部搞定。

第3步:查询集合

查询同样简单到令人发指。

# 定义查询query_texts = ["什么是向量数据库?"]# 执行查询results = collection.query(    query_texts=query_texts,    n_results=2  # 我们想找最相关的2个结果)# 打印结果import jsonprint(json.dumps(results, indent=2, ensure_ascii=False))

输出结果:

{  "ids": [    [      "id3",      "id2"    ]  ],  "distances": [    [      0.4851231575012207,      1.0456184148788452    ]  ],  "metadatas": [    [      {        "source": "doc3",        "type": "tech"      },      {        "source": "doc2",        "type": "tech"      }    ]  ],  "embeddings": null,  "documents": [    [      "ChromaDB是一个对开发者友好的向量数据库。",      "FAISS是Facebook开源的向量检索库。"    ]  ],  "uris": null,  "data": null}

太完美了!返回的结果是一个结构清晰的对象,包含了ID、距离、元数据原始文档!我们不再需要拿着ID去另一个地方查找原文了。

第4. 杀手级特性:带元数据过滤的查询

如果我只想在“科技类(tech)”文档中进行搜索怎么办?ChromaDB的 where 子句可以轻松实现。

results_filtered = collection.query(    query_texts=["什么是向量数据库?"],    n_results=2,    where={"type": "tech"} # 只在type为'tech'的文档中搜索)# (你可以自行打印看看结果,它不会包含type为'daily'的文档)

这个功能在构建复杂的检索策略时极其有用!

总结与预告

今日小结:

    手动管理FAISS索引和元数据非常繁琐,难以维护和扩展。向量数据库(如ChromaDB)提供了一站式的解决方案,集成了存储、索引、元数据管理和持久化功能。使用ChromaDB,我们可以通过简单的addquery命令,轻松地管理和检索“文档-元数据-向量”三位一体的数据。元数据过滤是向量数据库的强大功能,能实现更精准、更灵活的检索。

到此,我们已经打通了RAG系统中“R”(Retrieval,检索)部分的基础全链路:文本分块 -> 向量嵌入 -> 存储与检索

但,检索出来的结果就完美了吗?我们取了Top 3的结果,是不是这3个都同等重要?有没有可能第3个结果其实比第1个更贴近用户的真实意图?

仅仅依靠向量相似度做的第一轮“海选”,有时候并不足够精确。我们需要一个“复试”环节,来对海选出来的结果进行精修和重排。

明天预告:RAG 每日一技(七):只靠检索还不够?用Re-ranking给你的结果精修一下

明天,我们将学习如何引入一个“精排模型(Re-ranker)”,对初步检索到的文档进行二次排序,把最最相关的答案推到最前面,为最终的生成环节提供最高质量的“弹药”!

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

向量数据库 ChromaDB RAG FAISS 元数据管理
相关文章