Status bar Hermes agent и как не сжигать токены на долгих сессиях

Что на самом деле значит каждый символ в статус-баре Hermes TUI (с поправками по исходникам — да, один из них точно не ETA), как заметить, что агент вот-вот съест месячный лимит nanogpt, и какие настройки реально что-то меняют.

Терминал: статус-бар Hermes agent с контекстом и расходом токенов

Я недавно писал про управление mpv из Telegram через Hermes agent на подписке nanogpt за $12/мес. TL;DR того поста: это круто, работает через hermes-medium от nanogpt, стоит примерно как бутерброд в месяц.

Что в том посте не сказано: при интенсивном использовании эта месячная подписка расходуется заметно быстрее, чем ожидаешь. Не катастрофически быстро, но достаточно ощутимо, если использовать Hermes не только как пульт от ТВ — для кодинга, многошаговых workflow, долгих чатов по отладке. Решение — частично не плодить длинные сессии без нужды, частично научиться читать status bar, чтобы вмешаться до того, как станет совсем плохо.

Поэтому этот пост о двух вещах:

  1. Корректное, проверенное по исходникам чтение status bar Hermes TUI.
  2. Настройки оптимизации, которые реально существуют в конфиге Hermes — не общие советы по LLM-ам, а конкретные параметры, которые лежат в ~/.hermes/config.yaml.

Что на самом деле говорит status bar

В Hermes TUI снизу есть однострочный футер вида:

⚕ hermes-medium │ 50.4K/256K │ [██░░░░░░░░] 20% │ 🗜️ 1 │ 6h 35m │ ⏲ 2m 4s

Я спрашивал у одной LLM, что значит каждое поле — получил уверенный, в основном правильный ответ с одним откровенно ошибочным утверждением. Вот корректная версия, сверенная с ~/.hermes/hermes-agent/cli.py:3384 (_get_status_bar_snapshot) и cli.py:3760-3789 (сборка фрагментов статуса):

СимволЗначениеПоле в коде
⚕ hermes-mediumТекущая модель. Обновляется на fallback — если Hermes переключился на другого провайдера прямо посреди сессии, тут будет показана новая модель, не та, что прописана в конфиге.agent.model (живое), с fallback на self.model
50.4K/256KТекущие токены в контексте / окно контекста модели.context_tokens / context_length
[██░░░░░░░░] 20%Тот же показатель визуально + цифрой. Цвет меняется — зелёный / жёлтый / красный по мере заполнения.context_percent
🗜️ 1Сколько раз в этой сессии уже выполнялась компрессия контекста. Не «уровень компрессии», не «количество слоёв» — просто счётчик: сколько раз Hermes уже упёрся в порог и саммаризировал старые сообщения. Показывается, только если ≥ 1.compressions
▶ NАктивные фоновые задачи (показывается, только если ≥ 1).active_background_tasks
6h 35mОбщее время сессии с момента старта TUI. Вот это поле хочу особо подсветить: это не ETA, не остаток лимита, не предсказание времени окончания. Это просто часы реального времени с того момента, как вы открыли эту сессию.от session_start до datetime.now()
⏲ 2m 4sПрошедшее время текущего промпта. Тикает в реальном времени, пока модель работает; замерзает, когда ответ пришёл.prompt_elapsed

Шестая строка — это то, на чём ошибается обобщённая объяснялка. Велик соблазн прочитать 6h 35m как «осталось 6.5 часов» — нет. Это «этот REPL открыт уже 6.5 часов». Если все эти 6.5 часов вы активно чатились, то вы за них и заплатили. Status bar отчитывается о фактах вашей сессии, он не прогнозирует будущее.

Зачем это всё на самом деле волнует: расход подписки

Первое, в чём стоит быть честным: подписка nanogpt за $12/мес — это не месячная квота. Это недельная квота, которая сбрасывается каждые 7 дней. Панель «Subscription Usage» в дашборде nanogpt говорит это прямо:

Weekly input tokens
Usage: 26 197 480 / 60 000 000
44% used
Time Until Reset: 6d 2h left (13% of period elapsed)

То есть 60 миллионов входных токенов в неделю. Звучит огромно. До тех пор, пока не посмотришь на скорость расхода: в этом снимке экрана 44% недельного лимита уже ушло, при том что от недели прошло только 13%. Это примерно в 3.4 раза выше темпа, который привёл бы к ровно 100% на день сброса. С такой скоростью квота заканчивается на 2–3 день цикла, и остальные 4–5 дней вы платите, но сидите в задушенном тарифе.

Модель «$12 — это безлимит» — неправильная. Правильная модель такая:

  • 8.57М токенов в день — это break-even линия. Останетесь под ней — хватит на всю неделю.
  • 60М токенов — жёсткий потолок, пополняется раз в 7 дней. Никакого переноса остатков.
  • Когда вы пробиваете недельный потолок, вам не выставляют доп. счёт — вас просто понижают в приоритете. Модель становится медленнее, потом, в конце концов, nanogpt вежливо отказывает. Вы ждёте окна сброса.

nanogpt щедрый для casual-использования. Но он не щедрый для агента, который:

  • Держит в контексте разговор на 50К токенов и пересылает большую его часть на каждом шаге
  • Спавнит фоновые задачи, которые сами по себе обращаются к модели
  • Перечитывает один и тот же файл три раза за сессию, потому что забыл, что уже его видел
  • Подгружает на каждом ходу системный промпт с несколькими скиллами

Если вы используете Hermes только как Telegram-пульт (/mpv_play lain, /mpv_pause — это zero-token quick-команды), вы недельного лимита вообще не заметите. Quick-команды полностью обходят модель, и в счётчик на 60М не добавляют ноль.

Но как только начинается реальная агентская работа — кодинг, рефакторинг по нескольким файлам, «иди разберись, почему gateway рестартится» — экономика меняется быстро. 6-часовая сессия с 🗜️ 4 компрессиями и 50K/256K контекстом означает, что вы отправляете десятки тысяч токенов на каждом шаге, десятки раз подряд. Один интенсивный вечер может съесть 10–15М токенов — четверть недели — и ничего внешне неправильного при этом происходить не будет.

Заметите вы это как замедление модели (вы попали в throttled-тариф) или, в конце концов, как вежливую ошибку от nanogpt. Но задолго до этого status bar уже всё рассказывал — а дашборд nanogpt показывает burn-rate и часы до сброса, если поглядывать.

Реальные настройки компрессии

Hermes уже умеет сжимать контекст — это не отдельная фича, которую надо прикручивать. Она в ~/.hermes/config.yaml:

compression:
enabled: true
threshold: 0.6
target_ratio: 0.25
protect_last_n: 20
protect_first_n: 3
hygiene_hard_message_limit: 400
abort_on_summary_failure: false
prompt_caching:
cache_ttl: 5m

Каждая строка — крутилка, которую полезно понимать:

  • threshold: 0.6 — начинать сжатие, когда контекст заполнен на 60% окна. При окне 256К это ~154К токенов. Понизьте (например, до 0.4), если хотите, чтобы Hermes саммаризировал раньше и отправлял меньше токенов в каждом вызове.
  • target_ratio: 0.25 — при компрессии целиться в 25% окна после прохода. Жёстче компрессия = меньше последующие промпты = меньше токенов в чеке.
  • protect_last_n: 20 — не сжимать последние 20 сообщений. Это те, от которых наиболее напрямую зависит ход рассуждений агента. Снижение увеличивает риск, что агент потеряет нить того, что только что делал; повышение стоит токенов.
  • protect_first_n: 3 — не сжимать первые 3 сообщения, обычно это системный промпт и начальные инструкции. Не трогайте.
  • hygiene_hard_message_limit: 400 — абсолютный потолок по количеству сообщений, независимо от токенов. Выше него — принудительная гигиена.
  • abort_on_summary_failure: false — если сама компрессия упала с ошибкой, продолжать с несжатым контекстом. true бы поднимал ошибку наружу вместо тихого раздувания контекста.
  • prompt_caching.cache_ttl: 5m — сколько провайдер кэширует префикс промпта. Если вы шлёте один и тот же длинный системный промпт несколько раз за 5 минут — полную цену вы платите только за первый раз. Это огромный плюс — не отключайте. Часть провайдеров (включая nanogpt) поддерживают prefix caching; делать сессии достаточно плотными, чтобы попадать в один и тот же cache key — заметно влияет.

Самое практически полезное изменение, которое я сделал — снизил threshold с 0.6 до 0.45. Hermes начинает саммаризировать раньше, контекст в памяти остаётся меньше, и счёт за каждый вызов соответственно падает. Trade-off — больше событий 🗜️, каждое из которых само по себе стоит одного вызова на компрессию — но при долгих сессиях итог положительный.

Привычки, которые реально что-то меняют

Конфигом можно сделать только до определённого предела. Большие выигрыши — в том, как вы используете Hermes изо дня в день:

1. Закрывайте сессии, когда закончили блок работы

Сессия 6h 35m, из которых 5h 50m вы были afk — не бесплатна. Контекст всё ещё загружен, и на любой новый ход он пересылается заново. /new ради чистого старта — обычно правильный шаг, когда закончили смысловую единицу работы. Поле длительности в status bar — полезный напоминатель: если оно измеряется часами и вы давно отошли, вы платите ни за что.

2. Складывайте стабильные знания в vault, а не в чат

Я держу vault в ~/Documents/vault/hermes/ для того, что Hermes должен знать между сессиями — рабочие конфиги, расположения файлов, «вот что мы поняли про i3-сокет». Когда что-то стабилизировалось — запишите туда и перестаньте объяснять это в чате заново. В будущих сессиях Hermes может один раз вызвать Read на файл из vault вместо того, чтобы выводить ту же информацию через десяток ходов разговора.

Полезный формат заметки в vault:

# tg-signals-bot
**Channel:** `-100XXXXXXXXX`
**Cron job ID:** `c16e107d5535`
**Scripts:** `~/.hermes/scripts/polymarket_signal/`

Полстраницы структурированных фактов заменяет десятки тысяч токенов на тему «как там тот cron-job ID назывался?».

3. Не вставляйте сырой вывод инструментов обратно в модель

Это самая частая трата, которую я вижу. Агент делает ls, печатает 200 строк, и в следующем ходу пишет «Исходя из листинга выше…». Этот ls-вывод уже в контексте и останется там до следующей компрессии. Лучше — попросить Hermes сразу же саммаризировать листинг по ходу дела («сколько .m3u файлов? есть больше 1 ГБ?») вместо того, чтобы тащить весь raw output дальше по чату.

4. Используйте quick-команды везде, где можно

Всё, чему не нужен естественный язык, должно быть quick-командой. Они стоят ноль токенов. mpv-сетап, про который я писал, использует 13 quick-команд для вещей, которые иначе уходили бы через модель. Если вы вызываете у Hermes одну и ту же операцию более 3 раз — напишите shell-скрипт и подключите его записью в quick_commands:.

5. Смотрите на 🗜️ N и реагируйте, когда растёт

Одна компрессия за долгую сессию — нормально. Когда вы видите 🗜️ 3 и 🗜️ 4 — сессия достаточно большая, чтобы вы платили за то, что куча избыточного контекста многократно ре-саммаризируется. Хороший момент, чтобы /new и начать с чистого листа.

6. Берите модель помельче для мелких задач

hermes-medium на nanogpt — это хороший баланс для большинства вещей. Для совсем тривиальной работы — «переименуй вот эту переменную в трёх файлах» — модель поменьше и побыстрее стоит дешевле за вызов и завершается раньше. model-presets.json делает переключение одной командой: /model nano-medium — вверх, /model zen-flash — вниз. Status bar обновляется мгновенно, можно сверить.

7. Будьте осознанны с фоновыми задачами

Индикатор ▶ N показывает активные фоновые таски. Каждая из них может независимо тратить токены. Фоновая задача, бегающая раз в 5 минут на 6-часовой сессии — это 72 неподнадзорных вызова модели. Убедитесь, что фоновые задачи делают работу, которая реально требует модели — многие cron-style рутины могут быть просто shell-скриптами с no_agent: true, и стоят ноль.

Что я в итоге накрутил

Конкретно, у меня в ~/.hermes/config.yaml:

  • compression.threshold: понизил до 0.45 (было 0.6)
  • compression.target_ratio: понизил до 0.20 (было 0.25)
  • compression.protect_last_n: оставил 20
  • prompt_caching.cache_ttl: оставил 5m — на nanogpt работает как есть

Плюс поведенческие привычки выше. Строгого бенчмарка «до/после» я не делал, но по ощущениям просадки подписочного тарифа теперь приходят сильно ближе к концу месяца, а не в середине.

Подытожим

Status bar в Hermes делает больше работы, чем кажется. Однострочный футер репортит шесть независимых метрик, и читать их правильно — это разница между «хм, что-то агент тормозит» и «у меня 120K/256K, 🗜️ 4, я уже 90 минут не вводил ничего — пора /new».

Два самых важных факта-поправки, если вы пропустите всё остальное:

  1. 6h 35m — это сколько вы уже сидите в этой сессии, а не сколько у вас осталось. Если эта цифра выглядит большой — недельный расход токенов, скорее всего, тоже.
  2. Тариф nanogpt за $12 — это потолок в 60М токенов в неделю, а не месячный лимит. Один интенсивный вечер может съесть четверть. Сброс приходит каждые 7 дней, остаток не переносится.

Если хотите общую картину, где это всё живёт — пост про mpv-контроллер из Telegram показывает всю установку, про которую status bar и отчитывается. Эти две статьи вместе — это примерно весь стек: как управлять ТВ домашнего сервера с телефона, и как делать это, не сжигая недельный лимит nanogpt до того, как добежит часы сброса.