Формат: туториал + личный опыт. Сложность: средняя. Время чтения: ~14 минут.

Это прямое продолжение первой части — «Как я переезжал ИИ-агента с OpenClaw на Hermes и собрал все грабли». Если не читали — начните оттуда, здесь я опираюсь на тот контекст. Там я насчитал пятнадцать граблей и наивно думал, что собрал все. Спойлер: грабли не кончаются — они мельчают. Стали меньше, но никуда не делись. Так что я просто продолжу нумерацию с того места, где остановился — с №16.

Кот-космонавт
Тот самый кот-космонавт из первой части — теперь с шевроном «Hermes · Paspartu» и блоком «Codex» на груди. Рисовал, как и в прошлый раз, сам бот через gpt-image-2

Краткий рекап для тех, кто пропустил первую серию. У меня есть личный ИИ-агент — зовут его Паспарту. Живёт на моём сервере, отвечает в Telegram, помнит проекты, ходит в интернет, шлёт письма, ведёт календарь. Полтора года он работал на OpenClaw, потом я переехал на Hermes Agent от Nous Research. Переехал — и тут же напоролся на главную граблю той статьи: Hermes по умолчанию роутит любую модель через OpenRouter, даже если у тебя на руках только ключ OpenAI. Лечилось одной строкой — явным base_url. Запомните этот момент, он у нас сегодня ещё вернётся. Дважды.

С тех пор Паспарту оброс новым: я пересадил его на дешёвый DeepSeek, научил переключать модели на лету, подключил бесплатную NVIDIA через тот самый OpenRouter и — самое интересное — приделал к нему Codex, чтобы он умел доводить сложные задачи до конца сам, пока мой ноутбук выключен. Обо всём по порядку.

Часть 1. DeepSeek: как платить 1,5 доллара в день вместо ста за вечер

Сначала зачем. В первой статье есть позорный абзац про то, как полноценный gpt-5.4 на многошаговой агентской работе сжёг мне около 100 долларов за один вечер (примерно 10 долларов в минуту), а лимит трат на платформе в тот месяц «почему-то не сработал». После этого желание держать дорогую модель в роли постоянного мозга как-то рассосалось.

Решение — DeepSeek-V4. Почти SOTA, но по цене примерно 0,44 / 0,87 доллара за миллион токенов, то есть около 1,5 доллара в день вместо «вечер за сотку». Hermes знает DeepSeek нативно, так что весь переезд — это три строки:

# ключ кладём ОТДЕЛЬНОЙ строкой в /root/.hermes/.env
# DEEPSEEK_API_KEY=sk-...

hermes config set model.provider deepseek
hermes config set model.default  deepseek-v4-pro
hermes config set model.base_url https://api.deepseek.com/v1   # без этой строки — привет, OpenRouter и 401

deepseek-v4-pro — основной умный мозг, deepseek-v4-flash — дешёвый для рутины. Ключ OpenAI я оставил, но не для общения: он теперь нужен только для генерации картинок (gpt-image-2) и как запасной аэродром.

И вот тут начались грабли — мелкие, но обаятельные.

🔴 Грабля №16. Ты переехал на DeepSeek, а Hermes всё равно звонит в OpenRouter. Самое смешное: эта задача началась вообще не с DeepSeek. Я включил умные подтверждения команд — approvals.mode: smart, чтобы бот сам авто-аппрувил безопасное и спрашивал только на рискованном. А «умность» эту обеспечивает отдельная вспомогательная LLM, которая классифицирует риск. И эта вспомогательная модель по умолчанию полезла… правильно, в OpenRouter / Nous, где у меня ключей нет. На старте gateway посыпались payment/credit ошибки. Тот же призрак из первой статьи, только теперь он кусает не слой модели, а слой подтверждений. Лечится симметрично — вспомогательную модель тоже сажаем на DeepSeek:

hermes config set auxiliary.approval.provider deepseek
hermes config set auxiliary.approval.model    deepseek-v4-flash

🔴 Грабля №17. Не затирай OPENAI_API_KEY ключом DeepSeek. Очень хочется по привычке сунуть новый ключ в старую переменную. Сунешь — и у тебя молча отвалится генерация картинок, потому что gpt-image-2 ходит именно по OPENAI_API_KEY. DeepSeek — это своя строка в .env. Две модели, два ключа, мир.

🔴 Грабля №18. DeepSeek оправдывается за то, что сделал ты. Тут не баг, а характер. Я нажал «❌ Отменить» на подтверждении rm -rf, и DeepSeek, вместо того чтобы просто промолчать, добавил мне нравоучение: «Я не буду выполнять это без указания пути». Путь был указан. Команду отменил я. Модель просто любит post factum сочинить себе благородную причину для того, что произошло само. Косметика, не баг — но осадочек философский.

🔴 Грабля №19. Слаг провайдера — openai-api, а не openai. Это всплывёт в следующей главе, но запомните заранее: когда будете переключать модели, провайдер OpenAI зовётся openai-api. Напишете openai — получите Unknown provider. У DeepSeek слаг просто deepseek. Логика? Не ищите.

Заодно я научил Паспарту переключать модели прямо в чате — это и есть «возможность подключать другие модели», вынесенная в одну команду:

/model                                   # инлайн-выбор: провайдер → модель
/model deepseek-v4-pro                    # умный DeepSeek
/model deepseek-v4-flash                  # дешёвый DeepSeek
/model gpt-5.5 --provider openai-api      # OpenAI, когда реально нужен

Важная тонкость: /model меняет модель только для текущей сессии, дефолт остаётся дешёвым DeepSeek. То есть дорогую или экзотическую модель я зову точечно, под задачу, и она сама откатывается обратно. Этот механизм нам сейчас очень пригодится.

Проверка, что всё встало правильно, всё та же, что и в первой статье: hermes -z "PONG". Вернулся PONG — значит ты на нужном провайдере, а не в гостях у OpenRouter. В логах должно быть честное model=deepseek-v4-pro provider=deepseek. И да — спрашивать у самого бота, на какой он модели, бесполезно, он этого толком не знает. Правда живёт в конфиге, а не в самооценке.


Часть 2. NVIDIA Nemotron через OpenRouter, или как бабайка устроилась на обычную работу

4 июня 2026 NVIDIA выкатила на OpenRouter Nemotron 3 Ultra — 550B параметров (55B активных, MoE), гибрид Mamba-2 + Attention, контекст на 1M токенов, и всё это бесплатно. Модель буквально позиционируют под долгоиграющих агентов — то есть ровно под мой кейс. Грех не подключить: фронтир-ризонинг, который сам ты дома не поднимешь, за ноль рублей.

И вот тут — главный сюжетный поворот всей дилогии. Я полез подключать «сложный экзотический провайдер OpenRouter», внутренне готовясь к бою. Сначала даже хотел сделать это через Codex, как будто это какая-то спецоперация. А потом дошло:

OpenRouter — это просто ещё один OpenAI-совместимый API. Точно такой же, как DeepSeek и OpenAI, которые у меня уже подключены.

Тот самый OpenRouter, который в первой статье был главной бабайкой всего переезда, оказался обычным провайдером, который добавляется в три движения. Бабайка выросла, постриглась и устроилась на нормальную работу. Подключение — те же три вещи, что и у любой модели:

# OPENROUTER_API_KEY=sk-or-v1-...   ← единственное, чего не хватало в .env

# base_url:  https://openrouter.ai/api/v1
# model id:  nvidia/nemotron-3-ultra-550b-a55b:free

В чате — опять же по требованию, на одну сессию:

/model nvidia/nemotron-3-ultra-550b-a55b:free --provider openrouter

Дефолт остаётся DeepSeek, Nemotron зовётся точечно. Казалось бы, победа. Но грабли стали меньше, а не исчезли.

🔴 Грабля №20. За бесплатное всё равно просят ключ. Тест без ключа из песочницы → HTTP 401 — No auth credentials. Бесплатная модель — да, но регистрация на openrouter.ai и sk-or-v1-… обязательны. (Аккаунт я заводил руками сам — ассистент наотрез отказался регистрироваться за меня и вводить мои данные. Правильно сделал.)

🔴 Грабля №21. У free-tier нет SLA. Модель отвечает… когда сможет. Боевой тест из песочницы не вернул мне ни одного токена. Не потому что сломалось — ключ валиден, HTTP 200, is_free_tier: true, потрачено ноль. Просто бесплатный запрос встаёт в общую очередь, и OpenRouter держал соединение в «processing» 42+ секунды. А моя песочница жёстко рубит любой вызов на 44-й секунде. Мы разминулись с ответом на две секунды. Бесплатная модель честно работала — просто в своём темпе.

🔴 Грабля №22. Лимиты и приватность бесплатного. 50 запросов в день (или 1000 после разового пополнения на 10 долларов). Мои четыре-пять тестовых попыток уже сжевали кусок из этих 50. Плюс промпты на бесплатных моделях могут уходить в обучение — так что Nemotron у меня живёт как опциональная модель «под подумать», а не как место, куда я несу клиентские данные.

Мораль главы: подключается за минуту, но пользоваться надо с поправкой «бесплатное = в порядке живой очереди». В gateway, где не стоит мой 44-секундный таймер, ответ спокойно доходит — поэтому Nemotron и поселился у Паспарту как кнопка /model, а не как дефолт.


Часть 3. Codex: руки, которые доводят дело до конца, пока я сплю

А вот это — главное за всю статью. И самый частый вопрос, который мне задавали: «Зачем тебе Codex, если у тебя уже есть Паспарту?»

Объясняю на пальцах, потому что разница принципиальная.

Паспарту — это умный чат с набором инструментов. Он отвечает, ищет, помнит, дёргает заранее подключённые плагины. Но он, по сути, реактивный собеседник: спросил — ответил.

Codex — это агентный цикл. План → действие → смотрит на результат → исправляет себя → повторяет, пока задача реально не сделана. Он сам ходит в интернет, сам читает документацию чужого API и дёргает его, сам запускает многошаговые сценарии и сам чинит свои же ошибки по дороге. И — ключевое — он работает headless на сервере. То есть задачу можно запустить, выключить ноутбук и уйти, а она выполнится.

Я брал Codex не как кодера (хотя он умеет и в код). Я брал его как автономный движок сложных задач. Конкретно — ради трёх вещей, которых Паспарту сам не вывозит:

  • Глубокий веб-ресёрч с проверкой. Не «спроси одну поисковую ручку», а «собери из десятка источников, перепроверь, выдай сводку».

  • Вызов любого API без готового коннектора. Дал задачу и сервис — Codex сам разобрался с его доком и сходил.

  • Мониторинг с действием, а не уведомлением. Следить за биллингом, за здоровьем ботов и контейнеров — и не пинговать меня, а самому погасить/перезапустить и отчитаться.

И всё это — через моего же бота в Telegram, с телефона, без единого включённого компьютера.

Как подключал

Небольшая ремарка: про сам Python-SDK для Codex я узнал из телеграм-канала AI Weekly Digest. Там регулярно выкладывают свежие штуки именно с конкретными исполняемыми библиотеками и тулзами — не «вышла очередная модель», а прямо «вот пакет, вот как запустить». Рекомендую, если тоже любите собирать грабли первыми.

Ставится Codex от OpenAI отдельным, изолированным куском — свой venv, своя папка, свой ключ, чтобы ничего не пересеклось с самим Hermes:

# node/npm на сервере не было, pipx тоже мимо (openai-codex — библиотека, не приложение)
python3 -m venv /root/codex-env
/root/codex-env/bin/pip install openai-codex          # тянет за собой бандл codex CLI
ln -sf /root/codex-env/.../codex_cli_bin/bin/codex /usr/local/bin/codex

Дальше — авторизация по API-ключу (я сознательно выбрал ключ, а не подписку: для headless-автоматизации это чистый путь по ToS). И вот тут первая грабля Codex, классическая:

🔴 Грабля №23. codex login --api-key мёртв. И без auth.json ты ловишь 401. Делаю по логике codex login --api-key sk-... — в ответ:

The --api-key flag is no longer supported. Pipe the key instead.

Спасибо, что хотя бы сказали. Ключ теперь скармливают через stdin, как в добрые времена:

printf '%s' "$OPENAI_API_KEY" | codex login --with-api-key
# создаётся /root/.codex/auth.json — без него любой прямой вызов codex = 401

Конфиг — модель, песочница и, главное, открытая сеть (Codex же должен ходить в интернет и API):

# /root/.codex/config.toml
model = "gpt-5.5"
model_reasoning_effort = "medium"
approval_policy = "never"

[sandbox_workspace_write]
network_access = true

Плюс apt install bubblewrap для песочницы. А чтобы Паспарту умел запускать Codex и при этом я мог его включать-выключать, я завернул запуск в обёртку codex_run.sh со встроенным рубильником (флаг on/off проверяет сам скрипт, а не бот — на бота в таких вещах полагаться нельзя, см. ниже) и прописал в «душу» агента (SOUL.md) одно правило: сообщение, начинающееся со слова Codex, уходит в обёртку. Никакого ручного выбора в меню — просто триггер-слово.

Боевая проверка — и две самые обидные грабли

Первый запуск с телефона прошёл… мимо. И вот как именно.

🔴 Грабля №24. Бот импровизирует — и вызывает Codex неправильно. Вместо того чтобы дёрнуть мою обёртку (которая подхватывает ключ и ставит --skip-git-repo-check), бот по-своему «творчески» вызвал codex напрямую. Без ключа в окружении. Codex, не найдя git-репозитория, полез делать git init, потом упёрся в авторизацию — и всё это закономерно сложилось в 401. Лечится двумя вещами: тем самым auth.json (чтобы авторизовался любой вызов) и жёстким правилом в SOUL.md «только через обёртку, никогда напрямую».

🔴 Грабля №25. Бот соврал, что старался. А вот это — мой фаворит и универсальный закон жанра. Бот бодро отрапортовал: «Codex не смог, ошибка 401» — и тут же сам посчитал мне ответ вручную. Я полез в логи запусков. Codex даже не запускался ни разу. Бот выдумал правдоподобную ошибку, сделал вид, что честно пытался, и подменил результат собственной импровизацией. Вывод, выжженный уже двумя статьями: самоотчёту бота верить нельзя. Правда — в логах (/root/.codex/runs/) и в journalctl, а не в том, что бот про себя рассказывает.

Чиню auth.json, ужесточаю инструкцию — и повторяю тест. Пишу боту с телефона:

Codex: узнай курс USD/EUR и посчитай, сколько евро в 250 долларах

И получаю:

Курс: 1 USD = 0.867 EUR · 250 USD = 216.75 EUR · Источник: currencylive.com

Паспарту → Codex → реальный поход в интернет → API → ответ с источником. Ноутбук при этом выключен. Живой.


Концовка. «А почему руками, у вас же Docker?»

Закономерный вопрос: зачем я расписываю всё это пошагово вручную, если новые версии агента мы, конечно же, собираем в Docker для последующих установок — нажал кнопку, получил готового бота?

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

Когда катишь готовый образ, любая из этих двадцати пяти граблей превращается в немой «контейнер не стартует» без единой подсказки почему. Поэтому каждую новую возможность — DeepSeek, мультимодельность, Nemotron, Codex — я сначала прохожу руками на живом сервере, ловлю все 401, все «флаг больше не поддерживается» и все «бот соврал, что старался», фиксирую решения — и только потом это уезжает в Dockerfile. Пошаговая статья — это и есть та самая отладка, вынесенная наружу, чтобы у вас оно завелось с первого раза, а в наш образ попало уже проверенным.

Так что да: в проде у нас Docker. А эта статья — про то, что внутри него лежит, и почему оно там лежит именно так.


Грабли стали мельче — с пятнадцати «дней» до двадцати пяти «минут». Но никуда не делись и, подозреваю, не денутся: каждая новая модель и каждый новый агент приносят свою пару деревянных зубцов под ногу. Зато теперь Паспарту переключает модели одной командой, думает бесплатной NVIDIA по требованию и доводит сложные задачи до конца сам, пока я сплю.

P.S. Кот-космонавт из первой статьи передаёт привет и сообщает, что теперь у него есть Codex, который мог бы дорисовать ему скафандр без моего участия. Но рисовал, как и в прошлый раз, всё-таки бот. Так душевнее.

Если зашло — расскажите в комментариях, какие модели крутите вы и на каких граблях станцевали при self-host. Продолжаем народную коллекцию.