Ver mi consumo y mis fugas

Tokens por sesión, worker y modelo, los bytes que el crush dejó fuera del cable, y los hábitos que los desperdician.

Prompt#

Muéstrame qué está gastando este workspace, y dónde estoy fugando contexto.

Qué hace el Chair#

Lee el ledger local — sin llamar a ningún proveedor — e imprime el gasto por asiento, y después la telemetría de fugas que nombra el hábito costoso.

Llamadas MCP#

usage_status({ "recent": 10 })
usage_status({ "view": "leaks" })
usage_status({ "view": "governance" })
usage_status({ "view": "workers" })

En CLI, para la versión legible por humanos:

orch usage                      # tabla: por sesión, por worker, por modelo
orch usage --format json --limit 10
orch usage --leaks              # relecturas, llamadas repetidas, resultados enormes, rachas mudas
orch usage --leaks --format json
orch usage --governance         # conflict_rate / duplicate_rate por sesión
orch usage --workers            # tiempo, estado, archivos, guardrails, llamadas a tools, tokens, costo por sesión
orch usage --export jsonl       # una línea JSON con claves gen_ai.* por sesión y por fila de tool
orch gateway status             # vivo/cooldown, posición del anillo, rotaciones por proveedor

Respuesta esperada#

usage_status acepta un view opcional: summary (por defecto), leaks, governance, workers o perf; un valor desconocido da error con view must be summary|leaks|governance|workers|perf. Esos cinco son la lista completa — los contadores por herramienta viven en la tabla cli_tool_usage, que lee view: workers; cli_tool_usage no es un view.

  • view: summary (u omitido) devuelve summary, saved_pct, total_bytes_saved, by_session[], by_worker[], by_model[], agents[], counters[]. Cada fila de desglose es {key, attempts, prompt_tokens, completion_tokens, bytes_saved}. Un bloque graph lleva lo que devolvieron code_snippet y trace_path contra el tamaño de los archivos que sustituyeron.
  • También devuelve by_worker_cli[]: tokens leídos directo de la salida propia del CLI de cada worker — el resultado --output-format json de agy, claude y cursor-agent, o la línea resumen Tokens ↑/↓ de copilot — para un CLI que nunca pasa por el gateway. Una vez parseados, esos mismos tokens también se suman a summary, agents[], counters[] y by_session[] — un worker CLI BYO-auth aparece en los números principales, no solo en by_worker_cli. cli_usage_unavailable[] lista cada sesión sin fila parseada, y por qué (usage block empty para un CLI conocido, no parser for this agent/CLI en cualquier otro caso) — un parser que lee todos los contadores en cero se trata como si no hubiera fila, nunca se imprime como medición.
  • view: leaks devuelve las mismas filas sin contenido que orch usage --leaks, por sesión (reread_files, repeated_calls, large_results, silent_streaks).
  • view: governance devuelve {sessions[], pairs[]} — las mismas métricas de conflicto/duplicado que orch usage --governance, más los conflictos por pareja.
  • view: workers devuelve {sessions[], tools[]}: una fila por sesión que nombra cada dimensión por la que se agregan las estadísticas de workers — session_id, agent_id (worker), task_id, project, day, más status, duration_ms, files_changed, guardrails, tool_calls/tool_errors/tool_time_ms, tokens medidos (input_tokens, output_tokens, cache_read_tokens, cache_write_tokens), cost_usd y source (de qué log de CLI salieron los tokens, o "" cuando nunca se parseó ninguno para esa sesión — nunca se muestra como cero tokens). tools[] es el desglose por tool a través de todas las sesiones: session_id, tool_name, call_count, success_count, error_count, total_time_ms — así se sabe qué tool se comió el presupuesto, contado por el propio servidor MCP de orch en cada tools/call que atiende, sin depender de lo que imprima el CLI que llama.

Presupuestos diarios#

orch.yaml puede topar los tokens medidos por día local, opcional y apagado salvo que lo configures:

budget:
  workspace_tokens_per_day: 2000000   # todo el proyecto, todos los asientos — 0/sin definir = ilimitado
  seat_tokens_per_day: 500000         # un agent id que despacha — 0/sin definir = ilimitado
  warn_at: 0.8                        # fracción del tope que agrega una nota en vez de denegar (default 0.8)

Ambos topes suman el cli_session_usage de hoy (día local) — tokens de entrada + salida + cache-write — los mismos números medidos que imprime orch usage --workers. Un dispatch en o por encima de cualquiera de los dos topes se deniega antes de que el agente arranque, tanto desde orch dispatch como desde la tool MCP dispatch_worker:

budget: seat exhausted (used 512000 of 500000 tokens today) — raise budget.* in orch.yaml or wait for the daily reset

Por debajo del tope pero por encima de warn_at, el dispatch igual corre y la respuesta lleva un budget_note (MCP) o imprime la nota antes de correr (CLI), en vez de gastar de más en silencio. orch budget status [--project P] [--format json] imprime el uso/tope de hoy para el workspace y para cada asiento que gastó tokens hoy, sin disparar ningún dispatch.

Trampas#

  • No lleva contenido, así que se lo puedes pegar a una persona. El ledger del gateway guarda conteos, nunca prompts. orch gateway status tampoco lleva contenido: ni llaves ni cuerpos.
  • Las fugas y la gobernanza también están por MCP. usage_status({ "view": "leaks" }) y usage_status({ "view": "governance" }) devuelven las mismas filas que las banderas de CLI — sin necesidad de shell.
  • cache_hits es gasto evitado, no gasto. Una petición que el gateway respondió desde su caché de coincidencia exacta lleva X-Orchemax-Cache: hit y no cuenta como intento upstream. Lee ahorrado y gastado como dos columnas, nunca como un neto.
  • La caché viene apagada. gateway.cache.ttl_sec es 0 salvo que la configures, y el streaming nunca se cachea — así que cache_hits: 0 casi siempre significa "no está habilitada", no "nunca pegó".
  • Solo se cuenta el tráfico que pasa por el gateway en summary/by_session/by_worker/by_model. Un preset en agents.auth.<preset>: account — Claude Code con su propio login de plan, y codex y cursor por defecto — no enruta tráfico de modelo aquí, así que muestra intentos pero no tokens de proveedor. by_worker_cli[] es cómo esos mismos workers BYO-auth igual muestran tokens medidos: leídos del propio log del CLI, no del gateway.
  • Los números de by_worker_cli son tan precisos como el CLI que los imprimió. agy, claude y cursor-agent reportan conteos exactos; el resumen de terminal de copilot viene redondeado a un decimal con sufijo "k" (168.1k → 168100), así que trátalo como aproximado, nunca como conteo exacto. Una medición redondeada sigue siendo una medición, no una afirmación sin base.
  • token_coverage.status es measured, partial o unavailable, nunca una adivinanza. measured cuando toda sesión con un CLI conocido tiene una fila de uso distinta de cero; partial mientras algunas sí y otras no — token_coverage.unmeasured[] nombra cuáles y por qué; unavailable cuando nunca se midió nada en absoluto (sin intento de gateway, sin hook de transcript, sin log de CLI parseado).
  • recent (MCP) y --limit (CLI) son la misma idea: adjuntar los N intentos más recientes. Omítelo si solo quieres el agregado.
  • by_worker_cli/workers ahora llevan cache_write_tokens junto a cache_read_tokens. El --output-format json de claude ya imprimía cache_creation_input_tokens; ahora se parsea y se guarda, no se descarta. agy y copilot no reportan una cifra de cache-write, así que sus filas quedan en 0 — no medido, no estimado.
  • orch usage --export jsonl es solo stdlib, sin dependencia de OTel. Una línea JSON por sesión (orch.source: "session") y una por par sesión/tool (orch.source: "tool"), con claves gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, gen_ai.usage.cache_read.input_tokens, gen_ai.usage.cache_write.input_tokens, gen_ai.tool.name, gen_ai.agent.name, orch.session, orch.project, orch.cli, orch.source — cada clave presente en cada línea, números solo de lo que realmente se midió. Cualquier colector OTLP-HTTP/JSONL lo ingiere tal cual.
  • Qué significan las columnas de fuga: releer un archivo que ya leíste, llamar la misma herramienta con los mismos argumentos, devolver resultados demasiado grandes para servir, y rachas largas de silencio. Cada una tiene una jugada más barata en Dejar de leer archivos enteros.