Agentes con Gemini en producción: lo que nadie te cuenta hasta que se te cae el servicio
Montar un agente de IA en un Jupyter Notebook dura diez minutos. Le das dos herramientas, tiras tres prompts y parece magia. El problema viene cuando mandas eso a producción, le metes tráfico real y ves la factura de Google Cloud a fin de mes.
Llevo todo este 2026 peleando con agentes basados en la suite de Gemini para clientes con volumen serio. He roto cosas, he tirado dinero a la basura por malas arquitecturas y he aprendido a trancazos qué funciona y qué no.
Te voy a resumir lo que de verdad importa para que no cometas los mismos errores que yo.
1. El mito del "modelo único": combina o arruínate
El error número uno que veo en equipos de dev es usar el modelo más potente para todo el ciclo del agente. Si pones a Gemini 2.5 Pro a decidir si el usuario dijo "hola" o a formatear un JSON básico, estás tirando el dinero y añadiendo 800 milisegundos de latencia innecesarios por llamada.
En producción, la arquitectura tiene que ser híbrida:
- Routing y tareas simples: Usa Gemini 2.5 Flash (o incluso modelos distilled ligeros). Es ridículamente rápido y barato. Lo usas para clasificar la intención de la entrada o validar datos.
- Razonamiento complejo y Tool Calling: Aquí sí metes Gemini 2.5 Pro. Cuando el agente necesita decidir qué herramienta usar entre un catálogo de 15 APIs, la capacidad de razonamiento de Pro justifica la latencia.
- Sintetizado de respuesta: Si la herramienta ya devolvió los datos y solo hay que redactar la respuesta final al usuario, vuelve a bajar a Flash.
Si haces este pipeline, bajas la factura un 60% y la latencia percibida por el usuario se reduce a la mitad.
2. Tool Calling en la vida real: Schemas estrictos o caos
La API de Gemini maneja bastante bien el function calling, pero si le dejas margen de interpretación a los esquemas de tus herramientas, va a alucinar parámetros tarde o temprano.
No definas herramientas con tipos ambiguos. Si una función espera una fecha, no pongas type: STRING sin más. Especifica el formato exacto en la descripción.
Mira este ejemplo en Python usando el SDK actualizado:
from google import genai
from google.genai import types
client = genai.Client()
# Definimos la herramienta de forma ultra específica
def buscar_reserva(id_reserva: str, fecha_checkin: str) -> dict:
"""
Busca los detalles de una reserva en la base de datos.
Args:
id_reserva: Código alfanumérico de 8 caracteres (ej. 'RES12345').
fecha_checkin: Fecha en formato YYYY-MM-DD.
"""
# Aquí iría tu lógica de negocio/DB
return {"status": "confirmada", "habitacion": 304}
# Forzamos respuesta estructurada y tool binding
config = types.GenerateContentConfig(
tools=[buscar_reserva],
temperature=0.0, # Cero siempre que uses herramientas
)
response = client.models.generate_content(
model='gemini-2.5-pro',
contents='¿Qué pasó con mi reserva RES99887 del 12 de julio de 2026?',
config=config
)
# Si el modelo decide llamar a la función:
if response.function_calls:
call = response.function_calls[0]
print(f"Llamando a {call.name} con args: {call.args}")
Un detalle crítico: temperature=0.0. No quieres "creatividad" cuando un modelo está intentando extraer argumentos para hacer una query a tu base de datos de producción.
3. Context Caching: La diferencia entre rentabilidad y quiebra
Gemini presume de ventanas de contexto gigantescas de millones de tokens. Eso está genial para demos, pero en producción pasarte 200.000 tokens de documentación del sistema en cada interacción del agente te va a arruinar.
Desde que Google estabilizó el Context Caching explícito a finales del año pasado, no hay excusa para no usarlo.
Si tu agente tiene un system prompt pesado, instrucciones de marca gigantes o un catálogo de herramientas enorme:
- Creas un cache en Gemini con esas instrucciones fijas.
- Cada llamada del agente apunta a ese
cache_name. - Pagas una fracción del costo de lectura y ahorras un tiempo de procesamiento enorme.
El código se ve algo así:
from google.genai import types
# Creamos el cache con la información pesada que no cambia
cache = client.caches.create(
model='gemini-2.5-pro',
config=types.CreateCachedContentConfig(
contents=['Aquí metes 50 páginas de documentación interna o schemas'],
ttl='86400s', # 24 horas de vida
)
)
# Luego en la llamada usas el cache
response = client.models.generate_content(
model='gemini-2.5-pro',
contents='¿Cómo devuelvo un producto según la política?',
config=types.GenerateContentConfig(
cached_content=cache.name
)
)
Si tus usuarios hacen varias preguntas dentro de una misma sesión, esto cambia las reglas del juego.
4. Bucle infinito y detección de fallos
Ningún tutorial te avisa de esto: los agentes se enganchan en bucles.
Un agente decide llamar a la herramienta buscar_usuario. La herramienta devuelve None. El agente cree que formateó mal la consulta, vuelve a llamar a buscar_usuario con los mismos datos. Y así 15 veces hasta que te salta un timeout o el cliente cierra la pestaña.
Tienes que meter control de flujo defensivo en tu propio código (no te fíes de que el LLM "se dé cuenta"):
- Límite de pasos (Max Steps): Corta la ejecución si el agente hace más de 4 o 5 llamadas a herramientas en un solo turno.
- Detección de llamadas duplicadas: Si el agente llama a la misma función con los mismos argumentos dos veces seguidas, interrumpe el ciclo y pásale un mensaje del sistema tipo: "Error: Ya probaste esta función y falló. Pídele aclaración al usuario."
- Fallback a humano: Si en 3 pasos no ha resuelto la intención, transfiere el estado de la conversación a un operador real o muestra un formulario estático.
5. Observabilidad: Si no lo mides, está roto
No puedes lanzar un agente a producción sin un sistema de trazabilidad. Necesitas saber:
- Cuántos tokens consume cada paso.
- Qué herramientas fallan más por argumentos mal formados.
- Cuánto tarda cada API externa en responder versus cuánto tarda Gemini en procesar la respuesta.
Nosotros usamos OpenTelemetry combinado con dashboards personalizados. Cuando un usuario dice "el bot no funciona", 9 de cada 10 veces no es que Gemini haya alucinado, es que la API REST de nuestro propio backend devolvió un 500 Internal Server Error y el agente no supo cómo reaccionar porque nadie le enseñó qué hacer ante un error HTTP.
En resumen
Construir agentes útiles en 2026 no va de poner los prompts más ingeniosos. Va de ingeniería de software tradicional envuelta alrededor de un modelo estadístico:
- Modela tus flujos separando tareas entre modelos rápidos y modelos capaces.
- Usa
Context Cachingpara no pagar por el mismo contexto mil veces. - Tipa y valida cada entrada y salida de las herramientas.
- Pon límites duros para evitar bucles infinitos.
Empieza pequeño, mide todo y no le des al agente permisos de escritura en tus bases de datos hasta que lleve un mes funcionando en modo lectura sin fallar.
Top comments (0)