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:
- Injeção automática de contexto + armazenamento de turnos — a camada de integração faz isso por você.
- 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:
| Ferramenta | O 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
GraphMemoryServicecom injeção/armazenamento automático. Zero esforço do agente. - Um agente de aprendizado →
GraphMemoryService+ ferramentasremember/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ção | Fonte | Limite |
|---|---|---|
Earlier in this conversation: | Os eventos da sessão anterior | IntegrationConfig::max_history_injection (padrão 20 turnos) |
Relevant recalled context: | MemoryService::search | IntegrationConfig::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
_sessione 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.