Скрытые способы экономии в исходном коде Claude Code: как сократить счета за API вдвое

April 1, 2026

Сложность: Средняя | Время: 25 минут | Итог: Освоение 7 техник экономии на уровне исходного кода, сокращение счетов за API на 30–60%

Портрет целевого читателя

Full-stack инженеры, которые уже используют или планируют активно использовать Claude Code, особенно индивидуальные разработчики и небольшие команды, заботящиеся о контроле затрат на API. Если ваше понимание Claude Code ограничивается стадией «установил и пользуйся», эта статья покажет, сколько регулируемых параметров скрыто под капотом.

Основные зависимости и окружение

  • Node.js 18+
  • Claude Code 2.1.88
  • Базовые знания TypeScript (достаточно уметь читать определения типов)
  • npm или pnpm
  • Действующий ANTHROPIC_API_KEY

TIP

Все примеры исходного кода в статье основаны на версии 2.1.88. Проверить версию можно командой: claude --version. В разных версиях детали кода могут отличаться, но основные механизмы идентичны.

Полная структура проекта

# Структура исходного кода Claude Code (релевантные директории)
src/
├── cost-tracker.ts              # Ядро отслеживания затрат
├── costHook.ts                  # Хук для вывода стоимости
├── Tool.ts                      # Абстрактная фабрика инструментов
├── tools.ts                     # Регистрация и фильтрация инструментов
├── tools/
│   ├── BashTool/                # Инструмент выполнения Shell
│   │   └── BashTool.tsx
│   │   └── readOnlyValidation.ts # Логика проверки «только чтение»
│   ├── FileReadTool/            # Чтение файлов
│   ├── FileEditTool/            # Редактирование файлов
│   └── ...
├── services/
│   ├── compact/                 # Сервис сжатия контекста
│   │   └── compact.ts
│   └── tools/
│       └── toolOrchestration.ts # Параллельное разделение инструментов
├── skills/
│   └── loadSkillsDir.ts         # Загрузка навыков (skills)
├── types/
│   └── permissions.ts           # Определение режимов разрешений
├── upstreamproxy/               # Прокси апстрима (корпоративный уровень)
│   ├── upstreamproxy.ts
│   └── relay.ts
└── utils/
    └── git.ts                   # Инструменты Git / Worktree

1. Почему счета за Claude Code становятся такими большими

Прежде чем говорить об экономии, давайте разберемся, на что тратятся деньги. Счета за API Claude Code формируются в основном под влиянием трех факторов:

1. Общий объем токенов контекста

При каждом диалоге Claude Code упаковывает историю сообщений, результаты вызовов инструментов и содержимое файлов для отправки в API. Чем больше контекст, тем выше цена каждого запроса. В cost-tracker.ts потребление каждой сессии отслеживается с высокой точностью:

// src/cost-tracker.ts
interface ModelUsage {
  inputTokens: number;
  outputTokens: number;
  cacheReadInputTokens: number;    // Чтение из кэша (дешевле)
  cacheCreationInputTokens: number; // Создание кэша (разовая плата)
  webSearchRequests: number;
  costUSD: number;
}

Здесь есть два ключевых момента: cacheReadInputTokens примерно в 10 раз дешевле обычных входящих токенов, а cacheCreationInputTokens — это разовые затраты на создание кэша. Это напрямую определяет нашу стратегию сжатия далее.

2. Частота вызовов инструментов

В среднем Claude Code инициирует десятки вызовов инструментов за один диалог. Каждый вызов порождает запрос к API (потоковое использование инструментов). Чем больше инструментов и чем чаще они вызываются, тем быстрее раздувается контекст.

3. Конкурентность агентов

Когда вы запускаете дочернего агента через AgentTool или используете режим координатора для одновременного управления несколькими воркерами, каждая сессия становится независимой — стоимость моментально удваивается.

Claude Code имеет встроенный cost-tracker.ts для отслеживания этих расходов в реальном времени. При выходе он сохраняет данные в конфигурацию проекта:

// src/costHook.ts
// Автоматическое сохранение и печать сводки счета при выходе из процесса
process.on('exit', () => {
  if (hasConsoleBillingAccess()) {
    console.log(formatTotalCost()); // Вывод счета с разбивкой по моделям
  }
  saveCurrentSessionCosts(getFpsMetrics?.());
});

WARNING

Отслеживание счетов изолировано на уровне проекта — расходы сессий в разных директориях не суммируются. Если вы используете Claude Code в нескольких проектах, у каждого будет своя история затрат.


2. Техника экономии №1: Сжатие контекста (Compact), экономия 30-50%

В Claude Code встроен сервис compact, который «сжимает» историю диалога в краткую сводку, удерживая контекст в разумных пределах. Ключевые параметры в исходном коде очевидны:

// src/services/compact/compact.ts
const POST_COMPACT_TOKEN_BUDGET = 50_000;           // Лимит токенов после сжатия
const POST_COMPACT_MAX_TOKENS_PER_FILE = 5_000;      // Макс. 5K токенов на один файл
const POST_COMPACT_MAX_TOKENS_PER_SKILL = 5_000;     // Макс. 5K токенов на один Skill
const POST_COMPACT_SKILLS_TOKEN_BUDGET = 25_000;     // Общий лимит для всех Skills — 25K
const POST_COMPACT_MAX_FILES_TO_RESTORE = 5;         // Восстановление максимум 5 файлов после сжатия

Процесс сжатия состоит из трех этапов: Триггер → API-саммаризация → Повторное прикрепление ключевых файлов. Сначала срабатывают хуки pre_compact, вызывается API сжатия (это отдельный запрос), затем срабатывают хуки post_compact, и в конце заново прикрепляются недавно прочитанные файлы.

Практический совет: Регулировка порога срабатывания позволяет контролировать частоту сжатия и, соответственно, расходы.

// settings.json — в директории .claude/ корня проекта
{
  "compact": {
    "autoCompactThreshold": 0.85  // Сжатие при заполнении контекста на 85% (по умолчанию)
  }
}

Снижение порога (например, до 0.7) приведет к более частому сжатию: стоимость каждого сжатия будет меньше, но качество сводки может немного снизиться. Повышение порога (0.95) даст обратный эффект.

TIP

Если вы заметили, что в длинных диалогах Claude Code начинает «забывать» детали, скорее всего, важный контекст был отсечен при сжатии. В таком случае можно вручную добавить ключевую информацию в диалог или снизить autoCompactThreshold, чтобы сжатие происходило чаще, но меньшими порциями.


3. Техника экономии №2: Грамотное использование инструментов Read-only для оптимизации

У каждого инструмента в Claude Code есть метод isReadOnly() — он определяет, вызывает ли инструмент побочные эффекты. Планировщик инструментов использует этот флаг для решения вопроса о параллельном выполнении:

// src/Tool.ts — Инструменты по умолчанию консервативны (fail-closed)
const TOOL_DEFAULTS = {
  isConcurrencySafe: (_input) => false,  // По умолчанию небезопасно для параллелизма
  isReadOnly: (_input) => false,          // По умолчанию имеет побочные эффекты
  isDestructive: (_input) => false,       // По умолчанию не деструктивно
};

Ключевой момент заключается в BashTool. В него встроена детальная логика классификации команд:

// src/tools/BashTool/BashTool.tsx
// Белый список команд только для чтения — они безопасны для параллельного запуска
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', ':'];

Практический совет: Когда вы отправляете запрос типа ls -la, Claude Code понимает, что это операция чтения, и упаковывает её вместе с другими операциями чтения для параллельного выполнения, сокращая время ожидания. Но если вы выполните rm -rf node_modules, команда будет распознана как деструктивная, требующая последовательной обработки и подтверждения.

Понимая эту логику, вы можете сами организовывать команды для лучшей оптимизации:

# Хорошая практика: объединение операций чтения в одну команду для уменьшения вызовов
find . -name "*.ts" | head -20 && wc -l src/**/*.ts

# Плохая практика: смешивание деструктивных операций с чтением
find . -name "*.log" && rm -rf logs/  # Это вызовет последовательную блокировку

4. Техника экономии №3: Система Skills для сокращения повторных промптов

Claude Code поддерживает систему навыков (Skills), которая по сути является набором многоразовых фрагментов промптов. Если вы создадите папку skills/ в корне проекта и положите туда Markdown-файлы, Claude Code загрузит их автоматически:

your-project/
└── skills/
    └── my-workflow/
        └── SKILL.md   # Формат: skill-name/SKILL.md

Файл Skill содержит метаданные frontmatter:

---
name: my-skill
description: Стандартный процесс рефакторинга React-компонентов
whenToUse: Используйте при необходимости рефакторинга или разделения крупных компонентов
paths: ["src/**/*.tsx", "src/**/*.ts"]  # Активируется только для этих путей
allowedTools: [Read, Edit, Bash]       # Ограничение доступных инструментов
arguments: [filePath, scope]
executionContext: inline               # inline или fork
---
# Тело навыка — здесь ваш стандартный промпт для рефакторинга

Почему это экономит деньги? Каждый раз при создании нового диалога Claude Code вставляет описания инструментов, правила и контекст в системный промпт. Skills позволяют стандартизировать рабочие процессы, уменьшая количество токенов, которые вы тратите, вводя одни и те же инструкции вручную.

Поле paths — это душа механизма условной активации: навык появится в списке кандидатов только при совпадении путей. Это предотвращает засорение контекста ненужными навыками:

// src/skills/loadSkillsDir.ts
// Условная активация использует сопоставление в стиле gitignore
activateConditionalSkillsForPaths(filePaths, cwd) {
  // Навыки React активируются только после обращения к файлам src/**/*.tsx
}

TIP

Часто используемые навыки лучше размещать в ~/.claude/skills/ (уровень пользователя), а навыки конкретного проекта — в его корне. Чем выше уровень навыка, тем шире охват и заметнее эффект экономии.


5. Техника экономии №4: Зонирование параллелизма для уменьшения повторов

Claude Code не выполняет все вызовы инструментов строго последовательно. У него есть интеллектуальный распределитель, который группирует инструменты, способные «работать одновременно»:

// src/services/tools/toolOrchestration.ts
// Чтение лимита параллелизма, по умолчанию 10
function getMaxToolUseConcurrency() {
  return parseInt(process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY ?? '10', 10);
}

// Распределение: если идут подряд read-only инструменты — объединяем, иначе — новый батч
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); // Безопасно, объединяем
    } else {
      acc.push({ isConcurrencySafe, blocks: [toolUse] }); // Новый батч
    }
    return acc;
  }, []);
}

Практический совет: Если ваши MCP-инструменты поддерживают параллелизм, обязательно укажите isConcurrencySafe: true при их определении. Инструменты без этого флага по умолчанию выполняются последовательно, а скрытые затраты токенов при повторах из-за Rate Limit в последовательном режиме могут быть значительными.

// settings.json — объявление безопасности параллелизма для вашего MCP
{
  "mcpServers": {
    "my-mcp": {
      "command": "npx",
      "args": ["-y", "my-mcp-tool"],
      "isConcurrencySafe": true  // Позволяет запускать инструмент параллельно с другими read-only
    }
  }
}

Лимит параллелизма также можно увеличить через переменную окружения:

# Подходит при высокой производительности машины и достаточном лимите API
export CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY=20

6. Техника экономии №5: Изоляция через Worktree вместо полного клонирования

В Claude Code встроена поддержка Git Worktree. Это позволяет извлекать несколько веток одного репозитория в разные папки без необходимости клонировать весь репозиторий целиком. Функция findCanonicalGitRoot автоматически распознает пути Worktree:

// src/utils/git.ts
function resolveCanonicalRoot(gitRoot: string): string {
  const gitDirContent = readFileSync(path.join(gitRoot, '.git'), 'utf8');
  // Формат файла .git: gitdir: /path/to/.git/worktrees/<name>
  const commonDir = extractCommonDir(gitDirContent);
  // Проверка безопасности: директория должна быть внутри commonDir/worktrees/
  validateWorktreeSecurity(worktreeGitDir, commonDir);
  return mainRepoRoot;
}

Принцип экономии: Если ваша команда привыкла клонировать репозиторий для каждой ветки фичи, то каждая директория .git (которая может весить гигабайты) будет попадать в сканирование контекста. В режиме Worktree директория .git только одна, что значительно сокращает объем сканируемого контекста.

# Создание Worktree (вместо клонирования)
git worktree add ../feature-sidebar feature/sidebar

# Claude Code автоматически распознает Worktree и использует общий контекст
cd ../feature-sidebar && claude

WARNING

Механизм безопасности Worktree важен: Claude Code проверяет пути, чтобы избежать выхода из песочницы (sandbox escape). Однако при работе с недоверенными репозиториями все равно стоит проявлять осторожность.


7. Техника экономии №6: Оптимизация режимов разрешений (Permission)

В Claude Code есть система разрешений с 5 режимами, определяющими, когда инструменту требуется ваше подтверждение:

// src/types/permissions.ts
type PermissionMode =
  | 'acceptEdits'   // Автоматически принимать правки
  | 'bypassPermissions' // Полный обход проверок (опасно, но быстро)
  | 'default'       // Запрос по правилам
  | 'dontAsk'       // Не спрашивать
  | 'plan'          // Режим планирования
  | 'auto';         // ИИ решает сам (при включенном TRANSCRIPT_CLASSIFIER)
РежимПоведениеСкоростьБезопасность
defaultСпрашивает по правиламМедленноБезопасно
autoИИ-классификатор решает самСреднеОтносительно безопасно
dontAskВыполняет без вопросовБыстроНа свой страх и риск
bypassPermissionsПолный пропуск проверокБыстрее всегоВысокий риск
planНе выполняет в режиме планаМедленнее всегоМакс. безопасность

Практический совет: Для директорий, которым вы полностью доверяете (ваши проекты с git), можно настроить детализацию в settings.json:

// ~/.claude/settings.json (пользовательский) или .claude/settings.json (проектный)
{
  "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" }
    ]
  }
}

Режим auto — это компромисс между удобством и безопасностью. Он использует ИИ для оценки безопасности операции, избегая лишних всплывающих окон. Каждое сэкономленное взаимодействие — это экономия токенов на переключение контекста.

WARNING

Режим bypassPermissions фактически превращает Claude Code в скрипт с правами root — любой ввод будет выполнен немедленно. Используйте его только в изолированных тестовых средах.


8. Техника экономии №7: Кэширование через корпоративный прокси

Модуль upstreamproxy обеспечивает маршрутизацию для Claude Code Connect (CCR). В коде стоит обратить внимание на список 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 в белом списке, прокси не нужен
  'registry.npmjs.org', 'pypi.org', 'files.pythonhosted.org',
  'index.crates.io', 'proxy.golang.org'
];

Практический совет: Даже если вы не используете корпоративную версию, понимание этой логики поможет оптимизировать локальные настройки. В корпоративных сетях трафик может идти через прокси, где реализовано кэширование токенов — это базовый механизм экономии для крупных клиентов.

Для собственных MCP-сервисов можно включить кэширование ответов в конфиге:

// settings.json
{
  "mcpServers": {
    "local-knowledge": {
      "command": "node",
      "args": ["server.js"],
      "env": {
        "MCP_CACHE_TTL": "3600"  // Кэш на 1 час для уменьшения повторных вызовов
      }
    }
  }
}

9. Устранение типичных проблем

Q1: Изменил всего одну строку, а счет огромный?

Высокий счет часто связан не с редактированием, а с «раздуванием контекста». В длинных диалогах история сообщений и результаты инструментов остаются в контексте до сжатия. Проверьте вывод formatTotalCost(): если inputTokens намного больше outputTokens, значит контекст перегружен.

Q2: После сжатия (Compact) качество ответов упало?

Это вопрос гранулярности. Попробуйте изменить autoCompactThreshold с 0.85 до 0.95. Сжатие будет происходить реже, но вы должны следить, чтобы важные проектные решения фиксировались в начале диалога для лучшего качества сводки.

Q3: Насколько безопасен режим bypass?

Небезопасен, но управляем в изоляции. Если необходимо его использовать, добавьте правила в permissions.deny для подстраховки:

{
  "permissions": {
    "defaultMode": "bypassPermissions",
    "deny": [
      { "toolName": "Bash", "ruleContent": "sudo*" },
      { "toolName": "Bash", "ruleContent": "curl*|wget*" }
    ]
  }
}

Q4: Как отслеживать ежедневный расход токенов?

Claude Code печатает счет при выходе из сессии (если есть доступ к биллингу). Более системно можно проверять JSON-файлы в директории .claude/cost/<session-id>.json.

Q5: Тратят ли Skills дополнительные токены?

Да, но это контролируемо. Объем токенов для Skills ограничен лимитом POST_COMPACT_SKILLS_TOKEN_BUDGET (25K). Пишите навыки лаконично и используйте поле paths, чтобы они загружались только тогда, когда действительно нужны.


10. Дополнительное чтение / Продвинутые темы

  1. Создание собственных Skills: Вынесите повторяющиеся инструкции типа «пиши код в этом стиле» в глобальный навык в ~/.claude/skills/. Напишите один раз — экономьте постоянно.
  2. Локальные MCP вместо облачных вызовов: Поиск по коду и работу с БД лучше делать через локальные MCP-инструменты. Это снижает зависимость от API Claude и ускоряет отклик.
  3. Мониторинг логов сжатия: Используйте режим --verbose, чтобы видеть, когда срабатывает compact, и подстроить порог под масштаб вашего проекта.
claude --verbose 2>&1 | grep -i compact
Updated April 1, 2026