在上一篇文章中,我们了解了什么是向量数据库,并以开源向量数据库Weaviate为例,介绍了它的使用安装和基本使用方法。
本文将继续回到LangChain框架的用法上,详细分析在LangChain中,如何使用VectorStore组件将向量数据存储到向量数据库中。
文中所有示例代码:github.com/wzycoding/l...
一、VectorStore组件介绍
对非结构化数据的存储与检索,最常用的方法是先将文本进行嵌入,转换为向量后存储到向量数据库中;在查询时,同样将查询文本嵌入生成向量,再将该向量传递给向量数据库,由数据库完成后续的相似度计算与检索过程。
在 LangChain 中,这一过程由顶层接口 VectorStore 统一管理,不同类型的向量数据库只需实现该接口中的抽象方法即可完成集成。VectorStore 接口提供了多个常用方法,例如:
add_texts
:将文本列表转换为向量,并存储到向量数据库。add_documents
:将文档列表转换为向量,并存储到向量数据库。as_retriever
:返回向量数据库初始化的检索器。similarity_search_with_relevance_scores
:进行相似性检索,返回文档及其相关性得分(范围在[0, 1]之间)。delete
:根据向量id删除向量数据from_texts
:传入文本列表、元数据信息、文本嵌入模型,返回创建好的VectorStore。
VectorStore
接口,常用的实现类如下:
类名 | 描述 |
---|---|
InMemoryVectorStore | 基于内存实现的向量数据库 |
ElasticsearchStore | Elasticsearch为基础实现的向量数据库 |
TencentVectorDB | 腾讯向量数据库,当前类还在community包下,没有独立出来 |
PineconeVectorStore | Pinecone向量数据库 |
WeaviateVectorStore | Weaviate向量数据库 |
二、 WeaviateVectorStore数据存储
WeaviateVectorStore 是 VectorStore 接口的一个实现类,下面将以它为例介绍 VectorStore 的用法。在使用 WeaviateVectorStore 之前,需要先安装 langchain-weaviate
依赖:
bash
pip install langchain-weaviate==0.0.2
执行命令,生成依赖版本快照
bash
pip freeze > requirements.txt
接下来,先展示如何使用 WeaviateVectorStore 进行数据存储。示例程序如下:在构造 WeaviateVectorStore 对象时,需要传入 Weaviate Client 对象、text_key
、文本嵌入对象以及 Weaviate 集合名称。其中,text_key
表示存储原文的 key 名,这里命名为 text_key
。
Weaviate 数据库支持将文本片段的原文直接保存到 Weaviate 中,这样在检索时就可以直接获取原文,避免了通过元数据中的 segment_id
再去关系型数据库查询的额外操作。这种方式适用于文本数量较少的情况;当文本数量较大时,建议将原文保存到关系型数据库中,更便于管理和维护。
构建好 WeaviateVectorStore 后,将准备好的文本信息和元数据信息通过 add_texts()
方法添加到向量数据库中。WeaviateVectorStore 会使用传入的文本嵌入模型自动对文本进行嵌入,并在对象创建成功后返回对应的 UUID 列表。
python
import dotenv
import weaviate
from langchain_openai import OpenAIEmbeddings
from langchain_weaviate import WeaviateVectorStore
# 读取env配置
dotenv.load_dotenv()
# 1.创建Weaviate客户端
client = weaviate.connect_to_local(
host="localhost",
port=8080,
grpc_port=50051,
)
# 2.创建文本嵌入模型
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
# 3.创建Weaviate向量数据库
vector_store = WeaviateVectorStore(
client=client,
text_key="text_key",
embedding=embeddings,
index_name="Database"
)
# 4.准备好要保存的文本数据、元数据
texts = [
"光明科技公司总部位于北京市朝阳区,是一家专注于人工智能与大数据分析的高新技术企业,现有员工500人。",
"公司董事长张三,男,40岁,籍贯黑龙江漠河市,毕业于清北大学,曾在硅谷工作十年,现负责公司战略规划与重大项目决策。",
"总经理李四,男,38岁,江苏南京人,拥有十五年软件工程经验,主导过多个国家重点科技项目。",
"副总经理王五,男,35岁,四川成都人,负责公司运营管理与市场拓展。",
"技术部拥有120名开发人员,主要从事机器学习模型训练、数据挖掘、云计算平台研发等工作。",
"光明科技公司在2024年获得国家科技进步二等奖,并与多所高校建立产学研合作关系。",
"公司设有技术部、市场部、运营部和人力资源部,其中技术部是公司的核心部门。",
"张三不仅担任董事长,还热衷公益事业,曾多次捐助贫困地区教育项目。",
"李四毕业于上海交通大学计算机系,擅长分布式系统与云架构设计。",
"王五在加入光明科技公司前,曾任某知名互联网企业运营总监,具有丰富的企业管理经验。"
]
metadatas = [
{"segment_id": "1"},
{"segment_id": "2"},
{"segment_id": "3"},
{"segment_id": "4"},
{"segment_id": "5"},
{"segment_id": "6"},
{"segment_id": "7"},
{"segment_id": "8"},
{"segment_id": "9"},
{"segment_id": "10"},
]
# 5.存储数据到向量数据库
uuids = vector_store.add_texts(texts, metadatas)
# 6.打印返回的uuid列表
print(f"存储到Weaviate向量数据库的对象的uuid列表:{uuids}")
执行结果如下,返回了创建对象的uuid列表。
python
存储到Weaviate向量数据库的对象的uuid列表:['61adde43-8fac-4ed9-82ae-79b73b7eaf94', 'a9864354-80b5-4426-98c4-30e0da4e5cd7', 'f8b3f2e5-dda8-493d-9e73-00763dd5e274', '5dbf58ab-5db8-4e7a-94aa-d1d2dba0d9af', '9d12f56c-96f4-4867-8ee9-a5f05757dfc8', '63f94a88-160e-4b1e-b049-245af8f20962', 'df850306-45ae-4d70-ab48-01e00a652a7a', '61634caf-e65c-4b4c-a1b5-4d44d855d70a', '8b0e22f1-652f-4ef5-b5a1-3be03673d833', '0529d236-9253-4a22-a413-72798c5f4f27']
三、WeaviateVectorStore数据检索
在上面的示例程序中,我们将文本信息和元数据信息都保存到了数据库中。接下来,使用 VectorStore的similarity_search_with_relevance_scores()
方法进行相似性检索。在调用该方法时,传入查询文本 query
,并指定 k=3
,即返回匹配分数最高的三条数据(k
的默认值为 4)。
python
import dotenv
import weaviate
from langchain_openai import OpenAIEmbeddings
from langchain_weaviate import WeaviateVectorStore
# 读取env配置
dotenv.load_dotenv()
# 1.创建Weaviate客户端
client = weaviate.connect_to_local(
host="localhost",
port=8080,
grpc_port=50051,
)
# 2.创建文本嵌入模型
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
# 3.创建Weaviate向量数据库
vector_store = WeaviateVectorStore(
client=client,
text_key="text_key",
embedding=embeddings,
index_name="Database"
)
# 4、进行数据检索
search_result = vector_store.similarity_search_with_relevance_scores(query="光明公司的董事长是谁?", k=3)
# 5、打印检索结果
for document, score in search_result:
print(f"文档内容:{document.page_content}")
print(f"文档元数据信息:{document.metadata}")
print(f"相关度得分:{score}")
print("=================================")
执行结果如下,返回了3个与查询文本最相关的文本信息。
python
文档内容:王五在加入光明科技公司前,曾任某知名互联网企业运营总监,具有丰富的企业管理经验。
文档元数据信息:{'segment_id': '10', 'text': None}
相关度得分:0.6681877695251427
=================================
文档内容:公司董事长张三,男,40岁,籍贯黑龙江漠河市,毕业于清北大学,曾在硅谷工作十年,现负责公司战略规划与重大项目决策。
文档元数据信息:{'segment_id': '2', 'text': None}
相关度得分:0.6405468061607247
=================================
文档内容:光明科技公司总部位于北京市朝阳区,是一家专注于人工智能与大数据分析的高新技术企业,现有员工500人。
文档元数据信息:{'segment_id': '1', 'text': None}
相关度得分:0.6342571121423872
=================================
四、总结
本文详细介绍了 LangChain 的 VectorStore
接口,VectorStore
提供了add_texts
、similarity_search_with_relevance_scores
、delete
等常用方法,该接口有多种数据库(Weaviate、Pinecone、Elasticsearch 等)的实现类。
接下来,以WeaviateVectorStore介绍了如何进行向量数据的存储,在存储完成后,使用similarity_search_with_relevance_scores
进行带得分的相似性检索,分数越高表示越相关,检索结果同时返回文档内容与元数据,方便后续处理。
通过本文可以快速掌握 LangChain的VectorStore
组件,以及LangChain如何集成 Weaviate 的基本流程,从数据存储、向量化,到检索查询,掌握完整的数据存储检索流程,在下一篇文章中,将会继续介绍LangChain中Retrievers检索器组件的用法,欢迎持续关注。