Activaste el prompt caching esperando que tus preguntas repetidas salieran baratas, y tus tokens de entrada sí recibieron un descuento. Pero el modelo igual se despierta, igual razona la tarea, igual llama a cada herramienta y igual escribe la respuesta completa desde cero, cada vez, incluso cuando alguien hace exactamente la misma pregunta que respondió hace un minuto. El prompt caching descuenta la entrada que vuelves a enviar. Nunca reutiliza la respuesta.
Aquí está la parte que duele. Tu agente ya sabe la respuesta a buena parte de lo que le preguntan. Alguien pregunta "¿qué documentos necesito para viajar a Japón?" en la mañana, y para la tarde otras tres personas han preguntado lo mismo con tres redacciones distintas, y tu agente paga el precio completo por las cuatro. El ahorro real no vive en los tokens de entrada. Vive en el trabajo que puedes saltarte: la respuesta que ya generaste, el plan que ya resolviste, la API que ya llamaste. El prompt caching no puede alcanzar nada de eso, porque nunca mira el significado.
De esa capa trata esta serie. Cuando cacheas por significado en lugar de por texto exacto, una pregunta repetida regresa en milisegundos sin generación, y una pregunta nueva pero similar se salta la mayor parte de la exploración que el agente rehacería. En este primer post mapeo dónde puede cachear un agente de IA, te muestro los cachés a nivel de aplicación que eliminan trabajo en lugar de descontarlo (el caché semántico de respuesta y el caché de razonamiento), y comparto los resultados medidos y las trampas de un despliegue.
Este es el primer post de una serie. Todo el código está en este repositorio, sobre dos backends intercambiables. Puedes empezar con los notebooks locales de Jupyter, que cachean un agente Strands desde tu máquina con nada más que credenciales de AWS (sin CDK, sin VPC), y los stacks de producción despliegan el mismo patrón con AWS CDK (Cloud Development Kit). Los siguientes dos posts cubren cada backend a fondo. Está construido sobre Strands Agents.
Lo que hace que todo esto sea sencillo es dónde vive el caché. No es un envoltorio pegado alrededor del agente; se conecta al propio ciclo de vida del agente. Strands expone dos capacidades que sostienen todo el diseño. Los Hooks te permiten suscribirte a eventos a lo largo del bucle del agente y reaccionar a ellos: un hook al inicio de una petición puede responder desde el caché y detener el modelo antes de que corra, un hook antes de una llamada a herramienta puede devolver un resultado almacenado para que la herramienta real nunca se ejecute, y un hook al final puede capturar lo que pasó para la próxima vez. La Memory le da al agente conocimiento duradero que persiste entre sesiones, que es donde viven los planes y las trayectorias reutilizadas. Los cachés son componentes normales de Strands; la única llamada que hace tu aplicación sigue siendo agent(question). Los siguientes posts muestran el cómo; este trata del qué y el porqué. El código está aquí y las capacidades están documentadas en las guías de Strands hooks y Strands memory.
⚠️ Este post asume familiaridad con agentes de IA.
¿Por qué no basta con el prompt caching?
Todos los proveedores de modelos importantes ofrecen prompt caching. El prefijo procesado de tu prompt se reutiliza, así que pagas menos por los tokens de entrada repetidos. Es valioso, y nunca devuelve una respuesta almacenada. En palabras de los propios proveedores, "el prompt caching no tiene efecto en la generación de tokens de salida" (Anthropic), y "el prompt caching no cambia cómo el modelo genera los tokens de salida" (OpenAI).
Mira lo que cuesta una sola pregunta repetida. Tu agente respondió "¿Qué tiempo hace en Madrid?" hace tres segundos. Un segundo usuario pregunta "¿Cómo está el clima en Madrid?" y el agente corre el bucle completo otra vez: ciclos de planificación, llamadas a herramientas y generación. Un tercer usuario pregunta lo mismo en inglés, "What's the weather in Madrid?", y paga el precio completo una tercera vez. El prompt caching descontó el prefijo de entrada y nada más, y una redacción distinta o un idioma distinto es un prefijo distinto, así que nunca coincide. La gestión de conversación recorta el historial, pero no puede detectar que la pregunta en sí es una paráfrasis de una ya respondida. Misma respuesta, precio completo, tres veces.
Dónde puede cachear un agente de IA
Un agente de IA puede cachear en cinco capas. Dos las obtienes gratis (el proveedor del modelo te da el prompt caching, tu framework de agente te da la gestión de conversación); las otras tres las construyes tú. Este sample construye esas tres:
| Capa | Qué ahorra | Quién la provee |
|---|---|---|
| Prompt caching | El precio de los tokens de entrada en prefijos repetidos; el modelo igual genera cada respuesta | El proveedor del modelo |
| Gestión de conversación | Tokens del historial reenviados en cada turno | Tu framework de agente |
| Caché semántico de respuesta | La generación completa en una pregunta repetida (0 tokens en un acierto) | Tú (este sample) |
| Caché de razonamiento | Ciclos de planificación en una pregunta nueva pero similar (el modelo igual genera) | Tú (este sample) |
| Caché de resultado de herramienta | La llamada a la API externa en sí: su latencia, su costo de terceros y sus límites de tasa | Tú (este sample) |
El prompt caching viene del proveedor del modelo (tú lo activas, el proveedor hace el cacheo) y la gestión de conversación viene de tu framework de agente (Strands trae gestores de ventana deslizante y de resumen); este sample no reimplementa ninguno de los dos. Construye los últimos tres, los cachés a nivel de aplicación. Ahí está el ahorro real, porque saltan trabajo en lugar de descontarlo: el caché de respuesta salta la generación completa, el caché de razonamiento recorta ciclos de planificación, y el caché de resultado de herramienta salta la llamada a la API externa. El marco de decisión es una pregunta por capa. ¿Se repite la pregunta (caché de respuesta), se repite el razonamiento (caché de razonamiento), o se repite la llamada a herramienta (caché de resultado de herramienta)?
¿Cómo funciona un caché semántico de respuesta?
Un caché semántico de respuesta empareja las preguntas entrantes con las ya respondidas por significado, no por texto exacto. Genera el embedding de la pregunta entrante con un modelo de embeddings, corre una búsqueda vectorial de la pregunta ya respondida más cercana, y en un acierto por encima de un umbral de similitud (0.85 por defecto en el sample) devuelve la respuesta almacenada. Cero generación. En un fallo, corre el agente y guarda el nuevo par con un TTL (Time To Live, tiempo de vida).
La similitud por sí sola te va a mentir, así que el sample añade tres guardas:
- Guarda de parámetros críticos. "Vuelos el 2026-09-15" y "vuelos el 2026-12-15" puntúan ~0.97 de similitud coseno en el harness de calibración del repo, lo bastante cerca como para que el embedding las trate como la misma pregunta. La redacción puede variar libremente (para eso está el embedding); solo las fechas y los números extraídos de ambas preguntas deben coincidir exactamente. Mismas fechas, redacción distinta es un acierto; misma redacción, fecha distinta es un fallo.
- Modo reescritura. En un acierto donde la respuesta cacheada está en un idioma distinto al de la pregunta, una llamada barata reexpresa esa respuesta ya verificada en el idioma de la pregunta. No vuelve a correr el agente ni las herramientas y no investiga ni añade datos, solo traduce la respuesta almacenada (una pregunta en español contra una respuesta cacheada en inglés costó ~195 tokens por la traducción, frente a una corrida completa del agente). Si la respuesta ya está en el idioma correcto, se devuelve sin cambios.
- Fallo abierto (fail open). Si el almacén de caché o la llamada de embedding fallan, el agente corre normalmente. El caché es una optimización, nunca una dependencia.
¿Cómo funciona un caché de razonamiento?
El caché de respuesta se dispara cuando la pregunta se repite. El caché de razonamiento se dispara cuando la pregunta es nueva pero similar. La respuesta cambia, pero la trayectoria (qué herramientas, en qué orden) es estable. El clima de Madrid y el clima de Roma necesitan datos distintos de las mismas dos llamadas a herramientas.
El sample lo construye con hooks del ciclo de vida del agente. Cuando llega una pregunta similar, el hook inyecta el plan conocido y la trayectoria de herramientas antes del primer ciclo, para que el agente vaya directo a las herramientas correctas en lugar de redescubrirlas. Las llamadas a herramientas repetidas se sirven desde el caché de resultado de herramienta, con políticas de frescura ajustadas a la volatilidad de cada herramienta. La geocodificación puede vivir semanas, el clima horas, los precios minutos, y ante un error de API se sirve un resultado viejo en lugar de fallar la corrida.
¿Cuánto ahorró en una demo?
Medido sobre el sample desplegado (Amazon Nova Lite, us-east-1), verificado en agosto de 2026:
| Métrica | Corrida en frío | Corrida en caliente | Ahorro |
|---|---|---|---|
| Razonamiento: ciclos del bucle | 5 | 2 | 60% |
| Razonamiento: tokens totales | 7,000 | 2,965 | 58% (4,035 tokens) |
| Razonamiento: ejecuciones de herramientas | 3 | 0 | 100% |
A lo largo de las corridas de prueba, el ahorro en caliente osciló entre el 40% y el 85% de tokens y ciclos, porque la exploración en frío la dirige el modelo; el ahorro en ejecuciones de herramientas se mantuvo estable. Como referencia externa, el benchmark publicado por AWS para el cacheo semántico reporta hasta un 86% de ahorro de costo y 88% de reducción de latencia.
Las trampas que me costaron tiempo
- La primera iteración no ahorró nada. El plan hint se inyectaba de una forma que el agente ignoraba, y las corridas en frío y en caliente costaban lo mismo hasta que se arregló el prompt del hint. Mide el ahorro con corridas reales; nunca asumas que el hint llegó.
- Errores de medición por arranque en frío. La primera petición paga la creación del índice y el establecimiento de la conexión. Mide aciertos y fallos por separado, después del calentamiento.
- Ajustar el umbral es dato, no folclore. Cada acierto en el sample reporta su puntaje de similitud y los casi-aciertos se registran, así que el umbral se ajusta con tráfico real en lugar de a ojo.
- Una respuesta cacheada puede estar equivocada mañana. La guarda de parámetros críticos mantiene separadas las respuestas específicas de una fecha, y los TTL por herramienta expiran los datos volátiles (un precio de vuelo vive minutos, una geocodificación vive semanas) mientras las respuestas estables permanecen cacheadas.
- Un caché compartido es una superficie de seguridad. La respuesta cacheada de un usuario puede contener datos personales que recupera la pregunta similar de otro usuario, y el contenido leído de fuentes no confiables puede plantar instrucciones que se cachean y se reproducen. Detecta PII (Información de Identificación Personal) en la frontera del caché y valida lo que se escribe, con la misma disciplina que validar antes de que un agente escriba en la memoria, mantener el contenido envenenado fuera del vector store, y detener la inyección de prompts desde la salida de herramientas no confiables.
¿Sobre qué backend deberías desplegar?
El repositorio trae el mismo agente, las mismas herramientas y la misma UI web sobre dos tracks. Comparten el caché de respuesta y el de resultado de herramienta, y cada uno reutiliza el razonamiento a su manera. Uno le da pistas al agente mientras piensa, el otro guarda el plan terminado y lo reutiliza como plantilla. Elige por carga de trabajo, no por ranking.
| Track | Ideal para |
|---|---|
| En memoria (búsqueda vectorial en ElastiCache for Valkey) | Tráfico sostenido en la ruta caliente, la menor latencia de búsqueda; corre en una VPC (Virtual Private Cloud, nube privada virtual) |
| Serverless (búsqueda vectorial en Amazon DynamoDB, una tabla) | Tráfico irregular, sin costo de cómputo en reposo; sin VPC |
"En memoria" y "serverless" no son solo etiquetas para lo mismo con otro nombre. En memoria significa que el índice vectorial y los valores cacheados viven en la RAM de un nodo en ejecución (ElastiCache for Valkey), así que una búsqueda es una lectura de sub-milisegundo y nunca toca disco. Esa velocidad es el punto en una ruta caliente, pero el nodo corre y factura llegue o no tráfico, vive en una VPC, y su memoria es un tamaño fijo que aprovisionas.
Serverless (DynamoDB con búsqueda vectorial nativa) no tiene nodo que correr: la tabla escala bajo demanda, pagas por petición sin piso en reposo, no hay VPC, y la capacidad no es algo que dimensiones.
El costo es una latencia por búsqueda mayor que una lectura en RAM, aunque sigue muy por debajo de una llamada al LLM. Así que las diferencias reales son el piso de latencia, el costo en reposo, la huella de VPC y cómo se gestiona la capacidad, no la palabra en la caja. La lógica de caché, el agente, las herramientas y los resultados son idénticos en ambos; solo cambia el almacén de abajo.
El siguiente post de esta serie construye el track serverless de principio a fin, y el que le sigue profundiza en el track en memoria con las guardas de producción que necesita cada backend.
Preguntas frecuentes
¿Qué es el cacheo semántico para LLMs?
Un caché que empareja las preguntas entrantes con las ya respondidas por significado (similitud vectorial) en lugar de texto exacto. Ante una coincidencia por encima de un umbral de similitud, se devuelve la respuesta almacenada y el LLM (Large Language Model, gran modelo de lenguaje) nunca corre, ahorrando los tokens de esa invocación y la mayor parte de su latencia.
¿En qué se diferencia un caché semántico del prompt caching?
El prompt caching reutiliza el prefijo procesado de tu entrada para recortar el costo de los tokens de entrada; el modelo igual genera cada respuesta. Un caché semántico salta la generación por completo en un acierto. Se apilan; usa ambos.
¿Cuál es la diferencia entre un caché de respuesta y un caché de razonamiento?
El caché de respuesta se dispara cuando la pregunta se repite (respuesta almacenada, cero tokens). El caché de razonamiento se dispara cuando el razonamiento se repite en una pregunta nueva (plan y trayectoria de herramientas conocidos, menos ciclos y llamadas a herramientas).
¿Es seguro un caché semántico compartido para datos personales?
No por defecto. Valida antes de escribir, detecta PII en la frontera del caché, y particiona por inquilino en cuanto las respuestas dependan de quién pregunta. Trata el sample como una demo.
Despliega el sample, repite una pregunta, y mira cómo la segunda se salta el modelo por completo. Y luego cuéntame en los comentarios: ¿cuánto del tráfico de tu agente son preguntas que ya respondió?
Recursos
- Repositorio del sample: cachés semántico y de razonamiento para agentes de IA
- Cacheo semántico con ElastiCache (documentación de AWS)
- Búsqueda vectorial en Amazon DynamoDB (documentación de AWS)
- Well-Architected Agentic AI Lens: capas de cacheo del agente
- Documentación de hooks de Strands Agents
Gracias!



Top comments (0)