Latency Monitoring para agentes

Ayuda a seguir tiempo de respuesta y retrasos de ejecucion.
En esta página
  1. Idea en 30 segundos
  2. Problema principal
  3. Como funciona
  4. Metricas de latency tipicas en production
  5. Como leer la latency-layer
  6. Cuando usar
  7. Ejemplo de implementacion
  8. Investigation
  9. Errores tipicos
  10. Solo se mira la latency promedio
  11. No hay desglose de latency por tools y step type
  12. Se ignora queue time
  13. No hay metricas de timeout-rate ni retry-overhead
  14. No hay alertas para p95/p99 y timeout spikes
  15. Autoevaluacion
  16. FAQ
  17. Paginas relacionadas

Idea en 30 segundos

Latency monitoring para agentes de IA muestra donde se ralentiza el sistema: en pasos LLM, tools, colas o iteraciones repetidas.

Sin esto, es dificil entender por que el usuario espera mas, incluso cuando el run termina formalmente con exito.

Problema principal

Un run puede terminar correctamente, pero ser demasiado lento para production.

Dos solicitudes con la misma respuesta pueden tener latency distinta por una cadena de reasoning mas larga, un tool lenta o retries. Sin latency monitoring, esto normalmente se ve solo despues de quejas de usuarios.

Ahora veamos como leer estas senales y encontrar que exactamente ralentiza un run.

En production esto suele verse asi:

  • la latency promedio parece normal, pero p95 ya sube;
  • una tool se vuelve bottleneck sin notarse;
  • retries agregan segundos sin crecimiento visible de trafico;
  • el equipo ve el problema solo despues de caida parcial.

Por eso la latency-layer conviene monitorearla por separado, no solo con metricas generales de run.

Como funciona

Latency monitoring se construye alrededor de dos tipos de senales:

  • runtime signals (queue_time, step_latency, tool_latency, ttft);
  • service signals (run_latency_p50/p95/p99, timeout_rate, retry_overhead_ms).

Estas metricas responden "donde y por que el sistema se ralentiza con el tiempo". Logs y tracing hacen falta para explicar un run lento concreto.

Latency != user experience. Los usuarios no sienten el promedio - sienten p95/p99. Las solicitudes lentas definen la percepcion del sistema. Latency suele estar ligada directamente al cost. Runs mas largos implican mas tokens, mas llamadas a tools y mas retries, lo que aumenta el cost directamente.

Metricas de latency tipicas en production

MetricaQue muestraPara que sirve
run_latency_p50tiempo tipico de ejecucion de runcontrol base de velocidad
run_latency_p95 / p99cola larga y runs mas lentosdeteccion temprana de degradacion
step_latency_p95que pasos del agente se ralentizanlocalizar etapa problematica
tool_latency_p95latency de tools concretasbuscar bottlenecks externos
ttft_p95time-to-first-token para LLMcontrol de velocidad de primera respuesta
queue_time_p95cuanto espera un run antes de iniciarcontrol de carga y capacity
timeout_rateproporcion de pasos con timeoutsenal temprana de inestabilidad
retry_overhead_mscuanto tiempo agregan los retriesimpacto de recuperacion sobre latency

run_latency_p95 y run_latency_p99 normalmente se calculan en dashboard/consultas de metricas, no como contador separado en codigo.

Para que las metricas sean practicas, suelen segmentarse por release, model, tool y tipo de workflow.

Importante: no agregues campos de alta cardinalidad (run_id, request_id, user_id) en labels, o el storage de metricas se sobrecarga rapido.

Como leer la latency-layer

Donde aparece el retraso -> como se comporta el agente -> que exactamente ralentiza el run. Son tres niveles que siempre hay que mirar juntos.

Es clave mirar tendencias en el tiempo y diferencias entre releases, no valores aislados.

Ahora revisa combinaciones de senales:

  • run_latency_p95 up + tool_latency_p95 up -> bottleneck en herramientas externas;
  • run_latency_p95 up + step_count up -> el agente hace iteraciones extra;
  • ttft_p95 up + tool_latency_p95 ~= estable -> problema en capa LLM, no en tools;
  • timeout_rate up + retry_overhead_ms up -> retries enmascaran inestabilidad y agregan latency;
  • queue_time_p95 up + run_count up -> falta capacity en el sistema.

Cuando usar

Latency monitoring completo no siempre es necesario.

Para un prototipo simple, puede bastar tiempo de respuesta base.

Pero monitoreo detallado de latency se vuelve critico cuando:

  • el sistema ya esta en production y tiene SLO/SLA de velocidad;
  • el agente usa varias tools externas y dependencias;
  • hay releases frecuentes y hay que ver regresiones de latency;
  • en el workflow hay colas, retries o loops de reasoning de varios pasos.

Ejemplo de implementacion

Abajo tienes un ejemplo simplificado de instrumentacion de metricas de latency estilo Prometheus. Muestra control base: run latency, pasos, tools, timeouts y retry overhead.

PYTHON
import time
from prometheus_client import Counter, Histogram

# perf_counter() se usa en lugar de time.time()
# para obtener mediciones monotonicas y precisas de latency
RUN_TOTAL = Counter(
    "agent_run_total",
    "Total number of agent runs",
    ["status", "stop_reason", "release"],
)

RUN_LATENCY_MS = Histogram(
    "agent_run_latency_ms",
    "Run latency in milliseconds",
    ["release"],
    buckets=(100, 250, 500, 1000, 2000, 5000, 10000, 20000),
)

STEP_LATENCY_MS = Histogram(
    "agent_step_latency_ms",
    "Latency by step type in milliseconds",
    ["step_type", "release"],
    buckets=(20, 50, 100, 250, 500, 1000, 2000, 5000),
)

TOOL_LATENCY_MS = Histogram(
    "agent_tool_latency_ms",
    "Tool latency in milliseconds",
    ["tool", "release"],
    buckets=(20, 50, 100, 250, 500, 1000, 2000, 5000),
)

QUEUE_TIME_MS = Histogram(
    "agent_queue_time_ms",
    "Queue wait time before run start",
    ["release"],
    buckets=(0, 20, 50, 100, 250, 500, 1000, 2000),
)

TTFT_MS = Histogram(
    "agent_ttft_ms",
    "Time to first token in milliseconds",
    ["model", "release"],
    buckets=(50, 100, 200, 400, 800, 1500, 3000),
)

TIMEOUT_TOTAL = Counter(
    "agent_timeout_total",
    "Total timeout errors by layer",
    ["layer", "release"],
)

RETRY_OVERHEAD_MS = Histogram(
    "agent_retry_overhead_ms",
    "Added latency from retries",
    ["release"],
    buckets=(0, 50, 100, 250, 500, 1000, 2000, 5000),
)


def run_agent(agent, task, queue_time_ms=0, release="2026-03-22"):
    run_status = "ok"
    stop_reason = "max_steps"
    started_at = time.perf_counter()

    if queue_time_ms > 0:
        QUEUE_TIME_MS.labels(release=release).observe(queue_time_ms)

    try:
        for step in agent.iter(task):
            step_type = step.type
            step_started_at = time.perf_counter()

            try:
                result = step.execute()
            except TimeoutError:
                run_status = "error"
                if step_type == "tool_call":
                    stop_reason = "tool_timeout"
                elif step_type == "llm_generate":
                    stop_reason = "llm_timeout"
                else:
                    stop_reason = "step_timeout"
                layer = (
                    "tool"
                    if step_type == "tool_call"
                    else "llm"
                    if step_type == "llm_generate"
                    else "runtime"
                )
                TIMEOUT_TOTAL.labels(layer=layer, release=release).inc()
                raise
            except Exception:
                run_status = "error"
                if step_type == "tool_call":
                    stop_reason = "tool_error"
                elif step_type == "llm_generate":
                    stop_reason = "llm_error"
                else:
                    stop_reason = "step_error"
                raise
            finally:
                step_latency_ms = (time.perf_counter() - step_started_at) * 1000
                STEP_LATENCY_MS.labels(step_type=step_type, release=release).observe(step_latency_ms)
                if step_type == "tool_call":
                    TOOL_LATENCY_MS.labels(
                        tool=getattr(step, "tool_name", "unknown"),
                        release=release,
                    ).observe(step_latency_ms)
                # retry overhead puede existir incluso si el paso falla
                retry_overhead_ms = float(getattr(step, "retry_overhead_ms", 0) or 0)
                if retry_overhead_ms > 0:
                    RETRY_OVERHEAD_MS.labels(release=release).observe(retry_overhead_ms)

            if step_type == "llm_generate":
                model = getattr(step, "model", "unknown")
                ttft_ms = float(getattr(result, "ttft_ms", 0) or 0)
                if ttft_ms > 0:
                    TTFT_MS.labels(model=model, release=release).observe(ttft_ms)

            if result and result.is_final:
                stop_reason = "completed"
                break
    finally:
        run_latency_ms = (time.perf_counter() - started_at) * 1000
        RUN_LATENCY_MS.labels(release=release).observe(run_latency_ms)
        RUN_TOTAL.labels(status=run_status, stop_reason=stop_reason, release=release).inc()

# run_latency_p95 y run_latency_p99 normalmente se calculan en dashboard:
# histogram_quantile(...) sobre bucket-metrics agent_run_latency_ms.

Asi se ven estas metricas juntas en un dashboard real:

Segmentp50 latencyp95 latencytimeout_rateEstado
gpt-4.1 + tools1.1s4.8s2.9%critical: SLO risk
mini-model + cache420ms1.2s0.4%ok
research workflow1.7s6.1s1.8%warning: p95 sube

Investigation

Cuando dispara una alerta de latency:

  1. encontrar segmento con anomalia (release, tool, model);
  2. revisar runs lentos en tracing;
  3. revisar en logs retries, timeout y stop_reason;
  4. encontrar root cause (tool, LLM, queue, logica del agente, servicio externo).

Errores tipicos

Incluso cuando ya hay metricas de latency, muchas veces no ayudan por errores tipicos.

Solo se mira la latency promedio

La media suele ocultar degradacion. Para production, minimo p50 y p95, y para escenarios criticos tambien p99.

No hay desglose de latency por tools y step type

Sin esto, cuesta saber que es lento: LLM, tool o el propio loop del agente. En esa situacion, cuesta localizar rapido fallo de herramienta.

Se ignora queue time

Un run puede ser lento antes de empezar a ejecutarse. Sin queue_time_p95, es facil perder problemas de capacity.

No hay metricas de timeout-rate ni retry-overhead

Retries pueden ocultar inestabilidad e inflar latency artificialmente. Esto suele combinarse con spam de herramientas.

No hay alertas para p95/p99 y timeout spikes

Sin alertas, el equipo se entera tarde, cuando el SLO ya esta roto.

Autoevaluacion

Abajo tienes un checklist corto de latency monitoring base antes de release.

Progreso: 0/9

⚠ Falta observability base

Será difícil depurar el sistema en production. Empieza con run_id, structured logs y tracing de tool calls.

FAQ

P: En que se diferencia latency monitoring del monitoreo normal de velocidad API?
R: Para agentes, hay que monitorear no solo tiempo total de respuesta, sino tambien pasos internos: reasoning, tools, retries y queue time.

P: Cual es el minimo de metricas de latency para empezar?
R: Empieza con run_latency_p50/p95, tool_latency_p95, timeout_rate y queue_time_p95.

P: Por que p95 es mas importante que latency promedio?
R: Porque p95 muestra que pasa con solicitudes lentas, las que mas notan los usuarios.

P: Como separar problemas de latency en tools de problemas en LLM?
R: Compara tool_latency_p95 y ttft_p95: si solo sube tool-latency, el bottleneck esta en tools; si sube ttft, el problema esta en capa LLM.

Paginas relacionadas

Siguiente sobre el tema:

⏱️ 8 min de lecturaActualizado 22 de marzo de 2026Dificultad: ★★★
Integrado: control en producciónOnceOnly
Guardrails para agentes con tool-calling
Lleva este patrón a producción con gobernanza:
  • Presupuestos (pasos / topes de gasto)
  • Permisos de herramientas (allowlist / blocklist)
  • Kill switch y parada por incidente
  • Idempotencia y dedupe
  • Audit logs y trazabilidad
Mención integrada: OnceOnly es una capa de control para sistemas de agentes en producción.

Autor

Nick — ingeniero que construye infraestructura para agentes de IA en producción.

Enfoque: patrones de agentes, modos de fallo, control del runtime y fiabilidad del sistema.

🔗 GitHub: https://github.com/mykolademyanov


Nota editorial

Esta documentación está asistida por IA, con responsabilidad editorial humana sobre la exactitud, la claridad y la relevancia en producción.

El contenido se basa en fallos reales, post-mortems e incidentes operativos en sistemas de agentes de IA desplegados.