---
date: 2026-06-20
type: decision
tags: [dttb, german, hermes, omniroute, cliproxy, max, out-of-usage, troubleshooting]
---

# German (Hermes LXC 141) — `400 out of extra usage` на cc/* через OmniRoute

> **Handoff-документ.** Проблема НЕ закрыта полностью на 2026-06-20. Сделаны два смягчающих фикса (привязка аккаунта + retry-патч), но остаточные пики `out of usage` остаются. Окончательное решение — за Олегом (Extra usage / разгрузка нагрузки). Ниже — всё, чтобы продолжить без повторного прохода по тупикам.

## Симптом
German-бот (@german_dttb_bot, Hermes Agent v0.16.0, LXC 141) периодически отвечает ошибкой вместо ответа:
```
400 - You're out of extra usage. Add more at claude.ai/settings/usage and keep going.
```
Интермиттентно: ~7-12% запросов cc/* падают, остальные 200. Бот «то работает, то нет».

## Что НЕ является причиной (проверено — НЕ тратить время заново)
1. **НЕ баг версии OmniRoute.** Обновил 3.8.29 → 3.8.30 (`npm install omniroute@latest` в `/root/.npm/_npx/cb5891f90ae65d14`, ExecStart уже `dist/server.js`). Ошибка осталась. (В 2026-06-09 похожая ошибка реально была багом 3.8.7 — но не в этот раз.)
2. **НЕ реальный лимит подписки Олега.** Скриншоты Claude Code Plan usage: 5h-limit 43→53%, Weekly 5-6%, Sonnet 0% — **свободно**. Олег прав: «лимитов нет».
3. **НЕ размер запроса.** Тест: контекст 357K симв (~90K токенов) → 200 на opus-4-7/opus-4-8/sonnet. Размер ни при чём.

## Архитектура (как cc/* доходит до Anthropic)
```
German (LXC 141) → OmniRoute (LXC 132, 10.0.0.179:20128) → cliproxy (/root/.cli-proxy-api:8319) → Anthropic Max OAuth
```
- В OmniRoute `provider_connections` (БД `/root/.omniroute/storage.sqlite`) — **два Claude-аккаунта**:
  - `e8a70f39-564d-4529-a911-4b5d0a47e512` — priority 1, **перегружен**: SwarmClaw (8 агентов) + code-server жгут через него ~**13К `opus-4-8`/час** → сыпет 400/429/502/529.
  - `883152e1-7160-4d5c-90eb-88822d50db31` = **`batlaew@gmail.com`** — рабочий аккаунт Олега (тот, что в скриншоте 53%), свободнее, почти всё 200.
- Ключи German/openclaw в OmniRoute `api_keys`: **`claw`** и **`test-key`** (оба `sk-225e902dc95ff…` — это и есть `OPENAI_API_KEY` в `/root/.hermes/.env` German). SwarmClaw-нагрузка (13К) идёт БЕЗ `api_key_name` (мастер-путь), отдельно от этих ключей.

## Главная диагностическая команда (с неё начинать в будущем)
```bash
# на LXC 132 (через pct exec 132 с Proxmox 10.0.0.250 root/1qaz!QAZ):
sqlite3 -column /root/.omniroute/storage.sqlite \
 "SELECT model, account, status, COUNT(*) n FROM call_logs WHERE model LIKE '%opus%' GROUP BY model,account,status ORDER BY n DESC LIMIT 20"
```
Поля `account` + `status` сразу показывают, какой аккаунт сыпет 400 и какой 200. **Не гадать про версию/лимит — смотреть сюда.**

## Что СДЕЛАНО (два смягчающих фикса)
### 1. Привязка ключей German/openclaw к рабочему аккаунту
Ключи `claw`/`test-key` имели пустой `allowed_connections` → ротация кидала German на перегруженный `e8a70f39`. Привязал к `batlaew`:
```bash
# на LXC 132. Формат allowed_connections = JSON-массив id (JSON.parse, length>0 ограничивает)
sqlite3 /root/.omniroute/storage.sqlite \
 "UPDATE api_keys SET allowed_connections='[\"883152e1-7160-4d5c-90eb-88822d50db31\"]' WHERE name IN ('claw','test-key')"
systemctl restart omniroute   # сбросить кэш ключей
```
- Бэкап БД: `/root/.omniroute/storage.sqlite.bak-keybind`.
- Проверено: 10/10 запросов German-ключом → account=batlaew. SwarmClaw не затронут (другой путь).
- Откат: `UPDATE api_keys SET allowed_connections=NULL WHERE name IN ('claw','test-key')`.

### 2. Retry-патч Hermes (out-of-usage → retryable)
До патча Hermes считал `400 out of extra usage` фатальной (`Aborting`). Сделал retryable:
- Файл: `/usr/local/lib/hermes-agent/agent/error_classifier.py` — добавлен паттерн `status_code==400 and "out of extra usage" in error_msg → FailoverReason.rate_limit, retryable=True` (перед «── 2. HTTP status code classification»).
- `config.yaml`: `agent.api_max_retries` 3 → 5.
- Проверено вызовом `classify_api_error`: на этот текст RETRYABLE=True, обычные 400 остаются non-retryable.
- Бэкап: `error_classifier.py.bak-outofusage`. **Переналожатель: `/root/hermes-patch-outofusage.py`** — запустить ПОСЛЕ обновления Hermes (патч в коде слетает).

## Текущий статус (на 2026-06-20 ~16:00)
- German **отвечает, когда нет пика** (проверено в логах: 14:16 inbound `?` → ответ; и прямыми тестами все модели 200).
- В **длинные пики** (>~50с, ретраи 5×40с не хватает) German всё ещё возвращает ошибку «model provider failed after retries».
- **Пульсация `out of usage` остаётся на ОБОИХ аккаунтах** (e8a70f39 и batlaew) периодически — ДАЖЕ при свободном 5h (53%). Это похоже на burst/моментную механику Anthropic Max, из логов OmniRoute до конца НЕ объяснено.

## Что осталось — варианты окончательного решения (ВЫБОР ОЛЕГА)
1. **Extra usage on** — `claude.ai/settings/usage`, секция Extra usage (не Plan usage). Поднять spend limit → overflow в пик оплачивается, `out of usage` исчезает для ВСЕХ ботов. Самое прямое, платно, в биллинге Олега.
2. **Разгрузить главного пожирателя** — SwarmClaw (8 агентов) + code-server с `cc/claude-opus-4-8` (~13К/час) на Sonnet/меньше агентов → давление на Max-пул/burst падает.
3. **Восстановить не-Max тракт** для German (вывести из Max-пула). На 2026-06-20 ВСЕ мертвы: Kiro (`402`/нет кредов), Codex (`not supported`/таймаут), gemini-cli (`403` нет лицензии), GLM (`429` баланс 0).
4. Поднять retry-окно German ещё (api_max_retries + backoff) — пережидать и длинные пики, ценой задержки ответа на 1-2 мин (плохой UX).

## Связанные факты
- German модель: `config.yaml` `model.default: cc/claude-opus-4-7`, fallback `cc/claude-haiku → claude/claude-haiku` (всё Max-tract; при пике все падают — fallback бесполезен, ретрай важнее). **Рекомендация:** рассмотреть `cc/claude-opus-4-8` как primary (Олег его юзает в Claude Code; в тестах не хуже).
- Доступ: Proxmox `10.0.0.250` root/`1qaz!QAZ` → `pct exec 141` (German) / `pct exec 132` (OmniRoute+cliproxy).
- Память: [[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_omniroute_update]], [[../../.claude/projects/-Users-ai-knowledge-base/memory/project_german_hermes]].
- Деплой German: [[2026-06-18-german-hermes-agent-deploy]].

## Продолжение 2026-06-20 (вечер) — e8a70f39 МЁРТВ, изоляция невозможна
Олег выбрал «реанимировать e8a70f39» → **не сработало по жёсткой причине**:
- Флипнул `is_active=1` (priority 1). При первом master-вызове OmniRoute попытался обновить протухший токен (expired 06-16) и получил `Refresh token consumed (unrecoverable_refresh)` → **авто-выключил аккаунт обратно** (`is_active=0`), вызов свалился на batlaew (200). Это и есть причина, почему e8a70f39 был выключен 06-16: его OAuth refresh-токен сожжён безвозвратно. **Поднять без свежего OAuth-логина нельзя.** БД вернулась в исходное сама (бэкап `storage.sqlite.bak-reactivate-e8a70f39`).
- **Вывод: рабочий Claude-аккаунт в OmniRoute РОВНО ОДИН — batlaew.** Двух-пуловая изоляция (фикс #1) больше неактуальна — изолировать не на что. Привязка ключей к batlaew стала бессмысленной (он и так единственный), но не вредит.

### Профиль «почему то работает, то нет» (опровергает «весь день без ошибок»)
German-ключи (claw/test-key) сегодня по часам: 09 `18×200/3×400/14×429`, 13 `2×200/**18×400**`, 14 `8×200/6×400`, **15 `24×200` (чисто)**, 16 `1×200/6×400`. То есть весь день **интермиттирующие burst-провалы**, худший в 13:00; в 15:00 — идеально. Олег тестировал в 16:xx → попал в burst. Спайки 1-в-1 со спайками `out of extra usage` у batlaew (09:5, 12:9, 13:21, 14:7, 16:7).
**«Лимитов нет» объясняется так:** дашборд **Plan usage** (5h 53%) — сглаженное среднее и burst не показывает. Блок `out of extra usage` — это потолок **Extra usage** (pay-as-you-go overflow), который стоит на **$0**. В момент пика суммарный спрос на batlaew (German + SwarmClaw + code-server, все сошлись на нём после смерти e8a70f39 06-16) превышает включённый в план объём, а раз overflow $0 — Anthropic жёстко режет вместо очереди.

### Сделано в этом проходе
- German default-модель `cc/claude-opus-4-7` → **`cc/claude-opus-4-8`** (запрос Олега). Бэкап `config.yaml.bak-opus48`. Проверено: German-ключ → opus-4-8 → 200. *Внимание: opus-4-8 НЕ снижает out-of-usage — тот же аккаунт/пул.*

### Реальные варианты (e8a70f39 вычеркнут) — ВЫБОР ОЛЕГА
1. **Extra usage ON на batlaew** (`claude.ai/settings/usage` → Extra usage, не Plan) — единственное, что убирает out-of-usage насовсем при одном аккаунте. Платно, биллинг Олега. **Рекомендация #1.**
2. **Разгрузить burst-пожирателей** — SwarmClaw (8 агентов) + code-server с `cc/opus-4-8` на Sonnet/меньше агентов → суммарный пик влезает в план batlaew.
3. **Свежий OAuth второго Max-аккаунта** в OmniRoute (заново залогинить — хоть тот же, что был e8a70f39, хоть новый) → восстановить двух-пуловую изоляцию. Требует интерактивного OAuth (Олег).
4. Реальный backoff ретраев German (сейчас 5 ретраев летят за <1с — бесполезно против burst в секунды-минуту). Пережидать пик ценой задержки ответа.

## Продолжение 2026-06-20 (вечер-2) — СМЕНА СТРАТЕГИИ: почему Антошка работает, а German нет
Олег ткнул верно: **openclaw (Антошка) на том же OmniRoute/Opus 4.8 работает стабильно** → теория «account-level cap» неполна. Сравнил два бота эмпирически (call_logs) — **3 реальные разницы:**
1. **Объём.** Антошка (ключ `claw`) сегодня = 2 вызова; German (`test-key`) = 114 (+ master/SwarmClaw+codeserver 130). German — половина нагрузки batlaew и worst fail-rate (39/114=34%). Антошка «работает» во многом потому что лёгкий → редко попадает в burst.
2. **Фоллбэк-цепочка.** У German была `cc/claude-haiku → claude/claude-haiku` (ОБА Max → бьются в тот же `out of extra usage`, что и opus — проверено: sonnet-4-6 тоже ловит этот 400). У Антошки последний фоллбэк = **`kr/claude-sonnet-4.5`** (Kiro, FREE, не-Max) → когда Max в пике, Антошка уезжает на не-Max и продолжает отвечать.
3. **Пин ключа (КОРЕНЬ).** Фикс #1 (`allowed_connections=['883152e1'/batlaew]`) делался против перегруженного e8a70f39 — но тот **мёртв**. Пин же **запер German на единственном перегруженном batlaew**: эскейп-маршруты `kr/`/`cx/` ключом German отдавали **400** (connection-not-allowed). Пин из «защиты» превратился в «ловушку». [[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_root_cause_recurring]]: лечил симптом, корень — в своём же конфиге.

### Сделано (привёл German к схеме Антошки, всё в рамках моих прав, без биллинга)
1. **Снят пин** с `test-key` и `claw`: `UPDATE api_keys SET allowed_connections=NULL WHERE name IN ('test-key','claw')`. Теперь opus-4-8 всё равно → batlaew (других Max-аккаунтов нет), а kr//cx/ доходят до своих провайдеров. Проверено: до — kr/cx=400, после — opus-4-8=200, kr/cx доходят (402/timeout = флап free-пулов, но маршрут открыт).
2. **Фоллбэк-цепочка** German переписана как у Антошки: `cc/claude-sonnet-4-6 → kr/claude-sonnet-4.5 → cx/gpt-5.5` (выкинул мёртвый haiku→haiku). Бэкап `config.yaml.bak-fallback-*`.
3. Primary = `cc/claude-opus-4-8`. German стабилен (`NRestarts=0`), opus-4-8 → 200.

### Честный остаток (Олегу знать)
Это **не делает German неуязвимым** — free-эскейпы (Kiro/Codex/GLM) сейчас сами полудохлые (Kiro: «reached the limit» 402 / «fetch failed» 502 / 429; Codex throttled; GLM баланс 0). В ГЛУБОКИЙ burst, когда и batlaew capped, и free-пулы лежат — German всё ещё может блипнуть (как блипнул бы и Антошка под такой нагрузкой). German теперь **архитектурно равен** рабочему боту, а не сломан. Для полной неуязвимости при тяжёлой нагрузке всё равно нужно одно из: **Extra usage ON** на batlaew / **разгрузка master-пути** (SwarmClaw 8 агентов + code-server = вторая половина нагрузки batlaew) / **свежий 2-й Max-аккаунт** (OAuth). Возможный твик при рецидиве: снизить `api_max_retries` 5→3 (сейчас burst → шторм 5×4 тира вызовов, сам прогревает cap).

## Продолжение 2026-06-20 (вечер-3) — ДОКАЗАНО: это всё-таки account-level cap, протокол ни при чём
Олег давил: «дело не в лимитах, почему Антошка работает». Проверил гипотезу «формат запроса»:
- **Эндпоинт-разница реальна:** Антошка (`claw`) шлёт нативный Anthropic `/v1/messages` (`source_format=claude`), German (`test-key`) — OpenAI-формат `/v1/chat/completions`+`/v1/responses`. История: claw 448×200 / **0×400**; `/v1/messages` суммарно 355×200 / **0 out-of-usage**, а ВСЕ **396** `out of extra usage` — на `/v1/chat/completions`. Выглядело как корень.
- **Перевёл German primary на `provider: anthropic` + `/v1/messages`** (+ `ANTHROPIC_API_KEY` в .env). Подтвердил: трафик пошёл `path=/v1/messages source_format=claude`. **И всё равно поймал `out of extra usage` 400** (17:11/17:12 на opus-4-8 через /v1/messages; в 17:04 был 200 — т.е. интермиттентно).
- **РЕШАЮЩИЙ ТЕСТ:** бил `/v1/messages` opus-4-8 **обоими ключами** (claw Антошки + test-key German) залпами. В пик — оба 400, вне пика — оба 200×5. **Ключ Антошки ловит ту же ошибку.** Значит «0×400 у claw» в истории = следствие МАЛОГО ОБЪЁМА (claw сегодня 2 вызова против 114 у German), а не иммунитета протокола.
- **Вывод:** `out of extra usage` — **account-level cap на batlaew, интермиттентный (burst)**, бьёт по ЛЮБОМУ пути (/v1/messages и /chat/completions) и ЛЮБОЙ модели (opus/sonnet/haiku — всё проверено). Антошка «работает» только потому что лёгкий. Дашборд Олега = **Plan usage** (5h-среднее, 53%), а режет потолок **Extra usage** (overflow) = $0. Это и есть лимит, просто не тот, что на дашборде.
- **Откат:** протокол-правку вернул к проверенному `provider: custom`+`/v1` (anthropic-режим не помог и не проверен на tool-нагрузке German — спекулятивная правка). `ANTHROPIC_API_KEY` убран. Бэкап отката `config.yaml.bak-anthropic-170948`.

### Итоговое состояние German (что осталось включённым)
- primary `cc/claude-opus-4-8` (custom/openai-compat, проверенный путь), фоллбэк `cc/sonnet-4-6 → kr/sonnet-4.5 → cx/gpt-5.5`, ключ **распинён** (NULL). active, opus-4-8→200.

### Финал (без иллюзий): убрать `out of extra usage` можно только так
1. **Extra usage ON на batlaew** — `claude.ai/settings/usage` → секция **Extra usage** (не Plan). Это буквально то, что просит текст ошибки. Снимает cap для всех.
2. **Срезать конкурентную burst-нагрузку на batlaew:** SwarmClaw (8 агентов) + code-server (cc/opus-4-8) = вторая половина трафика, льют параллельно → создают пики. Throttle/Sonnet/меньше агентов.
3. German усиливает пики своим retry-штормом (5 ретраев × 4 тира мгновенно). Снизить `api_max_retries` 5→3 — меньше шторм, меньше вклад в cap.
4. Свежий 2-й Max-аккаунт (OAuth) — изоляция German на отдельный пул.

## Продолжение 2026-06-20 (вечер-4) — SwarmClaw НЕ ест лимит + фикс «работает» через overloaded-backoff
Олег: «SwarmClaw 3 дня не юзаю, как он ест лимит?» — прав, проверил:
- **Master-путь на batlaew (opus) по дням: 06-17=268, 06-18=591, 06-19=82, 06-20=74.** Тяжёлый поток был 3 дня назад, сошёл на нет. SwarmClaw сейчас лимит НЕ ест — прежняя атрибуция неверна для текущего момента.
- **Крупнейший потребитель СЕЙЧАС — сам German:** opus-токены batlaew сегодня — test-key(German) **916K** fresh in / 877K cache; (master) 394K; claw(Антошка) 83K. German грузит большой KB-контекст в каждый ход × tool-loop → ест в 2.3× больше master и 11× больше Антошки. Антошка лёгкий → не упирается.

### Почему backoff раньше «не работал» (казалось мгновенным)
В логе 16:17 5 ретраев были на timestamp 16:17:10 — иллюзия от буферизации (`_buffer_vprint` флашится разом). Реально backoff ЕСТЬ: `conversation_loop.py:3439` `jittered_backoff(base_delay=2.0, max_delay=60.0)` + respects Retry-After. НО для `rate_limit` есть **eager-failover** (2764): при наличии фоллбэк-цепочки Hermes сразу прыгает на следующую модель, минуя ожидание opus — и каскадит через дохлые free-пулы (kr 400/cx 429) → быстро сдаётся.

### Фикс «чтобы работал» (выбор Олега делегирован мне)
1. **out-of-usage классифицирован как `FailoverReason.overloaded`** (было `rate_limit`) в `error_classifier.py:674`. overloaded НЕ триггерит eager-failover (2764 ловит только rate_limit/billing) → German **пережидает burst на самом opus-4-8 с backoff** (2с→60с jittered), а не каскадит на мёртвые фоллбэки. Проверено `classify_api_error`: out-of-usage→overloaded/retryable=True; обычная 400→model_not_found/non-retryable (узкий паттерн). Бэкап `error_classifier.py.bak-overloaded-*`, переналожатель `/root/hermes-patch-outofusage.py` обновлён (rate_limit→overloaded).
2. **`api_max_retries` 5→6** — окно пережидания ~1-2 мин (jittered 2с..60с × 6).
3. Сохранены: opus-4-8 primary, распин ключа, цепочка фоллбэков (теперь — последний резерв ПОСЛЕ ожидания opus).

**Механика:** batlaew кратко капается → German ждёт (2с,4с,8с…до 60с) и повторяет opus, ловя восстановление за ~1-2 мин, вместо мгновенной ошибки. Цена — в пик ответ на десятки секунд позже (но ОТВЕЧАЕТ). Это не победит длинный (>2 мин) аккаунт-аутаж, но такие редки; обычный burst — секунды. Полностью убирает out-of-usage всё равно только Extra usage ON / урезание контекста German (RAG вместо полного KB).

## Продолжение 2026-06-20 (вечер-5) — НАСТОЯЩЕЕ различие German vs Антошка: агентный burst
Олег: «какие ещё идеи, почему German не работает, а Антошка да». Проверил оставшиеся гипотезы на уровне запроса:
- **Per-key лимиты** (test-key vs claw): у обоих пусто — исключено.
- **Холодный кэш** (идея: German простаивает → cache_ttl 5m протухает → дорогой re-create): ОПРОВЕРГНУТО. German кэшируется нормально (3 дня: cache_read **1.5M** vs cache_creation 450K). Антошка кэш вообще не читает (read=0), но ему и не надо.
- **Тела запросов** (max_tokens/thinking): артефакты OmniRoute хранятся усечённо (~572 симв) → ненадёжно.
- **★ НАЙДЕНО — агентный burst вызовов:**
  | | Антошка (claw) | German (test-key) |
  |---|---|---|
  | макс. opus-вызовов/мин | **1** | **8** (стабильно 6-7) |
  | вызовов за 3 дня | 13 | 158 |
  
  German — агентный (tool-loop): 1 сообщение Олега → каскад **6-8 Opus-вызовов/мин**, каждый тащит ~45K-контекст → ~360K Opus-токенов залпом в минуту. Антошка — разговорный, **1 вызов** на обращение. 5h-лимит Max **взвешенный** (Opus ~5× Sonnet), и минутный burst German пробивает мгновенную взвешенную планку Opus → `out of extra usage`. Дашборд (53%) = 5h-среднее, не минутный пик. **Это и есть «почему German, а не Антошка» — частота Opus-вызовов на сообщение (агентность vs разговорность), не формат/ключ/кэш/KB.**

### Сделано
- **`agent.max_turns` 80 → 25** (`goals.max_turns` 20 не трогал) — ограничивает размер burst: одна сложная задача больше не выстрелит до 80 Opus-вызовов подряд. Бэкап `config.yaml.bak-maxturns-*`. German active, opus-4-8→200.

### Полный набор активных мер для German (итог всей цепочки)
1. primary `cc/claude-opus-4-8`; ключ распинён (NULL); фоллбэк `cc/sonnet-4-6 → kr/sonnet-4.5 → cx/gpt-5.5` (резерв).
2. out-of-usage → `overloaded` (backoff-пережидание burst на opus, не каскад на дохлые фоллбэки) + `api_max_retries` 6.
3. `max_turns` 25 (меньше burst).
Остаточный полный фикс (если рецидив): **Sonnet 4.6 как primary** (в ~5× легче по весу Max, «Sonnet 0%» — почти без лимита) ИЛИ **Extra usage ON**.

## Урок (мне на будущее)
Я трижды выдал неверный диагноз (баг версии → реальный лимит → перегрузка пула), прежде чем дошёл до `call_logs` по `account`. **При `out of usage` на cc/* — СНАЧАЛА `call_logs` GROUP BY account,status, потом гипотезы.** См. [[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_root_cause_recurring]].
