Partilhar via


Fornecedor de Armazenamento do Histórico de Conversações

O ChatHistoryMemoryProvider é um Fornecedor de Contexto de IA que armazena todo o histórico de conversas em um armazenamento de vetores e recupera mensagens relacionadas de forma a complementar a conversa atual. Isto permite aos agentes recordar contexto relevante de interações anteriores através da pesquisa por similaridade semântica.

Como funciona

O fornecedor opera em duas fases:

  1. Armazenamento: Após cada invocação de agente, novas mensagens de pedido e resposta são armazenadas na loja vetorial com embeddings gerados a partir do seu conteúdo.

  2. Recuperação: Antes de cada invocação (ou on-demand via chamada de função), o fornecedor pesquisa no armazenamento vetorial mensagens semanticamente semelhantes à entrada atual do utilizador e injeta-as como contexto.

As mensagens armazenadas são definidas usando identificadores configuráveis (aplicação, agente, utilizador, sessão), permitindo um controlo detalhado sobre que histórico é armazenado e pesquisável.

Pré-requisitos

Sugestão

Consulte a documentação de integração do Vector Stores para mais informações sobre a abstração do VectorData e as implementações disponíveis.

Usage

O exemplo seguinte demonstra a criação de um agente com o ChatHistoryMemoryProvider usando um armazenamento vetorial em memória.

Note o uso apenas do userid para o âmbito de pesquisa. Isto permite ao agente recordar informações de conversas anteriores com o mesmo utilizador para informar novas respostas.

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.InMemory;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") 
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
var embeddingDeploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME") 
    ?? "text-embedding-3-large";

// Create a vector store with an embedding generator.
// For production, replace InMemoryVectorStore with a persistent store.
VectorStore vectorStore = new InMemoryVectorStore(new InMemoryVectorStoreOptions()
{
    EmbeddingGenerator = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
        .GetEmbeddingClient(embeddingDeploymentName)
        .AsIEmbeddingGenerator()
});

// Create the agent with ChatHistoryMemoryProvider
AIAgent agent = new AzureOpenAIClient(
    new Uri(endpoint),
    new DefaultAzureCredential())
    .GetChatClient(deploymentName)
    .AsAIAgent(new ChatClientAgentOptions
    {
        ChatOptions = new() { Instructions = "You are a helpful assistant." },
        Name = "MemoryAgent",
        AIContextProviders = [new ChatHistoryMemoryProvider(
            vectorStore,
            collectionName: "chathistory",
            vectorDimensions: 3072,
            session => new ChatHistoryMemoryProvider.State(
                // Configure where messages are stored
                storageScope: new() { UserId = "user-123", SessionId = Guid.NewGuid().ToString() },
                // Configure where to search (can be broader than storage scope)
                searchScope: new() { UserId = "user-123" }))]
    });

// Start a session and interact with the agent
AgentSession session = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("I prefer window seats on flights.", session));

// Start a new session - the agent can recall the user's preference
AgentSession session2 = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("Book me a flight to Seattle.", session2));

Sugestão

Utilize diferentes configurações de storageScope e searchScope para controlar o isolamento de memória. Por exemplo, armazene por sessão, mas procure em todas as sessões de um utilizador.

Opções de configuração

A ChatHistoryMemoryProviderOptions classe fornece configuração para o comportamento do fornecedor.

Comportamento da pesquisa

Option Tipo Predefinição Descrição
SearchTime SearchBehavior BeforeAIInvoke Controla quando a pesquisa de memória é executada.

O SearchBehavior enum tem dois valores:

  • BeforeAIInvoke: Procura automaticamente memórias relevantes antes de cada invocação da IA e injeta-as como mensagens de contexto. Este é o comportamento padrão.
  • OnDemandFunctionCalling: Expõe uma ferramenta funcional que o modelo de IA pode invocar para pesquisar memórias a pedido. Usa isto quando quiseres que o modelo decida quando recordar memórias.

Opções de resultados de pesquisa

Option Tipo Predefinição Descrição
MaxResults int? 3 Número máximo de resultados do histórico de conversas para obter por pesquisa.
ContextPrompt string? "## Memories\nConsider the following memories..." O texto do prompt precedia os resultados da pesquisa antes da injeção.

Opções de ferramentas de função sob demanda

Estas opções só se aplicam quando SearchTime está definido para OnDemandFunctionCalling:

Option Tipo Predefinição Descrição
FunctionToolName string? "Search" O nome da ferramenta de pesquisa disponibilizada ao modelo.
FunctionToolDescription string? "Allows searching for related previous chat history..." A descrição da ferramenta de pesquisa.

Filtragem de mensagens

Option Tipo Predefinição Descrição
SearchInputMessageFilter Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? Apenas mensagens externas Filtro aplicado a mensagens de pedido ao construir consultas de pesquisa.
StorageInputRequestMessageFilter Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? Apenas mensagens externas Filtro aplicado a mensagens de pedido antes do armazenamento.
StorageInputResponseMessageFilter Func<IEnumerable<ChatMessage>, IEnumerable<ChatMessage>>? Sem filtro Filtro aplicado às mensagens de resposta antes do armazenamento.

Registo e telemetria

Option Tipo Predefinição Descrição
EnableSensitiveTelemetryData bool false Quando true, dados sensíveis (IDs de utilizador, conteúdo das mensagens) aparecem nos registos inalterados.
Redactor Redactor? Editor que substitui texto por "<redacted>" Redator personalizado para valores sensíveis ao registar. Ignorado se EnableSensitiveTelemetryData estiver true.

Gestão do Estado

Option Tipo Predefinição Descrição
StateKey string? Nome do tipo de fornecedor Chave usada para armazenar o estado do fornecedor no AgentSession.StateBag. Substituir ao usar múltiplas ChatHistoryMemoryProvider instâncias na mesma sessão.

Configuração do âmbito

A ChatHistoryMemoryProviderScope classe controla como as mensagens são organizadas e filtradas na loja vetorial.

Propriedade Tipo Descrição
ApplicationId string? Restrinja as mensagens a uma aplicação específica. Se não estiver definido, abrange todas as aplicações.
AgentId string? Direcione as mensagens para um agente específico. Se não estiver definido, abrange todos os agentes.
UserId string? Direcione as mensagens para um utilizador específico. Se não estiver definido, abrange todos os utilizadores.
SessionId string? Limite as mensagens a uma sessão específica.

Armazenamento vs âmbito de pesquisa

A ChatHistoryMemoryProvider.State classe aceita dois escopos:

  • storageScope: Define como as novas mensagens são etiquetadas quando armazenadas. Todas as propriedades do âmbito são escritas como metadados.
  • searchScope: Define os critérios do filtro ao pesquisar. Defina este âmbito mais amplo do que o armazenamento para pesquisar em várias sessões ou agentes.

Exemplo: Armazenar por sessão, pesquisar em todas as sessões de um utilizador.

new ChatHistoryMemoryProvider.State(
    storageScope: new() { UserId = "user-123", SessionId = "session-456" },
    searchScope: new() { UserId = "user-123" })

Considerações de segurança

Advertência

Analise estas considerações de segurança antes de implementar o ChatHistoryMemoryProvider em produção.

  • Injeção indireta de prompt: As mensagens recuperadas do armazém vetorial são injetadas no contexto do LLM. Se o armazenamento vetorial for comprometido, o conteúdo adversarial pode influenciar o comportamento dos LLMs. Os dados da loja são aceites as-is sem validação.

  • PII e dados sensíveis: Mensagens de conversa (incluindo entradas de utilizador e respostas de LLM) são armazenadas como vetores. Estas mensagens podem conter PII ou informações sensíveis. Garanta que a sua loja vetorial tem controlos de acesso adequados e encriptação em repouso.

  • Ferramenta de pesquisa on-demand: Ao usar OnDemandFunctionCalling, o modelo de IA controla quando e o que procurar. A consulta de pesquisa é gerada por IA e deve ser tratada como entrada não confiável pela implementação do vector store.

  • Registo de traços: Quando LogLevel.Trace está ativado, as consultas e resultados completos da pesquisa podem ser registados. Estes dados podem conter PII. Utilize a Redactor opção ou então desative a telemetria sensível em produção.

Este fornecedor ainda não está disponível para Python. Consulte o separador C# para exemplos de utilização.

Passos seguintes