ARCANADA
Все записи
Блог 30 мая 2026

Как агрессивное сжатие токенов вешало macOS: хроника кросс-рантаймовой экономии

Как агрессивное сжатие токенов вешало macOS: хроника кросс-рантаймовой экономии

Однажды утром Mac перестал отвечать. Не тормозил — завис намертво: курсор не двигался, SSH недоступен, хард-ресет неизбежен. Причиной оказалась не утечка памяти и не перегрев. Ранняя версия RTK-плагина включала подмену команд для всех окружений сразу — и на macOS при определённых условиях запуска это вызывало бесконечный каскад: обёртки запускали сами себя в каждом новом окне терминала. Потеряно 15 минут, история команд пропала.

Это хроника того, как Datarim и Coworker дошли до нынешнего состояния: 883 563 обработанных команды, 68,1% взвешенной экономии токенов, три рантайма с полным паритетом. Через реальные сбои, три переработки механизма перехвата и один баг, который чуть не превратил git push в бесконечный цикл.

Откуда берутся токены в агентных сессиях

Токен — это примерно три-четыре символа текста. Звучит незначительно, но в агентных сессиях токены расходуются не на ответы модели, а на чтение. Соотношение входных и выходных токенов — около 25:1: на каждый токен, который модель тратит на ответ, приходится 25 входящих. Перед правкой файла агент читает его целиком. Перед коммитом — читает git diff. При отладке — читает логи. Чтобы запустить тест — читает предыдущий вывод.

Три источника расходов поддаются независимой оптимизации. Первый: чтение файлов — агент читает полное содержимое каждого релевантного файла, даже если нужен один фрагмент. Второй: генерация структурных черновиков — спецификации, тесты, документация следуют предсказуемым паттернам, но всё равно генерируются дорогой моделью. Третий: вывод команд терминала — git log, find, pytest, docker logs возвращают объёмные данные, 80% которых модели не нужны.

Datarim: три рантайма без иерархии

Datarim — итеративный workflow-фреймворк для AI-разработки. 18 агентов, 55 скилов, 24 команды. Полный пайплайн: init → prd → plan → design → do → qa → compliance → archive. Complexity-aware: лёгкие задачи идут по короткому L1-пути (три шага), архитектурные фичи — через полный L4. Рефлексия встроена в команду archive — каждый цикл генерирует предложения по улучшению фреймворка.

Архитектурный принцип, который определил структуру решения: Datarim работает на трёх равноправных рантаймах — Claude Code, Codex CLI и Cursor. Не «основной плюс два вторичных». Три равноправные среды исполнения, одни и те же команды, одинаковые результаты.

У каждого рантайма есть реальные сильные стороны. Claude Code — интерактивные сессии и тонкая работа с контекстом. Codex CLI — автоматизация и скрипты. Cursor — интеграция в IDE и ускорение цикла работы в редакторе. Обеспечить одинаковое поведение на всех трёх — это не удобство, это архитектурное требование предсказуемости.

Coworker: три независимых механизма для трёх источников расходов

Принцип Coworker: дорогая модель рассуждает, дешёвая обрабатывает bulk I/O. Это vendor-neutral CLI с пятью провайдерами (Moonshot, DeepSeek, Groq, OpenRouter, OpenAI — все через OpenAI-совместимый API), переключение флагом --provider.

Три инструмента независимы и закрывают три разных источника расходов:

coworker ask делегирует чтение файлов дешёвой модели. Правило срабатывает при объёме более 15 000 est-токенов или при трёх и более файлах за вопрос. Агент не читает файл самостоятельно — он задаёт дешёвой модели конкретный вопрос. Дорогая модель получает ответ, а не сырой файл.

coworker write генерирует структурный черновик по спецификации. Дешёвая модель строит скелет, дорогая делает только финальную правку с суждением. Шаблонные части — структура PRD, скелет плана, стандартные секции документации — не требуют Sonnet 4.6 для генерации.

RTK-плагин (Rust Token Killer, opt-in) работает принципиально иначе: сжимает вывод команд локально на машине, до отправки в контекст модели. API-вызов не происходит — Rust-бинарник фильтрует вывод без обращения к внешним сервисам. Три инструмента независимы: можно включить любой один или все три.

Актуальные цены (проверено 30 мая 2026): Sonnet 4.6 output — $15/M токенов. DeepSeek V4 Flash output — $0,28/M. Это 53,6× дешевле. Именно Flash — якорь экономии для coworker ask и coworker write. DeepSeek V4 Pro — опция для задач, где нужно выше качество генерации.

Почему «сжимать всё» — это ловушка

Когда видишь 90% экономии на pytest и git log --stat, первый импульс — включить сжатие для всех команд. Именно эта логика привела к багу с git push.

На коротких командах RTK работает в обратную сторону. git status на чистом репо: сырой вывод — 59 байт. После обработки RTK — 123 байта, то есть +108%. Сжатие добавило метаданные и структуру, которые весят больше самого сообщения. git log --oneline -50: 59 байт → 4144 байта, +6924%. RTK пытается «красиво оформить» уже компактный формат — и разворачивает его в многострочный отчёт.

Но проблема не только в размере. Проблема в надёжности.

Когда RTK сжимал вывод git push, он убирал строку подтверждения:

To github.com:Arcanada-one/coworker.git
   bd39466..3314623  main -> main

Для человека это просто информация. Для агента — критический сигнал: пуш прошёл. Если RTK классифицировал эту строку как «шум», агент не получал подтверждения. Агент считал пуш неуспешным. Агент повторял попытку. Цикл занимал около 15 минут до ручного вмешательства.

Второй пример: git status возвращает «nothing to commit, working tree clean». Это сигнал — рабочее дерево чистое, можно двигаться дальше. Если сжатие убирало или переформатировало это сообщение, агент не мог определить состояние репозитория. Во всех репозиториях одновременно всё казалось «clean», и агент вставал.

Граница принципиальная: bulk-шум — объёмные листинги, повторяющиеся строки, стектрейсы длиннее трёх фреймов, прогресс-бары, ANSI-коды. Шум можно сжимать. Сигнал — короткий, но критически значимый: пуш подтверждён, коммит создан, тест упал вот здесь. Сигнал трогать нельзя.

Passthrough-список: 13 команд без сжатия

Решение — passthrough-список (allowlist): набор команд, чей вывод доходит до модели сырым, без обработки. Как отдельный проход в аэропорту для пассажиров с известным профилем — быстро и без досмотра, потому что риск уже оценён.

В список по умолчанию вошли 13 git/gh команд: git push, git commit, git status, git checkout, git merge, git rebase, git pull, git fetch, git branch, git stash, gh pr create, gh pr merge, gh release create. Именно те команды, чей вывод несёт подтверждения операций. RTK сжимает только объёмный шум: pytest, find, docker logs, ruff check.

После добавления passthrough агент стал получать корректные сигналы от git-операций. Цикл с 15-минутным висяком исчез.

Три рантайма — три точки перехвата

Одна цель — разные точки входа в каждой среде. Пользователю это незаметно: экономия включается одной командой и работает одинаково. Под капотом — своя реализация для каждого рантайма.

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

Claude Code — это здание с постом на входе. У него есть встроенный механизм подписки на любое действие до его выполнения. Coworker регистрируется один раз в ~/.claude/settings.json, и после этого автоматически работает во всех сессиях без дополнительных настроек.

Codex CLI такого поста не имеет. Вместо этого используется другой подход: в переменную окружения PATH добавляется папка с обёртками-двойниками, которые стоят перед настоящими командами. Когда агент запускает команду, система находит обёртку раньше оригинала — та принимает решение о сжатии и передаёт управление дальше. Обёртки активны только пока работает сессия; после выхода PATH возвращается в исходное состояние.

Cursor поначалу числился «не поддерживается»: казалось, у редактора нет подходящей точки входа. После более глубокого изучения документации нашёлся встроенный перехватчик команд. После его реализации паритет стал полным: три рантайма, три механизма, один результат.

Технические названия механизмов — в справочной таблице:

Рантайм Механизм перехвата Точка регистрации
Claude Code PreToolUse hook ~/.claude/settings.json
Cursor beforeShellExecution IDE native hook
Codex CLI PATH-shim Активен только внутри сессии

Хроника разработки: от зависания macOS до 3/3

Первый баг: заморозка macOS. Ранняя версия включала подмену команд безусловно для всех окружений. На Linux работало нормально. На macOS при определённых условиях запуска система зависала намертво: обёртки запускали сами себя в каждой интерактивной оболочке и уходили в бесконечный круг. Требовался хард-ресет. Первое исправление: обёртка активируется только внутри сессии нужного инструмента. Заморозка исчезла.

Второй баг: «лживый статус» git. После подключения RTK агент перестал получать подтверждения push и commit — RTK классифицировал их как шум. Добавлен passthrough-список из 13 команд. Сигналы git-операций вернулись к корректной обработке.

Третий этап: Cursor. Первая итерация для Cursor проходила тесты, но не живые сессии — редактор пересобирал PATH после старта и обёртка оказывалась вне активного пути. Cursor был списан как «частичная поддержка». Потом нашёлся встроенный перехватчик — и паритет стал полным. Три рантайма, три механизма, один результат.

Четвёртый: диагностика. Статус-команда ложно показывала Claude Code как «отключён» при legacy-установке. Исправлена логика probe-запроса — ложноотрицательных результатов не стало.

Этот путь прошёл не в тестовой среде, а на живой машине с шестью параллельными агентными сессиями каждый день. Догфудинг на production-нагрузке.

Реальные замеры на 2026-05-30

Накопленная статистика на момент публикации:

Метрика Значение
Всего команд обработано 883 563
Input токены 9,3M
Output токены 3,0M
Сэкономлено 6,3M токенов — 68,1% (взвешенная по частоте)
Среднее время обработки 35 мс/команда

Отдельные команды дают экстремальные цифры: ps aux — 99,0%, Playwright test — 97,2%, rtk grep — 27,9%. Но 99% на ps aux — это замер одной объёмной команды, не репрезентативный для всего стека. Честная цифра — взвешенные 68,1%: она учитывает реальную частоту всех команд, включая нулевую экономию на коротких сигнальных.

Стоимость делегирования через coworker ask и coworker write за тот же период:

Провайдер Вызовов Input токены Output токены Стоимость
DeepSeek 1 701 21,7M 3,9M $4,16
Moonshot 426 4,7M 2,9M $15,99

DeepSeek V4 Flash output: $0,28/M — это 53,6× дешевле Sonnet 4.6 ($15/M). Именно на этой разнице строится экономика coworker ask: агент отдаёт на чтение десятки миллионов токенов через дешёвый провайдер за единицы долларов, а Sonnet получает только структурированный ответ.

Текущее состояние

Три независимых инструмента, одна установка, три рантайма. RTK работает локально без API-вызовов — 35 мс/команда при 883K+ обработанных. coworker ask и write делегируют bulk через дешёвый провайдер. Passthrough-список защищает сигнальные команды от сжатия. Все три рантайма получают одинаковое поведение через механизмы, соответствующие их архитектуре.

Жизнь одного человека имеет значение.