农妇山泉一亩田 发表于 2025-4-5 02:57:06

【记载一放学习】Embedding 与向量数据库

一、向量数据库

向量数据库(Vector Database),也叫矢量数据库,紧张用来存储和处理向量数据。
在数学中,向量是有大小和方向的量,可以利用带箭头的线段体现,箭头指向即为向量的方向,线段的长度体现向量的大小。两个向量的间隔或者相似性可以通过欧式间隔或者余弦间隔得到。
图像、文本和音视频这种非布局化数据都可以通过某种变更或者嵌入学习转化为向量数据存储到向量数据库中,从而实现对图像、文本和音视频的相似性搜索和检索。这意味着您可以利用向量数据库根据语义或上下文含义查找最相似或相关的数据,而不是利用基于准确匹配或预定义尺度查询数据库的传统方法。
向量数据库的紧张特点是高效存储与检索。利用索引技能和向量检索算法能实现高维大数据下的快速相应。向量数据库也是一种数据库,除了要管理向量数据外,还是支持对传统布局化数据的管理。实际利用时,有很多场景会同时对向量字段和布局化字段进行过滤检索,这对向量数据库来说也是一种挑战。
二、向量嵌入(Vector Embeddings)

对于传统数据库,搜索功能都是基于差别的索引方式(B Tree、倒排索引等)加上准确匹配和排序算法(BM25、TF-IDF)等实现的。本质还是基于文本的准确匹配,这种索引和搜索算法对于关键字的搜索功能非常合适,但对于语义搜索功能就非常弱。
比方,假如你搜索 “小狗”,那么你只能得到带有“小狗” 关键字相关的结果,而无法得到 “柯基”、“金毛” 等结果,因为 “小狗” 和“金毛”是差别的词,传统数据库无法辨认它们的语义关系,所以传统的应用需要人为的将 “小狗” 和“金毛”等词之间打上特征标签进行关联,这样才能实现语义搜索。而怎样将天生和挑选特征这个过程,也被称为 Feature Engineering (特征工程),它是将原始数据转化成更好的表达问题本质的特征的过程。
但是假如你需要处理非布局化的数据,就会发现非布局化数据的特征数目会开始快速膨胀,比方我们处理的是图像、音频、视频等数据,这个过程就变得非常困难。比方,对于图像,可以标注颜色、形状、纹理、边缘、对象、场景等特征,但是这些特征太多了,而且很难人为的进行标注,所以我们需要一种自动化的方式来提取这些特征,而这可以通过 Vector Embedding 实现
Vector Embedding 是由 AI 模子(比方大型语言模子 LLM)天生的,它会根据差别的算法天生高维度的向量数据,代表着数据的差别特征,这些特征代表了数据的差别维度。比方,对于文本,这些特征可能包括词汇、语法、语义、情感、情绪、主题、上下文等。对于音频,这些特征可能包括音调、节奏、音高、音色、音量、语音、音乐等。
比方对于现在来说,文本向量可以通过 OpenAI 的 text-embedding-ada-002 模子天生,图像向量可以通过 clip-vit-base-patch32 模子天生,而音频向量可以通过 wav2vec2-base-960h 模子天生。这些向量都是通过 AI 模子天生的,所以它们都是具有语义信息的。
比方我们将这句话 “Your text string goes here” 用 text-embedding-ada-002 模子进行文本 Embedding,它会天生一个 1536 维的向量,得到的结果是这样:“-0.006929283495992422, -0.005336422007530928, ... -4547132266452536e-05,-0.024047505110502243”,它是一个长度为 1536 的数组。这个向量就包含了这句话的全部特征,这些特征包括词汇、语法,我们可以将它存入向量数据库中,以便我们后续进行语义搜索。
三、特征和向量

固然向量数据库的焦点在于相似性搜索 (Similarity Search),但在深入了解相似性搜索前,我们需要先具体了解一下特征和向量的概念和原理。
我们先思考一个问题?为什么我们在生活中区分差别的物品和事物?
假如从理论角度出发,这是因为我们会通过辨认差别事物之间差别的特征来辨认种类,比方分别差别种类的小狗,就可以通过体型大小、毛发长度、鼻子是非等特征来区分。如下面这张照片按照体型排序,可以看到体型越大的狗越靠近坐标轴右边,这样就能得到一个体型特征的一维坐标和对应的数值,从 0 到 1 的数字中得到每只狗在坐标系中的位置。
https://i-blog.csdnimg.cn/img_convert/a956cebc725dd9143772ea9984f530da.png
然而单靠一个体型大小的特征并不敷,像照片中哈士奇、金毛和拉布拉多的体型就非常靠近,我们无法区分。所以我们会继续观察别的的特征,比方毛发的是非。
https://i-blog.csdnimg.cn/img_convert/3f2a4dc9e57d41fb7f7acd3643892e26.jpeg
这样每只狗对应一个二维坐标点,我们就能轻易的将哈士奇、金毛和拉布拉多区分开来,假如这时仍旧无法很好的区分德牧和罗威纳犬。我们就可以继续再从别的的特征区分,比如鼻子的是非,这样就能得到一个三维的坐标系和每只狗在三维坐标系中的位置。
在这种情况下,只要特征足够多,就可以或许将全部的狗区分开来,末了就能得到一个高维的坐标系,固然我们想象不出高维坐标系长什么样,但是在数组中,我们只需要一直向数组中追加数字就可以了。
实际上,只要维度够多,我们就可以或许将全部的事物区分开来,世间万物都可以用一个多维坐标系来体现,它们都在一个高维的特征空间中对应着一个坐标点。
那这和相似性搜索 (Similarity Search) 有什么关系呢?你会发现在上面的二维坐标中,德牧和罗威纳犬的坐标就非常靠近,这就意味着它们的特征也非常靠近。我们都知道向量是具有大小和方向的数学布局,所以可以将这些特征用向量来体现,这样就可以或许通过计算向量之间的间隔来判定它们的相似度,这就是相似性丈量
四、相似性丈量 (Similarity Measurement)

上面我们讨论了向量数据库的差别搜索算法,但是还没有讨论怎样衡量相似性。在相似性搜索中,需要计算两个向量之间的间隔,然后根据间隔来判定它们的相似度。
而怎样计算向量在高维空间的间隔呢?有三种常见的向量相似度算法:欧几里德间隔、余弦相似度和点积相似度。
五、欧几里得间隔(Euclidean Distance)

欧几里得间隔是用于衡量两个点(或向量)之间的直线间隔的一种方法。它是最常用的间隔度量之一,尤其在几何和向量空间中。可以将其理解为两点之间的“直线间隔”。
其中,A 和 B 分别体现两个向量,体现向量的维度。
https://i-blog.csdnimg.cn/img_convert/e144fe458de0013c0446de37c957aee0.png
https://i-blog.csdnimg.cn/img_convert/decf31953c94e3384db3e7e0f2712d77.png
https://i-blog.csdnimg.cn/img_convert/cfbb154db3233372626c9f1a332ab5f8.png
欧几里得间隔算法的优点是可以反映向量的绝对间隔,适用于需要思量向量长度的相似性计算。比方推荐体系中,需要根据用户的历史举动来推荐相似的商品,这时就需要思量用户的历史举动的数目,而不仅仅是用户的历史举动的相似度。
六、 余弦相似度(Cosine Similarity)

余弦相似度(Cosine Similarity)是一种用于衡量两个向量之间相似度的指标。它通过计算两个向量夹角的余弦值来判定它们的相似程度。其值介于 -1 和 1 之间,通常用于文本分析和推荐体系等领域。
https://i-blog.csdnimg.cn/img_convert/a423ad232c77ffb38bc8f430d2716
037.png
https://i-blog.csdnimg.cn/img_convert/ade5d47a0421eff544d10f9370b51226.png
特点

值域:结果在 -1 到 1 之间。1 体现完全相似,0 体现不相关,-1 体现完全相反。
余弦相似度对向量的长度不敏感,只关注向量的方向,因此适用于高维向量的相似性计算。比方语义搜索和文档分类。
https://i-blog.csdnimg.cn/img_convert/6080eadc474f8e579bfc358159fe4181.png
七、相似性搜索 (Similarity Search)

既然我们知道了可以通过比力向量之间的间隔来判定它们的相似度,那么怎样将它应用到真实的场景中呢?假如想要在一个海量的数据中找到和某个向量最相似的向量,我们需要对数据库中的每个向量进行一次比力计算,但这样的计算量是非常巨大的,所以我们需要一种高效的算法来解决这个问题。
高效的搜索算法有很多,其紧张头脑是通过两种方式进步搜索服从
1)减少向量大小——通过降维或减少体现向量值的长度。
2)缩小搜索范围——可以通过聚类或将向量组织成基于树形、图形布局来实现,并限制搜索范围仅在最靠近的簇中进行,或者通过最相似的分支进行过滤。
我们首先来先容一下大部门算法共有的焦点概念,也就是聚类。<
我们可以在生存向量数据后,先对向量数据先进行聚类。比方下图在二维坐标系中,划定了 4 个聚类中央,然后将每个向量分配到最近的聚类中央,经过聚类算法不断调整聚类中央位置,这样就可以将向量数据分成 4 个簇。每次搜索时,只需要先判定搜索向量属于哪个簇,然后再在这一个簇中进行搜索,这样就从 4 个簇的搜索范围减少到了 1 个簇,大大减少了搜索的范围。
https://i-blog.csdnimg.cn/img_convert/7587463a9733f41dbbbe946a27e5007f.png
工作原理

[*]初始化:选择 $ k $ 个随机点作为初始聚类中央。
[*]分配:将每个向量分配给离它最近的聚类中央,形成 $ k $ 个簇。
[*]更新:重新计算每个簇的聚类中央,即簇内全部向量的均匀值。
[*]迭代:重复“分配”和“更新”步调,直到聚类中央不再变化或达到最大迭代次数。
举例说明
假设我们有一组二维向量(点),比方: [(1, 2), (2, 1), (4, 5), (5, 4), (8, 9)] ,我们希望将它们聚成四个簇( k = 4 )。

[*]初始化:随机选择四个点作为初始聚类中央,比如 $ (1, 2)                                       、                                  、                     、 (2, 1)                                       、                                  、                     、 (4, 5) $ 和 $ (8, 9) $。
[*]分配:计算每个点到四个聚类中央的间隔,将每个点分配给最近的聚类中央。
形成四个簇:$ [(1, 2)]                                    ,                              ,                  , [(2, 1)]                                    ,                              ,                  , [(4, 5), (5, 4)]                                    ,                              ,                  , [(8, 9)] $。
- 点 $ (1, 2)更接近(1, 2) 。
- 点 $ (2, 1) $更接近(2, 1) $。
- 点 $ (4, 5) $ 更接近 $ (4, 5) $。
- 点 $ (5, 4) $ 更接近 $ (4, 5) $。
- 点 $ (8, 9) $ 更接近 $ (8, 9) $。

[*]更新:计算每个簇的新聚类中央。

[*]第一个簇的聚类中央是 $ (1, 2) $。
[*]第二个簇的聚类中央是 $ (2, 1) $。
[*]第三个簇的新聚类中央是 $ ((4+5)/2, (5+4)/2) = (4.5, 4.5) $。
[*]第四个簇的聚类中央是 $ (8, 9) $。

[*]迭代:重复分配和更新步调,直到聚类中央不再变化。
优点:通过将向量聚类,我们可以在进行相似性搜索时只需计算查询向量与每个聚类中央之间的间隔,而不是与全部向量计算间隔。这大大减少了计算量,进步了搜索服从。这种方法在处理大规模数据时尤其有效,可以显著加快搜索速率。
缺点,比方在搜索的时间,假如搜索的内容正利益于两个分类地区的中间,就很有可能遗漏掉最相似的向量。
八、Hierarchical Navigable Small Worlds (HNSW)

除了聚类以外,也可以通过构建树或者构建图的方式来实现近似最近邻搜索。这种方法的基本头脑是每次将向量加到数据库中的时间,就先找到与它最相邻的向量,然后将它们毗连起来,这样就构成了一个图。当需要搜索的时间,就可以从图中的某个节点开始,不断的进行最相邻搜索和最短路径计算,直到找到最相似的向量。
这种算法能保证搜索的质量,但是假如图中所以的节点都以最短的路径相连,如图中最下面的一层,那么在搜索的时间,就同样需要遍历全部的节点。
https://i-blog.csdnimg.cn/img_convert/dd4a7af656936e72a92e6b47d6c57182.png
解决这个问题的思路与常见的跳表算法相似,如下图要搜索跳表,从最高层开始,沿着具有最长 “跳过” 的边向右移动。假如发现当前节点的值大于要搜索的值 - 我们知道已经超过了目标,因此我们会在下一级中向前一个节点。
https://i-blog.csdnimg.cn/img_convert/c7725841c97c2bb46dfd3b89825a848e.png
https://i-blog.csdnimg.cn/img_convert/6e5bb713f5417dd617dcf7210cc5b03a.gif
HNSW 继承了相同的分层格式,最高层具有更长的边缘(用于快速搜索),而较低层具有较短的边缘(用于准确搜索)。
具体来说,可以将图分为多层,每一层都是一个小世界,图中的节点都是相互毗连的。而且每一层的节点都会毗连到上一层的节点,当需要搜索的时间,就可以从第一层开始,因为第一层的节点之间间隔很长,可以减少搜索的时间,然后再逐层向下搜索,又因为最下层相似节点之间相互关联,所以可以保证搜索的质量,可以或许找到最相似的向量。
HNSW 算法是一种经典的空间换时间的算法,它的搜索质量和搜索速率都比力高,但是它的内存开销也比力大,因为不仅需要将全部的向量都存储在内存中。还需要维护一个图的布局,也同样需要存储。所以这类算法需要根据实际的场景来选择。
通过一个简单的例子来说明 HNSW 的工作原理。
假设我们有以下五个二维向量:


[*]$ A = (1, 2) $
[*]$ B = (2, 3) $
[*]$ C = (3, 4) $
[*]$ D = (8, 9) $
[*]$ E = (9, 10) $
我们要利用 HNSW 来找到与查询向量 $ Q = (2, 2) 最相似的向量。
构建阶段

[*]初始化:

[*]首先,我们为每个向量随机选择其在 HNSW 中的层数。比方,假设:

[*]在第2层和第1层
[*]$ B $ 在第1层
[*]$ C $ 在第1层
[*]$ D $ 在第1层
[*]$ E $ 在第1层


[*]构建图:

[*]从最高层开始构建,$ A $ 是第2层唯一的节点。
[*]在第1层,全部节点都存在。我们通过计算欧氏间隔来毗连节点,确保每个节点只毗连到几个最近的邻居。

搜索阶段
总结
通过这种条理化的搜索过程,HNSW 可以或许快速缩小搜索范围,在大规模数据中高效找到近似最近邻。
九、 基于 Embedding 的问答助手和意图匹配

Embedding models(嵌入模子

Embeddings类是一个专为与文本嵌入模子进行交互而设计的类。有很多嵌入模子提供商(如OpenAI、Cohere、Hugging Face等)- 这个类旨在为它们提供一个尺度接口。
Embeddings类会为文本创建一个向量体现。这很有用,因为这意味着我们可以在向量空间中思考文本,并做一些雷同语义搜索的事情,比如在向量空间中寻找最相似的文本片段。
LangChain中的基本Embeddings类提供了两种方法:一个用于嵌入文档,另一个用于嵌入查询。前者.embed_documents 接受多个文本作为输入,而后者.embed_query接受单个文本。之所以将它们作为两个单独的方法,是因为一些嵌入提供商对文档(要搜索的文档)和查询(搜索查询本身)有差别的嵌入方法。.embed_query,将返回一个浮点数列表,.embed_documents将返回一个浮点数列表的列表。
https://i-blog.csdnimg.cn/img_convert/5d32cd115ccba3345077099b17a2fa75.png
十、设置



[*]OpenAI
首先,我们需要安装OpenAI合作同伴包:
pip install langchain-openai
访问API需要一个API密钥,您可以通过创建帐户并转到这里来获取它。一旦我们有了密钥,我们希望通过运行以下命令将其设置为环境变量:
export OPENAI_API_KEY="..."
假如您不想设置环境变量,可以在初始化OpenAI LLM类时通过api_key命名参数直接传递密钥:
from langchain_openai import OpenAIEmbeddings
embeddings_model = OpenAIEmbeddings(api_key="...")
否则,您可以不带任何参数初始化:
from langchain_openai import OpenAIEmbeddings
embeddings_model = OpenAIEmbeddings()
十一、嵌入文本列表(embed_documents)

利用.embed_documents来嵌入一个字符串列表,规复一个嵌入列表:
#示例:embed_documents.py
embeddings = embeddings_model.embed_documents(
    [
      "嗨!",
      "哦,你好!",
      "你叫什么名字?",
      "我的朋友们叫我World",
      "Hello World!"
    ]
)
len(embeddings), len(embeddings)
(5, 1536)
十二、嵌入单个查询(embed_query)

利用.embed_query来嵌入单个文本片段(比方,用于与其他嵌入的文本片段进行比力)。
#示例:embed_query.py
embedded_query = embeddings_model.embed_query("对话中提到的名字是什么?")
embedded_query[:5]

十三、问答助手

#示例:embed_search.py
from openai import OpenAI
#pip install numpy
from numpy import dot
from numpy.linalg import norm

client = OpenAI()


# 定义调用 Embedding API 的函数
def get_embedding(text):
    response = client.embeddings.create(
      input=text,
      model="text-embedding-ada-002"
    )
    return response.data.embedding


# 计算余弦相似度,参考文章:https://blog.csdn.net/Hyman_Qiu/article/details/137743190
#定义一个函数 cosine_similarity,该函数接受两个向量 vec1 和 vec2 作为输入。
def cosine_similarity(vec1, vec2):
    #计算并返回两个向量之间的余弦相似度,公式为:两个向量的点积除以它们范数的乘积。
    return dot(vec1, vec2) / (norm(vec1) * norm(vec2))

# 实现文本搜索功能
# 定义一个函数 search_documents,该函数接受一个查询字符串 query 和一个文档列表 documents 作为输入。
def search_documents(query, documents):
    # 调用 get_embedding 函数生成查询字符串的嵌入向量 query_embedding。
    query_embedding = get_embedding(query)
    # 对每个文档调用 get_embedding 函数生成文档的嵌入向量,存储在 document_embeddings 列表中。
    document_embeddings =
    # 计算查询嵌入向量与每个文档嵌入向量之间的余弦相似度,存储在 similarities 列表中
    similarities =
    # 找到相似度最高的文档的索引 most_similar_index。
    most_similar_index = similarities.index(max(similarities))
    # 返回相似度最高的文档和相似度得分。
    return documents, max(similarities)


# 测试文本搜索功能
if __name__ == "__main__":
    documents = [
      "OpenAI的ChatGPT是一个强大的语言模型。",
      "天空是蓝色的,阳光灿烂。",
      "人工智能正在改变世界。",
      "Python是一种流行的编程语言。"
    ]
    #".././resource/knowledge.txt" 文件内容,转换为上述documents
    #documents =

    query = "天空是什么颜色的?"

    most_similar_document, similarity_score = search_documents(query, documents)
    print(f"最相似的文档: {most_similar_document}")
    print(f"相似性得分: {similarity_score}")

最相似的文档: 天空是蓝色的,阳光灿烂。
相似性得分: 0.916
6142096488017
十四、意图匹配

#示例:embed_intention_recognition.py
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_openai import OpenAIEmbeddings

# 数据导入
loader = TextLoader(".././resource/qa.txt", encoding="UTF-8")
docs = loader.load()
# 数据切分
text_splitter = RecursiveCharacterTextSplitter()
documents = text_splitter.split_documents(docs)
# 创建embedding
embeddings = OpenAIEmbeddings()
# 通过向量数据库存储
vector = FAISS.from_documents(documents, embeddings)
# 查询检索
# 创建 prompt
prompt = ChatPromptTemplate.from_template("""仅根据提供的上下文回答以下问题::
<context>
{context}
</context>
Question: {input}""")
# 创建模型
llm = ChatOpenAI()
# 创建 document 的chain, 查询
document_chain = create_stuff_documents_chain(llm, prompt)
from langchain.chains import create_retrieval_chain

# # 创建搜索chain 返回值为 VectorStoreRetriever
retriever = vector.as_retriever()
retrieval_chain = create_retrieval_chain(retriever, document_chain)
# # 执行请求
response = retrieval_chain.invoke({"input": "天气"})
print(response["answer"])

抱歉,我无法回答关于天气的问题。如果您需要查询天气信息,请使用天气应用程序或者访问天气网站。我可以帮您订餐、播放音乐、设置闹钟或者讲笑话。有什么其他问题我可以帮助您解决吗?
十五、基于 LangChain 构建向量存储和查询:Chroma, Weaviate, Qdrant, Milvus

向量存储)

存储和搜索非布局化数据的最常见方法之一是将其嵌入并存储天生的嵌入向量, 然后在查询时将非布局化查询嵌入并检索与嵌入查询“最相似”的嵌入向量。 向量存储会处理存储嵌入数据并为您实行向量搜索。 可以通过以下方式将向量存储转换为检索器接口:
Retrievers(检索器)是一个接口,根据非布局化查询返回文档。 它比向量存储更通用。 检索器不需要可以或许存储文档,只需要可以或许返回(或检索)它们。 检索器可以从向量存储器创建,但也足够广泛,包括Wikipedia搜索和Amazon Kendra。 检索器接受字符串查询作为输入,并返回文档列表作为输出。
vectorstore = MyVectorStore()
retriever = vectorstore.as_retriever()
Chroma

官方文档:https://docs.trychroma.com/
Chroma ( /'kromə/ n. (色彩的)浓度,色度 )是一个以人工智能为基础的开源向量数据库,专注于开发者的生产力和幸福感。Chroma 利用 Apache 2.0 许可证。 利用以下命令安装 Chroma:
pip install langchain-chroma
Chroma 可以以多种模式运行。以下是每种模式的示例,均与 LangChain 集成:


[*]in-memory在 Python -脚本或 Jupyter 笔记本中
[*]in-memory with persistance -在脚本或笔记本中生存/加载到磁盘
[*]in a docker container- 作为在当地机器或云中运行的服务器
与任何其他数据库一样,您可以进行以下操纵:
.add
.get
.update
.upsert
.delete
.peek


[*]而.query则运行相似性搜索。
检察完备文档,请访问 docs。要直接访问这些方法,可以利用._collection.method()
基本示例

在这个基本示例中,我们获取《乔布斯演讲稿》,将其分割成片段,利用开源嵌入模子进行嵌入,加载到 Chroma 中,然后进行查询。
#示例:chroma_base.py# pip install langchain-chroma
from langchain_chroma import Chromafrom langchain_community.document_loaders import TextLoader# pip install -U langchain-huggingfacefrom langchain_huggingface import HuggingFaceEmbeddingsfrom langchain_text_splitters import CharacterTextSplitter# 加载文档并将其分割成片段loader = TextLoader("../../resource/knowledge.txt", encoding="UTF-8")documents = loader.load()# 将其分割成片段text_splitter = CharacterTextSplitter(chunk_size=1500, chunk_overlap=0)docs = text_splitter.split_documents(documents)# 创建开源嵌入函数embedding_function = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")# 将其加载到 Chroma 中db = Chroma.from_documents(docs, embedding_function)# 进行查询query = "Pixar公司是做什么的?"docs = db.similarity_search(query)# 打印结果print(docs
.page_content)


During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
基本示例(包括生存到磁盘)

在上一个示例的基础上,假如您想要生存到磁盘,只需初始化 Chroma 客户端并传递要生存数据的目次。
注意:Chroma 尽最大积极自动将数据生存到磁盘,但多个内存客户端可能会相互干扰。最佳做法是,任何给定时间只运行一个客户端。
#示例:chroma_disk.py

# 保存到磁盘
db2 = Chroma.from_documents(docs, embedding_function, persist_directory="./chroma_db")
docs = db2.similarity_search(query)
# 从磁盘加载
db3 = Chroma(persist_directory="./chroma_db", embedding_function=embedding_function)
docs = db3.similarity_search(query)
print(docs
.page_content)



During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
将 Chroma 客户端传递给 Langchain

您还可以创建一个 Chroma 客户端并将其传递给 LangChain。假如您希望更轻松地访问底层数据库,这将特别有用。
您还可以指定要让 LangChain 利用的聚集名称。
#示例:chroma_client.py
import chromadb
persistent_client = chromadb.PersistentClient()
collection = persistent_client.get_or_create_collection("collection_name")
collection.add(ids=["1", "2", "3"], documents=["a", "b", "c"])
langchain_chroma = Chroma(
    client=persistent_client,
    collection_name="collection_name",
    embedding_function=embedding_function,
)
print("在集合中有", langchain_chroma._collection.count(), "个文档")
Insert of existing embedding ID: 1
Insert of existing embedding ID: 2
Insert of existing embedding ID: 3
Add of existing embedding ID: 1
Add of existing embedding ID: 2
Add of existing embedding ID: 3
在集合中有 3 个项目

更新和删除

在构建真实应用步伐时,您不仅希望添加数据,还希望更新和删除数据。
Chroma 要求用户提供ids来简化这里的簿记工作。
ids可以是文件名,也可以是雷同
filename_paragraphNumber的组合哈希值。
Chroma 支持全部这些操纵,尽管有些操纵仍在通过 LangChain 接口进行整合。额外的工作流改进将很快添加。
以下是一个基本示例,展示怎样实行各种操纵:
#示例:chroma_update.py# pip install langchain-chroma
from langchain_chroma import Chromafrom langchain_community.document_loaders import TextLoader# pip install -U langchain-huggingfacefrom langchain_huggingface import HuggingFaceEmbeddingsfrom langchain_text_splitters import CharacterTextSplitter# 加载文档并将其分割成片段loader = TextLoader("../../resource/knowledge.txt", encoding="UTF-8")documents = loader.load()# 将其分割成片段text_splitter = CharacterTextSplitter(chunk_size=1500, chunk_overlap=0)docs = text_splitter.split_documents(documents)# 创建开源嵌入函数embedding_function = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")query = "Pixar公司是做什么的?"# 创建简单的 idsids = # 添加数据example_db = Chroma.from_documents(docs, embedding_function, ids=ids)docs = example_db.similarity_search(query)# 更新文档的元数据docs
.metadata = {    "source": "../../resource/knowledge.txt",    "new_value": "hello world",}print("更新前内容:")print(example_db._collection.get(ids=]))example_db.update_document(ids, docs
)print("更新后内容:")print(example_db._collection.get(ids=]))# 删除末了一个文档print("删除前计数", example_db._collection.count())print(example_db._collection.get(ids=]))example_db._collection.delete(ids=])print("删除后计数", example_db._collection.count())print(example_db._collection.get(ids=])) 更新前内容:
{'ids': ['1'], 'embeddings': None, 'metadatas': [{'source': '../../resource/knowledge.txt'}
], 'documents': ["\ufeffI am honored to be with you today at your commencement from one of the finest universities in the world. I never graduated from college. Truth be told, this is the closest I've ever gotten to a college graduation. Today I want to tell you three stories from my life. That's it. No big deal. Just three stories.\n我今天很荣幸能和你们一起参加毕业典礼,斯坦福大学是世界上最好的大学之一。我从来没有从大学中毕业。说实话,今天也许是在我的生命中离大学毕业最近的一天了。今天我想向你们讲述我生活中的三个故事。不是什么大不了的事情,只是三个故事而已。\n\nThe first story is about connecting the dots.\n第一个故事是关于如何把生命中的点点滴滴串连起来。\n\nI dropped out of Reed College after the first 6 months, but then stayed around as a drop-in for another 18 months or so before I really quit. So why did I drop out?\n我在Reed大学读了六个月之后就退学了,但是在十八个月以后——我真正的作出退学决定之前,我还经常去学校。我为什么要退学呢?"], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}
更新后内容:
{'ids': ['1'], 'embeddings': None, 'metadatas': [{'new_value': 'hello world', 'source': '../../resource/knowledge.txt'}], 'documents': ["During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.\n在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。"], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}
删除前计数 16

{'ids': ['16
'], 'embeddings': None, 'metadatas': [{'source': '../../resource/knowledge.txt'}
], 'documents': ['Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its course, they put out a final issue. It was the mid-1970s, and I was your age. On the back cover of their final issue was a photograph of an early morning country road, the kind you might find yourself hitchhiking on if you were so adventurous. Beneath it were the words: "Stay Hungry. Stay Foolish." It was their farewell message as they signed off. Stay Hungry. Stay Foolish. And I have always wished that for myself. And now, as you graduate to begin anew, I wish that for you.\nStewart和他的伙伴出版了几期的“整个地球的目录”,当它完成了自己使命的时候,他们做出了最后一期的目录。那是在七十年代的中期,你们的时代。在最后一期的封底上是清晨乡村公路的照片(如果你有冒险精神的话,你可以自己找到这条路的),在照片之下有这样一段话:“求知若饥,虚心若愚。”这是他们停止了发刊的告别语。“求知若饥,虚心若愚。”我总是希望自己能够那样,现在,在你们即将毕业,开始新的旅程的时候,我也希望你们能这样:\n\nStay Hungry. Stay Foolish.\n求知若饥,虚心若愚。\n\nThank you all very much.\n非常感谢你们。'], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}
删除后计数 15
{'ids': [], 'embeddings': None, 'metadatas': [], 'documents': [], 'uris': None, 'data': None, 'included': ['metadatas', 'documents']}
利用 OpenAI Embeddings

很多人喜欢利用 OpenAIEmbeddings,以下是怎样设置它。
#示例:chroma_openai.pyfrom langchain_openai import OpenAIEmbeddings# pip install langchain-chroma
from langchain_chroma import Chromaimport chromadbfrom langchain_text_splitters import CharacterTextSplitterfrom langchain_community.document_loaders import TextLoaderembeddings = OpenAIEmbeddings()persistent_client = chromadb.PersistentClient()new_client = chromadb.EphemeralClient()# 加载文档并将其分割成片段loader = TextLoader("../../resource/knowledge.txt", encoding="UTF-8")documents = loader.load()# 将其分割成片段text_splitter = CharacterTextSplitter(chunk_size=1500, chunk_overlap=0)docs = text_splitter.split_documents(documents)openai_lc_client = Chroma.from_documents(    docs, embeddings, client=new_client, collection_name="openai_collection")query = "Pixar公司是做什么的?"docs = openai_lc_client.similarity_search(query)print(docs
.page_content)


During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
其他功能

带分数的相似性搜索

返回的间隔分数是余弦间隔。因此,分数越低越好。
#示例:chroma_other.py
docs = db.similarity_search_with_score(query)
docs

#0.8513926863670349
(Document(metadata={'source': '../../resource/knowledge.txt'}
, page_content="During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.\n在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。"), 0.8513926863670349)
检索器选项

本节先容怎样在检索器中利用 Chroma 的差别选项。
MMR
除了在检索器对象中利用相似性搜索外,还可以利用 MMR(Maximal Marginal Relevance,最大边际相关性)是一种信息检索和文本摘要技能,用于在选择文档或文本片段时均衡相关性和多样性。其紧张目的是在检索结果中既包含与查询高度相关的内容,又避免结果之间的高度冗余。
MMR的作用

[*]进步结果的多样性:通过引入多样性,MMR可以避免检索结果中出现重复信息,从而提供更全面的答案。
[*]均衡相关性和新奇性:MMR在选择结果时,既思量与查询的相关性,也思量新信息的引入,以确保结果的多样性和覆盖面。
[*]减少冗余:通过避免选择与已选结果高度相似的文档,MMR可以减少冗余,进步信息的利用服从。
在检索器对象中利用MMR
在利用向量检索器(如FAISS)时,通常通过相似性搜索来查找与查询最相关的文档。然而,这种方法有时可能会返回很多相似的结果,导致信息冗余。MMR可以在这种情况下发挥作用,通过以下步调实现:

[*]计算相关性:首先,计算每个候选文档与查询的相似性得分。
[*]计算多样性:然后,计算每个候选文档与已选文档聚集的相似性得分。
[*]选择文档:在每一步选择一个文档,使得该文档在相关性和多样性之间达到最佳均衡。
#示例:chroma_other.py
retriever = db.as_retriever(search_type="mmr")
retriever.invoke(query)
page_content='During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
' metadata={'source': '../../resource/knowledge.txt'}
Weaviate

怎样利用 langchain-weaviate包在 LangChain 中开始利用 Weaviate 向量存储。
Weaviate 是一个开源的向量数据库。它答应您存储来自您喜爱的机器学习模子的数据对象和向量嵌入,并可以或许无缝地扩展到数十亿个数据对象。
官方文档:https://weaviate.io/developers/weaviate
要利用此集成,您需要运行一个 Weaviate 数据库实例。
最低版本

此模块需要 Weaviate1.23.7或更高版本。但是,我们发起您利用最新版本的 Weaviate。
毗连到 Weaviate

在本文中,我们假设您在http://localhost:8080上运行了一个当地的 Weaviate 实例,并且端口 50051 用于 gRPC 通讯。因此,我们将利用以下代码毗连到 Weaviate:
weaviate_client = weaviate.connect_to_local()
其他部署选项

Weaviate 可以以很多差别的方式进行部署,比方利用Weaviate Cloud Services (WCS)、Docker或Kubernetes。
假如您的 Weaviate 实例以其他方式部署,可以在此处阅读更多信息关于毗连到 Weaviate 的差别方式。您可以利用差别的辅助函数,或者创建一个自定义实例。
请注意,您需要一个 v4 客户端 API,它将创建一个 weaviate.WeaviateClient 对象。
认证

一些 Weaviate 实例,比方在 WCS 上运行的实例,启用了认证,比方 API 密钥和/或用户名+密码认证。
阅读客户端认证指南以获取更多信息,以及深入的认证配置页面。
安装

# 安装包
# %pip install -Uqq langchain-weaviate
# %pip install openai tiktoken langchain
环境设置

本文利用OpenAIEmbeddings,通过 OpenAI API,我们发起获取一个 OpenAI API 密钥,并将其作为名为OPENAI_API_KEY的环境变量导出。
完成后,您的 OpenAI API 密钥将被自动读取。假如您对环境变量不熟悉,可以在此处或此指南中阅读更多关于它们的信息。
配置Weaviate的WCD_DEMO_URL和WCD_DEMO_RO_KEY
setx WCD_DEMO_URL ""
setx WCD_DEMO_RO_KEY ""
https://i-blog.csdnimg.cn/img_convert/5c547e10e7838fe34b3e7144e6a26b01.png
用法

通过相似性查找对象

以下是一个示例,演示怎样通过查询查找与之相似的对象,从数据导入到查询 Weaviate 实例。
步调 1:数据导入

首先,我们将创建要添加到Weaviate的数据,方法是加载并分块长文本文件的内容。
from langchain_community.document_loaders import TextLoader
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter
现在,我们可以导入数据。要这样做,毗连到 Weaviate 实例,并利用天生的 weaviate_client 对象。比方,我们可以将文档导入如下所示:
#示例:weaviate_client.py
weaviate_client = weaviate.connect_to_weaviate_cloud(
    cluster_url=wcd_url,# Replace with your Weaviate Cloud URL
    auth_credentials=Auth.api_key(wcd_api_key),# Replace with your Weaviate Cloud key
    headers={'X-OpenAI-Api-key': openai_api_key}# Replace with your OpenAI API key
)
db = WeaviateVectorStore.from_documents(docs, embeddings, client=weaviate_client)
第二步:实行搜索

现在我们可以实行相似度搜索。这将返回与查询文本最相似的文档,基于存储在 Weaviate 中的嵌入和从查询文本天生的等效嵌入
#示例:weaviate_search.py# pip install -Uqq langchain-weaviate# pip install openai tiktoken langchainimport osimport weaviatefrom langchain_community.document_loaders import TextLoader
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter
from langchain_weaviate.vectorstores import WeaviateVectorStorefrom weaviate.classes.init import Authembeddings = OpenAIEmbeddings()# 加载文档并将其分割成片段loader = TextLoader("../../resource/knowledge.txt", encoding="UTF-8")documents = loader.load()# 将其分割成片段text_splitter = CharacterTextSplitter(chunk_size=1500, chunk_overlap=0)docs = text_splitter.split_documents(documents)# Best practice: store your credentials in environment variableswcd_url = os.environ["WCD_DEMO_URL"]wcd_api_key = os.environ["WCD_DEMO_RO_KEY"]openai_api_key = os.environ["OPENAI_API_KEY"]weaviate_client = weaviate.connect_to_weaviate_cloud(    cluster_url=wcd_url,# Replace with your Weaviate Cloud URL    auth_credentials=Auth.api_key(wcd_api_key),# Replace with your Weaviate Cloud key    headers={'X-OpenAI-Api-key': openai_api_key}# Replace with your OpenAI API key)db = WeaviateVectorStore.from_documents(docs, embeddings, client=weaviate_client)query = "Pixar公司是做什么的?"docs = db.similarity_search(query)print(docs
.page_content)


weaviate_client.close() During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
量化结果相似性

您可以选择检索相关性“分数”。这是一个相对分数,体现特定搜索结果在搜索结果池中的优劣程度。
请注意,这是相对分数,意味着不应用于确定相关性的阈值。但是,它可用于比力整个搜索结果集中差别搜索结果的相关性。
#示例:weaviate_similarity.py
query = "Pixar公司是做什么的?"
docs = db.similarity_search_with_score(query, k=5)
for doc in docs:
    print(f"{doc:.3f}", ":", doc.page_content[:100] + "...")
0.700 : During the next five years, I started a company named NeXT, another company named Pixar, and fell in...
0.337 : I was lucky – I found what I loved to do early in life. Woz and I started Apple in my parents garage...
0.271 : I really didn't know what to do for a few months. I felt that I had let the previous generation of e...
0.256 : I'm pretty sure none of this would have happened if I hadn't been fired from Apple. It was awful tas...
0.191 : Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its...


Qdrant

Qdrant先容

Qdrant(读作:quadrant /'kwɑdrənt/ n. 象限;象限仪;四分之一圆)是一个向量相似度搜索引擎。它提供了一个生产停当的服务,具有方便的 API 来存储、搜索和管理点 带有附加载荷的向量。Qdrant
专门支持扩展过滤功能,使其对各种神经网络或基于语义的匹配、分面搜索和其他应用非常有用。
官方文档:https://qdrant.tech/documentation/
以下展示了怎样利用与Qdrant向量数据库相关的功能。
有各种运行Qdrant的模式,取决于所选择的模式,会有一些眇小的差别。选项包括:-


[*]当地模式,无需服务器
[*]Qdrant 云<
请参阅安装说明。
%pip install --upgrade --quietlangchain-qdrant langchain-openai langchain
#示例:qdrant_local.py
from langchain_community.document_loaders import TextLoader
from langchain_openai import OpenAIEmbeddings
from langchain_qdrant import Qdrant
from langchain_text_splitters import CharacterTextSplitter
loader = TextLoader("../../resource/knowledge.txt", encoding="UTF-8")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1500, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
当地模式

Python 客户端答应您在当地模式下运行相同的代码,而无需运行 Qdrant 服务器。这对于测试和调试或者假如您计划仅存储少量向量非常有用。嵌入可能完全生存在内存中或者持久化在磁盘上。
内存中

对于一些测试场景和快速实验,您可能更喜欢仅将全部数据生存在内存中,因此当客户端被烧毁时数据会丢失 - 通常在脚本/笔记本的末尾。
#示例:qdrant_local.py
qdrant = Qdrant.from_documents(
    docs,
    embeddings,
    location=":memory:",# 本地模式,仅内存存储
    collection_name="my_documents",
)
磁盘存储

在不利用 Qdrant 服务器的当地模式下,还可以将您的向量存储在磁盘上,以便它们在运行之间持久化。
#示例:qdrant_disk.py
qdrant = Qdrant.from_documents(
    docs,
    embeddings,
    path="/tmp/local_qdrant",
    collection_name="my_documents",
)
相似度搜索

利用 Qdrant 向量存储的最简单场景是实行相似度搜索。在幕后,我们的查询将利用embedding_function对查询进行编码,并用于在 Qdrant 聚集中查找相似的文档。
query = "Pixar公司是做什么的?"
found_docs = qdrant.similarity_search(query)
print(found_docs
.page_content)
During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
Qdrant 云

假如您不想忙于管理基础办法,可以选择在 Qdrant 云上设置一个完全托管的 Qdrant 集群。包括一个永久免费的 1GB 集群供试用。利用托管版本与利用 Qdrant 的紧张区别在于,您需要提供 API 密钥以防止公开访问您的部署。该值也可以设置在QDRANT_API_KEY环境变量中。
url = "<---qdrant cloud cluster url here --->"
api_key = "<---api key here--->"
qdrant = Qdrant.from_documents(
    docs,
    embeddings,
    url=url,
    prefer_grpc=True,
    api_key=api_key,
    collection_name="my_documents",
)
Milvus

Milvus先容

Milvus 是一个数据库,用于存储、索引和管来由深度神经网络和其他机器学习(ML)模子天生的大规模嵌入向量。
官方文档:https://milvus.io/docs/overview.md
下面讲解怎样利用与 Milvus 向量数据库相关的功能。
配置环境变量MILVUS_API_URL和MILVUS_API_KEY
setx MILVUS_API_URL ""
setx MILVUS_API_KEY ""
zilliz:https://cloud.zilliz.com/
https://i-blog.csdnimg.cn/img_convert/4f787bdc2b8011372920f4fb4d952f39.png
要运行,您应该已经启动并运行了一个Milvus 实例。
#示例:milvus_zilliz.py#pip install --upgrade --quietpymilvusfrom langchain_community.document_loaders import TextLoaderfrom langchain_community.vectorstores import Milvusfrom langchain_openai import OpenAIEmbeddingsfrom langchain_text_splitters import CharacterTextSplitterfrom langchain_community.document_loaders import TextLoaderloader = TextLoader("../../resource/knowledge.txt", encoding="UTF-8")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1500, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
vector_db = Zilliz.from_documents(# or Milvus.from_documents
    docs,
    embeddings,
    #存储到collection_1中
    collection_name="collection_1",
    connection_args={"uri": os.getenv("MILVUS_API_URL"), "token": os.getenv("MILVUS_API_KEY")},
    #drop_old=True,# Drop the old Milvus collection if it exists
    auto_id=True,
)
query = "Pixar公司是做什么的?"
docs = vector_db.similarity_search(query)
print(docs
.page_content)


During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
总结



[*]下面是 Chroma、Weaviate、Qdrant 和 Milvus 四个向量数据库的功能对比
功能/特性ChromaWeaviateQdrantMilvus数据模子向量 + 元数据向量 + 元数据向量 + 元数据向量 + 元数据支持的索引类型HNSWHNSW, IVF, FlatHNSWIVF, HNSW, ANNOY, Flat扩展性高高高高及时性及时更新及时更新及时更新及时更新多样化查询向量相似性搜索向量相似性搜索 + 混合查询向量相似性搜索向量相似性搜索 + 混合查询分布式架构是是是是支持的语言Python, JavaScriptPython, Java, Go, TypeScriptPython, GoPython, Java, Go, Node.js社区支持活跃活跃活跃活跃开源许可证Apache 2.0BSD-3-ClauseApache 2.0Apache 2.0部署选项当地, 云当地, 云当地, 云当地, 云额外功能数据版本控制知识图谱集成, 模子管理集成向量处理工具数据管理工具, 集身分析工具 这些数据库在功能和特性上各有优势,选择合适的数据库应根据具体的应用需求和技能栈来决定。
FAISS, Pinecone, Lance Similarity search

FAISS

Faiss先容

Facebook AI Similarity Search (Faiss /Fez/) 是一个用于高效相似度搜索和麋集向量聚类的库。它包含了在任意大小的向量聚集中进行搜索的算法,以致可以处理可能无法完全放入内存的向量聚集。它还包含用于评估和参数调整的支持代码。
Faiss 官方文档:https://faiss.ai/
下面展示怎样利用与 FAISS向量数据库相关的功能。它将展示特定于此集成的功能。在学习完这些内容后,探索相关的用例页面可能会很有资助,以了解怎样将这个向量存储作为更大链条的一部门来利用。
设置

该集成位于langchain-community包中。我们还需要安装faiss包本身。我们还将利用 OpenAI 进行嵌入,因此需要安装这些要求。我们可以利用以下命令进行安装:
pip install -U langchain-community faiss-cpu langchain-openai tiktoken
请注意,假如您想利用启用了 GPU 的版本,也可以安装 faiss-gpu
设置 LangSmith 以得到最佳的可观测性也会很有资助(但不是必须的)。
# os.environ["LANGCHAIN_TRACING_V2"] = "true"
# os.environ["LANGCHAIN_API_KEY"] = ""
导入

在这里,我们将文档导入到向量存储中。
#示例:faiss_search.py# 假如您需要利用没有 AVX2 优化的 FAISS 进行初始化,请取消下面一行的解释# os.environ['FAISS_NO_AVX2'] = '1'from langchain_community.document_loaders import TextLoaderfrom langchain_community.vectorstores import FAISSfrom langchain_openai import OpenAIEmbeddingsfrom langchain_text_splitters import CharacterTextSplitterloader = TextLoader("../../resource/knowledge.txt", encoding="UTF-8")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1500, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
db = FAISS.from_documents(docs, embeddings)print(db.index.ntotal) 16
查询

现在,我们可以查询向量存储。有几种方法可以做到这一点。最常见的方法是利用similarity_search
#示例:faiss_search.py
query = "Pixar公司是做什么的?"
docs = db.similarity_search(query)
print(docs
.page_content)


During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
作为检索器

我们还可以将向量存储转换为 Retriever 类。这使我们可以或许轻松地在其他 LangChain 方法中利用它,这些方法紧张用于检索器。
#示例:faiss_retriever.py
retriever = db.as_retriever()
docs = retriever.invoke(query)
print(docs
.page_content)


During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
带分数的相似度搜索

还有一些 FAISS 特定的方法。其中之一是similarity_search_with_score,它答应您返回文档以及查询与它们之间的间隔分数。返回的间隔分数是 L2 间隔。因此,得分越低越好。
#示例:faiss_similarity.py
#返回文档以及查询与它们之间的距离分数。返回的距离分数是 L2 距离。因此,得分越低越好。
docs_and_scores = db.similarity_search_with_score(query)
print(docs_and_scores)
#还可以使用`similarity_search_by_vector`来搜索与给定嵌入向量相似的文档,该函数接受一个嵌入向量作为参数,而不是字符串。
embedding_vector = embeddings.embed_query(query)
docs_and_scores = db.similarity_search_by_vector(embedding_vector)
print(docs_and_scores)
[(Document(metadata={'source': '../../resource/knowledge.txt'}
, page_content="During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.\n在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个厥后成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在厥后的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技能在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起创建了一个幸福的家庭。"), 0.3155345), (Document(metadata={'source': '../../resource/knowledge.txt'}
, page_content='I was lucky – I found what I loved to do early in life. Woz and I started Apple in my parents garage when I was 20. We worked hard, and in 10 years Apple had grown from just the two of us in a garage into a billion company with over 4000 employees. We had just released our finest creation - the Macintosh - a year earlier, and I had just turned 30. And then I got fired. How can you get fired from a company you started? Well, as Apple grew we hired someone who I thought was very talented to run the company with me, and for the first year or so things went well. But then our visions of the future began to diverge and eventually we had a falling out. When we did, our Board of Directors sided with him. So at 30 I was out. And very publicly out. What had been the focus of my entire adult life was gone, and it was devastating.\n我非常荣幸,因为我在很早的时间就找到了我钟爱的东西。沃兹和我在二十岁的时间就在父母的车库内里开创了苹果公司。我们工作得很积极,十年之后,这个公司从那两个车库中的穷光蛋发展到了超过四千名的雇员、代价超过二十亿的大公司。在公司建立的第九年,我们刚刚发布了最好的产品,那就是 Macintosh。我也快要到三十岁了。在那一年,我被炒了鱿鱼。你怎么可能被你自己创立的公司炒了鱿鱼呢?嗯,在苹果快速成长的时间,我们雇用了一个很有天分的家伙和我一起管理这个公司,在最初的几年,公司运转的很好。但是厥后我们对未来的见解发生了分歧, 最终我们吵了起来。当争吵不可开交的时间,董事会站在了他的那一边。所以在三十岁的时间,我被炒了。在这么多人的眼皮下我被炒了。在而立之年,我生命的全部支柱离自己远去,这真是毁灭性的打击。'), 0.444816
23), (Document(metadata={'source': '../../resource/knowledge.txt'}
, page_content="I really didn't know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down - that I had dropped the baton as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and I even thought about running away from the valley. But something slowly began to dawn on me – I still loved what I did. The turn of events at Apple had not changed that one bit. I had been rejected, but I was still in love. And so I decided to start over.\n在最初的几个月里,我真是不知道该做些什么。我把从前的创业豪情给丢了,我以为自己让与我一同创业的人都很沮丧。我和 David Pack 和 Bob Boyce 见面,并试图向他们道歉。我把事情弄得糟糕透顶了。但是我渐渐发现了曙光,我仍旧喜爱我从事的这些东西。苹果公司发生的这些事情丝毫的没有改变这些,一点也没有。我被驱逐了,但是我仍旧钟爱它。所以我决定重新再来。\n\nI didn't see it then, but it turned out that getting fired from Apple was the best thing that could have ever happened to me. The heaviness of being successful was replaced by the lightness of being a beginner again, less sure about everything. It freed me to enter one of the most creative periods of my life.\n我当时没有觉察,但是事后证实,从苹果公司被炒是我这辈子发生的最棒的事情。因为,作为一个成功者的极乐感觉被作为一个创业者的轻松感觉所重新代替:对任何事情都不那么特别看重。这让我以为如此自由,进入了我生命中最有创造力的一个阶段。"), 0.46826816
), (Document(metadata={'source': '../../resource/knowledge.txt'}
, page_content="I'm pretty sure none of this would have happened if I hadn't been fired from Apple. It was awful tasting medicine, but I guess the patient needed it. Sometimes life hits you in the head with a brick. Don't lose faith. I'm convinced that the only thing that kept me going was that I loved what I did. You've got to find what you love. And that is as true for your work as it is for your lovers. Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven't found it yet, keep looking. Don't settle. As with all matters of the heart, you'll know when you find it. And, like any great relationship, it just gets better and better as the years roll on. So keep looking until you find it. Don't settle.\n我可以非常肯定,假如我不被苹果公司开除的话,这其中一件事情也不会发生的。这个良药的味道实在是太苦了,但是我想病人需要这个药。有些时间,生活会拿起一块砖头向你的脑袋上猛拍一下。不要失去信心,我很清晰唯一使我一直走下去的,就是我做的事情令我无比钟爱。你需要去找到你所爱的东西,对于工作是如此,对于你的爱人也是如此。你的工作将会占据生活中很大的一部门。你只有信赖自己所做的是伟大的工作,你才能怡然得意。假如你现在还没有找到,那么继续找、不要停下来、经心全意的去找,当你找到的时间你就会知道的。就像任何真诚的关系,随着光阴的流逝只会越来越紧密。所以继续找,直到你找到它,不要停下来。\n\nMy third story is about death.\n我的第三个故事是关于殒命的。"), 0.4740282)] 生存和加载

您还可以生存和加载 FAISS 索引。这样做很有用,因为您不必每次利用时都重新创建它。
#示例:faiss_save.py
#保存索引
db.save_local("faiss_index")
#读取索引
new_db = FAISS.load_local("faiss_index", embeddings,allow_dangerous_deserialization=True)
docs = new_db.similarity_search(query)
docs
page_content='During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
' metadata={'source': '../../resource/knowledge.txt'}
Pinecone

Pinecone先容

Pinecone (/ˈpaɪnˌkon/ n. 松果;松球)是一个功能广泛的向量数据库。
官方文档:https://docs.pinecone.io/guides/get-started/quickstart
下面展示了怎样利用与 Pinecone向量数据库相关的功能。
设置以下环境变量以便在本文档中进行操纵:


[*]OPENAI_API_KEY:您的 OpenAI API 密钥,用于利用OpenAIEmbeddings
%pip install --upgrade --quiet\
    langchain-pinecone \
    langchain-openai \
    langchain \
    pinecone-notebooks
配置PINECONE_API_KEY 环境变量
setx PINECONE_API_KEY ""
https://i-blog.csdnimg.cn/img_convert/7a6a9157b18ee946b9f5d027e13e6a40.png
首先,让我们将我们的文本库拆分身分块的 docs
#示例:pinecone_search.pyfrom langchain_community.document_loaders import TextLoader
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter
loader = TextLoader("../../resource/knowledge.txt",encoding="UTF-8")documents = loader.load()text_splitter = CharacterTextSplitter(chunk_size=1500, chunk_overlap=0)docs = text_splitter.split_documents(documents)embeddings = OpenAIEmbeddings() 新创建的 API 密钥已存储在PINECONE_API_KEY环境变量中。我们将利用它来设置 Pinecone 客户端。
import os
pinecone_api_key = os.environ.get("PINECONE_API_KEY")
pinecone_api_key
import time
from pinecone import Pinecone, ServerlessSpec
pc = Pinecone(api_key=pinecone_api_key)
接下来,让我们毗连到您的 Pinecone 索引。假如名为index_name的索引不存在,将会被创建。
import time
index_name = "langchain-index"# 如果需要,可以更改
existing_indexes = for index_info in pc.list_indexes()]
if index_name not in existing_indexes:
    pc.create_index(
      name=index_name,
      dimension=1536,
      metric="cosine",
      spec=ServerlessSpec(cloud="aws", region="us-east-1"),
    )
    while not pc.describe_index(index_name).status["ready"]:
      time.sleep(1)
index = pc.Index(index_name)
现在我们的 Pinecone 索引已经设置好,我们可以利用PineconeVectorStore.from_documents将这些分块的文档作为内容进行更新。
from langchain_pinecone import PineconeVectorStore
docsearch = PineconeVectorStore.from_documents(docs, embeddings, index_name=index_name)
query = "Pixar"docs = docsearch.similarity_search(query)print(docs
.page_content)


During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
检察index创建:https://app.pinecone.io
Lance

LanceDB先容

Lance( /læns/ 长矛;执矛兵士;[医]柳叶刀)是一个基于持久存储构建的用于向量搜索的开源数据库,极大地简化了嵌入式的检索、过滤和管理。完全开源。
官网:https://lancedb.com/
官方文档:https://lancedb.github.io/lancedb/basic/
下面展示怎样利用与 LanceDB向量数据库相关的功能,基于 Lance 数据格式。
! pip install -U langchain-openai
! pip install lancedb
#示例:lance_search.py
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import LanceDB
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter

loader = TextLoader("../../resource/knowledge.txt", encoding="UTF-8")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1500, chunk_overlap=0)
documents = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
向量存储

docsearch = LanceDB.from_documents(documents, embeddings)query = "Pixar公司是做什么的?"docs = docsearch.similarity_search(query)print(docs
.page_content)


During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I retuned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
在接下来的五年里, 我创立了一个名叫 NeXT 的公司,还有一个叫Pixar的公司,然后和一个后来成为我妻子的优雅女人相识。Pixar 制作了世界上第一个用电脑制作的动画电影——“”玩具总动员”,Pixar 现在也是世界上最成功的电脑制作工作室。在后来的一系列运转中,Apple 收购了NeXT,然后我又回到了苹果公司。我们在NeXT 发展的技术在 Apple 的复兴之中发挥了关键的作用。我还和 Laurence 一起建立了一个幸福的家庭。
print(docs
.metadata) {'source': '../../resource/knowledge.txt'}
此外,要探索表格,可以将其加载到数据框中或将其生存在 csv 文件中:
tbl = docsearch.get_table()
print("tbl:", tbl)
pd_df = tbl.to_pandas()
pd_df.to_csv("docsearch.csv", index=False)
tbl: LanceTable(connection=LanceDBConnection(D:\tmp\lancedb), name="vectorstore")
总结

下面是 Pinecone、FAISS 和 Lance 三个向量数据库的功能对比表格:
功能/特性PineconeFAISSLance数据模子向量 + 元数据向量向量 + 元数据支持的索引类型HNSWIVF, HNSW, PQ, OPQHNSW扩展性高中高及时性及时更新批量处理及时更新多样化查询向量相似性搜索向量相似性搜索向量相似性搜索分布式架构是否是支持的语言Python, JavaScript, GoPython, C++Python社区支持活跃活跃新兴开源许可证专有MITApache 2.0部署选项云当地当地, 云额外功能自动扩展, 数据管理工具高度优化的搜索性能数据版本控制, 集身分析工具 这些数据库在功能和特性上各有优势,选择合适的数据库应根据具体的应用需求和技能栈来决定。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【记载一放学习】Embedding 与向量数据库