Arquitectura AWS — Módulo 6: estado y datos del agente
Sexto módulo del curso de arquitectura AWS: la memoria de la plataforma. Cada tipo de dato en su almacén — DynamoDB para sesiones y estado, Aurora/RDS para lo relacional, S3 como lago de todo, ElastiCache para lo caliente — y la decisión vectorial explicada: OpenSearch vs. Aurora pgvector vs. S3 Vectors, con la tabla de criterios para elegir según escala, latencia y costo.
☰ Índice del contenido
El módulo 3 dejó una regla — cómputo desechable, estado externo — y una deuda: ¿externo dónde? Este módulo la paga. Una plataforma de agentes genera y consume datos de naturalezas muy distintas (una sesión de conversación no se parece a un embedding, que no se parece a una factura), y el error de arquitectura típico no es elegir una base mala sino meter todo en la misma: el Postgres-para-todo que a los seis meses es cuello de botella, o el DynamoDB-para-todo que no puede responder la pregunta analítica más simple.
El principio del módulo es viejo y sano: cada tipo de dato en el almacén cuya forma de acceso coincide con la suya. AWS tiene un almacén administrado para cada forma; el trabajo de arquitectura es el reparto.
La tesis del módulo
El estado de una plataforma de agentes se reparte en cuatro formas de acceso — por clave (sesiones y estado), relacional (lo que se cruza y reporta), por similitud (lo que se busca por significado) y por objeto (todo lo demás, barato y para siempre) — y ningún almacén sirve bien a las cuatro. La pregunta de diseño nunca es “¿qué base uso?” sino “¿cómo se accede a este dato?”: la respuesta correcta a la segunda hace obvia la primera.
El reparto, dato por dato
Los datos que el catálogo de agentes del curso genera, con su forma de acceso y su casa natural:
| Dato del agente | Forma de acceso | Almacén | Por qué |
|---|---|---|---|
| Sesión / historial de conversación | Por clave (ID de sesión), lecturas rapidísimas | DynamoDB | Clave-valor administrado, latencia de milisegundos a cualquier escala, TTL nativo para expirar sesiones |
| Estado de flujos en curso (“cotización 123: esperando aprobación”) | Por clave, actualizaciones pequeñas y frecuentes | DynamoDB | Mismo perfil; el estado de Step Functions cubre el flujo, esto cubre el dominio |
| Clientes, cotizaciones, catálogo | Relacional: joins, transacciones, reportes | Aurora / RDS (PostgreSQL) | Es el dato de negocio clásico; SQL es su idioma |
| Embeddings para búsqueda semántica | Por similitud (vecinos más cercanos) | Vector store (decisión abajo) | Forma de acceso propia que ningún otro índice da |
| Documentos, transcripciones, artefactos | Por objeto completo, escritura una vez | S3 | Centavos por GB, durabilidad extrema, el punto de partida de todo pipeline |
| Caché de respuestas y datos calientes | Por clave, microsegundos, volátil | ElastiCache (Redis) | La capa que evita pagar dos veces lo ya calculado |
| Logs y trazas | Por tiempo, se escriben siempre y se leen poco | CloudWatch (módulo 11) | Almacén de observabilidad, no de negocio |
Dos matices que evitan sobre-arquitectura. Primero: S3 es el default silencioso — cuando dudes dónde va algo que se escribe una vez y se lee entero (una transcripción, un PDF, un artefacto del agente), es S3, y las demás bases guardan punteros al objeto, no el objeto. Segundo: DynamoDB y Aurora no compiten — la sesión del agente (clave, rápida, sin joins) y la cotización del negocio (relacional, transaccional, reportable) son formas distintas; la plataforma madura usa ambos sin drama.
Ojo — el historial es un honeypot: el almacén de sesiones concentra fragmentos de todo lo que pasó por los agentes — datos de clientes, decisiones, contexto interno. Es el activo de datos más sensible que la plataforma crea (antes no existía). Tres decisiones se toman el día uno, no tras el incidente: PII enmascarada antes de persistir (componente 5 de la landing zone), TTL/retención definida (¿por qué guardar conversaciones de hace 3 años?), y acceso por rol tan restringido como el dato más sensible que contiene. El módulo 10 remata con cifrado.
La decisión vectorial
La búsqueda semántica (el corazón de RAG) necesita un índice de vecinos más cercanos, y AWS ofrece tres caminos serios — más el atajo de dejar que Bedrock Knowledge Bases lo administre (módulo 9). La decisión, con criterios:
| Criterio | Aurora + pgvector | OpenSearch | S3 Vectors |
|---|---|---|---|
| Qué es | Extensión vectorial de tu Postgres | Motor de búsqueda dedicado (vector + texto/BM25) | Vectores nativos sobre S3 |
| Latencia | Baja | La más baja y estable a escala | ~100 ms en consultas frecuentes; sub-segundo en esporádicas |
| Escala cómoda | Millones de vectores | Cientos de millones | Hasta 2.000 millones por índice (GA dic. 2025), acceso menos frecuente |
| Costo | El de tu Aurora (marginal si ya existe) | El más alto (nodos/OCUs dedicados) | Hasta ~90% menos que las alternativas |
| Búsqueda híbrida (vector+keyword) | SQL + pgvector, artesanal | Nativa y madura | No es su fuerte |
| Cuándo elegirlo | Ya tienes Postgres y el volumen es moderado: cero piezas nuevas | Producción exigente: RAG a escala, latencia estricta, híbrida | Corpus enormes, consultas esporádicas, costo primero |
La lectura honesta: empieza por pgvector si ya tienes Aurora/Postgres en la arquitectura (y lo tienes: la fila relacional de arriba) — una pieza menos que operar es una victoria de arquitectura. Gradúa a OpenSearch cuando el volumen o la latencia lo exijan de verdad, con métricas en mano y no por prestigio. Considera S3 Vectors cuando el corpus es enorme y el patrón de consulta no justifica un índice caliente permanente — su llegada movió la economía del RAG frío. Y si el RAG completo lo administra Knowledge Bases (módulo 9), esta decisión se toma igual: KB te pide elegir el vector store de atrás.
El caché: la palanca de costo con forma de base
ElastiCache (Redis administrado) juega en la plataforma de agentes un papel mayor que en una app clásica, porque lo que evita repetir es caro:
- Caché de respuestas: la misma pregunta frecuente al asistente no paga inferencia dos veces. Con criterio — respuestas personalizadas o sensibles al tiempo no se cachean.
- Caché de datos de herramientas: el catálogo de productos que el cotizador consulta en cada corrida cambia una vez al día; leerlo de Redis en vez del CRM ahorra latencia y castigo al sistema origen.
- Deduplicación e idempotencia: la clave “¿ya procesé este mensaje?” del módulo 5 vive perfecta aquí — lecturas de microsegundos en el camino caliente de cada mensaje.
Nota que esto es distinto del prompt caching del proveedor de modelos (caso-04): aquel cachea el prefijo del prompt dentro de Bedrock; este cachea tus datos y respuestas dentro de tu plataforma. Se suman, no compiten.
EL MAPA DE DATOS DE LA PLATAFORMA
┌─────────────┐
│ agente │
└──────┬──────┘
│ cada dato a su almacén
┌──────────┬──┴───────┬──────────┐
▼ ▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│DynamoDB│ │ Aurora │ │ Redis │ │ S3 │
│sesiones│ │negocio+│ │ caché │ │objetos │
│ (+TTL) │ │pgvector│ │caliente│ │baratos │
└────────┘ └────────┘ └────────┘ └────────┘
Errores comunes
- Una base para todo. El Postgres-que-hace-de-cola-caché-y-vector funciona en la demo y colapsa por formas de acceso incompatibles en producción. El reparto por forma de acceso no es sobre-ingeniería: es la ingeniería.
- Guardar objetos gordos en la base. PDFs y transcripciones dentro de Aurora o DynamoDB infla costos y degrada todo. El objeto va a S3; la base guarda el puntero.
- Elegir OpenSearch por defecto para vectores. Es el mejor motor — y el más caro de operar. Si ya hay Postgres y el volumen es moderado, pgvector entrega casi todo con cero piezas nuevas. Se gradúa con métricas, no con miedo.
- Historial sin TTL ni política. Las sesiones se acumulan para siempre, con PII, hasta que la auditoría (o la fuga) pregunta por qué. Retención y enmascaramiento se deciden al crear la tabla.
- Cachear sin pensar qué no cachear. Una respuesta personalizada servida a otro usuario, o un precio de ayer servido hoy, es un incidente con forma de optimización. Toda regla de caché declara su invalidación.
- Ignorar que la decisión vectorial es re-visitable. Los embeddings se regeneran; migrar de pgvector a OpenSearch después es un proyecto mediano, no una condena. Elegir “lo grande por si acaso” al inicio sí es una condena — de costo.
La frase para llevarse
“No preguntes qué base usar; pregunta cómo se accede al dato: por clave, DynamoDB; con joins, Aurora; por significado, un vector store elegido con la tabla y no con el hype; por objeto, S3 con puntero. Y trata el historial de sesiones como lo que es: el dato más sensible que tu plataforma jamás creó.”
Qué viene
Módulo 7: el LLM gateway y Bedrock. Todas las piezas construidas hasta aquí rodean al ingrediente que faltaba: el modelo. Cómo consume modelos una plataforma en AWS — Bedrock como catálogo administrado (qué da: modelos, Converse API, inferencia cross-region, guardrails; qué cobra), cuándo un gateway propio delante (LiteLLM en tu ECS) sigue teniendo sentido, y el diseño de routing y fallback que hace que “se cayó el proveedor” sea una línea en los logs y no una página de incidente.
Material relacionado
Preguntas sobre este curso
Regístrate gratis para hacer preguntas y guardar tu progreso.
✉ Entérate de lo nuevo
Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.