codacle.
DocsIniciá sesión →

Docs · 60

Modelo de costos.

Cómo se calcula el USD de cada run, qué es el pricing_snapshot, y cómo navegar el reporting.

El problema

Anthropic cobra por token consumido, con rates diferentes según el modelo y el tipo de token:

TipoQué es
input_tokensLo que mandás (system + user + tool_results en el último turno).
output_tokensLo que devuelve el modelo.
cache_read_input_tokensInput que ya estaba cacheado en el prompt cache (descuento agresivo).
cache_creation_input_tokensInput que escribís al cache por primera vez (premium).

Los rates están en packages/db/src/pricing.ts como USD por millón de tokens. Update manual cuando Anthropic publica precios nuevos — un solo archivo, re-exportado donde haga falta.

export const PRICING_PER_MTOK: Record<string, ModelPricing> = {
  'claude-opus-4-7':           { input: 15,  output: 75,  cacheRead: 1.5,  cacheCreate: 18.75 },
  'claude-sonnet-4-6':         { input: 3,   output: 15,  cacheRead: 0.3,  cacheCreate: 3.75 },
  'claude-haiku-4-5-20251001': { input: 1,   output: 5,   cacheRead: 0.1,  cacheCreate: 1.25 },
};

El snapshot

Cuando un run termina, capturamos los rates vigentes en workspace_runs.pricing_snapshot (jsonb). Razón: si Anthropic baja Opus a la mitad mañana, queremos que el cost-report de la semana pasada siga mostrando lo que pagaste, no lo que pagarías re-corriéndolo hoy.

// Stage del workflow donde se captura — al cerrar el job:
await sb.from('workspace_runs').update({
  status: 'done',
  usage: anthropicUsage,
  pricing_snapshot: PRICING_PER_MTOK[model],  // snapshot del rate actual
  duration_ms,
  finished_at: new Date().toISOString(),
}).eq('id', runId);

costUsd() prefiere pricing_snapshot si está; falla al lookup actual si no (runs viejos pre-feature) o a 0 si el modelo no tiene rate configurado.

Dónde se ve

LugarQué muestra
/migrations/[id]/overview → "Costo acumulado"Suma USD de todos los workspace_runs del workspace.
/ops → métrica "Costo total"Suma USD del período + filtros activos (kit, stage, status, model).
/ops/trendsCosto por día / semana / mes.
/kits/[id] → columna "Costo total"Suma USD acumulado por versión del kit.
cost-report CLITabla agrupada por kit + modelo, exportable a CSV.

Casos borde

  • Run sin usage: pasa cuando el worker fallea antes de cerrar la session (timeout, network error). usage queda null y costUsd devuelve 0. Esto subestima el costo real porque Anthropic igual cobra por los tokens efectivamente procesados aunque no nos lleguen los counters.
  • Modelo desconocido: si el manifest declara un modelo que no está en PRICING_PER_MTOK, costUsd devuelve 0. Preferimos under-report a inflar. Solución: agregar el rate al pricing table.
  • Cache hits dramáticos: los kits que reusan mucho prompt cache (skills compartidos, system prompts grandes) pueden tener cache_read_input_tokens >>> input_tokens. El descuento es real — 10x más barato. Por eso lo trackeamos por separado en lugar de mergearlo con input.

Optimizar el costo

Tres palancas, ordenadas por impact típico:

  1. Modelo correcto para cada agent — agents simples (extractor de campos, classifier) corren bien en Haiku 4.5 a 1/15 del precio de Opus. Configurarlo por agent en el manifest:

    agents:
      - id: classifier
        model: claude-haiku-4-5-20251001  # override del default del kit
    
  2. Prompt caching — system prompts largos + skills grandes son los que más se benefician. Mantenelos estables entre runs (no incluyas datetimes, IDs random, etc.) para que Anthropic los cachee con el prompt_cache: 1h ya configurado.

  3. Estructura de outputs — si el agent emite tokens que no necesitás (chain-of-thought verbose, repetir contexto), eso es output cost directo. Pedile que sea conciso en el system prompt.

Auditar un run individual

pnpm --filter web inspect-run <run_id>

Imprime:

  • Stage, status, duración
  • Anthropic IDs (session, agent, env, memory_store)
  • Tokens por tipo + costo desglosado
  • Mensajes de error si falló