Использование векторных хранилищ с семантическим поиском текста ядра
Все соединители Vector Store можно использовать для поиска текста.
- Используйте соединитель Vector Store для получения коллекции записей, которую требуется выполнить поиск.
- Переключите коллекцию записей с
VectorStoreTextSearch
помощью . - Преобразуйте подключаемый модуль для использования в сценариях вызова RAG и (или) функций.
Скорее всего, вы хотите настроить функцию поиска подключаемых модулей таким образом, чтобы его описание отражало тип данных, доступных в коллекции записей. Например, если коллекция записей содержит сведения о отелях, описание функции поиска подключаемого модуля должно упомянуть об этом. Это позволит зарегистрировать несколько подключаемых модулей, например, один для поиска отелей, другой для ресторанов и другого для выполнения действий.
Абстракции поиска текста включают функцию для возврата нормализованного результата поиска, т. е. экземпляраTextSearchResult
.
Этот нормализованный результат поиска содержит значение и при необходимости имя и ссылку.
Абстракции поиска текста включают функцию для возврата строкового значения, например одно из свойств модели данных будет возвращено в качестве результата поиска.
Чтобы поиск текста работал правильно, необходимо предоставить способ сопоставления из модели данных векторного TextSearchResult
хранилища с экземпляром.
В следующем разделе описаны два варианта, которые можно использовать для выполнения этого сопоставления.
Совет
Чтобы запустить примеры, показанные на этой странице, перейдите в раздел GettingStartedWithTextSearch/Step4_Search_With_VectorStore.cs.
Использование модели векторного хранилища с текстовым поиском
Сопоставление из модели данных векторного хранилища с TextSearchResult
моделью данных можно сделать декларативно с помощью атрибутов.
[TextSearchResultValue]
— Добавьте этот атрибут в свойство модели данных, которая будет значениемTextSearchResult
текстовых данных, которые модель ИИ будет использовать для ответа на вопросы.[TextSearchResultName]
— добавьте этот атрибут в свойство модели данных, которое будет именемTextSearchResult
модели данных.[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; }
}
Сопоставление из модели данных векторного хранилища с моделью данных или string
а TextSearchResult
также может быть выполнено путем предоставления реализаций ITextSearchStringMapper
и ITextSearchResultMapper
соответственно.
Вы можете создать пользовательские схемы для следующих сценариев:
- Для предоставления значения необходимо объединить несколько свойств из модели данных, например, если для предоставления значения необходимо объединить несколько свойств.
- Для создания одного из свойств модели данных требуется дополнительная логика, например, если свойство ссылки необходимо вычислить из свойств модели данных.
В следующем примере показана модель данных и два примера реализаций mapper, которые можно использовать с моделью данных.
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.");
}
}
Реализации mapper можно указать в качестве параметров при создании, 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);
Использование векторного хранилища с текстовым поиском
В приведенном ниже примере показано, как создать экземпляр с VectorStoreTextSearch
помощью коллекции записей Vector Store.
Совет
Для следующих примеров требуются экземпляры IVectorStoreRecordCollection
и ITextEmbeddingGenerationService
.
Создание экземпляра 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}");
}
Создание подключаемого модуля поиска из векторного хранилища
В приведенном ниже примере показано, как создать подключаемый модуль с именем SearchPlugin
из экземпляра VectorStoreTextSearch
.
При использовании CreateWithGetTextSearchResults
создается новый подключаемый модуль с одной GetTextSearchResults
функцией, которая вызывает базовую реализацию поиска коллекции записей Vector Store.
Добавляется Kernel
в SearchPlugin
приложение, которое делает его доступным для вызова во время отрисовки запроса.
Шаблон запроса включает вызов, к {{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
));
Использование векторного хранилища с вызовом функции
В приведенном ниже примере также создается 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 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
Ниже приведены некоторые действия.
- Измените имя функции поиска, чтобы отразить то, что находится в связанной коллекции записей, например, вы можете присвоить имя функции
SearchForHotels
, если коллекция записей содержит сведения о отеле. - Измените описание функции. Точное описание функции помогает модели ИИ выбрать лучшую функцию для вызова. Это особенно важно при добавлении нескольких функций поиска.
- Добавьте дополнительный параметр в функцию поиска. Если коллекция записей содержит сведения о отеле, а одно из свойств — имя города, которое можно добавить в функцию поиска, чтобы указать город. Фильтр будет автоматически добавлен и будет фильтровать результаты поиска по городу.
Совет
В приведенном ниже примере используется реализация поиска по умолчанию. Вы можете предоставить собственную реализацию, которая вызывает базовую коллекцию записей 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));
Скоро
В ближайшее время будет больше.
Скоро
В ближайшее время будет больше.