Sérialisation de votre modèle de données vers et depuis différents magasins (préversion)
Pour que votre modèle de données soit stocké dans une base de données, il doit être converti dans un format que la base de données peut comprendre. Différentes bases de données nécessitent différents schémas et formats de stockage. Certains ont un schéma strict qui doit être respecté, tandis que d’autres autorisent le schéma à être défini par l’utilisateur.
Options de mappage
Les connecteurs de stockage de vecteurs fournis par le noyau sémantique offrent plusieurs façons de réaliser ce mappage.
Mappeurs intégrés
Les connecteurs de stockage de vecteurs fournis par le Noyau Sémantique ont des mappeurs intégrés qui associeront votre modèle de données entre votre modèle de données et les schémas de base de données. Consultez la page pour chaque connecteur pour plus d’informations sur la façon dont les mappeurs intégrés mappent les données de chaque base de données.
Mappeurs personnalisés
Les connecteurs de magasin de vecteurs fournis par le noyau sémantique prennent en charge la possibilité de fournir des mappeurs personnalisés en combinaison avec un VectorStoreRecordDefinition
. Dans ce cas, le VectorStoreRecordDefinition
peut différer du modèle de données fourni.
Le VectorStoreRecordDefinition
est utilisé pour définir le schéma de base de données, tandis que le modèle de données est utilisé par le développeur pour interagir avec le magasin vectoriel.
Un mappeur personnalisé est requis dans ce cas pour mapper du modèle de données au schéma de base de données personnalisé défini par l'VectorStoreRecordDefinition
.
Pourboire
Consultez Comment créer un mappeur personnalisé pour un connecteur Vector Store pour obtenir un exemple sur la création de votre propre mappeur personnalisé.
Pour que votre modèle de données soit défini comme une classe , soit comme une définition à stocker dans une base de données, il doit être sérialisé dans un format que la base de données peut comprendre.
Il existe deux façons de procéder, soit à l’aide de la sérialisation intégrée fournie par le noyau sémantique, soit en fournissant votre propre logique de sérialisation.
Les deux diagrammes suivants montrent les flux pour la sérialisation et la désérialisation des modèles de données vers et depuis un modèle de magasin.
Flux de sérialisation (utilisé dans Upsert)
Flux de désérialisation (utilisé dans Get and Search)
Les étapes marquées avec * (dans les deux diagrammes) sont implémentées par le développeur d’un connecteur spécifique et sont différentes pour chaque magasin. Les étapes marquées avec ** (dans les deux diagrammes) sont fournies sous la forme d’une méthode sur un enregistrement ou dans le cadre de la définition d’enregistrement, celle-ci est toujours fournie par l’utilisateur, consultez de sérialisation directe pour plus d’informations.
Approches de (dé)sérialisation
Sérialisation directe (modèle de données pour stocker le modèle)
La sérialisation directe est la meilleure façon de garantir un contrôle total sur la façon dont vos modèles sont sérialisés et pour optimiser les performances. L’inconvénient est qu’il est spécifique à un magasin de données, et par conséquent, lors de l’utilisation de ce paramètre, il n’est pas aussi facile de basculer entre différents magasins avec le même modèle de données.
Vous pouvez l’utiliser en implémentant une méthode qui suit le protocole SerializeMethodProtocol
dans votre modèle de données ou en ajoutant des fonctions qui suivent les SerializeFunctionProtocol
à votre définition d’enregistrement, les deux sont disponibles dans semantic_kernel/data/vector_store_model_protocols.py
.
Lorsque l’une de ces fonctions est présente, elle est utilisée pour sérialiser directement le modèle de données vers le modèle de magasin.
Vous pouvez même n'implémenter qu'un des deux et utiliser la (dé)sérialisation intégrée dans l'autre sens, cela peut par exemple être utile pour gérer une collection créée en dehors de votre contrôle, c'est-à-dire quand vous devez faire des personnalisations à la façon dont elle est désérialisée, et qu'un upsert n'est pas possible de toute façon.
Sérialisation/désérialisation intégrée (du modèle de données vers Dict et de Dict vers le modèle stocké, et inversement)
La sérialisation intégrée est effectuée en convertissant d’abord le modèle de données en dictionnaire, puis en sérialisant le modèle que le magasin comprend, pour chaque magasin différent et défini dans le cadre du connecteur intégré. La désérialisation est effectuée dans l’ordre inverse.
Étape 1 de sérialisation : Modèle de données en Dict
Selon le type de modèle de données dont vous disposez, les étapes sont effectuées de différentes manières. Il existe quatre façons de sérialiser le modèle de données dans un dictionnaire :
- méthode
to_dict
sur la définition (s’aligne sur l’attribut to_dict du modèle de données, en suivant l'ToDictFunctionProtocol
) - vérifier si l’enregistrement est un
ToDictMethodProtocol
et utiliser la méthodeto_dict
- vérifiez si l’enregistrement est un modèle Pydantic et utilisez la
model_dump
du modèle, consultez la note ci-dessous pour plus d’informations. - parcourir les champs de la définition et créer le dictionnaire
Étape 2 de sérialisation : Dict to Store Model
Une méthode doit être fournie par le connecteur pour convertir le dictionnaire en modèle de stockage. Cela est réalisé par le développeur du connecteur et varie selon chaque magasin.
Désérialisation, étape 1 : Stocker le modèle sur Dict
Une méthode doit être fournie par le connecteur pour convertir le modèle de magasin en dictionnaire. Cette tâche est effectuée par le développeur du connecteur et diffère pour chaque magasin.
Désérialisation, étape 2 : Dicter au modèle de données
La désérialisation est effectuée dans l’ordre inverse, elle tente ces options :
- méthode
from_dict
sur la définition (s’aligne sur l’attribut from_dict du modèle de données, en suivant l'FromDictFunctionProtocol
) - vérifier si l’enregistrement est un
FromDictMethodProtocol
et utiliser la méthodefrom_dict
- vérifiez si l’enregistrement est un modèle Pydantic et utilisez la
model_validate
du modèle, consultez la note ci-dessous pour plus d’informations. - effectuez une boucle dans les champs de la définition et définissez les valeurs, puis cette dictée est passée dans le constructeur du modèle de données en tant qu’arguments nommés (sauf si le modèle de données est une dictée elle-même, dans ce cas, elle est retournée comme c’est le cas)
Note
Utilisation de Pydantic avec sérialisation intégrée
Lorsque vous définissez votre modèle à l’aide d’un BaseModel Pydantic, il utilise les méthodes et model_dump
les model_validate
méthodes pour sérialiser et désérialiser le modèle de données vers et à partir d’un dict. Pour ce faire, utilisez la méthode model_dump sans paramètres, si vous souhaitez contrôler cela, envisagez d’implémenter l'ToDictMethodProtocol
sur votre modèle de données, car cela est essayé en premier.
Sérialisation de vecteurs
Lorsque vous avez un vecteur dans votre modèle de données, il doit être une liste de floats ou de listes d’ints, car c’est ce dont la plupart des magasins ont besoin, si vous souhaitez que votre classe stocke le vecteur dans un autre format, vous pouvez utiliser l’annotation serialize_function
et deserialize_function
la définir.VectorStoreRecordVectorField
Par exemple, pour un tableau numpy, vous pouvez utiliser l’annotation suivante :
import numpy as np
vector: Annotated[
np.ndarray | None,
VectorStoreRecordVectorField(
dimensions=1536,
serialize_function=np.ndarray.tolist,
deserialize_function=np.array,
),
] = None
Si vous utilisez un magasin de vecteurs qui peut gérer des tableaux numpy natifs et que vous ne souhaitez pas les convertir en arrière, vous devez configurer la sérialisation directe et la désérialisation méthodes pour le modèle et ce magasin.
Remarque
Cela est utilisé uniquement lors de l’utilisation de la sérialisation intégrée, lorsque vous utilisez la sérialisation directe, vous pouvez gérer le vecteur de n’importe quelle façon de votre choix.
Bientôt disponible
Plus d’informations prochainement.