Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los proveedores de almacén de vectores admiten varias formas de generar incrustaciones. Puede generarlos usted mismo y pasarlos como parte de un registro al usar un VectorStoreCollection<TKey,TRecord>. O pueden generarse internamente en el VectorStoreCollection<TKey,TRecord>.
Generar incrustaciones usted mismo
El enfoque más directo es generar incrustaciones antes de llamar a UpsertAsync o SearchAsyncy pasarlas junto con los registros o la consulta de búsqueda.
Construcción de un generador de inserción
Para obtener información sobre cómo construir Microsoft.Extensions.AI generadores de inserción, vea Incrustaciones en .NET.
Generación de incrustaciones en upsert con IEmbeddingGenerator
async Task GenerateEmbeddingsAndUpsertAsync(
IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator,
VectorStoreCollection<ulong, Hotel> collection)
{
// Upsert a record.
string descriptionText = "A place where everyone can be happy.";
ulong hotelId = 1;
// Generate the embedding.
ReadOnlyMemory<float> embedding =
(await embeddingGenerator.GenerateAsync(descriptionText)).Vector;
// Create a record and upsert with the already generated embedding.
await collection.UpsertAsync(new Hotel
{
HotelId = hotelId,
HotelName = "Hotel Happy",
Description = descriptionText,
DescriptionEmbedding = embedding,
Tags = ["luxury", "pool"]
});
}
Generación de incrustaciones en la búsqueda con IEmbeddingGenerator
async Task GenerateEmbeddingsAndSearchAsync(
IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator,
VectorStoreCollection<ulong, Hotel> collection)
{
// Upsert a record.
string descriptionText = "Find me a hotel with happiness in mind.";
// Generate the embedding.
ReadOnlyMemory<float> searchEmbedding =
(await embeddingGenerator.GenerateAsync(descriptionText)).Vector;
// Search using the already generated embedding.
IAsyncEnumerable<VectorSearchResult<Hotel>> searchResult = collection.SearchAsync(searchEmbedding, top: 1);
List<VectorSearchResult<Hotel>> resultItems = await searchResult.ToListAsync();
// Print the first search result.
Console.WriteLine("Score for first result: " + resultItems.FirstOrDefault()?.Score);
Console.WriteLine("Hotel description for first result: " + resultItems.FirstOrDefault()?.Record.Description);
}
Permitir que el almacén de vectores genere incrustaciones
Puede configurar un generador de inserción en el almacén de vectores, lo que permite que las inserciones se generen automáticamente durante las operaciones upsert y search. Este enfoque elimina la necesidad de preprocesamiento manual.
Para habilitar la generación automática de vectores en upsert, la propiedad vectorial del modelo de datos se define como el tipo de origen, por ejemplo, string, pero todavía está decorado con .VectorStoreVectorAttribute
[VectorStoreVector(1536)]
public required string Embedding { get; set; }
Antes de realizar el upsert, la propiedad Embedding debe contener la cadena desde la cual se debe generar un vector. El tipo del vector almacenado en la base de datos (por ejemplo, float32 o float16) se derivará del generador de inserción configurado.
Importante
Estas propiedades vectoriales no admiten la recuperación del vector generado o el texto original del que se generó el vector. Tampoco almacenan el texto original. Si es necesario almacenar el texto original, agregue una propiedad de datos independiente para almacenarlo.
Se admiten generadores de inserción que implementan las Microsoft.Extensions.AI abstracciones y se pueden configurar en varios niveles:
En el almacén de vectores:
Puede establecer un generador de inserción predeterminado para todo el almacén de vectores. Este generador se usará para todas las colecciones y propiedades a menos que se invalide.
VectorStore vectorStore = new QdrantVectorStore( new QdrantClient("localhost"), ownsClient: true, new QdrantVectorStoreOptions { EmbeddingGenerator = embeddingGenerator });En una colección:
Puede configurar un generador de incrustaciones para una colección específica, sustituyendo al generador a nivel de almacén.
var collectionOptions = new QdrantCollectionOptions { EmbeddingGenerator = embeddingGenerator }; var collection = new QdrantCollection<ulong, MyRecord>( new QdrantClient("localhost"), "myCollection", ownsClient: true, collectionOptions);En una definición de registro:
Al definir propiedades mediante programación mediante VectorStoreCollectionDefinition, puede especificar un generador de inserción para todas las propiedades.
var definition = new VectorStoreCollectionDefinition { EmbeddingGenerator = embeddingGenerator, Properties = [ new VectorStoreKeyProperty("Key", typeof(ulong)), new VectorStoreVectorProperty("DescriptionEmbedding", typeof(string), dimensions: 1536) ] }; collectionOptions = new QdrantCollectionOptions { Definition = definition }; collection = new QdrantCollection<ulong, MyRecord>( new QdrantClient("localhost"), "myCollection", ownsClient: true, collectionOptions);En una definición de propiedad vectorial:
Al definir propiedades mediante programación, puede establecer un generador de inserción directamente en la propiedad .
VectorStoreVectorProperty vectorProperty = new( "DescriptionEmbedding", typeof(string), dimensions: 1536) { EmbeddingGenerator = embeddingGenerator };
Ejemplo de uso
En el ejemplo siguiente se muestra cómo usar el generador de inserción para generar automáticamente vectores durante las operaciones upsert y search. Este enfoque simplifica los flujos de trabajo mediante la eliminación de la necesidad de precompletar incrustaciones manualmente.
// The data model.
internal class FinanceInfo
{
[VectorStoreKey]
public string Key { get; set; } = string.Empty;
[VectorStoreData]
public string Text { get; set; } = string.Empty;
// Note that the vector property is typed as a string, and
// its value is derived from the Text property. The string
// value will however be converted to a vector on upsert and
// stored in the database as a vector.
[VectorStoreVector(1536)]
public string Embedding => Text;
}
public static async Task RunAsync()
{
// Create an OpenAI embedding generator.
var embeddingGenerator = new OpenAIClient("your key")
.GetEmbeddingClient("your chosen model")
.AsIEmbeddingGenerator();
// Use the embedding generator with the vector store.
VectorStore vectorStore = new InMemoryVectorStore(new()
{ EmbeddingGenerator = embeddingGenerator }
);
InMemoryCollection<string, FinanceInfo> collection =
(InMemoryCollection<string, FinanceInfo>)vectorStore.GetCollection<string, FinanceInfo>("finances");
await collection.EnsureCollectionExistsAsync();
// Create some test data.
string[] budgetInfo =
[
"The budget for 2020 is EUR 100 000",
"The budget for 2021 is EUR 120 000",
"The budget for 2022 is EUR 150 000",
"The budget for 2023 is EUR 200 000",
"The budget for 2024 is EUR 364 000"
];
// Embeddings are generated automatically on upsert.
IEnumerable<FinanceInfo> records = budgetInfo.Select(
(input, index) => new FinanceInfo { Key = index.ToString(), Text = input }
);
await collection.UpsertAsync(records);
// Embeddings for the search is automatically generated on search.
IAsyncEnumerable<VectorSearchResult<FinanceInfo>> searchResult =
collection.SearchAsync("What is my budget for 2024?", top: 1);
// Output the matching result.
await foreach (VectorSearchResult<FinanceInfo> result in searchResult)
{
Console.WriteLine($"Key: {result.Record.Key}, Text: {result.Record.Text}");
}
}
Inserción de dimensiones
Normalmente, las bases de datos vectoriales requieren que especifique el número de dimensiones que tiene cada vector al crear la colección. Los diferentes modelos de inserción normalmente admiten la generación de vectores con varios tamaños de dimensión. Por ejemplo, OpenAI text-embedding-ada-002 genera vectores con 1536 dimensiones. Algunos modelos también permiten elegir el número de dimensiones que desea en el vector de salida. Por ejemplo, Google text-embedding-004 genera vectores con 768 dimensiones de forma predeterminada, pero permite elegir cualquier número de dimensiones entre 1 y 768.
Es importante asegurarse de que los vectores generados por el modelo de inserción tengan el mismo número de dimensiones que el vector coincidente en la base de datos.
Si crea una colección mediante las abstracciones de almacén de vectores, debe especificar el número de dimensiones necesarias para cada propiedad vectorial a través de anotaciones o mediante la definición de registro. En el código siguiente se muestran ejemplos de cómo establecer el número de dimensiones en 1536 mediante ambos mecanismos.
[VectorStoreVector(Dimensions: 1536)]
public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }
new VectorStoreVectorProperty(
"DescriptionEmbedding",
typeof(float),
dimensions: 1536);