RAG架构
·
RAG = Retrieval-Augmented Generation(检索增强生成),是当前大模型应用最主流的架构之一。
核心思路:不直接让模型凭"记忆"回答,而是先从外部知识库(基于目前所学内容就是chroma向量数据库)检索相关内容,把检索结果拼进 prompt,再让模型基于这些"证据"生成答案。
一、向量数据库(引入ollama第三方向量模型)
1.距离评估
# 创建向量库和评分方式[向量距离度量(Distance Metric)对比实验]
from langchain_ollama import OllamaEmbeddings
from langchain_chroma import Chroma
from langchain_core.documents.base import Document
embedding=OllamaEmbeddings(model='nomic-embed-text')
default_collection = Chroma(
persist_directory="./chroma_distanctdb",
embedding_function=embedding,
collection_name="default_collection" # L2
)# 1.计算向量距离的算法是此刻决定的,可以指定,也可以默认,如果默认,chroma选择的是l2算法,欧式距离
# 定义数据
docs = [
Document(page_content="这个小米手机很好用"),
Document(page_content="我国陕西地区盛产小米"),
]
# default_collection.add_documents(docs)
results = default_collection.similarity_search_with_score(
"我刚和朋友通了个电话"
)
for doc,score in results:
print(doc,score)
# 法二
# 使用ip算法,计算距离
collection_metadata = {"hnsw:space":"ip"}
ip_collection = Chroma(
persist_directory="./chroma_distanctdb",
embedding_function=embedding,
collection_name="ip_collection",
collection_metadata=collection_metadata
)
# ip_collection.add_documents(docs)
result = ip_collection.similarity_search_with_score("我刚和朋友通了个电话")
for doc,score in result:
print(doc,score)
# cosine
collection_metadata = {"hnsw:space":"cosine"}
cos_collection = Chroma(
persist_directory="./chroma_distanctdb",
embedding_function=embedding,
collection_name="cos_collection",
collection_metadata=collection_metadata
)
cos_collection.add_documents(docs)
result = cos_collection.similarity_search_with_score("我刚和朋友通了个电话")
for doc,score in result:
print(doc,score)
# 法四
collection_metadata = {"hnsw:space":"l2"}
l2_collection = Chroma(
persist_directory="./chroma_distanctdb",
embedding_function=embedding,
collection_name="l2_collection",
collection_metadata=collection_metadata
)
l2_collection.add_documents(docs)
result = l2_collection.similarity_search_with_score("我刚和朋友通了个电话")
for doc,score in result:
print(doc,score)
批注:
“hnsw:space”:“l2” 这是建库时确定、之后不可改的参数。想换必须删集合(表)重建、重新 embedding入库。
在运行代码并进行检索similarity_search_with_score时,有一个极其重要的 Chroma 机制需要注意:Chroma 返回的永远是“距离(Distance)”,而不是“相似度(Similarity)”。这意味着分数越小,代表越相似。
在算法IP(内积,即看方向又看大小)和cosine(1-两向量夹角的余弦值,看方向)是仅在向量归一化后等价,L2(看距离)在三种算法均是越小越相似
2.语义查询
2.1相似度查询
#1.相似度查询 k默认为4
results = collection.similarity_search("大模型",k=1)
print(len(results))
print(results[0].page_content)
2.2带分数的相似度查询(调节过滤阈值)
data=collection.similarity_search_with_score('大模型',k=1)
print(data)
for docs,score in data:
# # 0.6946302652359009
print(docs,score)
# if score>0.7:
# 告诉大模型,rag库中没有匹配的资料
'''
在实际开发 RAG(检索增强生成)系统时,通常会将过滤阈值(Threshold)设定在0.70到0.80之间。即:只保留分数<0.8的结果发送给大语言模型,大于这个分数的宁愿让模型回答“知识库中未找到相关内容”,也不要强行喂给它干扰信息。
距离值域取决于space:cosine是[0,2],l2是[0,+∞),ip无界
匹配等级:S(0-0.3)
A(0.3-0.7)
B(0.7-1.1)
C(>1.1)
传参:人类的纯文本
返回结果是:文档+具体的距离分数
底层执行步骤:1.自动调模型算向量
2.拿向量去ChromaDB查
3.打包计算出距离分数并返回
'''
2.3用向量进行相似度查询
# 把一段话先转成向量,用向量去库中查询
vector_query = embedding.embed_query("大模型")[embed_documents 接收的是列表]
print(len(vector_query[0]))
datas = collection.similarity_search_by_vector(vector_query[0])
print(datas)
'''
similarity_search_by_vector跳过embedding计算,适合你已经算好向量的场景(比如批量查询同一query),能省一次模型推理。
传参:纯数学向量
返回结果是:文档默认不带分数
底层执行步骤:1.直接拿向量去ChromaDB查
2.返回最相似的内容
'''
2.4用检索器进行相似度查询
from langchain_core.runnables import chain
@chain
def retrie(query:str):
return collection.similarity_search(query,k=1)
# 调用方式发生变化
results = retrie.invoke("大模型")
print(results)
'''
通过装饰器的方式将原本的普通函数包装成 LangChain的Runnable对象,invoke()是runnable的内部方法
'''
二、图片向量模型
import chromadb
from chromadb.utils.embedding_functions import OpenCLIPEmbeddingFunction
from chromadb.utils.data_loaders import ImageLoader
# 1. 获取持久化客户端
client = chromadb.PersistentClient(path="./chroma_image_db")
# 2. 初始化多模态嵌入模型
# embedding_function = OpenCLIPEmbeddingFunction()
# 3:实例化图像加载器
# data_loader = ImageLoader()
# 4. 创建集合 (Collection)
img_collection = client.get_or_create_collection(
name="my_photo_album",
embedding_function=OpenCLIPEmbeddingFunction(),
data_loader=ImageLoader() # 新增 3:把加载器绑定到集合上
)
# 5. 存入照片
img_collection.add(
ids=["photo_1", "photo_2","photo_3", "photo_4"],
uris=["./images/cat01.jpg", "./images/cat02.jpg","./images/dog01.png", "./images/dog02.jpeg"],
)
# A:以文搜图 (Text-to-Image)
text_results = img_collection.query(
query_texts=["一只可爱的小猫"],
n_results=1,
include=["uris", "distances"]
)
print( text_results)
# B:以图搜图 (Image-to-Image)
image_results = img_collection.query(
query_uris=["./images/cat03.png"],
n_results=1,
include=["uris", "distances"]
)
print(image_results)
'''
返回值中的内容是由include来决定,指定返回内容在[]内,其他未添加的为None,ids除外(必需字段,不管有无均要显示)
'''
更多推荐



所有评论(0)