共用方式為


如何使用向量存放區搭配語意核心文字搜尋

所有向量存放區 連接器 都可用於文字搜尋。

  1. 使用 Vector Store 連接器來擷取您想要搜尋的記錄集合。
  2. 使用 VectorStoreTextSearch包裝記錄集合。
  3. 轉換成外掛程式,以用於RAG和/或函式呼叫案例。

您可能想要自定義外掛程式搜尋函式,使其描述反映記錄集合中可用的數據類型。 例如,如果記錄集合包含有關旅館的資訊,外掛程式搜尋函式描述應該提及這一點。 這可讓您註冊多個外掛程式,例如,一個來搜尋酒店、另一個用於餐廳,另一個用於做事。

文字搜尋抽象概念包含可傳回正規化搜尋結果的函式,也就是的TextSearchResult實例。 這個正規化搜尋結果包含值,並選擇性地包含名稱和連結。 文字搜尋抽象概念包含傳回字串值的函式,例如,其中一個數據模型屬性會在搜尋結果時傳回。 若要讓文字搜尋正常運作,您必須提供從向量存放區數據模型對應至 實例的方法 TextSearchResult。 下一節說明可用來執行此對應的兩個選項。

提示

若要執行此頁面中顯示的範例,請移至 GettingStartedWithTextSearch/Step4_Search_With_VectorStore.cs

從向量存放區數據模型到的 TextSearchResult 對應可以使用屬性以宣告方式完成。

  1. [TextSearchResultValue] - 將這個屬性新增至數據模型的屬性,其將是 TextSearchResult的值,例如 AI 模型將用來回答問題的文字數據。
  2. [TextSearchResultName] - 將這個屬性新增至數據模型的屬性,該屬性將是 的名稱 TextSearchResult
  3. [TextSearchResultLink] - 將這個屬性新增至數據模型的屬性,該屬性將會是 的連結 TextSearchResult

下列範例顯示已套用文字搜尋結果屬性的數據模型。

using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Data;

public sealed class DataModel
{
    [VectorStoreRecordKey]
    [TextSearchResultName]
    public Guid Key { get; init; }

    [VectorStoreRecordData]
    [TextSearchResultValue]
    public string Text { get; init; }

    [VectorStoreRecordData]
    [TextSearchResultLink]
    public string Link { get; init; }

    [VectorStoreRecordData(IsFilterable = true)]
    public required string Tag { get; init; }

    [VectorStoreRecordVector(1536)]
    public ReadOnlyMemory<float> Embedding { get; init; }
}

從向量存放區數據模型到 stringTextSearchResult 的對應也可以藉由分別提供 和 ITextSearchResultMapperITextSearchStringMapper實作來完成。

您可以決定針對下列案例建立自訂對應器:

  1. 數據模型中的多個屬性必須結合在一起,例如,如果需要結合多個屬性以提供值。
  2. 需要額外的邏輯,才能產生其中一個屬性,例如,如果需要從數據模型屬性計算鏈接屬性。

下列範例顯示可搭配數據模型使用的數據模型和兩個範例對應程序實作。

using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Data;

protected sealed class DataModel
{
    [VectorStoreRecordKey]
    public Guid Key { get; init; }

    [VectorStoreRecordData]
    public required string Text { get; init; }

    [VectorStoreRecordData]
    public required string Link { get; init; }

    [VectorStoreRecordData(IsFilterable = true)]
    public required string Tag { get; init; }

    [VectorStoreRecordVector(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 IVectorStoreRecordCollection and ITextEmbeddingGenerationService 

// Create a text search instance using the vector store record collection.
var result = new VectorStoreTextSearch<DataModel>(vectorStoreRecordCollection, textEmbeddingGeneration, stringMapper, resultMapper);

下列範例示範如何使用 Vector Store 記錄集合建立 的 VectorStoreTextSearch 實例。

提示

下列範例需要 和ITextEmbeddingGenerationServiceIVectorStoreRecordCollection實例。 若要建立的 IVectorStoreRecordCollection 實例, 請參閱每個連接器的檔。 若要建立實例, 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 IVectorStoreRecordCollection and ITextEmbeddingGenerationService 

// Create a text search instance using the vector store record collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreRecordCollection, 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}");
}

從向量存放區建立搜尋外掛程式

下列範例示範如何從 實例建立名為 SearchPluginVectorStoreTextSearch外掛程式。 使用 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 IVectorStoreRecordCollection and ITextEmbeddingGenerationService

// Create a text search instance using the vector store record collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreRecordCollection, 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
));

搭配函數呼叫使用向量存放區

下列範例也會從 的 VectorStoreTextSearch實體建立 SearchPlugin 。 此外掛程式將會公告給模型,以在 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 IVectorStoreRecordCollection and ITextEmbeddingGenerationService

// Create a text search instance using the vector store record collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreRecordCollection, 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的搜尋函式描述。 您可能要執行的一些工作包括:

  1. 變更搜尋函式的名稱,以反映相關聯記錄集合中的內容,例如,如果記錄集合包含旅館資訊,您可能會想要將函 SearchForHotels 式命名。
  2. 變更函式的描述。 精確的函式描述可協助 AI 模型選取要呼叫的最佳函式。 如果您要新增多個搜尋函式,這特別重要。
  3. 將其他參數新增至搜尋函式。 如果記錄集合包含旅館資訊,且其中一個屬性是城市名稱,您可以將屬性新增至搜尋函式以指定城市。 系統會自動新增篩選,且會依城市篩選搜尋結果。

提示

下列範例會使用預設的搜尋實作。 您可以選擇提供自己的實作,以使用其他選項呼叫基礎 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 IVectorStoreRecordCollection and ITextEmbeddingGenerationService

// Create a text search instance using the vector store record collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreRecordCollection, 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));

即將推出

更多即將推出。

即將推出

更多即將推出。

下一步