Добавление Retrieval Augmented Generation (RAG) в агенты семантического ядра

Предупреждение

Функция RAG агента семантического ядра является экспериментальной, подверженной изменению, и будет завершена только на основе отзывов и оценки.

Использование TextSearchProvider для RAG

Компонент Microsoft.SemanticKernel.Data.TextSearchProvider позволяет агентам получать соответствующие документы на основе пользовательского ввода и интегрировать их в контекст агента для более обоснованных ответов. Он интегрирует Microsoft.SemanticKernel.Data.ITextSearch экземпляр с агентами семантического ядра. Существует несколько ITextSearch реализаций, поддерживая поиск по сходству векторных хранилищ и интеграции с поисковыми системами. Дополнительные сведения см. здесь.

Кроме того, мы предоставляем простое Microsoft.SemanticKernel.Data.TextSearchStore, в котором используется векторное хранилище текстовых данных для целей улучшенной генерации. TextSearchStore имеет встроенную схему для хранения и получения текстовых данных в хранилище векторов. Если вы хотите использовать собственную схему для хранения, ознакомьтесь с vectorStoreTextSearch.

Настройка поставщика поиска текста

TextSearchProvider можно использовать вместе с VectorStore и TextSearchStore для хранения и поиска текстовых документов.

В следующем примере показано, как настроить и использовать TextSearchProvider вместе с TextSearchStore и InMemoryVectorStore для выполнения агентом простой процедуры RAG над текстом.

// Create an embedding generator using Azure OpenAI.
var embeddingGenerator = new AzureOpenAIClient(new Uri("<Your_Azure_OpenAI_Endpoint>"), new AzureCliCredential())
    .GetEmbeddingClient("<Your_Deployment_Name>")
    .AsIEmbeddingGenerator(1536);

// Create a vector store to store documents.
var vectorStore = new InMemoryVectorStore(new() { EmbeddingGenerator = embeddingGenerator });

// Create a TextSearchStore for storing and searching text documents.
using var textSearchStore = new TextSearchStore<string>(vectorStore, collectionName: "FinancialData", vectorDimensions: 1536);

// Upsert documents into the store.
await textSearchStore.UpsertTextAsync(new[]
{
    "The financial results of Contoso Corp for 2024 is as follows:\nIncome EUR 154 000 000\nExpenses EUR 142 000 000",
    "The Contoso Corporation is a multinational business with its headquarters in Paris."
});

// Create an agent.
Kernel kernel = new Kernel();
ChatCompletionAgent agent = new()
{
    Name = "FriendlyAssistant",
    Instructions = "You are a friendly assistant",
    Kernel = kernel,
    // This setting must be set to true when using the on-demand RAG feature
    UseImmutableKernel = true
};

// Create an agent thread and add the TextSearchProvider.
ChatHistoryAgentThread agentThread = new();
var textSearchProvider = new TextSearchProvider(textSearchStore);
agentThread.AIContextProviders.Add(textSearchProvider);

// Use the agent with RAG capabilities.
ChatMessageContent response = await agent.InvokeAsync("Where is Contoso based?", agentThread).FirstAsync();
Console.WriteLine(response.Content);

Дополнительные возможности: ссылки и фильтрация

Поддерживаются TextSearchStore расширенные функции, такие как фильтрация результатов по пространству имен и включение ссылок в ответах.

Включение ссылок

Документы в них могут включать метаданные TextSearchStore , такие как имена источников и ссылки, что позволяет создавать ссылки в ответах агента.

await textSearchStore.UpsertDocumentsAsync(new[]
{
    new TextSearchDocument
    {
        Text = "The financial results of Contoso Corp for 2023 is as follows:\nIncome EUR 174 000 000\nExpenses EUR 152 000 000",
        SourceName = "Contoso 2023 Financial Report",
        SourceLink = "https://www.contoso.com/reports/2023.pdf",
        Namespaces = ["group/g2"]
    }
});

При извлечении этого документа TextSearchProvider по умолчанию будет включать имя источника и ссылку в свой ответ.

Фильтрация по пространству имен

При вставке или обновлении документов можно при желании указать одно или несколько пространств имен для каждого документа. Пространства имен могут быть любой строкой, определяющей область документа. Затем можно настроить TextSearchStore, чтобы ограничить результаты поиска только теми записями, которые соответствуют запрошенному пространству имён.

using var textSearchStore = new TextSearchStore<string>(
    vectorStore,
    collectionName: "FinancialData",
    vectorDimensions: 1536,
    new() { SearchNamespace = "group/g2" }
);

Автоматический режим против режима по запросу RAG

TextSearchProvider может автоматически выполнять поиск во время каждого вызова агента или разрешать поиск по требованию с помощью инструментов, когда агент нуждается в дополнительной информации.

Параметр по умолчанию — BeforeAIInvokeэто означает, что поиск будет выполняться перед вызовом каждого агента с помощью сообщения, переданного агенту. Это можно изменить на OnDemandFunctionCalling, что позволит агенту выполнять вызов инструмента для поиска с использованием строки поиска, выбранной агентом.

var options = new TextSearchProviderOptions
{
    SearchTime = TextSearchProviderOptions.RagBehavior.OnDemandFunctionCalling,
};

var provider = new TextSearchProvider(mockTextSearch.Object, options: options);

Предупреждение

При использовании TextSearchProvider с OnDemandFunctionCalling параметр UseImmutableKernel агента должен быть установлен на true, так как функция требует клонирования ядра при вызове агента. Обратите внимание, что параметр UseImmutableKerneltrue будет означать, что все изменения данных ядра, выполненные во время вызова агента, например подключаемыми модулями, не будут храниться после завершения вызова.

Параметры TextSearchProvider

Его TextSearchProvider можно сконфигурировать с различными параметрами для изменения его поведения. Параметры предоставляются посредством класса TextSearchProviderOptions конструктору TextSearchProvider.

Верх

Указывает максимальное количество результатов, возвращаемых из поиска сходства.

  • По умолчанию: 3

ВремяПоиска

Управляет выполнением поиска текста. Возможные варианты:

  • BeforeAIInvoke: поиск выполняется при каждом вызове модели или агента перед вызовом, а результаты предоставляются модели или агента через контекст вызова.
  • OnDemandFunctionCalling: поиск может выполняться моделью или агентом по запросу с помощью вызова функции.

PluginFunctionName

Указывает имя подключаемого метода, который будет доступен для поиска, если SearchTime задано значение OnDemandFunctionCalling.

  • По умолчанию: "Поиск"

PluginFunctionDescription

Содержит описание метода подключаемого модуля, который будет доступен для поиска, если значению SearchTime задано OnDemandFunctionCalling.

  • Значение по умолчанию: "Позволяет искать дополнительные сведения, чтобы помочь ответить на вопрос пользователя".

ContextPrompt

При вызове модели искусственного интеллекта и предоставлении ей фрагментов текста необходимо указать, для чего эти фрагменты предназначены и как их следует использовать. Этот параметр позволяет переопределить сообщения по умолчанию, встроенные в систему TextSearchProvider.

Включить запрос на цитирование

При предоставлении фрагментов текста модели ИИ при вызове необходимо указать модели, следует ли делать ссылки и как это делать. Этот параметр позволяет переопределить сообщения по умолчанию, встроенные в систему TextSearchProvider.

ContextFormatter

Этот необязательный обратный вызов можно использовать для полной кастомизации текста, созданного элементом TextSearchProvider. По умолчанию TextSearchProvider будет создавать текст, содержащий

  1. Запрос, сообщающий модели ИИ, для чего предназначены фрагменты текста.
  2. Список фрагментов текста с исходными ссылками и именами.
  3. Запрос, инструктирующий модель ИИ о включении ссылок.

Вы можете написать собственные выходные данные, реализуя и предоставляя этот обратный вызов.

Примечание. Если этот делегат указан, ContextPromptIncludeCitationsPrompt параметры не будут использоваться.

Объединение RAG с другими поставщиками

Эта TextSearchProvider можно объединить с другими поставщиками, такими как mem0 или WhiteboardProvider, чтобы создавать агентов с возможностями памяти и извлечения.

// Add both mem0 and TextSearchProvider to the agent thread.
agentThread.AIContextProviders.Add(mem0Provider);
agentThread.AIContextProviders.Add(textSearchProvider);

// Use the agent with combined capabilities.
ChatMessageContent response = await agent.InvokeAsync("What was Contoso's income for 2023?", agentThread).FirstAsync();
Console.WriteLine(response.Content);

Сочетая эти функции, агенты могут обеспечить более персонализированный и контекстный интерфейс.

Дальнейшие шаги

Скоро

Дополнительные сведения в ближайшее время.

Скоро

Дополнительные сведения в ближайшее время.