03 / 06 · Продвинутый

💰 Управление стоимостью Claude Code

Как работает тарификация, что тихо съедает токены, как считать бюджет задачи и реально сократить расходы на 50–90% через правильную конфигурацию.

💡

Ключевой принцип экономии

Большинство расходов — не от размера задачи, а от невидимых overhead-токенов: системного промпта, истории разговора и лишних файлов в контексте. Контролируя их, можно снизить счёт в 3–5 раз без потери качества.

📊 Как работает тарификация CC

Claude Code работает через API Anthropic и платит за каждый токен — ~0.75 слова. Два типа токенов, и они стоят принципиально по-разному:

Input Tokens
$3
за 1М токенов. Всё что идёт в модель: системный промпт, ваши сообщения, файлы, история разговора.
Output Tokens
$15
за 1М токенов (Sonnet 5). Всё что модель генерирует: код, объяснения, вызовы инструментов. В 5× дороже input!
Важно: Output дороже Input в 3–5×. Это значит: CC написал 200 строк кода вместо 50 нужных = вы заплатили в 4 раза больше. Точные промпты экономят деньги напрямую.

Цены на все модели (на 2026)

Модель Input Output Cache Read Cache Write Контекст
Claude Haiku 4.5 $1.00 $5.00 $0.10 $1.25 200K
Claude Sonnet 5 основной $3.00 $15.00 $0.30 $3.75 1M
Claude Opus 4.8 $5.00 $25.00 $0.50 $6.25 1M
Claude Fable 5 топовая $10.00 $50.00 $1.00 $12.50 1M

Цены указаны за 1 000 000 токенов (MTok). Cache Read — чтение из кэша Prompt Caching — в 10× дешевле обычного Input. У Sonnet 5 действует вводная цена $2 / $10 до 31.08.2026.

🕳️ Что съедает токены незаметно

Вы пишете короткое сообщение «добавь метод», а CC обрабатывает тысячи токенов overhead. Вот откуда они берутся:

Системный промпт CC — ~2000 токенов на каждый запрос

У CC есть встроенный системный промпт с инструкциями по использованию инструментов, безопасности и поведению. Он отправляется с каждым запросом — это неустранимый фиксированный overhead ~$0.006 за 1000 запросов.

CLAUDE.md загружается при каждом запросе

Ваш CLAUDE.md — часть системного промпта. Файл на 3000 слов (~4000 токенов) × 100 запросов в день = 400 000 дополнительных input-токенов в сутки = $1.20/день. Держите CLAUDE.md кратким или используйте Prompt Caching.

История разговора накапливается

Через 30 минут работы в одной сессии история может занимать 50–100K токенов. Каждый следующий запрос платит за всю эту историю заново. Команда /compact сжимает историю до ~2K токенов саммари.

Большие файлы в контексте

Когда CC читает файл — весь его текст становится частью input. Файл package-lock.json на 15 000 строк = ~20 000 токенов = $0.06 за одно чтение. .claudeignore предотвращает автоматическое включение таких файлов.

Неудачные попытки удваивают стоимость

Расплывчатый промпт → CC делает не то → вы говорите «нет, переделай» → CC читает весь предыдущий контекст + генерирует заново. Одно переделывание = 2× стоимость. Два переделывания = 3× стоимость.

Вызовы инструментов тоже стоят токенов

Каждый вызов MCP-инструмента или Bash — это сначала output (параметры вызова), потом input (результат). Глубокое рекурсивное сканирование директорий через MCP может стоить $0.10–0.30 само по себе.

🧮 Как считать стоимость задачи

Стоимость = (input_tokens × $3 + output_tokens × $15) ÷ 1 000 000
Для Claude Sonnet 5. Для Haiku 4.5: $1.00 / $5.00. Для Opus 4.8: $5 / $25.

Типичное соотношение input:output = 4:1 (много читает, меньше генерирует). При 10 000 input и 2 500 output токенов:

(10000 × $3 + 2500 × $15) ÷ 1 000 000 = $0.03 + $0.0375 = ~$0.07

Справочная таблица стоимостей задач

Задача Input Output Стоимость Модель
Написать функцию (30 строк) ~3K ~500 ~$0.01 Sonnet
Объяснить ошибку / дебаг ~5K ~800 ~$0.03 Sonnet
Ревью PR (10 файлов) ~15K ~2K ~$0.08 Sonnet
Рефакторинг модуля ~20K ~5K ~$0.14 Sonnet
Написать новый API-контроллер (Laravel) ~12K ~3K ~$0.08 Sonnet
Архитектурный анализ проекта ~50K ~5K ~$0.23 Opus
Полный рефакторинг большого модуля ~40K ~15K ~$0.35 Sonnet
Написать тесты для сервиса ~10K ~4K ~$0.09 Sonnet

💡 Топ-10 способов сократить расходы

1. /compact — когда и как часто использовать

Команда /compact сжимает историю разговора до краткого саммари (~2000 токенов), выбрасывая детали предыдущих обменов. Это самое мощное средство экономии при долгих сессиях.

СитуацияДействие
История > 20 сообщенийОбязательно /compact
Задача завершена, начинаете новую/compact или новая сессия
Вошли в контекстный лимит/compactCC предложит сам
Работа с большим файлом несколько раз/compact после каждого крупного изменения
Совет: /compact перед сном — экономия на следующем дне. Если не компактировали, завтра первый же запрос платит за всю вчерашнюю историю.

2. .claudeignore — исключите ненужное из контекста

Файл .claudeignore в корне проекта работает как .gitignore — предотвращает случайное чтение CC этих файлов и директорий.

# Зависимости (огромные, меняются редко)
node_modules/
vendor/
.pnp/

# Сборка и кэш
dist/
build/
.next/
.nuxt/
.output/
public/hot/

# Логи и временные файлы
storage/logs/
storage/framework/cache/
storage/framework/sessions/
bootstrap/cache/
*.log

# Версионный контроль
.git/

# Сгенерированные файлы
package-lock.json
composer.lock
yarn.lock
pnpm-lock.yaml

# Большие медиафайлы
*.mp4 *.mov *.avi *.mkv
*.psd *.ai *.sketch
public/storage/

# Python специфика
__pycache__/
*.pyc
.venv/
venv/
.pytest_cache/
htmlcov/

# IDE файлы
.idea/
.vscode/
*.swp
Эффект: node_modules типичного проекта содержит 50–200 МБ текста. Без .claudeignore CC может случайно прочитать их при поиске — стоимость одной такой «утечки» может достигать $0.50.
⚠️
Частая ошибка новичков: использовать Opus для всего подряд, считая что «лучшая модель = всегда лучше». Opus 4.8 стоит в ~1.7× дороже Sonnet и в 5× дороже Haiku. Для написания бойлерплейта, добавления комментариев или простой правки — Haiku даёт сопоставимое качество за 1/5 цены. Opus и топовый Fable 5 действительно нужны только для сложного архитектурного анализа и критических решений.

3. Выбирать модель по задаче

🐦
Haiku 4.5
$1.00 / $5.00
Простые правки, форматирование, объяснение ошибок, генерация бойлерплейта. В 3× дешевле Sonnet.
🎵
Sonnet 5
$3.00 / $15.00
Основная разработка, рефакторинг, написание тестов, ревью кода. Золотой стандарт для 90% задач.
🎭
Opus 4.8
$5.00 / $25.00
Архитектурные решения, сложные алгоритмы, критический анализ безопасности. Когда нужна максимальная глубина.
# Переключить на Haiku для простой задачи
claude --model claude-haiku-4-5

# Или внутри сессии
/model claude-haiku-4-5

# Вернуться на Sonnet
/model claude-sonnet-5

4. Точные промпты вместо расплывчатых

❌ Расплывчато (дорого)✅ Точно (дёшево)
«Посмотри на проект и предложи улучшения» «В файле app/Services/PaymentService.php метод charge() не обрабатывает исключение StripeException — добавь try/catch с логированием»
«Рефактори этот код» «Извлеки приватный метод validateAmount() из строк 45-67, используй guard clauses»
«Напиши тесты» «Напиши Pest тесты для UserService::create() — три кейса: успех, дублирующийся email, невалидные данные»

5. Не давать CC читать весь проект — указывать конкретные файлы

# ❌ Плохо — CC может сканировать всё
"посмотри на структуру проекта и исправь баг"

# ✅ Хорошо — читает только нужное
"в файле app/Http/Controllers/OrderController.php
метод store() (строки 34-89) не сохраняет related items.
Вот модель: app/Models/Order.php.
Вот миграция: database/migrations/2025_01_create_orders.php"

6. Переиспользовать контекст (не начинать новую сессию для связанных задач)

Если вы работаете с одним модулем несколько часов — дешевле оставаться в одной сессии и периодически вызывать /compact, чем начинать новую сессию каждый раз. В новой сессии CC снова читает CLAUDE.md, заново изучает структуру файлов — это лишние токены.

7. Сократить CLAUDE.md до минимума

Каждый символ в CLAUDE.md — это постоянный tax на каждый запрос. Оптимальная структура:

# Проект: MyApp (Laravel 11 + Vue 3 + PostgreSQL)

## Стек
- Backend: PHP 8.3, Laravel 11, Pest для тестов
- Frontend: Vue 3, TypeScript, Vite, Pinia
- DB: PostgreSQL 16, Redis для кэша
- Deploy: Docker + docker-compose

## Правила кода
- PSR-12, строгая типизация (declare(strict_types=1))
- Всегда писать Feature тесты для новых endpoint
- Модели: только $fillable, не $guarded
- Service layer обязателен для бизнес-логики

## НЕ ДЕЛАТЬ
- Не изменять migration файлы — только новые
- Не трогать .env.prod
- Не делать npm install без явной просьбы

8. Использовать headless-режим для batch-задач

Для автоматизированных задач (обработка множества файлов, регулярные отчёты) используйте --print режим — он отправляет один запрос без интерактивной сессии и возвращает результат, избегая overhead управления сессией.

# Анализ каждого сервис-класса без интерактивной сессии
Get-ChildItem app/Services -Filter "*.php" | ForEach-Object {
    $result = claude --print "Проверь PSR-12 в файле $($_.FullName)" 2>&1
    Write-Output "$($_.Name): $result"
}

9. Кэшировать результаты повторяющихся задач

Если вы регулярно запускаете CC с одним и тем же большим контекстом (например, анализ логов каждый час), используйте Prompt Caching через API — экономия до 90% на input токенах.

10. Мониторить расходы и ставить алерты

В Anthropic Console настройте лимиты и уведомления. Неожиданный скачок расходов — сигнал о бесконтрольном сканировании файлов или бесконечном цикле.

⚡ Prompt Caching — экономия 90% на повторяющихся запросах

Prompt Caching — механизм, при котором Anthropic сохраняет обработанный токен-контекст в кэше на 5 минут. Повторное использование закэшированных токенов стоит в 10× дешевле обычного чтения.

Как работает кэш

Запрос №1 — обычная цена

Весь контекст (системный промпт + CLAUDE.md + файлы) обрабатывается по стандартной цене $3/MTok. Anthropic сохраняет результат обработки в кэше.

Запросы №2–N в течение 5 минут — цена $0.30/MTok

Если начало контекста совпадает с закэшированным — Claude использует кэш. Стоимость чтения кэша: $0.30 вместо $3.00. Экономия 90%.

Через 5 минут — кэш истекает

TTL кэша = 5 минут. После истечения — снова полная цена. Для долгих операций это нужно учитывать.

Cache Write — небольшой overhead

Первая запись в кэш стоит $3.75/MTok (немного дороже обычного input). Это компенсируется уже на 2-м запросе.

Когда кэш работает автоматически в CC

Что кэшируетсяУсловиеЭкономия
Системный промпт CCВсегда, при частых запросахАвто
Ваш CLAUDE.mdБыстрые последовательные запросыВысокая
Большие прочитанные файлыЕсли файл не менялся между запросамиВысокая
История разговораНачало истории совпадаетСредняя

Как использовать Prompt Caching через API

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;

class AnalyzeLogsWithCaching extends Command
{
    protected $signature = 'logs:analyze {--since=1h}';
    protected $description = 'Анализ логов с Prompt Caching (экономия ~90% на системном промпте)';

    // Большой системный промпт — будет закэширован
    private string $systemPrompt = <<<'PROMPT'
Ты — эксперт по анализу логов Laravel-приложений.

## Правила анализа:
1. Группируй однотипные ошибки (не перечисляй каждую)
2. Приоритизируй: Critical > Error > Warning > Notice
3. Для каждой группы укажи:
   - Количество вхождений
   - Первое и последнее время
   - Вероятную причину
   - Рекомендованное действие

## Формат ответа: JSON
{
  "summary": "краткое резюме",
  "critical": [...],
  "errors": [...],
  "warnings": [...],
  "recommendations": [...]
}
PROMPT;

    public function handle(): int
    {
        $since = $this->option('since');
        $logPath = storage_path('logs/laravel.log');

        if (!file_exists($logPath)) {
            $this->error('Файл логов не найден');
            return 1;
        }

        // Читаем только свежие логи
        $logs = $this->getRecentLogs($logPath, $since);

        if (empty($logs)) {
            $this->info('Новых логов нет');
            return 0;
        }

        $this->info("Анализируем " . count($logs) . " записей логов...");

        // Запрос с cache_control для системного промпта
        $response = Http::withHeaders([
            'x-api-key' => config('services.anthropic.key'),
            'anthropic-version' => '2023-06-01',
            'anthropic-beta' => 'prompt-caching-2024-07-31',
        ])->post('https://api.anthropic.com/v1/messages', [
            'model' => 'claude-haiku-4-5', // Haiku — дешевле для batch
            'max_tokens' => 2048,
            'system' => [
                [
                    'type' => 'text',
                    'text' => $this->systemPrompt,
                    // Маркируем для кэширования — сохраняется на 5 минут
                    'cache_control' => ['type' => 'ephemeral'],
                ],
            ],
            'messages' => [
                [
                    'role' => 'user',
                    'content' => "Проанализируй следующие логи (за последние {$since}):\n\n"
                        . implode("\n", array_slice($logs, -500)), // Последние 500 строк
                ],
            ],
        ]);

        if ($response->failed()) {
            $this->error('API ошибка: ' . $response->body());
            return 1;
        }

        $data = $response->json();
        $usage = $data['usage'];

        // Выводим статистику токенов
        $this->table(
            ['Метрика', 'Токены', 'Стоимость'],
            [
                ['Input (обычный)', $usage['input_tokens'], '$' . number_format($usage['input_tokens'] * 0.0000008, 5)],
                ['Cache Read', $usage['cache_read_input_tokens'] ?? 0, '$' . number_format(($usage['cache_read_input_tokens'] ?? 0) * 0.00000008, 5)],
                ['Cache Write', $usage['cache_creation_input_tokens'] ?? 0, '$' . number_format(($usage['cache_creation_input_tokens'] ?? 0) * 0.000001, 5)],
                ['Output', $usage['output_tokens'], '$' . number_format($usage['output_tokens'] * 0.000004, 5)],
            ]
        );

        // Парсим и сохраняем результат
        $result = json_decode($data['content'][0]['text'], true);
        $this->displayAnalysis($result);

        return 0;
    }

    private function getRecentLogs(string $path, string $since): array
    {
        $content = file_get_contents($path);
        $lines = explode("\n", $content);

        // Фильтруем по времени
        $cutoff = now()->sub(\DateInterval::createFromDateString($since));

        return array_filter($lines, function (string $line) use ($cutoff) {
            if (preg_match('/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]/', $line, $m)) {
                return \Carbon\Carbon::parse($m[1])->isAfter($cutoff);
            }
            return false;
        });
    }

    private function displayAnalysis(array $result): void
    {
        $this->newLine();
        $this->line("📊 {$result['summary']}");

        foreach ($result['critical'] ?? [] as $issue) {
            $this->error("🚨 КРИТИЧНО [{$issue['count']}x]: {$issue['cause']}");
            $this->line("   → {$issue['action']}");
        }

        foreach ($result['errors'] ?? [] as $issue) {
            $this->warn("⚠️ ОШИБКА [{$issue['count']}x]: {$issue['cause']}");
        }

        if (!empty($result['recommendations'])) {
            $this->newLine();
            $this->info('💡 Рекомендации:');
            foreach ($result['recommendations'] as $rec) {
                $this->line("  • {$rec}");
            }
        }
    }
}

Реальная экономия на примере

📈 Расчёт экономии: CLAUDE.md = 5000 токенов, 100 запросов/день

Без кэширования: 5000 × 100 × $3/MTok $1.50/день
С кэшированием: 5000 × $3.75 (write) + 5000 × 99 × $0.30 (read) $0.17/день
Экономия $1.33/день = ~$40/месяц

👥 Командный бюджет и контроль расходов

Рекомендуемые модели по типу задачи

Тип задачи Модель Стоимость/задача Лимит в день
Быстрые правки, форматирование Haiku 4.5 $0.002–0.01 Без лимита
Написание кода, тесты Sonnet 5 $0.05–0.20 ~50 задач ($5)
Ревью PR, рефакторинг Sonnet 5 $0.10–0.40 ~20 ревью ($4)
Архитектура, сложный анализ Opus 4.8 $0.50–2.00 ~5 сессий ($5)
Batch-обработка (ETL, отчёты) Haiku 4.5 + Caching $0.001–0.005 Без лимита

Когда CC НЕ выгоден

ЗадачаВывод
Переименовать переменную в одном файле ❌ Быстрее вручную. 30 сек vs $0.02 и 15 сек ожидания
Добавить комментарий к методу ❌ Вручную. CC потратит больше токенов на объяснение, чем сам комментарий
Поиск файла по имени find или IDE-поиск быстрее и бесплатно
Запуск php artisan migrate ❌ Делайте сами. CC ещё и спросит подтверждение — двойные токены
Задача с точным ответом (формула, алгоритм) CC выгоден — точный ответ с первого раза
Написание бойлерплейта (CRUD, миграции) ✅ Haiku справится дёшево и быстро

📈 Мониторинг расходов

Anthropic Console — основной инструмент

Перейдите на console.anthropic.com → раздел Usage. Там доступны:

Настройка алертов на бюджет

В разделе Settings → Billing → Budget alerts установите пороги:

ПорогДействие
50% от месячного лимитаEmail-уведомление
80% от месячного лимитаEmail + рассмотреть оптимизацию
100% от лимитаHard limit — API прекращает работу

Экспорт данных использования через API

<?php

// Получение данных использования за период
$response = Http::withHeaders([
    'x-api-key' => config('services.anthropic.key'),
    'anthropic-version' => '2023-06-01',
])->get('https://api.anthropic.com/v1/usage', [
    'start_date' => now()->startOfMonth()->format('Y-m-d'),
    'end_date' => now()->format('Y-m-d'),
    'granularity' => 'day',
]);

$usage = $response->json();

foreach ($usage['data'] as $day) {
    $inputCost  = $day['input_tokens'] * 3 / 1_000_000;
    $outputCost = $day['output_tokens'] * 15 / 1_000_000;
    $cacheCost  = ($day['cache_read_tokens'] ?? 0) * 0.30 / 1_000_000;

    echo sprintf(
        "%s | Input: $%.4f | Output: $%.4f | Cache: $%.4f | Total: $%.4f\n",
        $day['date'],
        $inputCost,
        $outputCost,
        $cacheCost,
        $inputCost + $outputCost + $cacheCost
    );
}

Hook для локального трекинга стоимости сессии

// Записывает стоимость каждой CC-сессии в лог
const fs = require('fs');
const path = require('path');

const input = JSON.parse(process.stdin.read() || '{}');

// CC передаёт usage в Stop-хуке
const usage = input?.usage ?? input?.stop_usage ?? {};
const inputTokens  = usage.input_tokens ?? 0;
const outputTokens = usage.output_tokens ?? 0;
const cacheRead    = usage.cache_read_input_tokens ?? 0;
const cacheWrite   = usage.cache_creation_input_tokens ?? 0;

// Sonnet цены
const PRICES = {
  input:       3.00 / 1_000_000,
  output:     15.00 / 1_000_000,
  cacheRead:   0.30 / 1_000_000,
  cacheWrite:  3.75 / 1_000_000,
};

const totalCost =
  inputTokens  * PRICES.input +
  outputTokens * PRICES.output +
  cacheRead    * PRICES.cacheRead +
  cacheWrite   * PRICES.cacheWrite;

const logEntry = {
  timestamp: new Date().toISOString(),
  tokens: { inputTokens, outputTokens, cacheRead, cacheWrite },
  cost: totalCost.toFixed(6),
  costFormatted: `$${totalCost.toFixed(4)}`,
};

// Добавляем в файл лога
const logPath = path.join(process.env.USERPROFILE || process.env.HOME, '.claude', 'cost-log.jsonl');
fs.appendFileSync(logPath, JSON.stringify(logEntry) + '\n');

// Выводим в stderr (видно в CC)
process.stderr.write(`\n💰 Сессия завершена: ${logEntry.costFormatted} (${inputTokens + outputTokens} токенов)\n`);

process.exit(0);
Регистрация хука в settings.json: Добавьте в секцию "hooks""Stop"[{"hooks": [{"type": "command", "command": "node ~/.claude/hooks/cost-tracker.cjs"}]}]

Итоговая таблица: приоритеты экономии

ДействиеСложностьЭкономияДелать сейчас
Создать .claudeignore Низкая Высокая (защита от случайного чтения) ✅ Да
Сократить CLAUDE.md до <2000 токенов Низкая Средняя ✅ Да
Использовать /compact регулярно Нулевая Высокая при долгих сессиях ✅ Да
Выбирать Haiku для простых задач Низкая Высокая (4× дешевле) ✅ Да
Prompt Caching через API Средняя Очень высокая (90%) для batch 🔶 При batch-задачах
Настроить алерты в Console Нулевая Превентивная ✅ Да