Dificultad: media | Duración: 25 minutos | Beneficio: aprender 7 técnicas de ahorro a nivel de código fuente; reduce tu factura de la API un 30-60%
Perfil del público objetivo
Ingenieros full-stack que están usando o planean usar Claude Code a fondo, especialmente desarrolladores individuales y equipos pequeños que se enfocan en el control del coste de la API. Si tu idea de Claude Code todavía está en la fase de “lo instalas y ya funciona”, este artículo te mostrará cuántos parámetros ajustables esconde.
Dependencias y entorno clave
- Node.js 18+
- Claude Code 2.1.88
- Conocimientos básicos de TypeScript (basta con que puedas leer definiciones de tipos)
- npm o pnpm
- Una ANTHROPIC_API_KEY válida
TIP
Todos los ejemplos del artículo están basados en la versión 2.1.88. Para ver el número de versión: claude --version. Los detalles del código fuente pueden variar ligeramente entre versiones, pero el mecanismo central es el mismo.
Estructura completa del proyecto (árbol)
# Estructura del código fuente de Claude Code (directorios relacionados)
src/
├── cost-tracker.ts # Núcleo del seguimiento de costes
├── costHook.ts # Hook de salida del coste
├── Tool.ts # Fábrica de abstracción de herramientas
├── tools.ts # Registro y filtrado de herramientas
├── tools/
│ ├── BashTool/ # Herramienta de ejecución de shell
│ │ └── BashTool.tsx
│ │ └── readOnlyValidation.ts # Lógica de validación en modo solo lectura
│ ├── FileReadTool/ # Lectura de archivos
│ ├── FileEditTool/ # Edición de archivos
│ └── ...
├── services/
│ ├── compact/ # Servicio de compresión de contexto
│ │ └── compact.ts
│ └── tools/
│ └── toolOrchestration.ts # Particionado de concurrencia de herramientas
├── skills/
│ └── loadSkillsDir.ts # Carga de skills
├── types/
│ └── permissions.ts # Definición del modo de permisos
├── upstreamproxy/ # Proxy hacia el upstream (empresarial)
│ ├── upstreamproxy.ts
│ └── relay.ts
└── utils/
└── git.ts # Herramientas de Git / Worktree
I. ¿Cómo se vuelve más cara la factura de Claude Code?
Antes de hablar de ahorrar, aclaremos en qué se va el dinero. La factura de la API de Claude Code está impulsada principalmente por tres cosas:
1. Total de tokens del contexto
En cada conversación, Claude Code empaqueta los mensajes históricos, los resultados de llamadas a herramientas y el contenido de archivos para enviarlo a la API. Cuanto mayor es el contexto, más alto es el precio por cada solicitud. En cost-tracker.ts, el consumo de cada sesión se rastrea con precisión:
// src/cost-tracker.ts
interface ModelUsage {
inputTokens: number;
outputTokens: number;
cacheReadInputTokens: number; // Lectura desde caché (más barato)
cacheCreationInputTokens: number; // Creación de caché (coste único)
webSearchRequests: number;
costUSD: number;
}
Aquí hay dos puntos clave: cacheReadInputTokens es aproximadamente 10 veces más barato que los tokens input normales, mientras que cacheCreationInputTokens es un coste único por crear la caché. Esto determina directamente la estrategia de compresión que viene más adelante.
2. Frecuencia de llamadas a herramientas
En promedio, Claude Code dispara decenas de llamadas a herramientas por conversación. Cada llamada a herramienta genera una solicitud a la API (tool use en modo streaming). Cuantas más herramientas y cuantas más llamadas, más rápido se infla el contexto.
3. Número de agentes en concurrencia
Cuando usas AgentTool para iniciar un sub-agente, o cuando en modo Coordinator se programan varios Workers a la vez, cada ejecución ocurre como una sesión independiente. El coste se duplica directamente.
Claude Code incluye cost-tracker.ts para rastrear estos consumos en tiempo real. Al salir, persiste los datos en la configuración del proyecto:
// src/costHook.ts
// Guardado automático y resumen de la factura al terminar el proceso
process.on('exit', () => {
if (hasConsoleBillingAccess()) {
console.log(formatTotalCost()); // Imprime la factura con desglose por modelo
}
saveCurrentSessionCosts(getFpsMetrics?.());
});
WARNING
El rastreo de la factura está aislado a nivel de proyecto: el consumo de sesiones de distintos directorios no se combina. Si usas Claude Code en varios proyectos, cada proyecto tiene su propio registro de costes.
II. Truco de ahorro 1: Compactar el contexto con Compact para ahorrar 30-50%
Claude Code incluye un servicio compact que “comprime” las conversaciones históricas en forma de resumen, manteniendo el contexto en un tamaño razonable. Los parámetros clave del código fuente están a la vista:
// src/services/compact/compact.ts
const POST_COMPACT_TOKEN_BUDGET = 50_000; // Límite total de tokens tras la compresión
const POST_COMPACT_MAX_TOKENS_PER_FILE = 5_000; // Máximo 5K tokens por archivo
const POST_COMPACT_MAX_TOKENS_PER_SKILL = 5_000; // Máximo 5K tokens por Skill
const POST_COMPACT_SKILLS_TOKEN_BUDGET = 25_000; // Límite total de 25K para todas las Skills
const POST_COMPACT_MAX_FILES_TO_RESTORE = 5; // Máximo 5 archivos para restaurar tras la compresión
El proceso de compresión tiene tres pasos: disparar → resumen vía API → re-adjuntar archivos clave. Primero dispara los hooks pre_compact, llama a la API de compresión (esta es una llamada API independiente), luego dispara los hooks post_compact y, al final, vuelve a adjuntar los archivos leídos más recientemente.
Consejo práctico: ajustar el umbral de disparo controla la frecuencia de compresión y, por tanto, el coste.
// settings.json — bajo la carpeta .claude/ en la raíz del proyecto
{
"compact": {
"autoCompactThreshold": 0.85 // Se dispara la compresión cuando se usa el 85% del contexto; valor por defecto
}
}
Bajar el umbral (por ejemplo 0.7) hará que se compacte con más frecuencia: el coste por compresión será menor, aunque la calidad del resumen puede bajar un poco. Subirlo (0.95) es lo contrario.
TIP
Si notas que Claude Code “olvida” hacia el final de una conversación larga, es muy probable que el contexto clave se haya cortado después de la compresión. En ese caso puedes añadir información clave manualmente en la conversación o bajar autoCompactThreshold para comprimir más a menudo, pero con menos tokens por compresión.
III. Truco de ahorro 2: Aprovecha las herramientas de solo lectura para evitar consumos innecesarios
Cada herramienta en Claude Code tiene el método isReadOnly(), que determina si la herramienta produce efectos secundarios. El programador de herramientas usa esta marca para decidir si permite ejecutar en concurrencia:
// src/Tool.ts — por defecto las herramientas son conservadoras (fail-closed)
const TOOL_DEFAULTS = {
isConcurrencySafe: (_input) => false, // Por defecto no es seguro para concurrencia; no en paralelo
isReadOnly: (_input) => false, // Por defecto tiene efectos secundarios
isDestructive: (_input) => false, // Por defecto no destructiva
};
La clave está en BashTool. Trae una lógica detallada de clasificación de comandos:
// src/tools/BashTool/BashTool.tsx
// Lista blanca de comandos solo lectura — estos comandos pueden ejecutarse en paralelo de forma segura sin modificar ningún estado
const BASH_SEARCH_COMMANDS = ['find', 'grep', 'rg', 'ag', 'ack', 'locate', 'which', 'whereis'];
const BASH_READ_COMMANDS = ['cat', 'head', 'tail', 'less', 'more', 'wc', 'stat', 'file', 'strings', 'jq', 'awk', 'cut', 'sort', 'uniq', 'tr'];
const BASH_LIST_COMMANDS = ['ls', 'tree', 'du'];
const BASH_SEMANTIC_NEUTRAL_COMMANDS = ['echo', 'printf', 'true', 'false', ':'];
Consejo práctico: cuando emites un comando como ls -la para consultar la estructura de un directorio, Claude Code sabe que es una operación solo lectura y lo empaqueta junto con otras operaciones de solo lectura para ejecutarlas en concurrencia, reduciendo el tiempo de espera. Pero si ejecutas rm -rf node_modules, se reconoce como una operación destructiva y debe tratarse en serie: en cada caso te pedirá confirmación.
Si entiendes esta lógica, puedes organizar tus comandos para activar mejores optimizaciones de concurrencia:
# Buenas prácticas: las operaciones solo lectura se pueden combinar en un solo comando para reducir llamadas a herramientas
find . -name "*.ts" | head -20 && wc -l src/**/*.ts
# Malas prácticas: mezclar operaciones destructivas con comandos solo lectura
find . -name "*.log" && rm -rf logs/ # Esta se intercepta en serie
IV. Truco de ahorro 3: El sistema de Skills reduce prompts repetidos y ahorra tokens de prompt
Claude Code admite el sistema de Skills. En esencia, son fragmentos de prompt reutilizables. Cuando creas una carpeta skills/ en la raíz del proyecto y colocas allí archivos Markdown, Claude Code los carga automáticamente:
tu-proyecto/
└── skills/
└── mi-workflow/
└── SKILL.md # Formato de directorio: skill-name/SKILL.md
Los archivos de Skill tienen metadata frontmatter:
---
name: my-skill
description: Flujo estándar para refactorizar componentes de React
whenToUse: Cuando necesites refactorizar un componente o dividir componentes grandes
paths: ["src/**/*.tsx", "src/**/*.ts"] # Se activa solo al coincidir con estas rutas
allowedTools: [Read, Edit, Bash] # Limita las herramientas disponibles
arguments: [filePath, scope]
executionContext: inline # inline o fork
---
# Cuerpo de la Skill — Aquí escribes tu prompt de flujo de refactorización estándar
¿Por qué ahorra dinero? Cada vez que creas una conversación nueva, Claude Code necesita incluir en el system prompt todas las descripciones de herramientas, reglas y contexto. Skills estandariza los flujos de trabajo habituales y reduce la repetición de tokens que implica escribir las mismas instrucciones cada vez. Lo que se ahorra es la longitud del prompt que normalmente copiarías y pegarías.
El campo paths es el alma del mecanismo de activación condicional: solo cuando coincide con las rutas especificadas, esta Skill aparece en la lista de candidatas. Esto evita que Skills no relacionadas “ensucien” el contexto:
// src/skills/loadSkillsDir.ts
// Activación condicional con patrones estilo gitignore
activateConditionalSkillsForPaths(filePaths, cwd) {
// Cuando se acceden archivos src/**/*.tsx, se activan las Skills relacionadas con React
}
TIP
Las Skills de alta reutilización deberían colocarse en ~/.claude/skills/ (nivel usuario). Las Skills específicas del proyecto solo deben ponerse en el propio proyecto. Cuanto más alto esté en la jerarquía, mayor será el alcance e impacto de ahorro.
V. Truco de ahorro 4: Partición por concurrencia para reducir reintentos y ahorrar consumo del Rate Limit
Claude Code no ejecuta todas las llamadas a herramientas de forma secuencial. Tiene un particionador inteligente: agrupa las herramientas “que se pueden ejecutar a la vez” y procesa por separado las que “tienen que ir en cola”:
// src/services/tools/toolOrchestration.ts
// Lee el límite de concurrencia; por defecto 10
function getMaxToolUseConcurrency() {
return parseInt(process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY ?? '10', 10);
}
// Partición de llamadas a herramientas: si son consecutivas solo de herramientas solo-lectura, se combinan; si no, se abre un nuevo batch
function partitionToolCalls(toolUseMessages, toolUseContext): Batch[] {
return toolUseMessages.reduce((acc, toolUse) => {
const isConcurrencySafe = tool.isConcurrencySafe(parsedInput.data);
if (isConcurrencySafe && acc[acc.length-1]?.isConcurrencySafe) {
acc[acc.length-1].blocks.push(toolUse); // Seguro para concurrencia, se combina
} else {
acc.push({ isConcurrencySafe, blocks: [toolUse] }); // Nuevo batch
}
return acc;
}, []);
}
Consejo práctico: si tus herramientas MCP soportan concurrencia, debes declararlo explícitamente al definirlas: isConcurrencySafe: true. Si no lo declaras, las herramientas se tratan por defecto como secuenciales. Cuando una herramienta secuencial se topa con el Rate Limit, los reintentos consumen tokens de forma indirecta; al acumularse, el coste puede ser considerable.
// settings.json — declara seguridad de concurrencia para tus herramientas MCP
{
"mcpServers": {
"my-mcp": {
"command": "npx",
"args": ["-y", "my-mcp-tool"],
"isConcurrencySafe": true // Declarada, puede ejecutarse en paralelo con otras herramientas solo-lectura
}
}
}
El límite de concurrencia también se puede aumentar con variables de entorno:
# Úsalo cuando el rendimiento de la máquina sea bueno y tengas cuotas de API suficientes
export CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY=20
VI. Truco de ahorro 5: Aislar con Worktree en lugar de clonar todo para simplificar el contexto de colaboración
Claude Code incluye soporte para Worktree. Git Worktree te permite hacer check-out de múltiples ramas en el mismo repositorio, en distintos directorios, sin necesidad de clonar varias veces el repositorio. findCanonicalGitRoot de Claude Code analiza automáticamente las rutas de Worktree:
// src/utils/git.ts
// Parseo seguro de la raíz de Worktree
function resolveCanonicalRoot(gitRoot: string): string {
const gitDirContent = readFileSync(path.join(gitRoot, '.git'), 'utf8');
// Formato del archivo .git: gitdir: /path/to/.git/worktrees/<name>
const commonDir = extractCommonDir(gitDirContent);
// Validación segura: worktreeGitDir debe ser un subdirectorio de commonDir/worktrees/
// Evita que un repositorio malicioso use el archivo .git para escapar del sandbox
validateWorktreeSecurity(worktreeGitDir, commonDir);
return mainRepoRoot;
}
Principio de ahorro: si tu equipo tiene la costumbre de clonar una copia por cada rama de funcionalidad, cada clon incluye su propio directorio .git (posiblemente varios GB), y Claude Code lo incluye dentro del alcance del escaneo del contexto. En modo Worktree solo hay un .git: el volumen del escaneo de contexto se reduce drásticamente.
# Crea un Worktree (en lugar de clonar una nueva copia)
git worktree add ../feature-sidebar feature/sidebar
# Claude Code lo reconoce automáticamente y comparte el contexto del repositorio principal
# Al cambiar a otro worktree, solo tienes que hacer cd y arrancar claude
cd ../feature-sidebar && claude
WARNING
El mecanismo de seguridad de Worktree es importante: Claude Code valida que la ruta del archivo .git no se use para hacer sandbox escape. Pero si usas Worktree en repositorios no confiables, sigue recomendándose ser cuidadoso.
VII. Truco de ahorro 6: Ajusta el modo de Permisos para reducir interacciones de confirmación
Claude Code tiene un sistema completo de permisos: 5 modos determinan cuándo las herramientas te pedirán confirmación:
// src/types/permissions.ts
type PermissionMode =
| 'acceptEdits' // Acepta automáticamente las ediciones
| 'bypassPermissions' // Salta completamente la verificación de permisos (peligroso pero más rápido)
| 'default' // Pregunta según reglas
| 'dontAsk' // No pregunta
| 'plan' // Modo Plan
| 'auto'; // Clasificación automática por IA (cuando está habilitado TRANSCRIPT_CLASSIFIER)
| Modo | Comportamiento | Velocidad | Seguridad |
|---|---|---|---|
default | Pregunta según reglas | Lento | Seguro |
auto | El clasificador de IA decide automáticamente | Medio | Algo más seguro |
dontAsk | No pregunta; ejecuta directamente | Rápido | Riesgo bajo tu responsabilidad |
bypassPermissions | Salta completamente las verificaciones | Más rápido | Alto riesgo |
plan | En modo Plan no ejecuta | Más lento | El más seguro |
Consejo práctico: para directorios completamente confiables (tus propios proyectos, donde el código ya está versionado en git), puedes afinar la configuración en settings.json:
// ~/.claude/settings.json (nivel usuario) o .claude/settings.json (nivel proyecto)
{
"permissions": {
"defaultMode": "auto",
"allow": [
{ "toolName": "Bash", "ruleContent": "pnpm*" },
{ "toolName": "Read" },
{ "toolName": "Glob" },
{ "toolName": "Grep" }
],
"deny": [
{ "toolName": "Bash", "ruleContent": "rm -rf /" }
],
"ask": [
{ "toolName": "Bash", "ruleContent": "git push" }
]
}
}
El modo auto es un buen equilibrio entre comodidad y seguridad: usa el clasificador por IA para evaluar si una operación es segura, evitando ventanas emergentes innecesarias. Cada vez que eliminas una confirmación, también reduces el consumo de tokens por los cambios de contexto.
WARNING
El modo bypassPermissions es como convertir Claude Code en un script con privilegios de root: cualquier entrada se ejecuta directamente. Úsalo solo en directorios de prueba aislados; no lo abras nunca en el proyecto principal.
VIII. Truco de ahorro 7: Caché del proxy upstream a nivel empresarial para reducir llamadas API repetidas
El módulo upstreamproxy de Claude Code proporciona el enrutado de proxy para Claude Code Connect (CCR, versión empresarial). En el código fuente, vale la pena prestar atención al valor NO_PROXY_LIST:
// src/upstreamproxy/upstreamproxy.ts
const NO_PROXY_LIST = [
'localhost', '127.0.0.1', '::1',
'169.254.0.0/16', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16',
'anthropic.com', 'github.com', '*.github.com',
// npm / PyPI / Rust registry están en la lista blanca; no necesitan pasar por proxy
'registry.npmjs.org', 'pypi.org', 'files.pythonhosted.org',
'index.crates.io', 'proxy.golang.org'
];
Consejo práctico: incluso si no usas la versión empresarial, entender esta lógica te ayuda a optimizar tu configuración local. Si estás en una red de empresa, Claude Code enruta automáticamente el tráfico hacia el proxy empresarial. A nivel de proxy se pueden hacer caché y reutilización de tokens; este es el mecanismo de fondo que permite ahorrar a los usuarios CCR empresariales.
Para servicios MCP montados por tu cuenta, puedes habilitar caché de respuestas en la configuración de MCP:
// settings.json
{
"mcpServers": {
"local-knowledge": {
"command": "node",
"args": ["server.js"],
"env": {
"MCP_CACHE_TTL": "3600" // Caché durante 1 hora; reduce llamadas API repetidas
}
}
}
}
IX. Resolución de problemas frecuentes
P1: Cambié solo 1 línea y aun así la factura es alta
La factura alta no siempre proviene de la edición. Puede deberse a la “inflación del contexto”. En conversaciones largas, incluso un cambio de 1 línea: los mensajes históricos previos y los resultados de herramientas antes de la compresión siguen en el contexto. Cómo verificarlo: al finalizar la sesión, revisa formatTotalCost() y mira inputTokens. Compáralo con outputTokens: cuanto mayor sea el primero, más “pesado” es el contexto.
P2: ¿La calidad de la respuesta baja claramente después de Compact?
Esto suele ser un problema de granularidad de la compresión. Ajusta autoCompactThreshold desde el valor por defecto 0.85 a 0.95 para reducir la frecuencia de compresión. Al mismo tiempo, asegúrate de que las decisiones de diseño importantes y la información de contexto queden registradas claramente al principio de la conversación. Así, la calidad del resumen será mayor.
P3: ¿El modo bypass es realmente inseguro?
Sí, pero en un entorno aislado es controlable. Si necesitas usar bypass, se recomienda reforzarlo con reglas permissions.deny como contramedida:
{
"permissions": {
"defaultMode": "bypassPermissions",
"deny": [
{ "toolName": "Bash", "ruleContent": "sudo*" },
{ "toolName": "Bash", "ruleContent": "curl*|wget*" }
]
}
}
P4: ¿Cómo monitorizar el consumo de tokens cada día?
Claude Code imprime automáticamente la factura al salir de cada sesión (si tienes consoleBillingAccess). La forma más sistemática es crear un script de seguimiento a nivel de proyecto:
# Añade un hook post-checkout en el directorio .git/hooks/ del proyecto para registrar
# Pero lo más útil es comprobar directamente .claude/cost/<session-id>.json
P5: ¿Skills consumen tokens adicionales cada vez?
Sí, pero es controlable. La ocupación de tokens del contenido de Skill se incluye en POST_COMPACT_SKILLS_TOKEN_BUDGET (límite 25K). Cuantas más Skills y más detalladas sean, mayor será el contexto. Por eso, el principio de redacción de Skills es: ajuste preciso, información mínima necesaria. Aprovecha paths para que la Skill solo se cargue cuando se accedan a archivos relevantes.
P6: ¿Claude Code se comporta de forma extraña después de usar Worktree?
Worktree tiene un mecanismo de validación de seguridad: si el formato del archivo .git no es estándar, Claude Code hace fallback al directorio actual. Verifica que el contenido del archivo .git tenga el formato gitdir: /absolute/path/to/.git/worktrees/<name>.
X. Lecturas adicionales / Direcciones de nivel avanzado
1. Escribe tus propias Skills para reducir ingeniería repetitiva
Si descubres que en varios proyectos repites prompts como “escribe código siguiendo este estilo” una y otra vez, conviértelo en una Skill, ponla en ~/.claude/skills/ y tendrá efecto global. Una vez la escribes: ahorras muchas veces.
2. Usa MCP para construir una cadena de herramientas local en lugar de llamadas a la nube
Las operaciones que consumen tokens suelen poder localizarse: búsqueda de código, consultas de documentación, operaciones de bases de datos. Encapsula esas capacidades en herramientas MCP locales para reducir la dependencia de la API de Claude y, al mismo tiempo, mejorar la velocidad de respuesta.
3. Monitorea los logs de compact para optimizar continuamente la estrategia de contexto
Activa el modo verbose para observar cuándo se dispara compact y cuál es su efecto. Ajusta continuamente autoCompactThreshold hasta encontrar el equilibrio adecuado para el tamaño de tu proyecto.
claude --verbose 2>&1 | grep -i compact
4. Entiende el clasificador de permisos a nivel de código fuente
Detrás del modo auto de Claude Code hay un clasificador por IA (Transcript Classifier). Determina el nivel de riesgo según el contenido de la operación. Si quieres profundizar, estudia la definición del tipo YoloClassifierResult en src/types/permissions.ts.