Memoria en sesiones en tiempo real
Una voz que te olvida entre llamadas se siente como un quiosco. ADK-Rust permite a un
agente en tiempo real recordar —recuperar lo que aprendió sobre un usuario antes de
hablar, y curar nuevos hechos en mitad de la conversación— conectando una MemoryService en
la IntegratedRealtimeRunner.
Hay dos mecanismos que cooperan:
- Inyección automática de contexto + almacenamiento por turno — la capa de integración hace esto por ti.
- Memoria curada por el agente mediante herramientas — el agente decide qué merece la pena conservar, usando herramientas de grafo de conocimiento puenteadas.
1. Inyección y almacenamiento automáticos
Adjunta una MemoryService y el runner se encarga del ida y vuelta:
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()?;
- Al conectar, se consulta la memoria del usuario y los resultados se incorporan en el contexto de la sesión, de modo que el agente los saluda ya conociendo el historial relevante.
- Por turno, los intercambios completados se escriben de vuelta (cuando
store_to_memory), así la siguiente sesión se apoya en esta.
Cualquier MemoryService funciona — la de memoria en el proceso para desarrollo, o el
backend de grafo de conocimiento de abajo.
2. El backend de grafo de conocimiento
adk-memory GraphMemoryService almacena la memoria como un grafo de conocimiento
bi-temporal: entidades y relaciones, cada una rastreada a lo largo del tiempo de evento
(cuándo era cierto) y del tiempo de ingesta (cuándo el sistema lo aprendió). Eso significa
que el agente puede responder "¿cuál es el plan actual del usuario?" sin tropezar
con el hecho de que antes era otra cosa — los hechos superados permanecen en el historial
en lugar de sobrescribir el presente.
use adk_memory::GraphMemoryService;
use std::sync::Arc;
let kg = Arc::new(GraphMemoryService::new(/* backing store */));
Pásalo como la memory_service y la inyección automática de arriba ahora se apoya en
el grafo.
3. Permitir que el agente cure la memoria
El patrón más poderoso: dale al agente herramientas para escribir en el propio grafo,
de modo que recuerde deliberadamente en lugar de volcar cada transcripción. adk-tool
(función graph-memory-tools) incluye dos que se integran directamente en una sesión
en tiempo real:
| Herramienta | Qué hace el agente con ella |
|---|---|
RememberTool (remember) | Almacenar un hecho relevante ("prefiere el correo electrónico al teléfono"). |
RelateTool (relate) | Conectar dos entidades ("Order A-10293 → belongs-to → este usuario"). |
Conéctalos con .adk_tool(...) (ver Tools):
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()?;
Luego indica al agente que los use:
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.
El recuerdo es basado en tokens: el grafo devuelve las entidades/relaciones más
relevantes para la conversación, limitado por max_memory_injection, de modo que el contexto se
mantiene pequeño incluso cuando el grafo crece.
Elegir una profundidad
- Demostración sin estado → sin
memory_service. Cada sesión empieza desde cero. - Continuidad entre sesiones → en memoria o
GraphMemoryServicecon inyección/almacenamiento automáticos. Cero esfuerzo del agente. - Un agente de aprendizaje →
GraphMemoryService+ herramientasremember/relate, para que el agente curará un modelo limpio y consultable del usuario en lugar de un montón de transcripciones.
El ejemplo de coaching MIA usa el grafo + herramientas para que el coach recuerde los objetivos y preferencias del usuario entre sesiones; ver Examples.
Siguiente: Building web apps →
Qué se перенос into una sesión reanudada
IntegratedRealtimeRunner::connect construye un bloque de contexto y lo antepone a la instrucción del sistema
antes de que se cree la sesión del proveedor:
| Sección | Fuente | Límite |
|---|---|---|
Earlier in this conversation: | Los eventos de la sesión anterior | IntegrationConfig::max_history_injection (20 turnos por defecto) |
Relevant recalled context: | MemoryService::search | IntegrationConfig::max_memory_injection (10 entradas por defecto) |
Ambos están acotados porque la instrucción se envía una vez al crear la sesión y cuenta contra
el contexto del modelo. Cada turno se renderiza como role: text, truncado a 400 caracteres, y
los turnos sin texto se descartan. Establecer un límite en cero deshabilita esa sección.
IntegratedRealtimeRunner::instruction() devuelve lo con lo que se creó la sesión, de modo que el
contexto transportado puede afirmarse en lugar de inferirse:
runner.connect().await?;
let instruction = runner.instruction().await.unwrap_or_default();
assert!(instruction.contains("Relevant recalled context"));
Importante: este contexto se cargó y descartó previamente: la sesión anterior se obtuvo en
_sessiony se descartó, y la rama de memoria registró "injecting memory entries into session context" junto a un comentario que indicaba que la inyección era una mejora futura. Una sesión reanudada comenzó sin ninguno de los dos, mientras que los registros decían lo contrario.