AI--向量的存储和检索

step1 Document

LangChain 实现了Document抽象,旨在表示文本单元和相关元数据。它具有两个属性:

  • page_content:代表内容的字符串;
  • metadata:包含任意元数据的字典。

该metadata属性可以捕获有关文档来源、其与其他文档的关系以及其他信息的信息.单个Document对象通常代表较大文档的一部分。

from langchain_core.documents import Document

documents = [
    Document(
        page_content="Dogs are great companions, known for their loyalty and friendliness.",
        metadata = {"source": "mammal-pets-doc"},
    ),
     Document(
        page_content="Cats are independent pets that often enjoy their own space.",
        metadata={"source": "mammal-pets-doc"},
    ),
    Document(
        page_content="Goldfish are popular pets for beginners, requiring relatively simple care.",
        metadata={"source": "fish-pets-doc"},
    ),
    Document(
        page_content="Parrots are intelligent birds capable of mimicking human speech.",
        metadata={"source": "bird-pets-doc"},
    ),
    Document(
        page_content="Rabbits are social animals that need plenty of space to hop around.",
        metadata={"source": "mammal-pets-doc"},
    ),
]

step2 向量检索

向量检索是一种常见的存储和检索非结构化数据的方式,主要思路是存储文本的数据向量,给出一个查询,我们编码查询成同一个维度的数据向量,然后使用相似度去查找相关数据
LangChain VectorStore对象包含用于将文本和Document对象添加到存储区以及使用各种相似度指标查询它们的方法。它们通常使用嵌入模型进行初始化,这些模型决定了如何将文本数据转换为数字向量。

下面我是使用bce-embedding模型作为编码模型,地址下载

from langchain.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores.utils import DistanceStrategy

# init embedding model
model_kwargs = {'device': 'cuda'}
encode_kwargs = {'batch_size': 64, 'normalize_embeddings': True}

embed_model = HuggingFaceEmbeddings(
    model_name=EMBEDDING_PATH,
    model_kwargs=model_kwargs,
    encode_kwargs=encode_kwargs
  )
vetorstore = Chroma.from_documents(
    documents,
    embedding=embed_model,
)

vetorstore.similarity_search("cat")

输出结果为:

[Document(page_content=‘Cats are independent pets that often enjoy their own space.’, metadata={‘source’: ‘mammal-pets-doc’}),
Document(page_content=‘Goldfish are popular pets for beginners, requiring relatively simple care.’, metadata={‘source’:
‘fish-pets-doc’}),
Document(page_content=‘Dogs are great companions, known for their loyalty and friendliness.’, metadata={‘source’:‘mammal-pets-doc’}),
Document(page_content=‘Parrots are intelligent> birds capable of mimicking human speech.’, metadata={‘source’:‘bird-pets-doc’})]

搜索返回相似度分数

vetorstore.similarity_search_with_score("cat")

[(Document(page_content=‘Cats are independent pets that often enjoy their own space.’, metadata={‘source’: ‘mammal-pets-doc’}),
0.9107884),
(Document(page_content=‘Goldfish are popular pets for beginners, requiring relatively simple care.’, metadata={‘source’: ‘fish-pets-doc’}),
1.3231826),
(Document(page_content=‘Dogs are great companions, known for their loyalty and friendliness.’, metadata={‘source’: ‘mammal-pets-doc’}),
1.4060305),
(Document(page_content=‘Parrots are intelligent birds capable of mimicking human speech.’, metadata={‘source’: ‘bird-pets-doc’}),
1.4284585),
(Document(page_content=‘Rabbits are social animals that need plenty of space to hop around.’, metadata={‘source’: ‘mammal-pets-doc’}),
1.4566814)]

上面结果返回的score,越小表示越接近

基于向量查询

embedding = embed_model.embed_query("cat")
vetorstore.similarity_search_by_vector(embedding)

输出结果

[Document(page_content=‘Cats are independent pets that often enjoy their own space.’, metadata={‘source’: ‘mammal-pets-doc’}),
Document(page_content=‘Goldfish are popular pets for beginners, requiring relatively simple care.’, metadata={‘source’: ‘fish-pets-doc’}),
Document(page_content=‘Dogs are great companions, known for their loyalty and friendliness.’, metadata={‘source’: ‘mammal-pets-doc’}),
Document(page_content=‘Parrots are intelligent birds capable of mimicking human speech.’, metadata={‘source’: ‘bird-pets-doc’})]

step3 检索

LangChainVectorStore对象没有Runnable子类,因此不能立即集成到 LangChain 表达语言链中。

LangChain Retrievers是 Runnable,因此它们实现了一组标准方法(例如同步和异步invoke操作batch)并且旨在纳入 LCEL 链。

我们可以自己创建一个简单的版本,而无需子类化Retriever。如果我们选择要使用的方法检索文档,我们可以轻松创建一个可运行的程序。下面我们将围绕该similarity_search方法构建一个:

from typing import List

from langchain_core.documents import Document
from langchain_core.runnables import RunnableLambda


retriever = RunnableLambda(vetorstore.similarity_search).bind(k=1)

print(retriever.invoke("cat"))
print(retriever.batch(["cat","dog"]))

输出结果

[Document(page_content=‘Cats are independent pets that often enjoy their own space.’, metadata={‘source’: ‘mammal-pets-doc’})]
[[Document(page_content=‘Cats are independent pets that often enjoy their own space.’, metadata={‘source’: ‘mammal-pets-doc’})], [Document(page_content=‘Dogs are great companions, known for their loyalty and friendliness.’, metadata={‘source’: ‘mammal-pets-doc’})]]

Vectorstore 实现了as_retriever一个生成 Retriever 的方法,特别是VectorStoreRetriever。这些检索器包括特定的search_type属性search_kwargs,用于标识要调用的底层向量存储的哪些方法以及如何参数化它们。

retriever = vetorstore.as_retriever(
    search_type="similarity",
    search_kwargs={"k": 1},
)

retriever.batch(["cat", "shark"])

输出结果

[[Document(page_content=‘Cats are independent pets that often enjoy their own space.’, metadata={‘source’: ‘mammal-pets-doc’})],
[Document(page_content=‘Goldfish are popular pets for beginners, requiring relatively simple care.’, metadata={‘source’: ‘fish-pets-doc’})]]

检索器可以轻松地合并到更复杂的应用程序中,例如检索增强生成(RAG)应用程序,

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough

chat = ChatOpenAI()

message = """
Answer this question using the provided context only.

{question}

Context:
{context}
"""

retriever = vetorstore.as_retriever(
    search_type="similarity",
    search_kwargs={"k": 1},
)

prompt = ChatPromptTemplate.from_messages(
    [
        ("human",message),
    ]
)


rag_chat = {"context":retriever,"question":RunnablePassthrough()} | prompt |chat

response = rag_chat.invoke("tell me about cats")
print(response.content)

输出结果

Cats are independent pets that often enjoy their own space.

  • 29
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值