TCVectorDB 向量数据库:Embedding数据导入与查询及由于Metadata未被正确设置导致无法记录原文信息以及检索时创建 `Document` 文档失败的Bug修复。

1. 内置 Embedding 导入数据与查询

在这里插入图片描述

TCVectorDB 向量数据库内置了多种 Embedding 模型,支持五种嵌入方式。以下是各模型的详细信息:

模型名适用语言类型维度最大 Token 数量分类得分聚类得分检索得分
bge-base-zh(推荐)中文76851267.0647.6469.53
m3e-base中文76851267.5247.6856.91
text2vec-large-chinese中文102451260.6630.0241.94
e5-large-v2英文102451275.2444.4950.56
multilingual-e5-base多语言76851463.3540.6840.68

使用内置的 Embedding 模型可以显著提高处理速度(目前,LangChain 封装的 TCVectorDB 使用内置 Embedding 没有已知问题),但也存在一些限制,特别是在迁移数据库时,所有文本需要重新生成 Embedding。

2. 内置 Embedding 模型文档说明&计费

有关内置 Embedding 模型的详细文档与计费信息,请参阅以下文档:

3. 代码示例

import os

import dotenv
from langchain_community.vectorstores import TencentVectorDB
from langchain_community.vectorstores.tencentvectordb import (
    ConnectionParams,
)
from langchain_openai import OpenAIEmbeddings

dotenv.load_dotenv()

embedding = OpenAIEmbeddings(model="text-embedding-3-small")
db = TencentVectorDB(
    embedding=None,
    connection_params=ConnectionParams(
        url=os.environ.get("TC_VECTOR_DB_URL"),
        username=os.environ.get("TC_VECTOR_DB_USERNAME"),
        key=os.environ.get("TC_VECTOR_DB_KEY"),
        timeout=int(os.environ.get("TC_VECTOR_DB_TIMEOUT")),
    ),
    database_name=os.environ.get("TC_VECTOR_DB_DATABASE"),
    collection_name="dataset-builtin",
)

texts = [
    "笨笨是一只很喜欢睡觉的猫咪",
    "我喜欢在夜晚听音乐,这让我感到放松。",
    "猫咪在窗台上打盹,看起来非常可爱。",
    "学习新技能是每个人都应该追求的目标。",
    "我最喜欢的食物是意大利面,尤其是番茄酱的那种。",
    "昨晚我做了一个奇怪的梦,梦见自己在太空飞行。",
    "我的手机突然关机了,让我有些焦虑。",
    "阅读是我每天都会做的事情,我觉得很充实。",
    "他们一起计划了一次周末的野餐,希望天气能好。",
    "我的狗喜欢追逐球,看起来非常开心。",
]

ids = db.add_texts(texts)
print("添加文档id列表:", ids)

print(db.similarity_search_with_score("我养了一只猫,叫笨笨"))

输出示例

添加文档id列表: ['1721204162283324200-8452797147690134545-0', '1721204162283324200-4748609318240602995-1', '1721204162283324200-5687737768520280782-2', '1721204162283324200--327905253905429573-3', '1721204162283324200--4217514370195306218-4', '1721204162283324200-5510932568003309936-5', '1721204162283324200-7945499047074485108-6', '1721204162283324200-8077162730065074156-7', '1721204162283324200-36196153077512649-8', '1721204162283324200-3472252428185052217-9']

[(Document(page_content='笨笨是一只很喜欢睡觉的猫咪'), 0.874507), (Document(page_content='我的狗喜欢追逐球,看起来非常开心。'), 0.757709), (Document(page_content='猫咪在窗台上打盹,看起来非常可爱。'), 0.748665), (Document(page_content='昨晚我做了一个奇怪的梦,梦见自己在太空飞行。'), 0.735823)]

4. 外部 Embedding 导入数据与查询

除了使用内置的 Embedding 模型,TCVectorDB 也支持自定义文本嵌入模型。然而,在 LangChain 中封装的 TencentVectorDB 存在一个已知的 bug。当使用外部 Embedding 模型时,必须进行以下配置:

  1. 配置 meta_fields 属性: 指定需要存储的元数据字段。
  2. 指定字段名称为 text: 确保 metadatas 中包含 text 字段,这样向量数据库才能记录原文信息。

如果未配置 meta_fields 或未添加 text 字段,metadata 中的所有字段将不会被保存。这会导致在检索操作时,由于找不到原文信息而无法创建 Document 文档,从而引发错误。

4.1 示例配置
# 示例代码(请根据实际需求调整)
from some_module import TencentVectorDB

# 初始化腾讯向量数据库实例
tencent_vdb = TencentVectorDB(...)

# 设置 meta_fields 属性
meta_fields = ['text']  # 确保 'text' 字段被包含

# 添加文本和元数据
metadatas = [{'text': '原文本内容', '其他字段': '其他值'}]
embeddings = [...]  # 自定义的嵌入向量

# 添加数据到数据库
tencent_vdb.add_vectors(embeddings, metadatas, meta_fields=meta_fields)

5. Bug 源码分析

TencentVectorDB 的实现中,如果 meta_fields 未被正确设置,metadata 中的字段将不会被存储。这是导致无法记录原文信息的原因,因此在进行检索时创建 Document 文档会失败。

为了避免这个问题,请确保在使用自定义 Embedding 模型时,正确配置 meta_fields 并包含 text 字段。

了解更多关于该问题的详细信息和解决方案,请参考LangChain 文档。

# langchain_community/vectorstores/tencentvectordb.py->TencentVectorDB::add_texts
def add_texts(
    self,
    texts: Iterable[str],
    metadatas: Optional[List[dict]] = None,
    timeout: Optional[int] = None,
    batch_size: int = 1000,
    ids: Optional[List[str]] = None,
    **kwargs: Any,
) -> List[str]:
    ...
    if embeddings:
        doc_attrs["vector"] = embeddings[id]
    else:
        doc_attrs["text"] = texts[id]
    ...

Bug修复示例

import os

import dotenv
from langchain_community.vectorstores import TencentVectorDB
from langchain_community.vectorstores.tencentvectordb import (
    ConnectionParams,
    MetaField,
    META_FIELD_TYPE_STRING,
)
from langchain_openai import OpenAIEmbeddings

dotenv.load_dotenv()

embedding = OpenAIEmbeddings(model="text-embedding-3-small")
db = TencentVectorDB(
    embedding=embedding,
    connection_params=ConnectionParams(
        url=os.environ.get("TC_VECTOR_DB_URL"),
        username=os.environ.get("TC_VECTOR_DB_USERNAME"),
        key=os.environ.get("TC_VECTOR_DB_KEY"),
        timeout=int(os.environ.get("TC_VECTOR_DB_TIMEOUT")),
    ),
    database_name=os.environ.get("TC_VECTOR_DB_DATABASE"),
    collection_name="dataset-external",
    meta_fields=[
        # 配置text字段,防止LangChain在检索时,找不到字段构建Document文档,从而触发错误
        MetaField(name="text", data_type=META_FIELD_TYPE_STRING),
    ]
)

texts = [
    "笨笨是一只很喜欢睡觉的猫咪",
    "我喜欢在夜晚听音乐,这让我感到放松。",
    "猫咪在窗台上打盹,看起来非常可爱。",
    "学习新技能是每个人都应该追求的目标。",
    "我最喜欢的食物是意大利面,尤其是番茄酱的那种。",
    "昨晚我做了一个奇怪的梦,梦见自己在太空飞行。",
    "我的手机突然关机了,让我有些焦虑。",
    "阅读是我每天都会做的事情,我觉得很充实。",
    "他们一起计划了一次周末的野餐,希望天气能好。",
    "我的狗喜欢追逐球,看起来非常开心。",
]
# 将原始文本数据合并到metadata中,
metadata = [{"text": text, "page": index} for index, text in enumerate(texts)]

ids = db.add_texts(texts, metadata)
print("添加文档id列表:", ids)

print(db.similarity_search("我养了一只猫,叫笨笨"))

输出内容

添加文档id列表: ['1721204290046443100--7979142186803955240-0', '1721204290046443100--2991801275249710134-1', '1721204290046443100-7229055024046586038-2', '1721204290046443100-6820010242590464795-3', '1721204290046443100-1761951776563722534-4', '1721204290046443100-7105227574091896456-5', '1721204290046443100-385681627517092469-6', '1721204290046443100-2611196434988287836-7', '1721204290046443100-5925412479147078471-8', '1721204290046443100--5880598133876375674-9']

[Document(page_content='笨笨是一只很喜欢睡觉的猫咪', metadata={'text': '笨笨是一只很喜欢睡觉的猫咪'}), Document(page_content='猫咪在窗台上打盹,看起来非常可爱。', metadata={'text': '猫咪在窗台上打盹,看起来非常可爱。'}), Document(page_content='我的狗喜欢追逐球,看起来非常开心。', metadata={'text': '我的狗喜欢追逐球,看起来非常开心。'}), Document(page_content='我的手机突然关机了,让我有些焦虑。', metadata={'text': '我的手机突然关机了,让我有些焦虑。'})]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值