ベクター ストア プロバイダーでは、 埋め込みを生成する複数の方法がサポートされています。 VectorStoreCollection<TKey,TRecord>を使用する場合は、それらを自分で生成し、レコードの一部として渡すことができます。 または、 VectorStoreCollection<TKey,TRecord>に対して内部的に生成することもできます。
埋め込みを自分で生成する
最も直接的な方法は、 UpsertAsync または SearchAsyncを呼び出す前に埋め込みを生成し、レコードまたは検索クエリと共に渡すことです。
埋め込みジェネレーターを構築する
Microsoft.Extensions.AI埋め込みジェネレーターを構築する方法については、「.NET での埋め込み」を参照してください。
アップサート時に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"]
});
}
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);
}
ベクター ストアに埋め込みを生成させる
ベクター ストアに埋め込みジェネレーターを構成できます。これにより、アップサート操作と検索操作の両方で埋め込みを自動的に生成できます。 この方法により、手動による前処理が不要になります。
アップサートでベクターを自動的に生成できるようにするには、データ モデルの vector プロパティがソースの種類 (たとえば、 string) として定義されますが、 VectorStoreVectorAttributeで修飾されます。
[VectorStoreVector(1536)]
public required string Embedding { get; set; }
アップサートする前に、 Embedding プロパティには、ベクターの生成元となる文字列が含まれている必要があります。 データベースに格納されているベクターの型 ( float32 や float16など) は、構成された埋め込みジェネレーターから派生します。
Important
これらのベクター プロパティは、生成されたベクターまたはベクターが生成された元のテキストの取得をサポートしていません。 元のテキストも格納されません。 元のテキストを格納する必要がある場合は、別のデータ プロパティを追加して格納します。
Microsoft.Extensions.AI抽象化を実装する埋め込みジェネレーターはサポートされており、さまざまなレベルで構成できます。
ベクター ストアで次の手順を実行します。
ベクター ストア全体の既定の埋め込みジェネレーターを設定できます。 このジェネレーターは、オーバーライドされない限り、すべてのコレクションとプロパティに使用されます。
VectorStore vectorStore = new QdrantVectorStore( new QdrantClient("localhost"), ownsClient: true, new QdrantVectorStoreOptions { EmbeddingGenerator = embeddingGenerator });コレクションの場合:
特定のコレクションの埋め込みジェネレーターを構成し、ストア レベルのジェネレーターをオーバーライドできます。
var collectionOptions = new QdrantCollectionOptions { EmbeddingGenerator = embeddingGenerator }; var collection = new QdrantCollection<ulong, MyRecord>( new QdrantClient("localhost"), "myCollection", ownsClient: true, collectionOptions);レコード定義の場合:
VectorStoreCollectionDefinitionを使用してプログラムでプロパティを定義する場合は、すべてのプロパティに埋め込みジェネレーターを指定できます。
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);ベクター プロパティ定義の場合:
プログラムでプロパティを定義する場合は、埋め込みジェネレーターをプロパティに直接設定できます。
VectorStoreVectorProperty vectorProperty = new( "DescriptionEmbedding", typeof(string), dimensions: 1536) { EmbeddingGenerator = embeddingGenerator };
使用例
次の例では、埋め込みジェネレーターを使用して、アップサート操作と検索操作の両方でベクトルを自動的に生成する方法を示します。 この方法では、埋め込みを手動で事前に計算する必要がなくなり、ワークフローが簡略化されます。
// 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}");
}
}
埋め込みディメンション
ベクター データベースでは、通常、コレクションの作成時に各ベクターに含まれる次元の数を指定する必要があります。 通常、さまざまな埋め込みモデルでは、さまざまなディメンション サイズのベクターの生成がサポートされます。 たとえば、OpenAI text-embedding-ada-002 は 1536 次元のベクトルを生成します。 一部のモデルでは、出力ベクターで必要な次元の数を選択することもできます。 たとえば、Google text-embedding-004 では、既定で 768 次元のベクトルが生成されますが、1 から 768 までの任意の数のディメンションを選択できます。
埋め込みモデルによって生成されるベクターの次元数が、データベース内の一致するベクターと同じになるようにすることが重要です。
ベクター ストアの抽象化を使用してコレクションを作成する場合は、 注釈 または レコード定義を使用して、各ベクター プロパティに必要な次元の数を指定する必要があります。 次のコードは、両方のメカニズムを使用してディメンションの数を 1536 に設定する例を示しています。
[VectorStoreVector(Dimensions: 1536)]
public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }
new VectorStoreVectorProperty(
"DescriptionEmbedding",
typeof(float),
dimensions: 1536);
こちらも参照ください
.NET