- Distinguir coste reservado antes de una llamada y coste real después.
- Detectar repeticiones por intención, herramienta y argumentos normalizados.
- Limitar pasos, tiempo, llamadas por herramienta y falta de progreso.
- Guardar una traza que explique por qué se ejecutó o bloqueó una acción.
- Probar las guardas con fallos deterministas antes de conectar un modelo.
El problema no es solo un loop infinito
Un agente puede consumir demasiado sin repetir exactamente la misma acción: cambia una palabra, consulta veinte fuentes distintas o sigue produciendo texto sin acercarse al objetivo. OWASP denomina unbounded consumption al riesgo de permitir inferencia o consumo de recursos sin límites adecuados; sus consecuencias incluyen denegación de servicio y pérdidas económicas.
Por eso no basta con max_iterations. Necesitas varias barreras independientes y una política clara para decidir cuál informa del corte.
| Guarda | Qué mide | Cuándo bloquea |
|---|---|---|
| Pasos | Acciones ya ejecutadas | Antes de superar el máximo por tarea |
| Tiempo | Duración total monotónica | Antes de ejecutar fuera de la ventana |
| Presupuesto | Coste actual + reserva propuesta | Antes de contraer el gasto |
| Cuota de tool | Llamadas por herramienta | Antes de exceder su cuota individual |
| Fingerprint | Intención, tool y argumentos | Antes de la repetición sospechosa |
| Progreso | Cambio de un marcador verificable | Tras varios pasos sin cambio |
Reserva primero, reconcilia después
Antes de llamar a un modelo no conoces los tokens reales de salida. Sí conoces una estimación de entrada y el máximo de salida permitido. Reserva ese peor caso antes de la llamada:
reserva = tokens_entrada_estimados × tarifa_entrada + tokens_salida_maximos × tarifa_salida si coste_acumulado + reserva > presupuesto: bloquear antes de llamar si la llamada termina: sustituir reserva por uso_real guardar tokens, coste, latencia y resultado
Laboratorio: siete formas de detenerse
El ejemplo MIT no instala paquetes, no usa la red y no contiene claves. Simula una ejecución sana y seis cortes: repetición, presupuesto, cuota de herramienta, pasos, tiempo y falta de progreso. Todos los importes se guardan como microdólares enteros para evitar errores de coma flotante.
git clone https://github.com/aulafy/taller.git cd taller/cursos/agentes-automatizacion/laboratorios/guardas-coste-y-loops npm run verificar
Qué debe ocurrir en cada escenario
| Escenario | Resultado esperado | Acción que no se ejecuta |
|---|---|---|
sano | Completa 4 pasos | Ninguna |
loop-fingerprint | Corta tras 2 llamadas | Tercera consulta idéntica |
presupuesto | Conserva el coste en 1.200 | Reserva propuesta de 7.000 |
cuota-tool | Permite 2 búsquedas | Tercera búsqueda |
max-pasos | Completa 8 pasos | Paso número 9 |
timeout | Completa 1 paso | Acción fuera de 5 minutos |
sin-progreso | Completa 2 pasos | Tercera acción sin cambio |
Fingerprint: repetición semántica acotada
El laboratorio normaliza la intención, ordena recursivamente los argumentos y calcula un hash deintención + tool + args. Así, cambiar el orden de las claves JSON no evade el límite. No compara texto libre completo: una coma distinta no debería crear una acción nueva.
fingerprint = sha256({
intencion: normalizar("reintentar consulta"),
tool: "consultar_crm",
args: ordenar_claves({ cliente_id: "CLI-DEMO-99" })
})
si apariciones(fingerprint) >= 3:
bloquear
guardar "fingerprint_repetido"No confundas repetición y falta de progreso
Tres búsquedas distintas producen fingerprints distintos, pero pueden aportar cero evidencia nueva. Define un marcador de progreso que el código pueda comprobar: registros pendientes, fuentes válidas encontradas, campos completados o estado de una máquina. «El agente cree que avanza» no es un marcador.
Orden seguro de una acción
- Recibe una propuesta estructurada del modelo.
- Valida esquema, tipos, permisos y destino.
- Calcula fingerprint, cuota, tiempo, pasos y progreso.
- Reserva el coste máximo de la acción.
- Bloquea con un motivo trazable o ejecuta con idempotencia.
- Registra uso real, latencia, error y efecto.
- Reconcilia la reserva y persiste el nuevo estado.
OpenTelemetry dispone de convenciones semánticas para observar llamadas a modelos y herramientas, incluidos los conteos de tokens. Úsalas para evitar nombres incompatibles entre proveedores, pero no registres prompts, respuestas o datos personales por defecto.
Modo degradado y revisión humana
Cortar no significa fallar en silencio. Devuelve un estado explícito: límite alcanzado, trabajo completado, evidencia reunida, acción pendiente y forma segura de continuar. Una operación sensible debe quedar pendiente de aprobación; no reinicies automáticamente el contador.
{
"estado": "detenido",
"motivo": "presupuesto_reservado",
"pasos_ejecutados": 1,
"coste_microusd": 1200,
"reserva_bloqueada_microusd": 7000,
"siguiente_accion": "revisar alcance o aprobar nuevo presupuesto"
}Qué no demuestra este laboratorio
- No calcula el precio real de ningún modelo ni proveedor.
- No decide el presupuesto aceptable para una empresa.
- No mide calidad, veracidad o utilidad de la respuesta.
- No sustituye permisos, sandboxing, idempotencia ni revisión humana.
- No prueba concurrencia entre procesos ni facturación agregada diaria.
Fuentes primarias
- OpenAI · optimización de costes
- OWASP · consumo no acotado
- LangGraph · límite de recursión
- OpenTelemetry · observabilidad de IA generativa
Probado el 27 de julio de 2026. Node.js 20.11+, sin red ni dependencias externas.
Si has guardado la evidencia de esta lección, continúa con «Governance MCP». Si no, repite la comprobación antes de avanzar.