向量数据库Chroma DB 的介绍以及在RAG中的应用
1. 什么是 RAG?
RAG 是一个框架(framework),通过从外部来源检索相关信息来增强语言模型,并利用这些信息生成更准确的基于事实的响应,从而减少可能发生的幻觉数量。
RAG 解决的核心问题:
- LLM 的上下文窗口有限 - 无法在单个提示中包含所有信息
- 知识在训练时被冻结
- LLM 可能会出现幻觉
2. RAG 流程步骤
- 提供与用例相关的源文档,并可能将其拆分为更小的块(chunks)or(nodes)
- 对源文档或其块进行嵌入
- 将嵌入存储在向量数据库中,如 Chroma DB
- 接收用户的提示(prompts)
- 对用户的提示进行嵌入
- 检索器从向量存储中选择与用户提示最匹配的块
- 检索到的文本与用户的原始提示结合,生成增强提示
- 将增强提示传递给 LLM,以生成上下文感知的响应
3. RAG 中的向量数据库职责
向量数据库可以处理几个关键问题:
- 嵌入 源文档和用户提示
- 存储 这些嵌入
- 检索 最相关的匹配项
- 提供 检索到的内容以增强提示
注意:某些 RAG 流程步骤,例如嵌入文档和提示,也可以在外部执行。在这种情况下,向量数据库主要用于存储和检索向量。
4. 为什么在RAG步骤中使用向量数据库
-
防止错误 - 比如意外使用不同的嵌入模型处理源文档和用户提示,或错误地将嵌入与其对应的源文档链接。
-
开发变得更快更简洁 - 移动部件更少,自定义逻辑更少,使得代码库保持简单且易于维护,从而加快实现和调试的速度。
-
性能优势 - 向量数据库专为高速、可扩展的语义搜索而构建,使用先进的索引算法。定制构建的替代方案通常无法在没有显著优化工作的情况下匹配这种性能。
5. 常见的 RAG pipeline 陷阱
需要避免的关键错误:
-
对文档和查询使用不同的嵌入模型可能会完全破坏检索。
- 解决方案: 在整个过程中使用相同的嵌入模型。向量数据库通常会自动处理这一点。
-
不良的分块策略 - 创建的块过大或过小。
- 解决方案: 选择一个足够长的块大小,以保留意义而不包含过多无关内容。
-
在更改距离度量或嵌入模型后忘记重新嵌入内容。
- 注意: 对于某些数据库,如 Chroma DB,这不能在现有数据库上完成,可能需要克隆您的集合。
-
假设检索结果总是最佳答案。
- 解决方案: 始终测试您的结果,因为稍微调整可能会带来很大的不同。
6. Chroma DB 基本操作
创建集合
-
1. import chromadb 2. import chromadb.utils.embedding_functions as embedding_functions 3. 4. # Define the embedding model 5. sentence_transformer_ef = embedding_functions.SentenceTransformerEmbeddingFunction( 6. model_name="all-MiniLM-L6-v2" 7. ) 8. 9. # Define chromadb client 10. client = chromadb.Client() 11. 12. # Create collection 13. collection = client.create_collection( 14. name="my_collection", 15. metadata={"description": "A collection for storing user data"}, 16. configuration={ 17. "embedding_function": sentence_transformer_ef 18. } 19. )
链接到现有集合
collection = client.get_collection(name="my_collection")
修改集合
1. # Alter collection using modify method
2. collection.modify(
3. name="new_collection_name",
4. metadata={"key": "value"}
5. )
提示: 某些更改,例如修改嵌入模型或距离度量,无法对现有集合进行。要应用这些更改,需要克隆一个集合,如果集合中存储了大量数据,这是一个耗费算力的操作。
添加文档
1. # Add documents to collection
2. collection.add(
3. documents=[
4. "This is a document about LangChain",
5. "This is a document about LlamaIndex"
6. ],
7. metadatas=[
8. {"source": "langchain.com", "version": "0.2"},
9. {"source": "llamaindex.ai", "version": "0.12"}
10. ],
11. ids=["id1", "id2"]
12. )
注意: 确保在传递给 ids 参数的列表中为每个文档包含一个 ID。
检索文档
1. # Get all documents (returns Python dictionary)
2. results = collection.get()
3.
4. # Get specific documents by ID
5. results = collection.get(ids=["id1"])
6.
7. # Include embeddings in results
8. results = collection.get(include=['embeddings'])
注意: get 方法默认不返回嵌入,以保持输出简洁。然而,嵌入实际上是存储在集合中的。
更新文档
1. # Update existing documents
2. collection.update(
3. ids=["id1"],
4. metadatas=[{"source": "langchain.com", "version": "0.3"}],
5. documents=["This an updated document about LangChain"]
6. )
重要: Chroma DB 在后台处理重新嵌入,立即在提交更新后重新计算文档的嵌入。
删除文档
1. # Delete by IDs
2. collection.delete(ids=["id1"])
3.
4. # Delete using metadata filter
5. collection.delete(where={"source": "doc_to_delete.pdf"})
6.
7. # Combine IDs and filters
8. collection.delete(
9. ids=["id1"],
10. where={"version": "1.0"}
11. )
7. Chroma DB中的距离函数
Chroma DB使用层次可导航的小世界(HNSW)算法执行近似最近邻搜索(ANN)。
space参数定义了嵌入空间中使用的距离函数:
l2(默认)- 平方L2范数cosine- 余弦距离ip- 内积或点积距离
配置距离函数
1. # Specify distance function at collection creation
2. collection = client.create_collection(
3. name="my_collection",
4. metadata={"description": "A collection for storing user data"},
5. configuration={
6. "embedding_function": sentence_transformer_ef,
7. "hnsw": {"space": "cosine"}
8. }
9. )
8. 向量数据库无法处理的内容
一些 RAG pipeline 任务通常在数据库之外进行,例如:
- 分块 通常在数据进入向量数据库之前完成
- 额外的检索逻辑 如过滤和重新排序可能需要额外的工具
- 提示增强 通常在数据库之外处理
- 与 LLM 的集成 大多数向量数据库中并未内置
9. RAG 框架
像 LangChain 和 LlamaIndex 这样的工具 包装向量数据库,帮助管理从文档准备到最终响应的整个流程。
这些框架:
- 提供额外的结构。
- 连接所有组件。
- 进一步简化 RAG 应用程序的开发和部署。
10. 关键要点
- 向量数据库是基础,使得检索增强生成得以实现。
- RAG提升了LLM的响应质量,通过检索相关的外部信息,帮助模型生成更准确且有支持的输出。
- 在所有相关的RAG步骤中使用向量数据库有助于防止关键错误,加快应用开发,并优化性能。
- 集合是组织数据的一种方式,在Chroma DB中使用。
- 元数据帮助跟踪集合的目的和内容。
- 始终测试结果 - 一点fine-tuning可以带来很大的不同。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)