
De tu laptop a producción: desplegar agentes de IA con Amazon Bedrock AgentCore
Acabas de construir un agente genial. Corre en tu máquina, le preguntas algo y te responde justo como querías. El siguiente paso natural es que otras personas lo usen: enseñárselo a tus amigos, ponerlo en línea, que viva en algún lado que no sea tu terminal.
Ya construiste tu agente. Ahora, ¿cómo lo usan los demás?
Acabas de construir un agente genial. Corre en tu máquina, le preguntas algo y te responde justo como querías. El siguiente paso natural es que otras personas lo usen: enseñárselo a tus amigos, ponerlo en línea, que viva en algún lado que no sea tu terminal.
Y ahí aparece la parte difícil. Tu agente solo existe mientras tengas la terminal abierta; si la cierras, deja de existir. No aguanta a muchos usuarios a la vez, y no tienes forma de ver qué hizo cuando algo sale mal. Es el clásico "funciona en mi máquina", pero para agentes.
Amazon Bedrock AgentCore es donde corre tu agente en producción. Le da un lugar donde vivir, escala cuando le caen muchos usuarios, aísla a cada persona, le puede dar memoria, y te deja ver qué está haciendo por dentro. Lo importante: no es un framework de agentes. No reemplaza a Strands ni a LangGraph ni te pide reescribir nada. Tomas el agente que ya tienes y AgentCore lo lleva a producción. En este artículo vemos cómo, con el ejemplo de Ritmo, un asistente de una plataforma de streaming de música.
Si todavía no construiste tu primer agente, empieza por Tu primer agente de IA con Strands Agents . Aquí asumo que ya tienes uno y que lo que quieres es desplegarlo.
El agente de ejemplo: Ritmo
Ritmo responde dudas de la cuenta del usuario: su plan, cuánto ha escuchado, cuándo se le renueva. Es un agente de Strands común: un modelo que razona, un system prompt con sus instrucciones, y una herramienta que puede llamar cuando necesita datos. El código completo está en
agente_local.py ; aquí me quedo con la decisión de diseño que importa para el resto del artículo.En vez de darle la base de datos, le damos una herramienta
Ritmo necesita datos del usuario, y hay dos formas de dárselos. La fácil es conectar el agente directo a la base de datos. La que uso aquí: el agente llama a una herramienta, y esa herramienta le pide los datos a un servicio interno que es el único que toca la base. El agente nunca ve la base de datos.

La herramienta es apenas unas líneas, y llama a
servicio_datos.py :1
2
3
4
5
6
7
8
9
10
11
def consultar_cuenta(usuario_id: str) -> str:
"""Devuelve el resumen de la cuenta: plan, precio, renovación y actividad."""
cuenta = obtener_cuenta(usuario_id) # llama al servicio, no a la base
if cuenta is None:
return "No encuentro esa cuenta. ¿Puedes confirmar el identificador?"
return (
f"Plan {cuenta['plan']}, ${cuenta['precio_mxn']} MXN al mes, "
f"renueva el {cuenta['renovacion']}. "
f"Este mes: {cuenta['horas_mes']} horas escuchadas."
)¿Por qué este rodeo? Por seguridad, aislamiento y porque te deja las manos libres para cambiar los datos después:
- Seguridad. Un modelo que arma consultas contra tu base de producción a partir de texto de usuario es un riesgo. Si llega un prompt malicioso, no quieres que se convierta en un query malicioso. Como el agente no arma consultas, ese vector desaparece.
- Aislamiento. El agente corre en un entorno gestionado por AgentCore. Darle credenciales de base de datos ahí rompe ese límite.
- Contrato estable. La herramienta es el contrato. Lo de adentro del servicio puede cambiar (hoy un diccionario, mañana una base real) sin tocar el agente.
Esta misma idea de separar el agente de los datos vuelve más adelante, cuando hablemos de Gateway.
Las cuatro líneas que lo vuelven desplegable
Para que AgentCore pueda correr tu agente, solo le agregas cuatro líneas. Vamos una por una.
1. Importa AgentCore.
1
from bedrock_agentcore.runtime import BedrockAgentCoreApp2. Inicializa la aplicación. Esto es lo que AgentCore va a correr.
1
app = BedrockAgentCoreApp()3. Marca la puerta de entrada. El decorador le dice a AgentCore qué función recibe cada petición. El
payload trae el prompt del usuario; el context trae metadatos como el session_id.1
2
3
4
5
def invocar(payload, context=None):
mensaje = payload.get("prompt", "")
resultado = agente(mensaje)
return {"result": resultado.message}4. Arranca el servidor.
1
2
if __name__ == "__main__":
app.run()Eso es todo. El modelo, el system prompt y la herramienta no cambian. Lo único que se va es el loop de
input() de la terminal, porque ahora quien invoca es AgentCore, no tú. Esta imagen muestra el antes y el después lado a lado:
El archivo completo está en
agente.py . Antes de desplegar, puedes probarlo en local: python agente.py levanta el servidor en el puerto 8080 y lo invocas con curl -X POST http://<localhost:8080>/invocations -d '{"prompt": "¿Qué plan tengo? soy u-1042"}'.Desplegar, un comando a la vez
El deploy usa el starter toolkit de AgentCore (
pip install bedrock-agentcore-starter-toolkit), que trabaja directo sobre tu agente.py. Son tres comandos, y conviene correrlos uno por uno para ver qué hace cada uno.Configura el deploy:
1
agentcore configure --entrypoint agente.pyconfigure prepara el agente y te hace unas preguntas. Dos valen la pena: el rol de IAM de ejecución (los permisos con los que corre tu agente) y el repositorio de ECR (donde vive la imagen del contenedor). Para empezar, deja que el toolkit los cree en automático; en un sistema real los defines tú, con permisos mínimos.Aquí también eliges cómo quieres empaquetar tu agente, y hay dos caminos:
- CodeZip (el default): mete tu código en un zip y lo sube a S3. No necesitas Docker, así que es el más rápido para empezar y es el que uso en esta demo.
- Container: construye una imagen de contenedor y la publica en ECR. Necesitas Docker corriendo, pero te da control total sobre la imagen, útil si ya tienes un pipeline de contenedores.
Si apenas estás probando, quédate con CodeZip y sigue adelante.
Despliega:
1
agentcore deployEsto empaqueta tu agente, lo publica en AgentCore Runtime y te devuelve un ARN , que es la dirección donde ahora vive. La primera invocación tarda un poco más por el arranque en frío.
Invócalo:
1
agentcore invoke '{"prompt": "¿Qué plan tengo? soy u-1042"}'La misma respuesta que en local, ahora servida desde la nube. No montaste un servidor, no configuraste escalado, no tocaste infraestructura.
Y algo que me parece importante: cada sesión de usuario corre en su propia microVM aislada, con su propia CPU, memoria y sistema de archivos. El agente de un usuario no puede tocar los datos de otro, y cuando la sesión termina, esa microVM se destruye y su memoria se limpia. Si mil personas le escriben a Ritmo al mismo tiempo, son mil entornos separados. Es la misma idea de la sección anterior (mantener al agente separado de lo que no le toca), ahora a nivel de infraestructura.
Lo que viene después
Con eso ya tienes tu agente en producción. A partir de aquí, AgentCore trae varias piezas más que vale la pena conocer, aunque cada una da para su propio artículo:
- Observability. Las trazas de cada invocación (qué herramienta llamó, cuánto tardó, dónde falló) llegan solas a CloudWatch, sin que instrumentes nada. Viene habilitado por defecto en el Runtime. Documentación .
- Memory. Para que Ritmo recuerde a cada usuario entre sesiones, sin que montes almacenamiento. Le agregas un session manager y AgentCore se encarga del resto. El código está en
agente_memoria.py. - Cualquier framework. El mismo entrypoint y el mismo deploy funcionan con otro framework. En el repo está
agente_langgraph.py: mismo Ritmo con LangGraph en vez de Strands, solo cambia cómo se arma el agente por dentro. Usar cualquier framework con AgentCore . - Gateway e Identity. Cuando el acceso a datos crece de un servicio a varios, Gateway expone esos servicios como herramientas gobernadas con la autenticación fuera del código del agente. Es la separación agente/datos de antes, ahora como infraestructura gestionada.
Un momento honesto
No voy a mentir, lo que de verdad me costó no fue el deploy de Strands, fue probar el mismo flujo con LangGraph. En modo
direct_code_deploy, el toolkit empaquetaba las dependencias del requirements.txt de la raíz aunque yo le pasara --requirements-file, y el runtime reventaba con ModuleNotFoundError: No module named 'langchain'. Me sentí perdida un buen rato hasta entender qué pasaba: la solución fue poner las dependencias de LangGraph como el requirements.txt de la raíz para ese deploy y limpiar el caché de .bedrock_agentcore/. Si te pasa, créeme, no estás solo.Cierre
Empezamos con un agente que solo vivía en la laptop y terminamos con uno desplegado en producción, aislado por usuario y listo para que lo use quien quieras. La idea que une todo: AgentCore separa cómo construyes el agente de cómo lo llevas a producción, y por eso trabaja con lo que ya tienes.
Te dejo el repo
ritmo-agent en GitHub para que lo clones y lo sigas a tu ritmo. Si te animas a desplegar tu agente y te topas con algo raro, cuéntame en los comentarios. Nos vemos en la nube. ☁️Recursos
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article