Partilhar via


Adicionando geração aumentada de recuperação (RAG) a agentes semânticos do kernel

Advertência

A funcionalidade RAG do Semantic Kernel Agent é experimental, sujeita a alterações e só será finalizada com base em feedback e avaliação.

Usando o TextSearchProvider para RAG

O Microsoft.SemanticKernel.Data.TextSearchProvider permite que os agentes recuperem documentos relevantes com base na entrada do usuário e os injetem no contexto do agente para respostas mais informadas. Ele integra uma Microsoft.SemanticKernel.Data.ITextSearch instância com agentes do Kernel Semântico. Existem várias ITextSearch implementações, suportando pesquisas de semelhança em repositórios vetoriais e integração com mecanismos de pesquisa. Mais informações podem ser encontradas aqui.

Nós também fornecemos um Microsoft.SemanticKernel.Data.TextSearchStore que oferece armazenamento vetorial simples e especializado de dados textuais para fins de Geração de Recuperação Aumentada. TextSearchStore tem um esquema interno para armazenar e recuperar dados textuais em um repositório vetorial. Se você deseja usar seu próprio esquema para armazenamento, confira VectorStoreTextSearch.

Configurando o TextSearchProvider

O TextSearchProvider pode ser usado com VectorStore e TextSearchStore para armazenar e pesquisar documentos de texto.

O exemplo a seguir demonstra como configurar e usar o TextSearchProvider com a TextSearchStore e InMemoryVectorStore para um agente executar RAG simples sobre texto.

// 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);

Recursos avançados: citações e filtragem

O TextSearchStore suporta recursos avançados, como filtragem de resultados por namespace e inclusão de citações em respostas.

Incluindo citações

Documentos no TextSearchStore podem incluir metadados como nomes de origem e links, permitindo a geração de citações nas respostas dos agentes.

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"]
    }
});

Quando o TextSearchProvider recupera este documento, ele incluirá, por padrão, o nome da fonte e o link em sua resposta.

Filtrando por namespace

Ao atualizar documentos, você pode, opcionalmente, fornecer um ou mais namespaces para cada documento. Namespaces podem ser qualquer cadeia de caracteres que define o escopo de um documento. Em seguida, pode configurar a TextSearchStore para limitar os resultados de pesquisa apenas aos registos que correspondem ao namespace solicitado.

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

RAG automático vs sob demanda

O TextSearchProvider pode realizar pesquisas automaticamente durante cada invocação de agente ou permitir pesquisas sob demanda por meio de chamadas de ferramenta quando o agente precisar de informações adicionais.

A configuração padrão é BeforeAIInvoke, o que significa que as pesquisas serão realizadas antes de cada invocação do agente usando a mensagem passada para o agente. Isso pode ser alterado para OnDemandFunctionCalling, o que permitirá que o Agente faça uma chamada de ferramenta para fazer pesquisas usando uma cadeia de caracteres de pesquisa escolhida pelo agente.

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

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

Advertência

Ao utilizar o TextSearchProvider com OnDemandFunctionCalling, a configuração UseImmutableKernel no agente deve ser definida como true, pois o recurso requer a clonagem do kernel ao chamar o agente. Observe que a configuração UseImmutableKernel para true significará que quaisquer modificações de dados do kernel feitas durante a invocação do agente por, por exemplo, plugins, não serão retidas após a conclusão da invocação.

Opções de TextSearchProvider

O TextSearchProvider pode ser configurado com várias opções para personalizar seu comportamento. As opções são fornecidas usando a TextSearchProviderOptions classe para o TextSearchProvider construtor.

Início

Especifica o número máximo de resultados a serem retornados da pesquisa de similaridade.

  • Padrão: 3

Tempo de Pesquisa

Controla quando a pesquisa de texto é executada. As opções incluem:

  • BeforeAIInvoke: Uma pesquisa é realizada cada vez que o modelo/agente é invocado, imediatamente antes da invocação, e os resultados são fornecidos ao modelo/agente através do contexto de invocação.
  • OnDemandFunctionCalling: Uma pesquisa pode ser realizada pelo modelo/agente sob demanda por meio de chamada de função.

NomeDaFunçãoDoPlugin

Especifica o nome do método de plug-in que será disponibilizado para pesquisa se SearchTime estiver definido como OnDemandFunctionCalling.

  • Padrão: "Pesquisar"

Descrição da Função do Plugin

Fornece uma descrição do método de plug-in que será disponibilizado para pesquisa se SearchTime estiver definido como OnDemandFunctionCalling.

  • Padrão: "Permite pesquisar informações adicionais para ajudar a responder à pergunta do usuário."

ContextPrompt

Ao fornecer os blocos de texto para o modelo de IA na invocação, é necessário um prompt para indicar ao modelo de IA para que servem os blocos de texto e como eles devem ser usados. Essa configuração permite substituir as mensagens padrão incorporadas ao TextSearchProvider.

PromptDeIncluirCitações

Ao fornecer os blocos de texto para o modelo de IA na invocação, é necessário um prompt para dizer ao modelo de IA se e como fazer citações. Essa configuração permite substituir as mensagens padrão incorporadas ao TextSearchProvider.

Formatador de Contexto

Esta função de retorno opcional pode ser usada para personalizar completamente o texto produzido pelo TextSearchProvider. Por padrão, o TextSearchProvider produzirá texto que inclui

  1. Um prompt informando ao modelo de IA para que servem os blocos de texto.
  2. A lista de blocos de texto com links e nomes de fontes.
  3. Um prompt instruindo o modelo de IA sobre a inclusão de citações.

Você pode escrever sua própria saída implementando e fornecendo esse retorno de chamada.

Nota: Se este delegado for fornecido, as configurações ContextPrompt e IncludeCitationsPrompt não serão usadas.

Combinando RAG com outros provedores

O TextSearchProvider pode ser combinado com outros provedores, como mem0 ou WhiteboardProvider, para criar agentes com recursos de memória e recuperação.

// 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);

Ao combinar esses recursos, os agentes podem oferecer uma experiência mais personalizada e sensível ao contexto.

Próximos passos

Brevemente

Mais informações em breve.

Brevemente

Mais informações em breve.