Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Integrierte Unterstützung für die Einbettungsgenerierung im Vektorspeicher
Das Update vom April 2025 führt integrierte Unterstützung für die Einbettungsgenerierung direkt im Vektorspeicher ein. Durch die Konfiguration eines Einbettungsgenerators können Sie jetzt automatisch Einbettungen für Vektoreigenschaften generieren, ohne sie extern vorkompilieren zu müssen. Dieses Feature vereinfacht Workflows und reduziert die Notwendigkeit zusätzlicher Vorverarbeitungsschritte.
Konfigurieren eines Einbettungsgenerators
Einbettungsgeneratoren, die die Microsoft.Extensions.AI Abstraktionen implementieren, werden unterstützt und können auf verschiedenen Ebenen konfiguriert werden:
Im Vektorspeicher: Sie können einen Standardeinbettungsgenerator für den gesamten Vektorspeicher festlegen. Dieser Generator wird für alle Sammlungen und Eigenschaften verwendet, sofern keine Überschreibung vorgenommen wird.
using Microsoft.Extensions.AI; using Microsoft.SemanticKernel.Connectors.Qdrant; using OpenAI; using Qdrant.Client; var embeddingGenerator = new OpenAIClient("your key") .GetEmbeddingClient("your chosen model") .AsIEmbeddingGenerator(); var vectorStore = new QdrantVectorStore(new QdrantClient("localhost"), new QdrantVectorStoreOptions { EmbeddingGenerator = embeddingGenerator });In einer Sammlung: Sie können einen Einbettungsgenerator für eine bestimmte Sammlung konfigurieren und den Generator auf Speicherebene außer Kraft setzen.
using Microsoft.Extensions.AI; using Microsoft.SemanticKernel.Connectors.Qdrant; using OpenAI; using Qdrant.Client; var embeddingGenerator = new OpenAIClient("your key") .GetEmbeddingClient("your chosen model") .AsIEmbeddingGenerator(); var collectionOptions = new QdrantVectorStoreRecordCollectionOptions<MyRecord> { EmbeddingGenerator = embeddingGenerator }; var collection = new QdrantVectorStoreRecordCollection<ulong, MyRecord>(new QdrantClient("localhost"), "myCollection", collectionOptions);Bei einer Datensatzdefinition: Beim programmgesteuerten
VectorStoreRecordDefinitionDefinieren von Eigenschaften können Sie einen Einbettungsgenerator für alle Eigenschaften angeben.using Microsoft.Extensions.AI; using Microsoft.Extensions.VectorData; using Microsoft.SemanticKernel.Connectors.Qdrant; using OpenAI; using Qdrant.Client; var embeddingGenerator = new OpenAIClient("your key") .GetEmbeddingClient("your chosen model") .AsIEmbeddingGenerator(); var recordDefinition = new VectorStoreRecordDefinition { EmbeddingGenerator = embeddingGenerator, Properties = new List<VectorStoreRecordProperty> { new VectorStoreRecordKeyProperty("Key", typeof(ulong)), new VectorStoreRecordVectorProperty("DescriptionEmbedding", typeof(string), dimensions: 1536) } }; var collectionOptions = new QdrantVectorStoreRecordCollectionOptions<MyRecord> { VectorStoreRecordDefinition = recordDefinition }; var collection = new QdrantVectorStoreRecordCollection<ulong, MyRecord>(new QdrantClient("localhost"), "myCollection", collectionOptions);Bei einer Vector-Eigenschaftsdefinition: Beim programmgesteuerten Definieren von Eigenschaften können Sie einen Einbettungsgenerator direkt in die Eigenschaft festlegen.
using Microsoft.Extensions.AI; using Microsoft.Extensions.VectorData; using OpenAI; var embeddingGenerator = new OpenAIClient("your key") .GetEmbeddingClient("your chosen model") .AsIEmbeddingGenerator(); var vectorProperty = new VectorStoreRecordVectorProperty("DescriptionEmbedding", typeof(string), dimensions: 1536) { EmbeddingGenerator = embeddingGenerator };
Anwendungsbeispiel
Im folgenden Beispiel wird veranschaulicht, wie der Einbettungsgenerator verwendet wird, um Vektoren während der Hochladen- und Einfügevorgänge sowie der Suchvorgänge automatisch zu generieren. Dieser Ansatz vereinfacht Workflows, da keine manuellen Einbettungen vorkompiliert werden müssen.
// The data model
internal class FinanceInfo
{
[VectorStoreRecordKey]
public string Key { get; set; } = string.Empty;
[VectorStoreRecordData]
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.
[VectorStoreRecordVector(1536)]
public string Embedding => this.Text;
}
// Create an OpenAI embedding generator.
var embeddingGenerator = new OpenAIClient("your key")
.GetEmbeddingClient("your chosen model")
.AsIEmbeddingGenerator();
// Use the embedding generator with the vector store.
var vectorStore = new InMemoryVectorStore(new() { EmbeddingGenerator = embeddingGenerator });
var collection = vectorStore.GetCollection<string, FinanceInfo>("finances");
await collection.CreateCollectionAsync();
// 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.
var 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.
var searchResult = collection.SearchAsync(
"What is my budget for 2024?",
top: 1);
// Output the matching result.
await foreach (var result in searchResult)
{
Console.WriteLine($"Key: {result.Record.Key}, Text: {result.Record.Text}");
}
Übergang von IVectorizableTextSearch und IVectorizedSearch zu IVectorSearch
Die Schnittstellen IVectorizableTextSearch und IVectorizedSearch wurden als veraltet gekennzeichnet und durch die einheitlichere und flexiblere IVectorSearch Schnittstelle ersetzt.
Diese Änderung vereinfacht die API-Oberfläche und bietet einen konsistenteren Ansatz für Vektorsuchvorgänge.
Wichtige Änderungen
Einheitliche Schnittstelle:
- Die
IVectorSearchSchnittstelle konsolidiert die Funktionalität sowohl vonIVectorizableTextSearchals auch vonIVectorizedSearchzu einer einzigen Schnittstelle.
- Die
Methodenumbenennung:
-
VectorizableTextSearchAsyncvonIVectorizableTextSearchwurde durchSearchAsyncinIVectorSearchersetzt. -
VectorizedSearchAsyncvonIVectorizedSearchwurde durchSearchEmbeddingAsyncinIVectorSearchersetzt.
-
Verbesserte Flexibilität:
- Die
SearchAsyncMethode imIVectorSearchkümmert sich um die Einbettungsgenerierung und unterstützt entweder lokale Einbettung, wenn ein Einbettungsgenerator konfiguriert ist, oder serverseitige Einbettung. - Die
SearchEmbeddingAsyncMethode inIVectorSearchermöglicht direkte Einbettungs-basierte Suchvorgänge und stellt eine API auf niedriger Ebene für erweiterte Anwendungsfälle bereit.
- Die
Rückgabetypänderung für Suchmethoden
Zusätzlich zur Änderung der Benennung für Suchmethoden wurde der Rückgabetyp für alle Suchmethoden geändert, um die Verwendung zu vereinfachen.
Der Ergebnistyp der Suchmethoden ist jetzt IAsyncEnumerable<VectorSearchResult<TRecord>>, wodurch die Ergebnisse direkt durchlaufen werden können. Zuvor enthielt das zurückgegebene Objekt eine IAsyncEnumerable-Eigenschaft.
Unterstützung für die Suche ohne Vektoren / gefilterter Abruf
Mit dem Update vom April 2025 wird unterstützung für das Auffinden von Datensätzen mithilfe eines Filters und das Zurückgeben der Ergebnisse mit einer konfigurierbaren Sortierreihenfolge eingeführt. Dies ermöglicht das Aufzählen von Datensätzen in einer vorhersehbaren Reihenfolge, was besonders nützlich ist, wenn der Vektorspeicher mit einer externen Datenquelle synchronisiert werden muss.
Beispiel: Verwenden gefilterter Elemente GetAsync
Im folgenden Beispiel wird die Verwendung der GetAsync Methode mit einem Filter und Optionen zum Abrufen von Datensätzen aus einer Vektorspeicherauflistung veranschaulicht. Mit diesem Ansatz können Sie Filterkriterien anwenden und die Ergebnisse in einer vorhersehbaren Reihenfolge sortieren.
// Define a filter to retrieve products priced above $600
Expression<Func<ProductInfo, bool>> filter = product => product.Price > 600;
// Define the options with a sort order
var options = new GetFilteredRecordOptions<ProductInfo>();
options.OrderBy.Descending(product => product.Price);
// Use GetAsync with the filter and sort order
var filteredProducts = await collection.GetAsync(filter, top: 10, options)
.ToListAsync();
In diesem Beispiel wird veranschaulicht, wie sie mithilfe der GetAsync Methode gefilterte Datensätze abrufen und anhand bestimmter Kriterien wie z. B. Preis sortieren können.
Neue Methoden für IVectorStore
Einige neue Methoden sind in der IVectorStore-Schnittstelle verfügbar, mit denen Sie mehr Operationen direkt durchführen können, ohne auf ein VectorStoreRecordCollection-Objekt angewiesen zu sein.
Überprüfen, ob eine Auflistung vorhanden ist
Sie können nun überprüfen, ob eine Auflistung im Vektorspeicher vorhanden ist, ohne ein VectorStoreRecordCollection-Objekt erstellen zu müssen.
// Example: Check if a collection exists
bool exists = await vectorStore.CollectionExistsAsync("myCollection", cancellationToken);
if (exists)
{
Console.WriteLine("The collection exists.");
}
else
{
Console.WriteLine("The collection does not exist.");
}
Löschen einer Auflistung
Mit einer neuen Methode können Sie eine Auflistung aus dem Vektorspeicher löschen, ohne ein VectorStoreRecordCollection-Objekt erstellen zu müssen.
// Example: Delete a collection
await vectorStore.DeleteCollectionAsync("myCollection", cancellationToken);
Console.WriteLine("The collection has been deleted.");
Ersetzung von VectorStoreGenericDataModel<TKey> durch Dictionary<string, object?>
Die Vektordatenabstraktionen unterstützen das Arbeiten mit Datenbanken, bei denen das Schema einer Auflistung zur Erstellungszeit nicht bekannt ist.
Zuvor wurde dies über den VectorStoreGenericDataModel<TKey> Typ unterstützt, in dem dieses Modell anstelle eines benutzerdefinierten Datenmodells verwendet werden kann.
In dieser Version wurde VectorStoreGenericDataModel<TKey> obsolet, und der empfohlene Ansatz besteht darin, stattdessen Dictionary<string, object?> zu verwenden.
Wie zuvor muss eine Datensatzdefinition angegeben werden, um das Schema der Auflistung zu bestimmen. Beachten Sie außerdem, dass der Schlüsseltyp, der beim Abrufen der Sammlungsinstanz erforderlich ist, object ist, während er im Schema auf string festgelegt ist.
var recordDefinition = new VectorStoreRecordDefinition
{
Properties = new List<VectorStoreRecordProperty>
{
new VectorStoreRecordKeyProperty("Key", typeof(string)),
new VectorStoreRecordDataProperty("Text", typeof(string)),
new VectorStoreRecordVectorProperty("Embedding", typeof(ReadOnlyMemory<float>), 1536)
}
};
var collection = vectorStore.GetCollection<object, Dictionary<string, object?>>("finances", recordDefinition);
var record = new Dictionary<string, object?>
{
{ "Key", "1" },
{ "Text", "The budget for 2024 is EUR 364 000" },
{ "Embedding", vector }
};
await collection.UpsertAsync(record);
var retrievedRecord = await collection.GetAsync("1");
Console.WriteLine(retrievedRecord["Text"]);
Änderung der Benennungskonvention für Batchmethoden
Die IVectorStoreRecordCollection Schnittstelle wurde aktualisiert, um die Konsistenz bei Methodenbenennungskonventionen zu verbessern.
Insbesondere wurden die Batch-Methoden umbenannt, um das Wort "Batch" aus ihren Namen zu entfernen. Diese Änderung entspricht einer präziseren Benennungskonvention.
Umbenennen von Beispielen
Alte Methode:
GetBatchAsync(IEnumerable<TKey> keys, ...)
Neue Methode:GetAsync(IEnumerable<TKey> keys, ...)Alte Methode:
DeleteBatchAsync(IEnumerable<TKey> keys, ...)
Neue Methode:DeleteAsync(IEnumerable<TKey> keys, ...)Alte Methode:
UpsertBatchAsync(IEnumerable<TRecord> records, ...)
Neue Methode:UpsertAsync(IEnumerable<TRecord> records, ...)
Rückgabetypänderung für Batch-Upsert-Methode
Der Rückgabetyp für die Batch-Upsert-Methode wurde von IAsyncEnumerable<TKey> zu Task<IReadOnlyList<TKey>>" geändert.
Diese Änderung wirkt sich auf die Verwendung der Methode aus. Sie können jetzt einfach auf das Ergebnis warten und eine Liste der Schlüssel zurückholen.
Um sicherzustellen, dass alle Upserts abgeschlossen wurden, musste der IAsyncEnumerable früher vollständig aufgezählt werden.
Dies vereinfacht die Entwicklerumgebung bei Verwendung der Batch-Upsert-Methode.
Die CollectionName-Eigenschaft wurde in Name geändert.
Die CollectionName Eigenschaft auf der IVectorStoreRecordCollection Schnittstelle wurde umbenannt in Name.
IsFilterable und IsFullTextSearchable umbenannt in IsIndexed und IsFullTextIndexed
Die Eigenschaften IsFilterable und IsFullTextSearchable in den Klassen VectorStoreRecordDataAttribute und VectorStoreRecordDataProperty wurden in IsIndexed bzw. IsFullTextIndexed umbenannt.
Dimensionen sind jetzt für Vektorattribute und Definitionen erforderlich.
Im Update vom April 2025 ist die Angabe der Anzahl der Dimensionen bei Verwendung von Vektorattributen oder Vektoreigenschaftsdefinitionen obligatorisch geworden. Dadurch wird sichergestellt, dass der Vektorspeicher immer über die erforderlichen Informationen verfügt, um Einbettungen korrekt zu verarbeiten.
Änderungen an VectorStoreRecordVectorAttribute
VectorStoreRecordVectorAttribute Zuvor konnten Sie den Dimensions Parameter weglassen. Dies ist nicht mehr zulässig, und der Dimensions Parameter muss jetzt explizit bereitgestellt werden.
Vor:
[VectorStoreRecordVector]
public ReadOnlyMemory<float> DefinitionEmbedding { get; set; }
Nach:
[VectorStoreRecordVector(Dimensions: 1536)]
public ReadOnlyMemory<float> DefinitionEmbedding { get; set; }
Änderungen an VectorStoreRecordVectorProperty
Ebenso ist beim Definieren einer Vektoreigenschaft programmgesteuert mit VectorStoreRecordVectorProperty der dimensions-Parameter erforderlich.
Vor:
var vectorProperty = new VectorStoreRecordVectorProperty("DefinitionEmbedding", typeof(ReadOnlyMemory<float>));
Nach:
var vectorProperty = new VectorStoreRecordVectorProperty("DefinitionEmbedding", typeof(ReadOnlyMemory<float>), dimensions: 1536);
Für alle Auflistungen muss der Schlüsseltyp als generischer Typparameter übergeben werden.
Beim direkten Erstellen einer Auflistung ist es jetzt erforderlich, den TKey generischen Typparameter bereitzustellen.
Zuvor erlaubten einige Datenbanken nur einen Schlüsseltyp; jetzt ist dies ein erforderlicher Parameter. Um jedoch die Verwendung von Sammlungen mit einem Dictionary<string, object?> Typ und einem object Schlüsseltyp zu ermöglichen, muss TKey immer bereitgestellt werden.
Nicht zutreffend
Diese Änderungen gelten derzeit nur in C#
Nicht zutreffend
Diese Änderungen gelten derzeit nur in C#