问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

将数据模型序列化到不同存储以及从不同存储进行序列化(预览版)

创作时间:
作者:
@小白创作中心

将数据模型序列化到不同存储以及从不同存储进行序列化(预览版)

引用
1
来源
1.
https://learn.microsoft.com/zh-cn/semantic-kernel/concepts/vector-store-connectors/serialization?pivots=programming-language-csharp

为了使数据模型定义为类或要存储在数据库中的定义,需要序列化为数据库可以理解的格式。
可通过两种方式完成,可以使用语义内核提供的内置序列化或提供自己的序列化逻辑。
以下两个关系图显示了数据模型在与存储模型之间进行序列化和反序列化的过程。

序列化流(用于 Upsert)

反序列化流(用于获取和搜索)

标有 *(在这两个关系图中)的步骤由特定连接器的开发人员实现,并且对于每个商店都是不同的。 标记为 ** 的步骤(在这两个关系图中)都作为记录上的方法提供,或者作为记录定义的一部分提供,这始终由用户提供,有关详细信息,请参阅直接序列化。

(反)序列化方法

直接序列化(从数据模型到存储模型)

直接序列化是确保完全控制模型序列化方式和优化性能的最佳方式。 缺点是,它特定于一个数据存储,因此,在使用时,与采用相同数据模型的不同存储之间切换并不容易。

可以通过在数据模型中实现遵循
SerializeMethodProtocol
协议的方法,或者将遵循
SerializeFunctionProtocol
的函数添加到记录定义中,这两种方法都可以在
semantic_kernel/data/vector_store_model_protocols.py
中找到。

当其中一个函数存在时,它将用于将数据模型直接序列化到存储模型。

你甚至可以只实现两种方法中的一种,并使用内置的(反)序列化处理另一个方向。例如,当处理一个不在你控制范围内创建的集合时,这可能会非常有用,并且你需要对反序列化的方式进行一些定制(而且无论如何也无法进行更新插入操作)。

内置序列化和反序列化(数据模型到字典对象、字典对象到存储模型,反之亦然)

内置序列化首先将数据模型转换为字典,然后将其序列化为存储理解的模型,对于每个存储区(不同且定义为内置连接器的一部分)来完成。 反序列化按相反的顺序完成。

序列化步骤 1:数据模型到字典

根据你拥有的数据模型类型,这些步骤以不同的方式完成。 可通过四种方式尝试将数据模型序列化为字典:

  1. 定义上的
    to_dict
    方法(与数据模型to_dict属性一致,遵循
    ToDictFunctionProtocol

  2. 检查记录是否为
    ToDictMethodProtocol
    并使用
    to_dict
    方法

  3. 检查记录是否为 Pydantic 模型并使用模型的
    model_dump
    ,有关详细信息,请参阅以下说明。

  4. 遍历定义中的字段并创建字典

序列化步骤 2:字典储存模型

连接器必须提供一种方法,以便将字典转换为存储模型。 这由连接器的开发人员完成,对于每个商店都是不同的。

反序列化步骤 1:将模型存储到字典

连接器必须提供一种方法,以便将存储模型转换为字典。 这由连接器的开发人员完成,对于每个商店都是不同的。

反序列化步骤 2:字典到数据模型

反序列化按相反的顺序完成,它会尝试以下选项:

  1. 定义中的
    from_dict
    方法(与数据模型的 from_dict 属性对齐,遵循
    FromDictFunctionProtocol
    )。

  2. 检查记录是否为
    FromDictMethodProtocol
    并使用
    from_dict
    方法

  3. 检查记录是否为 Pydantic 模型并使用模型的
    model_validate
    ,有关详细信息,请参阅以下说明。

  4. 循环遍历定义中的字段并设置其值,然后将这个字典作为命名参数传递给数据模型的构造函数(除非数据模型本身是一个字典,在这种情况下,它将按原样返回)。

注意

将 Pydantic 与内置序列化配合使用

使用 Pydantic BaseModel 定义模型时,它将使用
model_dump

model_validate
方法将数据模型序列化和反序列化到听写。 这是通过使用不带任何参数的 model_dump 方法来完成的,如果您希望对此进行控制,建议在您的数据模型上实现
ToDictMethodProtocol
,因为系统会优先尝试该方法。

矢量的序列化

在数据模型中有矢量时,它需要是浮点列表或 ints 列表,因为这是大多数存储所需的,如果希望类以不同的格式存储向量,则可以使用
serialize_function
注释中
deserialize_function
定义的和
VectorStoreRecordVectorField
定义。 例如,对于 numpy 数组,可以使用以下注释:

import numpy as np
vector: Annotated[
    np.ndarray | None,
    VectorStoreRecordVectorField(
        dimensions=1536,
        serialize_function=np.ndarray.tolist,
        deserialize_function=np.array,
    ),
] = None  

如果您确实使用可以处理原生 numpy 数组的矢量存储,并且不希望它们来回转换,您应该为模型和该存储建立直接序列化和反序列化方法。

注意

仅在使用内置序列化时才会用到它,而使用直接序列化时,你可以以任何方式处理向量。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号