这是一个RAG架构(或RAG系统)的例子。
感谢:迪潘
现在我们来看看Retriever的概念。
检索器是一种工具或组件,它根据非结构化的查询来返回文档。它比向量存储更为通用。检索器不需要存储文档的能力,只需要返回或检索它们。向量存储可以作为检索器的基础,但也有各种其他类型的检索器。
检索程序接受一个字符串 query
作为输入,并返回一个包含 Document
的列表作为输出结果。
- 环境配置 :
import os
from dotenv import load_dotenv
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
load_dotenv()
load_dotenv()
用于加载环境变量,这有助于设置 API 密钥等敏感信息。
2. 持久化目录和嵌入:
# 定义持久存储目录
current_dir = os.path.dirname(os.path.abspath(__file__))
db_dir = os.path.join(current_dir, "db")
persistent_directory = os.path.join(db_dir, "chroma_db_with_metadata")
# 定义嵌入向量模型
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
- 代码定义了存放向量数据库的目录,并初始化了OpenAI的
text-embedding-3-small
模型。
3. 向量存储的初始化
## 加载带有嵌入函数的现有向量存储库
db = Chroma(persist_directory=persistent_directory,
embedding_function=embeddings)
- 向量数据库(
Chroma
)从持久目录加载,并使用嵌入函数。
4. 查询功能模块
# 查询向量存储的函数,支持不同搜索类型和参数
def query_vector_store(
store_name, query, embedding_function, search_type, search_kwargs
):
if os.path.exists(persistent_directory):
print(f"\n--- 正在查询向量存储 {store_name} ---")
db = Chroma(
persist_directory=persistent_directory,
embedding_function=embedding_function,
)
retriever = db.as_retriever(
search_type=search_type,
search_kwargs=search_kwargs,
)
relevant_docs = retriever.invoke(query)
# 以下是带有元数据的相关文档
print(f"\n--- {store_name} 的相关文档 ---")
for i, doc in enumerate(relevant_docs, 1):
print(f"文档编号 {i}:\n{doc.page_content}\n")
if doc.metadata:
print(f"来源:{doc.metadata.get('source', '未知')}\n")
else:
print(f"找不到向量存储 {store_name}。")
query_vector_store()
函数设计用于通过不同的搜索类型(例如similarity
、mmr
、similarity_score_threshold
)查询向量库。- 该函数接受几个参数,如库名、查询、嵌入方法、搜索类型以及特定搜索参数。
5. 用户提问
“朱丽叶是怎么死的?” 这个用户的提问用来展示不同的检索方法是如何运作的。
6. 不同的检索方式
# 展示不同的检索方法
# 1. 相似度搜索
# 这种方法通过向量相似度来检索文档。
# 它根据余弦相似度找到与查询向量最相似的文档。
# 当你要查找与查询向量最相似的 k 个文档时,可以使用这种方法。
print("\n--- 使用相似度搜索 ---")
query_vector_store("chroma_db_with_metadata", query,
embeddings, "similarity", {"k": 3})
# 2. 最大边际相关性 (MMR)
# 这种方法在选择与查询相关的文档和文档之间的多样性之间取得平衡。
# 'fetch_k' 指定了根据相似度最初检索的文档数量。
# 'lambda_mult' 控制结果的多样性:1 表示最低多样性,0 表示最高多样性。
# 当你想避免冗余并检索多样且相关的文档时使用这种方法。
# 注意:相关性衡量文档与查询匹配的程度,数值越大表示匹配得越好。
# 注意:多样性确保检索到的文档之间差异性较大,提供更广泛的信息范围。
print("\n--- 使用最大边际相关性 (MMR) ---")
query_vector_store(
"chroma_db_with_metadata",
query,
embeddings,
"mmr",
{"k": 3, "fetch_k": 20, "lambda_mult": 0.5},
)
# 3. 相似度阈值
# 这种方法检索那些相似度分数超过特定阈值的文档。
# 'score_threshold' 设置文档被视为相关的最小相似度分数。
# 当你希望确保检索到的文档足够相关时,可以使用这种方法。
print("\n--- 使用相似度阈值 ---")
query_vector_store(
"chroma_db_with_metadata",
query,
embeddings,
"similarity_score_threshold",
{"k": 3, "score_threshold": 0.1},
)
print("使用不同搜索类型完成的查询演示已经结束。")
- 相似性搜索:基于向量相似度检索文档,适用于找到最相似的前k个文档。
- 最大边际相关性(Max Marginal Relevance,MMR):通过平衡相关性和多样性来工作,有助于避免冗余并确保结果多样性。
- 相似性得分阈值:仅检索超过相似性得分阈值的高度相关的文档,过滤掉不太相关的文档。
7. 执行:
这段代码展示了如何使用每种方法,通过查询向量存储中的内容来显示相关文档及其元数据。
每个检索器生成的输出都需要相互对比,并根据您的实际业务需求相应地使用。
这段代码提供了一个全面的例子,展示如何处理向量存储、嵌入技术以及不同的检索方法,以便根据用户的查询来查找语义相似的文档。我们迄今为止讨论的各种检索方法可以满足RAG解决方案的基本需求,但如果想要提高评估指标,我们可以研究更高级的检索策略。
参考文献:
- https://python.langchain.com/v0.1/docs/modules/data_connection/document_transformers/?source=post_page-----3225af44e7ea--------------------------------
2.https://python.langchain.com/v0.1/docs/modules/data_connection/text_embedding/?source=post_page-----3225af44e7ea--------------------------------
- 有关聊天集成的Python LangChain文档 https://python.langchain.com/v0.2/docs/integrations/chat/
4. https://brandonhancock.io/langchain-master-class
5. https://platform.openai.com/docs/guides/embeddings/what-are-embeddings (有关嵌入式技术的介绍)
6.https://python.langchain.com/v0.1/docs/modules/data_connection/retrievers/
共同学习,写下你的评论
评论加载中...
作者其他优质文章