Memória em Sessões Realtime

Uma voz que se esquece de você entre chamadas parece um quiosque. ADK-Rust permite que um agente em tempo real lembre — recupere o que aprendeu sobre um usuário antes de falar, e selecione novos fatos durante a conversa — ao conectar um MemoryService ao IntegratedRealtimeRunner.

Há dois mecanismos que cooperam:

  1. Injeção automática de contexto + armazenamento de turnos — a camada de integração faz isso por você.
  2. Memória curada pelo agente via tools — o agente decide o que vale a pena manter, usando tools de grafo de conhecimento conectadas.

1. Injeção automática e armazenamento

Anexe um MemoryService e o runner cuida do vai e volta:

let runner = IntegratedRealtimeRunner::builder()
    .model(model)
    .config(config)
    .identity("support", &user_id, &session_id)
    .session_service(sessions)
    .memory_service(memory.clone())
    .integration_config(IntegrationConfig {
        inject_memory_context: true,   // query memory at connect
        max_memory_injection: 10,      // cap injected items
        store_to_memory: true,         // write each completed turn back
        persist_transcripts: true,
    })
    .build()?;
  • Na conexão, a memória é consultada para o usuário e os resultados são incorporados ao contexto da sessão, de modo que o agente o cumprimente já conhecendo o histórico relevante.
  • A cada turno, as trocas concluídas são gravadas de volta (quando store_to_memory), então a próxima sessão se baseia nesta.

Qualquer MemoryService funciona — o em memória para desenvolvimento, ou o backend de grafo de conhecimento abaixo.

2. O backend de grafo de conhecimento

O GraphMemoryService de adk-memory armazena a memória como um grafo de conhecimento bi-temporal: entidades e relacionamentos, cada um acompanhado ao longo do tempo do evento (quando era সত্যico) e do tempo de ingestão (quando o sistema o aprendeu). Isso significa que o agente pode responder "qual é o plano atual do usuário?" sem tropeçar no fato de que antes era algo diferente — fatos substituídos permanecem no histórico em vez de sobrescrever o presente.

use adk_memory::GraphMemoryService;
use std::sync::Arc;

let kg = Arc::new(GraphMemoryService::new(/* backing store */));

Passe isso como o memory_service e a injeção automática acima passará a usar o grafo.

3. Permitindo que o agente faça a curadoria da memória

O padrão mais poderoso: dê ao agente tools para gravar no próprio grafo, para que ele se lembre de forma deliberada em vez de despejar cada transcrição. adk-tool (recurso graph-memory-tools) inclui duas que fazem a ponte diretamente para uma sessão realtime:

FerramentaO que o agente faz com ela
RememberTool (remember)Armazena um fato relevante ("prefere e-mail a telefone").
RelateTool (relate)Conecta duas entidades ("Pedido A-10293 → pertence a → este usuário").

Conecte-os com .adk_tool(...) (veja Ferramentas):

use adk_tool::{RememberTool, RelateTool};

let runner = IntegratedRealtimeRunner::builder()
    .model(model).config(config)
    .identity("support", &user_id, &session_id)
    .memory_service(kg.clone())
    .adk_tool(Arc::new(RememberTool::new(kg.clone())))
    .adk_tool(Arc::new(RelateTool::new(kg)))
    .build()?;

Depois, instrua o agente a usá-los:

When you learn a durable fact about the customer (a preference, an account
detail, a decision), call `remember` to store it. Use `relate` to link orders
or items to the customer. Recall naturally — don't announce that you're saving.

A recuperação é baseada em tokens: o grafo retorna as entidades/relações mais relevantes para a conversa, limitadas por max_memory_injection, então o contexto permanece pequeno mesmo à medida que o grafo cresce.

Escolhendo uma profundidade

  • Demonstração sem estado → sem memory_service. Cada sessão começa do zero.
  • Continuidade entre sessões → em memória ou GraphMemoryService com injeção/armazenamento automático. Zero esforço do agente.
  • Um agente de aprendizadoGraphMemoryService + ferramentas remember/relate, para que o agente organize um modelo limpo e consultável do usuário em vez de uma pilha de transcrições.

O exemplo de coaching MIA usa o grafo + ferramentas para que o coach se lembre das metas e preferências do usuário entre sessões; veja Exemplos.

Próximo: Construindo apps web →

O que é carregado em uma sessão retomada

IntegratedRealtimeRunner::connect constrói um bloco de contexto e o adiciona antes da instrução do sistema antes que a sessão do provedor seja criada:

SeçãoFonteLimite
Earlier in this conversation:Os eventos da sessão anteriorIntegrationConfig::max_history_injection (padrão 20 turnos)
Relevant recalled context:MemoryService::searchIntegrationConfig::max_memory_injection (padrão 10 entradas)

Ambos são limitados porque a instrução é enviada uma vez na criação da sessão e conta contra o contexto do modelo. Cada turno é renderizado como role: text, truncado em 400 caracteres, e turnos sem texto são descartados. Definir um limite como zero desativa essa seção.

IntegratedRealtimeRunner::instruction() retorna o que a sessão foi criada com, então o contexto transportado pode ser afirmado em vez de inferido:

runner.connect().await?;
let instruction = runner.instruction().await.unwrap_or_default();
assert!(instruction.contains("Relevant recalled context"));

Importante: este contexto foi carregado e descartado anteriormente — a sessão anterior foi buscada em _session e descartada, e o ramo de memória registrou "injecting memory entries into session context" ao lado de um comentário dizendo que a injeção seria uma melhoria futura. Uma sessão retomada começou sem nenhum dos dois, enquanto os logs diziam o contrário.