Metricas de uso de herramientas

Las metricas muestran con que frecuencia los agentes llaman tools.
En esta página
  1. Idea en 30 segundos
  2. Problema principal
  3. Como funciona
  4. Metricas tipicas de production para tools
  5. Como leer la tool-layer
  6. Cuando usar
  7. Ejemplo de implementacion
  8. Investigation
  9. Errores tipicos
  10. Hay conteo total de llamadas, pero no desglose por tool
  11. No se rastrean llamadas repetidas
  12. No hay p95 latency por herramienta
  13. Labels de alta cardinalidad
  14. No hay alertas del tool-layer
  15. Autoevaluacion
  16. FAQ
  17. Paginas relacionadas

Idea en 30 segundos

Tool usage metrics muestran no solo si el agente funciona, sino como usa herramientas y donde se rompe la tool-layer.

Ayudan a entender que tools se llaman mas, donde crece la latency y donde empiezan llamadas repetidas o con error.

Sin estas metricas, es dificil detectar a tiempo sobrecarga en la tool-layer y crecimiento de costos.

Problema principal

Las metricas generales de run no muestran que pasa exactamente a nivel de herramientas.

Dos runs pueden tener latency total similar, pero en un caso el problema es search lenta, y en otro son llamadas repetidas a fetch. Sin metricas por tools, esto es dificil de ver antes del incidente.

Ahora vemos como leer estas senales y encontrar problemas.

En production normalmente se ve asi:

  • una tool se vuelve un hot spot sin notarse;
  • crecen retries, pero la causa no es obvia;
  • parte de los runs gasta demasiados pasos justo en herramientas;
  • el equipo detecta el problema solo cuando sube error rate o presupuesto.

Por eso conviene monitorear la tool-layer por separado, y no solo con metricas generales de run.

Como funciona

Tool usage metrics se construyen alrededor de eventos tool_call y tool_result.

Las tool metrics se dividen en:

  • infra metrics (tool_latency_p95, tool_error_rate);
  • behavior metrics (repeated_tool_calls, tool_calls_per_run, unique_tools_per_run).

Estas metricas responden "como se comporta la tool-layer en el tiempo". Los logs y el tracing siguen siendo necesarios para explicar un run problematico concreto.

Retries suelen ocurrir a nivel runtime, no a nivel de codigo: el agente recibe error de tool como observation e intenta otra vez. Retries no son solo llamadas repetidas, sino una senal de que el agente intenta adaptarse al fallo de herramienta.

Metricas tipicas de production para tools

MetricaQue muestraPara que sirve
tool_calls_totalcantidad total de llamadas a toolscontrol de carga en la tool-layer
tool_calls_per_runcuantas tool calls hay por rundeteccion de llamadas excesivas o ciclicas
unique_tools_per_runcuantas tools distintas usa un runevaluacion de complejidad del workflow
tool_error_rateproporcion de tool calls con errordeteccion temprana de herramientas inestables
tool_latency_p50 / p95latency tipica y de cola por toolslocalizar dependencias lentas
repeated_tool_callsllamadas que repiten la misma tool con los mismos argsdeteccion de spam de herramientas
tool_cost_per_runcosto estimado de tools dentro de un runcontrol de presupuesto y deteccion de tools caras

Para que sean practicas, estas metricas suelen segmentarse por tool, release y, cuando hace falta, model.

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

Como leer la tool-layer

Que se llama -> como se comporta el agente -> que pasa en el tiempo. Son tres niveles que siempre hay que mirar juntos.

Hay que mirar tendencias en el tiempo y diferencias entre releases, no valores aislados.

Miremos combinaciones de senales:

  • tool_error_rate ↑ + repeated_tool_calls ↑ -> tool inestable, el agente reintenta
  • tool_latency_p95 ↑ + tool_cost_per_run ↑ -> degradacion de una tool cara
  • tool_calls_per_run ↑ + unique_tools_per_run ↑ -> complejidad excesiva del workflow

Cuando usar

El set completo de tool-metrics no siempre es necesario.

Para un agente simple con 1-2 herramientas, a veces alcanzan tool_calls_total y tool_error_rate.

Pero metricas detalladas de uso de tools se vuelven criticas cuando:

  • el agente usa activamente APIs externas o BD;
  • hay retries frecuentes;
  • es importante controlar costos de herramientas;
  • hay que detectar tool spam antes de afectar usuarios.

Ejemplo de implementacion

Abajo tienes un ejemplo simplificado de instrumentacion Prometheus para tool usage metrics. El ejemplo muestra control base: volumen de llamadas, latency, clases de error, repeticiones y carga de herramientas por run.

PYTHON
import hashlib
import json
import time
from prometheus_client import Counter, Histogram

TOOL_CALL_TOTAL = Counter(
    "agent_tool_call_total",
    "Total tool calls",
    ["tool", "status", "release"],
)

TOOL_ERROR_TOTAL = Counter(
    "agent_tool_error_total",
    "Total tool errors by class",
    ["tool", "error_class", "release"],
)

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

TOOL_CALLS_PER_RUN = Histogram(
    "agent_tool_calls_per_run",
    "Number of tool calls per run",
    ["release"],
    buckets=(0, 1, 2, 4, 8, 12, 16, 24, 32),
)

UNIQUE_TOOLS_PER_RUN = Histogram(
    "agent_unique_tools_per_run",
    "Number of unique tools used in run",
    ["release"],
    buckets=(0, 1, 2, 3, 4, 6, 8, 12),
)

REPEATED_TOOL_CALL_TOTAL = Counter(
    "agent_repeated_tool_call_total",
    "Repeated tool calls with same tool+args signature",
    ["tool", "release"],
)

TOOL_COST_USD_TOTAL = Counter(
    "agent_tool_cost_usd_total",
    "Estimated total tool cost in USD",
    ["tool", "release"],
)

STEP_ERROR_TOTAL = Counter(
    "agent_step_error_total",
    "Total non-tool step errors by type and class",
    ["step_type", "error_class", "release"],
)


def stable_hash(value):
    # default=str da compatibilidad base;
    # en sistemas criticos conviene serializacion explicita (por ejemplo ISO 8601)
    payload = json.dumps(value, sort_keys=True, ensure_ascii=False, default=str).encode("utf-8")
    return hashlib.sha256(payload).hexdigest()


def run_agent(agent, task, release="2026-03-21"):
    tool_calls = 0
    unique_tools = set()
    seen_signatures = set()

    try:
        for step in agent.iter(task):
            step_type = step.type
            result = None

            if step_type != "tool_call":
                try:
                    result = step.execute()
                except Exception as error:
                    STEP_ERROR_TOTAL.labels(
                        step_type=step_type,
                        error_class=type(error).__name__,
                        release=release,
                    ).inc()
                    raise

                if result and result.is_final:
                    break
                continue

            tool_name = getattr(step, "tool_name", "unknown")
            args = getattr(step, "args", {})

            tool_calls += 1
            unique_tools.add(tool_name)

            signature = (tool_name, stable_hash(args))
            if signature in seen_signatures:
                REPEATED_TOOL_CALL_TOTAL.labels(tool=tool_name, release=release).inc()
            else:
                seen_signatures.add(signature)

            started_at = time.time()
            try:
                result = step.execute()
                TOOL_CALL_TOTAL.labels(tool=tool_name, status="ok", release=release).inc()
                cost_usd = getattr(result, "cost_usd", None)
                if cost_usd:
                    TOOL_COST_USD_TOTAL.labels(tool=tool_name, release=release).inc(cost_usd)
            except Exception as error:
                TOOL_CALL_TOTAL.labels(tool=tool_name, status="error", release=release).inc()
                TOOL_ERROR_TOTAL.labels(
                    tool=tool_name,
                    error_class=type(error).__name__,
                    release=release,
                ).inc()
                # Este ejemplo hace raise.
                # En agentes reales, el error suele pasar al LLM como observation para retry.
                raise
            finally:
                TOOL_LATENCY_MS.labels(tool=tool_name, release=release).observe(
                    (time.time() - started_at) * 1000
                )

            if result and result.is_final:
                break
    finally:
        TOOL_CALLS_PER_RUN.labels(release=release).observe(tool_calls)
        UNIQUE_TOOLS_PER_RUN.labels(release=release).observe(len(unique_tools))

# tool_cost_per_run normalmente se calcula en dashboard:
# sum(agent_tool_cost_usd_total) / run_count

Asi se ven estas metricas juntas en un dashboard real:

Toolcalls/minerror_ratep95 latencyEstado
search_docs3206.8%1.9scritical: alert
fetch_url1801.4%680mswarning: p95 en alza
db_lookup950.3%120msok

Para error_class, conviene usar un diccionario normalizado de valores para evitar cardinalidad innecesaria.

Investigation

Cuando dispara una alerta:

  1. encontrar la tool anomala en metricas;
  2. revisar runs concretos en tracing;
  3. revisar args y respuestas en logs;
  4. encontrar root cause (tool, logica del agente o API externa).

Errores tipicos

Incluso con tool metrics agregadas, muchas veces no funcionan como se espera por errores tipicos.

Hay conteo total de llamadas, pero no desglose por tool

tool_calls_total sin desglose por herramienta casi no ayuda en incidentes. En esta situacion, es dificil encontrar rapido la fuente de fallo de herramienta.

No se rastrean llamadas repetidas

Sin repeated_tool_calls, cuesta ver que el agente llama la misma tool con los mismos args. Esto suele ocultar la fase temprana de spam de herramientas.

No hay p95 latency por herramienta

El sistema puede parecer estable mientras parte de usuarios ya espera 5+ segundos. Para tool-layer, el minimo es p50 y p95.

Labels de alta cardinalidad

Agregar run_id, request_id o args_hash en labels sobrecarga rapido el backend de metricas. Es mejor guardar esos datos en logs, no en labels.

No hay alertas del tool-layer

Sin alertas, las metricas quedan como telemetria pasiva. Asi es facil perder senales tempranas de explosion de presupuesto por exceso de llamadas a APIs externas.

Autoevaluacion

Abajo tienes un checklist corto de tool usage metrics base antes del 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 diferencian tool usage metrics de metricas generales del agente?
R: Las metricas generales muestran el estado global del sistema. Tool usage metrics muestran lo que pasa especificamente en la tool-layer.

P: Cual es el minimo de tool-metrics para empezar?
R: Empieza con tool_calls_total, tool_error_rate, tool_latency_p95 y tool_calls_per_run.

P: Conviene agregar args_hash en labels?
R: No. Casi siempre crea alta cardinalidad. Para esos datos conviene usar logs estructurados.

P: Como diferenciar un fallo aislado de un problema sistemico en tool-layer?
R: Revisa si el problema se repite para una tool concreta en varios runs y releases. Si se repiten las mismas senales (error_class, latency, repeated_tool_calls), es sistemico.

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.