所有向量存放區 連接器 都可用於文字搜尋。
- 使用 Vector Store 連接器來擷取您想要搜尋的記錄集合。
- 使用
VectorStoreTextSearch包裝記錄集合。 - 轉換為可用於 RAG 和/或函式呼叫情境的外掛程式。
您可能想要自定義外掛程式搜尋函式,使其描述反映記錄集合中可用的數據類型。 例如,如果記錄集合包含有關旅館的資訊,外掛程式搜尋函式描述應該提及這一點。 這可讓您註冊多個外掛程式,例如,一個來搜尋酒店、另一個用於餐廳,另一個用於做事。
文字搜尋抽象概念包含一個用來傳回正規化搜尋結果的函式,亦即 TextSearchResult 的實例。
這個正規化搜尋結果包含值,並選擇性地包含名稱和連結。
文字搜尋抽象層包含一個會傳回字串值的函式,例如,資料模型的其中一個屬性會作為搜尋結果傳回。
若要讓文字搜尋正常運作,您必須提供從向量存放區數據模型對應至 實例的方法 TextSearchResult。
下一節說明可用來執行此對應的兩個選項。
提示
若要執行此頁面中顯示的範例,請移至 GettingStartedWithTextSearch/Step4_Search_With_VectorStore.cs。
使用搭配文字搜尋的向量儲存模型
從向量存放區資料模型到 TextSearchResult 的對應可透過屬性以宣告式方式完成。
-
[TextSearchResultValue]- 將這個屬性新增至數據模型的屬性,其將是TextSearchResult的值,例如 AI 模型將用來回答問題的文字數據。 -
[TextSearchResultName]- 將這個屬性新增至數據模型的屬性,該屬性將是 的名稱TextSearchResult。 -
[TextSearchResultLink]- 將此屬性新增至資料模型中作為連結至TextSearchResult的屬性。
下列範例顯示已套用文字搜尋結果屬性的數據模型。
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Data;
public sealed class DataModel
{
[VectorStoreKey]
[TextSearchResultName]
public Guid Key { get; init; }
[VectorStoreData]
[TextSearchResultValue]
public string Text { get; init; }
[VectorStoreData]
[TextSearchResultLink]
public string Link { get; init; }
[VectorStoreData(IsFilterable = true)]
public required string Tag { get; init; }
[VectorStoreVector(1536)]
public ReadOnlyMemory<float> Embedding { get; init; }
}
將向量存放區資料模型對應至 string 或 TextSearchResult,也可以分別透過提供 ITextSearchStringMapper 和 ITextSearchResultMapper 的實作來完成。
您可以決定針對下列案例建立自訂對應器:
- 數據模型中的多個屬性必須結合在一起,例如,如果需要結合多個屬性以提供值。
- 需要額外的邏輯,才能產生其中一個屬性,例如,如果需要從數據模型屬性計算鏈接屬性。
下列範例顯示一個資料模型,以及兩個可搭配該資料模型使用的對應器實作範例。
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Data;
protected sealed class DataModel
{
[VectorStoreKey]
public Guid Key { get; init; }
[VectorStoreData]
public required string Text { get; init; }
[VectorStoreData]
public required string Link { get; init; }
[VectorStoreData(IsFilterable = true)]
public required string Tag { get; init; }
[VectorStoreVector(1536)]
public ReadOnlyMemory<float> Embedding { get; init; }
}
/// <summary>
/// String mapper which converts a DataModel to a string.
/// </summary>
protected sealed class DataModelTextSearchStringMapper : ITextSearchStringMapper
{
/// <inheritdoc />
public string MapFromResultToString(object result)
{
if (result is DataModel dataModel)
{
return dataModel.Text;
}
throw new ArgumentException("Invalid result type.");
}
}
/// <summary>
/// Result mapper which converts a DataModel to a TextSearchResult.
/// </summary>
protected sealed class DataModelTextSearchResultMapper : ITextSearchResultMapper
{
/// <inheritdoc />
public TextSearchResult MapFromResultToTextSearchResult(object result)
{
if (result is DataModel dataModel)
{
return new TextSearchResult(value: dataModel.Text) { Name = dataModel.Key.ToString(), Link = dataModel.Link };
}
throw new ArgumentException("Invalid result type.");
}
}
如以下所示,在建立 VectorStoreTextSearch 時,可以將映射器實作作為參數提供。
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Data;
// Create custom mapper to map a <see cref="DataModel"/> to a <see cref="string"/>
var stringMapper = new DataModelTextSearchStringMapper();
// Create custom mapper to map a <see cref="DataModel"/> to a <see cref="TextSearchResult"/>
var resultMapper = new DataModelTextSearchResultMapper();
// Add code to create instances of VectorStoreCollection and ITextEmbeddingGenerationService
// Create a text search instance using the vector store collection.
var result = new VectorStoreTextSearch<DataModel>(vectorStoreCollection, textEmbeddingGeneration, stringMapper, resultMapper);
將向量存放區與文字搜尋搭配使用
下列範例示範如何使用 Vector Store 記錄集合建立 的 VectorStoreTextSearch 實例。
提示
下列範例需要 VectorStoreCollection 和 ITextEmbeddingGenerationService 的實例。
若要建立 VectorStoreCollection 的執行個體,請參閱 每個連接器的文件。
若要建立 ITextEmbeddingGenerationService 的執行個體,請選取您想要使用的服務,例如 Azure OpenAI、OpenAI 等,或使用本機模型,例如 ONNX、Ollama 等,並建立對應的 ITextEmbeddingGenerationService 實作執行個體。
提示
VectorStoreTextSearch 也可以從 IVectorizableTextSearch 的實體建構而成。 在這裡情況下,不需要 ITextEmbeddingGenerationService 。
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.Data;
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;
// Add code to create instances of VectorStoreCollection and ITextEmbeddingGenerationService
// Create a text search instance using the vector store collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreCollection, textEmbeddingGeneration);
// Search and return results as TextSearchResult items
var query = "What is the Semantic Kernel?";
KernelSearchResults<TextSearchResult> textResults = await textSearch.GetTextSearchResultsAsync(query, new() { Top = 2, Skip = 0 });
Console.WriteLine("\n--- Text Search Results ---\n");
await foreach (TextSearchResult result in textResults.Results)
{
Console.WriteLine($"Name: {result.Name}");
Console.WriteLine($"Value: {result.Value}");
Console.WriteLine($"Link: {result.Link}");
}
從向量存放區建立搜尋外掛程式
下列範例示範如何從 實例建立名為 SearchPlugin 的 VectorStoreTextSearch外掛程式。
使用 CreateWithGetTextSearchResults 會建立一個新的外掛程式,其中包含單一的 GetTextSearchResults 函式,該函式會呼叫底層的 Vector Store 記錄集合搜尋實作。
SearchPlugin 會新增到 Kernel,因此可在提示轉譯時呼叫。
提示範本包含對 {{SearchPlugin.Search $query}} 的呼叫,其會叫用 SearchPlugin 以擷取與目前查詢相關的結果。
然後,結果會插入轉譯的提示字元中,再傳送至模型。
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.Data;
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;
// Create a kernel with OpenAI chat completion
IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.AddOpenAIChatCompletion(
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey);
Kernel kernel = kernelBuilder.Build();
// Add code to create instances of VectorStoreCollection and ITextEmbeddingGenerationService
// Create a text search instance using the vector store collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreCollection, textEmbeddingGeneration);
// Build a text search plugin with vector store search and add to the kernel
var searchPlugin = textSearch.CreateWithGetTextSearchResults("SearchPlugin");
kernel.Plugins.Add(searchPlugin);
// Invoke prompt and use text search plugin to provide grounding information
var query = "What is the Semantic Kernel?";
string promptTemplate = """
{{#with (SearchPlugin-GetTextSearchResults query)}}
{{#each this}}
Name: {{Name}}
Value: {{Value}}
Link: {{Link}}
-----------------
{{/each}}
{{/with}}
{{query}}
Include citations to the relevant information where it is referenced in the response.
""";
KernelArguments arguments = new() { { "query", query } };
HandlebarsPromptTemplateFactory promptTemplateFactory = new();
Console.WriteLine(await kernel.InvokePromptAsync(
promptTemplate,
arguments,
templateFormat: HandlebarsPromptTemplateFactory.HandlebarsTemplateFormat,
promptTemplateFactory: promptTemplateFactory
));
搭配函式呼叫使用向量儲存
下列範例也會從 的 SearchPlugin實體建立 VectorStoreTextSearch 。
此外掛程式將會在提示執行設定中透過 FunctionChoiceBehavior 提供給模型,供自動函式呼叫使用。
當您執行此範例時,模型會叫用搜尋函式,以擷取其他資訊以響應問題。
它可能會只搜尋「語意核心」,而不是整個查詢。
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.Data;
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;
// Create a kernel with OpenAI chat completion
IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.AddOpenAIChatCompletion(
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey);
Kernel kernel = kernelBuilder.Build();
// Add code to create instances of VectorStoreCollection and ITextEmbeddingGenerationService
// Create a text search instance using the vector store collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreCollection, textEmbeddingGeneration);
// Build a text search plugin with vector store search and add to the kernel
var searchPlugin = textSearch.CreateWithGetTextSearchResults("SearchPlugin");
kernel.Plugins.Add(searchPlugin);
// Invoke prompt and use text search plugin to provide grounding information
OpenAIPromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
KernelArguments arguments = new(settings);
Console.WriteLine(await kernel.InvokePromptAsync("What is the Semantic Kernel?", arguments));
自定義搜尋函式
下列範例如何自定義新增至 SearchPlugin的搜尋函式描述。
您可能要執行的一些工作包括:
- 變更搜尋函式的名稱,以反映相關聯記錄集合中的內容,例如,如果記錄集合包含旅館資訊,您可能會想要將函
SearchForHotels式命名。 - 變更函式的描述。 精確的函式描述可協助 AI 模型選取要呼叫的最佳函式。 如果您要新增多個搜尋函式,這特別重要。
- 將其他參數新增至搜尋函式。 如果記錄集合包含旅館資訊,且其中一個屬性是城市名稱,您可以將屬性新增至搜尋函式以指定城市。 系統會自動新增篩選,且會依城市篩選搜尋結果。
提示
下列範例會使用預設的搜尋實作。 您可以選擇自行提供實作,在呼叫底層的 Vector Store 記錄集時加入額外選項,以進一步微調搜尋方式。
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.Data;
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;
// Create a kernel with OpenAI chat completion
IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.AddOpenAIChatCompletion(
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey);
Kernel kernel = kernelBuilder.Build();
// Add code to create instances of VectorStoreCollection and ITextEmbeddingGenerationService
// Create a text search instance using the vector store collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreCollection, textEmbeddingGeneration);
// Create options to describe the function I want to register.
var options = new KernelFunctionFromMethodOptions()
{
FunctionName = "Search",
Description = "Perform a search for content related to the specified query from a record collection.",
Parameters =
[
new KernelParameterMetadata("query") { Description = "What to search for", IsRequired = true },
new KernelParameterMetadata("top") { Description = "Number of results", IsRequired = false, DefaultValue = 2 },
new KernelParameterMetadata("skip") { Description = "Number of results to skip", IsRequired = false, DefaultValue = 0 },
],
ReturnParameter = new() { ParameterType = typeof(KernelSearchResults<string>) },
};
// Build a text search plugin with vector store search and add to the kernel
var searchPlugin = textSearch.CreateWithGetTextSearchResults("SearchPlugin", "Search a record collection", [textSearch.CreateSearch(options)]);
kernel.Plugins.Add(searchPlugin);
// Invoke prompt and use text search plugin to provide grounding information
OpenAIPromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
KernelArguments arguments = new(settings);
Console.WriteLine(await kernel.InvokePromptAsync("What is the Semantic Kernel?", arguments));
即將推出
更多內容即將推出。
即將推出
更多內容即將推出。