Claude Code agent_summary: mide y reduce el consumo de tokens

Mide las solicitudes que generan las etiquetas de progreso de los agentes en segundo plano de Claude Code. Compara el 16.4% estimado por un equipo con el 2% general y el 6% en terminal comunicados por el equipo de Claude Code. Usa un receptor local de OpenTelemetry y evalúa la corrección de caché de 2.1.311+, los controles de agentes y los parches de la comunidad.

Índice
Claude Code agent_summary: mide y reduce el consumo de tokens

Actualiza Claude Code a 2.1.311 o posterior y mide agent_summary con OpenTelemetry antes de desactivar funciones de los agentes. Estas solicitudes de resumen pueden añadir costes mientras los agentes trabajan en segundo plano. El 16.4% difundido es la proporción del coste estimado de un equipo; no es un recargo universal de tokens.

Qué hace agent_summary

agent_summary genera etiquetas de progreso mediante solicitudes independientes al modelo. En el informe de dblumenau sobre Claude Code 2.1.312, cada solicitud enviaba el historial de un agente en segundo plano al modelo del propio agente. El resultado solicitado era una etiqueta de tres a cinco palabras. Ese caso se reprodujo con Haiku, por lo que el mecanismo no es exclusivo de Opus.

Los agentes que trabajan en segundo plano pueden activar estas solicitudes aproximadamente cada 30 segundos. Si el historial no cambia, pueden omitirse llamadas, como documenta el registro oficial de cambios. Cuenta las solicitudes reales en lugar de multiplicar por dos los minutos transcurridos.

Por tanto, un contexto largo puede influir más que la longitud de la etiqueta visible. Comprueba el modelo registrado y el uso de caché al investigar el coste.

Este mecanismo es independiente de la barra de estado configurable del terminal. La documentación de la línea de estado personalizada describe un script local que no consume tokens de API. Eliminar ese script no evita estas solicitudes de resumen al modelo.

Qué miden realmente el 16.4%, el 2% y el 6%

Los tres porcentajes de coste corresponden a poblaciones diferentes. A fecha de 2026-11-01, estos son los informes publicados relevantes:

InformePoblación y periodoProporción del coste atribuida a resúmenesBase del cálculo
Flamerix AIUna semana de medición de un equipo16.4%Estimaciones cost_usd de Claude Code por solicitud
edwinarbus, miembro del equipo de Claude CodeUsuarios que envían telemetría, durante la semana anterior a la respuesta del 29 de octubreAproximadamente 2%Coste a precios de catálogo de la API
La misma respuesta, subconjunto del terminalUso del terminal dentro de esa muestra de telemetríaAproximadamente 6%Coste a precios de catálogo de la API

Flamerix también informó de que los resúmenes representaban el 19.7% de las solicitudes de API. La proporción de solicitudes y la proporción del coste tienen denominadores distintos. Ninguna determina qué fracción del cupo de tu suscripción consumen los resúmenes.

Usa estos informes como motivo para medir tu propia carga de trabajo. Un equipo que delega muchas tareas largas puede obtener resultados muy distintos de quien trabaja principalmente en la conversación principal.

Actualiza primero, sin asumir un ahorro fijo

La versión 2.1.311+ corrige el caso costoso de las solicitudes de resumen que no reutilizan la caché del prompt, según la respuesta del equipo de Claude Code. Esa afirmación se refiere a una corrección de caché, no a la eliminación de las solicitudes de resumen. No demuestra un ahorro fijo para tus sesiones.

Para una instalación nativa, ejecuta lo siguiente en Bash:

claude --version
claude update
claude --version

Reinicia Claude Code después de actualizarlo. Si la instalación depende de un gestor de paquetes, usa su comando de actualización en las instrucciones oficiales de instalación. Comprueba la versión resultante: el canal de actualización o las políticas de tu organización pueden limitarla.

La misma respuesta describe el desarrollo de un modo más barato basado en notas breves y un modelo más pequeño. No indica una fecha de lanzamiento. A fecha de 2026-11-01, no hay una opción pública documentada para activar ese modo. No incluyas todavía ese ahorro en tu presupuesto.

Mide tu sesión con OpenTelemetry

Recoge los eventos de registro claude_code.api_request y agrúpalos por query_source. La referencia de monitorización documenta ese atributo, el model registrado y la estimación cost_usd.

Si tu organización ya recoge estos eventos, utiliza su plataforma de monitorización. Filtra una sesión o un intervalo controlado, cuenta los eventos de solicitudes de API y suma cost_usd por origen. Añade model como segunda agrupación cuando compares modelos.

El ejemplo local necesita Bash, Python 3 y una instalación de Claude Code ya autenticada. Úsalo en una máquina donde controles el destino de la telemetría. Mantiene los totales en memoria y muestra metadatos sin necesidad de capturar prompts ni respuestas completos.

Inicia el receptor local

Ejecuta este código en el primer terminal. Acepta OTLP HTTP JSON en la interfaz local y muestra totales acumulados por origen:

python3 -u - <<'PY'
import gzip, json, math
from collections import defaultdict
from http.server import BaseHTTPRequestHandler, HTTPServer

rows = defaultdict(lambda: [0, 0.0, 0])
models = defaultdict(set)
seen = set()

def scalar(value):
    return next((value[k] for k in ("stringValue", "doubleValue", "intValue", "boolValue")
                 if k in value), None)

def report():
    count = sum(row[0] for row in rows.values())
    cost = sum(row[1] for row in rows.values())
    missing = sum(row[2] for row in rows.values())
    print("\nquery_source\trequests\trequest_%\tknown_USD\tcost_%\tmissing_cost\tmodels")
    for source, (n, usd, absent) in sorted(rows.items()):
        share = f"{100 * usd / cost:.2f}" if cost > 0 and not missing else "n/a"
        names = ",".join(sorted(models[source]))
        print(f"{source}\t{n}\t{100 * n / count:.2f}\t{usd:.6f}\t{share}\t{absent}\t{names}")
    print(f"Total API records: {count}; missing costs: {missing}", flush=True)

class Receiver(BaseHTTPRequestHandler):
    def log_message(self, *args):
        pass

    def do_POST(self):
        if self.path != "/v1/logs":
            self.send_error(404)
            return
        raw = self.rfile.read(int(self.headers.get("Content-Length", "0")))
        try:
            if self.headers.get("Content-Encoding") == "gzip":
                raw = gzip.decompress(raw)
            data = json.loads(raw)
        except (ValueError, OSError):
            self.send_error(400)
            return
        for resource in data.get("resourceLogs", []):
            for scope in resource.get("scopeLogs", []):
                for record in scope.get("logRecords", []):
                    a = {item["key"]: scalar(item["value"])
                         for item in record.get("attributes", [])}
                    event = a.get("event.name") or scalar(record.get("body", {}))
                    if event in ("user_prompt", "claude_code.user_prompt"):
                        print("Received user_prompt event.", flush=True)
                    if event not in ("api_request", "claude_code.api_request"):
                        continue
                    identity = a.get("request_id") or json.dumps(record, sort_keys=True)
                    if identity in seen:
                        continue
                    seen.add(identity)
                    source = str(a.get("query_source") or "(missing)")
                    models[source].add(str(a.get("model") or "(missing)"))
                    row = rows[source]
                    row[0] += 1
                    try:
                        usd = (float(a["cost_usd"]) if a.get("cost_usd") is not None
                               else float(a["cost_usd_micros"]) / 1_000_000)
                        if not math.isfinite(usd) or usd < 0:
                            raise ValueError()
                        row[1] += usd
                    except (KeyError, ValueError, TypeError):
                        row[2] += 1
        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.end_headers()
        self.wfile.write(b"{}")
        report()

server = HTTPServer(("127.0.0.1", 4318), Receiver)
print("Listening on 127.0.0.1:4318. Stop after Claude exits with Ctrl+C.", flush=True)
try:
    server.serve_forever()
except KeyboardInterrupt:
    pass
finally:
    server.server_close()
    report()
PY

Inicia la sesión que vas a medir

Ejecuta lo siguiente en el segundo terminal. El subshell, una shell secundaria, limita estos cambios de entorno al proceso que vas a medir:

(
  export CLAUDE_CODE_ENABLE_TELEMETRY=1
  export OTEL_LOGS_EXPORTER=otlp
  export OTEL_METRICS_EXPORTER=none
  export OTEL_TRACES_EXPORTER=none
  export OTEL_EXPORTER_OTLP_LOGS_PROTOCOL=http/json
  export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://127.0.0.1:4318/v1/logs
  export OTEL_LOGS_EXPORT_INTERVAL=1000
  claude
)

Elige una tarea habitual que justifique trabajar en segundo plano. Por ejemplo, pide a un agente que revise las pruebas de autenticación sin editar archivos. Continúa trabajando en la conversación principal y confirma que el agente en segundo plano se inicia realmente.

Mantén la sesión interactiva, sin enviar la salida de Claude a una tubería. Sustituirla por claude -p cambia el modo de ejecución y puede modificar el comportamiento de los resúmenes.

Tras enviar un prompt, el primer terminal debería mostrar Received user_prompt event.. Después deberían aparecer las filas de solicitudes de API. Deja que termine el trabajo, sal de Claude normalmente y espera la última exportación antes de detener el receptor con Ctrl+C. Copia la tabla final del historial de salida del terminal.

Interpreta el resultado y diagnostica los datos ausentes

Consulta la fila agent_summary del intervalo medido. request_% usa todos los eventos de solicitudes de API capturados como denominador. cost_% usa la suma de los costes estimados de todas las solicitudes de API capturadas:

summary cost share = 100 × summary estimated USD / all captured estimated USD

La columna models enumera los modelos registrados para cada origen. Para investigar la caché en una plataforma de monitorización existente, revisa también input_tokens, cache_read_tokens, cache_creation_tokens y output_tokens.

El receptor mantiene las solicitudes sin origen en el denominador como (missing). Si alguna solicitud capturada carece de un coste válido, muestra n/a en los porcentajes de coste. Resuelve los campos ausentes antes de considerar completo el desglose.

Si no aparece una fila agent_summary, no se observaron esas solicitudes durante el intervalo. Eso no demuestra que la función esté desactivada. Confirma primero que llegaron eventos de prompts y solicitudes de API, y que hubo trabajo real en segundo plano.

Si no llega nada, comprueba que el receptor está activo, el protocolo es http/json y el endpoint termina en /v1/logs. Un destino gestionado por la organización puede prevalecer sobre la configuración local. Para continuar el diagnóstico, ejecuta claude --debug-file ./otel-debug.log dentro del mismo subshell. Revisa los errores del exportador con el prefijo [3P telemetry] según la guía de monitorización.

Por qué pueden diferir los historiales, /usage y las facturas

La ausencia de una fila en el historial puede ocultar el origen del consumo sin excluirlo del total de la sesión. En el issue #104358, rabitlord1324 informa de registros ausentes de solicitudes en segundo plano, aunque describe la contabilidad interna de Claude Code como correcta.

La documentación actual de uso describe los totales de la sesión y el uso por modelo. No ofrece el desglose por query_source que necesitamos aquí. Que un analizador del historial omita los resúmenes no demuestra que todos estén ausentes de /usage.

cost_usd sigue siendo una estimación. Claude Code suele usar precios de catálogo, pero una tabla modelPricing gestionada por la organización puede cambiar las tarifas de sus informes. El consumo del cupo de la suscripción y los cargos de API son cantidades distintas. Contrasta los resultados de pago por uso con los registros reales de tu proveedor.

Si usas BetterToken, la URL base documentada para Claude Code es https://bettertoken.ai. Su catálogo incluye claude-opus-5-5 a fecha de 2026-11-01. Compara el intervalo medido con el modelo, el consumo de tokens y los cargos en el panel de trabajo.

Elige una reducción que conserve el trabajo útil

Si el gasto medido es relevante, empieza por acotar las tareas o usar menos agentes en segundo plano. A fecha de 2026-11-01, las referencias de variables de entorno y subagentes no documentan un interruptor exclusivo para los resúmenes.

OpciónQué cambiaContrapartida
Menos tareas en segundo plano o tareas más cortasReduce las ocasiones de resumir repetidamente el historialPuede reducir el paralelismo útil; compara el tiempo de ejecución
Un modelo más pequeño para un subagente con una tarea acotadaCambia el modelo que realiza el trabajo delegadoComprueba la calidad del resultado y el modelo registrado en la telemetría
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 claudeDesactiva de forma amplia la ejecución en segundo plano mediante las herramientas afectadasClaude espera a que terminen los subagentes antes de continuar
CLAUDE_CODE_FORK_SUBAGENT=0 claudeDesactiva la creación autónoma de bifurcaciones de la conversaciónLos subagentes aún pueden trabajar en segundo plano; no se garantiza la supresión de resúmenes
Parche de la comunidad mediante Bun preloadIntenta interceptar el temporizador de resúmenesEjecuta código de terceros dentro de Claude Code y puede dejar de funcionar tras una actualización

La variable de tareas en segundo plano elimina run_in_background e impide el paso automático a segundo plano mediante las herramientas afectadas. Las tareas de MCP, la herramienta Monitor y las sesiones independientes en segundo plano tienen excepciones o controles separados. No es un interruptor para toda actividad en segundo plano.

El control del modo fork está documentado, pero no se garantiza que su efecto secundario suprima los resúmenes. En 2.1.312, chrisvaillancourt informó de que los suprimía en macOS. dblumenau seguía observando solicitudes en Linux. La configuración y el modo de ejecución difieren entre ambos informes.

Configura el control antes de iniciar una sesión nueva. Busca entradas env en conflicto en ~/.claude/settings.json y en los ajustes del proyecto; pueden sustituir valores heredados de la shell.

Trata el preload de Flamerix como una solución experimental de la comunidad. Examina el código de una revisión fijada antes de considerar su uso. Comprueba el número de solicitudes después de cada actualización del cliente; una etiqueta inmóvil no demuestra por sí sola que las solicitudes hayan cesado.

Para investigaciones acotadas, consulta la guía para verificar el modelo de un subagente de solo lectura. Si las definiciones extensas de herramientas aumentan el contexto, usa la comparación del coste del contexto MCP para comprobar si ayuda reducir las herramientas disponibles.

Cambia una variable cada vez. Compara la misma tarea, modelo, condiciones de contexto, resultado aceptado y tiempo transcurrido junto con el coste por origen. Restablece el trabajo en segundo plano si perder concurrencia útil cuesta más que el ahorro medido.

¿Quieres optimizar tu flujo de trabajo con LLM?

Conecta modelos mediante una API, gestiona claves y controla el gasto en IA.

Empezar gratis