Как я «переезжал» своего ИИ-агента с OpenClaw на Hermes и собрал все грабли (чтобы Вы не собирали). DevOps.. DevOps. Hermes.. DevOps. Hermes. llm.. DevOps. Hermes. llm. Open source.. DevOps. Hermes. llm. Open source. OpenClaw.. DevOps. Hermes. llm. Open source. OpenClaw. self-hosted.. DevOps. Hermes. llm. Open source. OpenClaw. self-hosted. искусственный интеллект.. DevOps. Hermes. llm. Open source. OpenClaw. self-hosted. искусственный интеллект. миграция.. DevOps. Hermes. llm. Open source. OpenClaw. self-hosted. искусственный интеллект. миграция. Системное администрирование.

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

Кот-космонавт, нарисованный ботом
Кота-космонавта в стиле акварели нарисовал сам бот через gpt-image-2 — уже после переезда

У меня есть личный ИИ-агент — зовут его Паспарту. Не «ассистент в облаке, который вежливо извиняется», а свой: живёт на моём сервере, отвечает в Telegram, помнит проекты, ходит в интернет, шлёт письма, ведёт календарь. Полтора года Паспарту работал на OpenClaw. А недавно я решил переехать на Hermes Agent от Nous Research — он опенсорсный (MIT), self-hosted, умеет приносить свои скиллы со временем и, главное, не привязан к одному вендору модели.

Звучало как «ну, вечерок». На деле — почти полноценный день, пятнадцать граблей и один кот-космонавт. Дальше — честный рассказ + рабочий гайд, по которому вы повторите переезд за пару часов и без половины моих синяков.

Зачем вообще переезжать

Если коротко — три причины:

  1. Bring-your-own-model. Hermes работает с любым OpenAI-совместимым эндпоинтом: OpenAI, Anthropic, OpenRouter или вообще локальная модель. Я остаюсь на дешёвом OpenAI-конфиге, но дверь к локалке открыта.

  2. Растёт со временем. Персистентная память + авто-генерация скиллов. Чем дольше работает — тем больше умеет.

  3. Веб-дашборд + 20 платформ. Telegram, Discord, Slack, WhatsApp, Signal, e-mail, CLI. Начал в одном — продолжил в другом.

Архитектурно Hermes и OpenClaw до неприличия похожи: и там, и там скиллы — это папки с SKILL.md, память — Markdown, конфиг — один файл. Поэтому я наивно решил, что «всё перельётся само».

Схема переезда OpenClaw → Hermes

Было → стало: переезд OpenClaw → Hermes на отдельный сервер

Главное правило переезда

Старый сервер не выключаем, пока новый не примем. OpenClaw оставляем как страховку: если Hermes закапризничает — одной командой возвращаемся. Никаких «снёс старое — поднимаю новое в проде».

Теперь поехали по шагам. Я специально оставил рядом с каждым шагом грабли, на которые наступил, — они выделены 🔴.


Шаг 1. Новый сервер и базовая подготовка

Берём чистый дроплет: Ubuntu 24.04, 4 vCPU / 8 ГБ. Отдельный сервер — это сразу снимает риск, что два «жирных» агента подерутся за память.

apt update && apt -y full-upgrade
apt -y install curl git rsync jq ufw ca-certificates ffmpeg build-essential
# firewall: OpenSSH РАЗРЕШАЕМ ДО включения, иначе закроем себе дверь
ufw allow OpenSSH && ufw allow 80 && ufw allow 443 && ufw --force enable
# swap на всякий случай
fallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
reboot   # после full-upgrade приехало новое ядро

🔴 Грабля №1. ufw --force enable без предварительного ufw allow OpenSSH — это классика «запер себя снаружи». Сначала SSH, потом enable.

🔴 Грабля №2. apt full-upgrade обновляет ядро, но не перезагружается сам. Если не ребутнуть — половина диагностик будет показывать «pending kernel». Ребут.


Шаг 2. Ставим Hermes (и привет, Ubuntu 24.04)

apt-get install -y python3-pip pipx python3-venv
pipx install hermes-agent
export PATH=$PATH:/root/.local/bin
hermes postinstall          # доставит uv, node, ripgrep, ffmpeg
hermes --version

🔴 Грабля №3 — PEP 668. На Ubuntu 24.04 системный pip install ругается «externally-managed-environment». Для самого Hermes — pipx. Для отдельных библиотек дальше — pip install --break-system-packages. Не пытайтесь воевать с системным pip, просто примите правила.


Шаг 3. Модель: и вот тут начинается боль

У меня в .env лежит OpenAI-ключ. Я выставил модель и… бот в Telegram ответил гениальной фразой:

⚠️ Provider authentication failed.

В логах — HTTP 401: Missing Authentication header, провайдер — openrouter. Стоп. Какой openrouter, у меня OpenAI-ключ?

А вот какой. Hermes по умолчанию роутит модель через OpenRouter. И строку openai/gpt-5.4-mini он понимает не как «OpenAI, модель gpt-5.4-mini», а как «openrouter, модель openai/gpt-5.4-mini». Ключа от OpenRouter у меня нет → 401.

Лечится двумя командами:

hermes config set model.default gpt-5.4-mini                 # без префикса openai/
hermes config set model.base_url https://api.openai.com/v1   # идём напрямую в OpenAI
# проверка без всякого Telegram:
hermes -z "Reply with exactly: PONG"

Когда hermes -z вернул PONG — выдохнул.

🔴 Грабля №4. base_url решает. Когда он задан — Hermes стучится прямо на этот эндпоинт и авторизуется через OPENAI_API_KEY. Без него — добро пожаловать в OpenRouter и 401.


Шаг 4. Переносим данные OpenClaw

Тут всё прозаично — rsync каталога ~/.openclaw со старого сервера на новый. Оба дроплета в одном дата-центре, так что летит быстро.

# на новом сервере тянем со старого (ключ тот же digocean)
rsync -a -e "ssh -o StrictHostKeyChecking=accept-new" 
  root@OLD_IP:/home/openclaw/.openclaw/ /root/openclaw-src/
# ⚠️ ключи живут ОТДЕЛЬНО:
rsync -a root@OLD_IP:/opt/openclaw.env /root/openclaw-src/.env

🔴 Грабля №5. Боевые ключи (OpenAI, Telegram) лежали не в ~/.openclaw, а в /opt/openclaw.env (его systemd подсовывает как EnvironmentFile). Если забыть его скопировать — миграция секретов не найдёт ни одного ключа, и вы будете долго удивляться.

И перед копированием — останавливаем бота на старом сервере:

systemctl stop openclaw

🔴 Грабля №6 — конфликт токена. У Telegram на один токен бота может работать только один «слушатель». Если старый OpenClaw и новый Hermes одновременно опрашивают одного бота — Telegram отдаёт 409 Conflict, и сообщения начинают рваться пополам. Поэтому: остановили старого → токен свободен → его займёт новый. Сервис при этом оставляем enabled — вернётся одной командой, если что.


Шаг 5. Нативная миграция

У Hermes есть встроенная команда hermes claw migrate — переносит память, persona, скиллы, провайдеров, MCP, TTS, allowlist и токены платформ.

hermes claw migrate --preset full --migrate-secrets --skill-conflict rename --overwrite --yes 
  --source /root/openclaw-src 
  --workspace-target /root/hermes-workspace

🔴 Грабля №7. Без --workspace-target файл AGENTS.md (инструкции воркспейса) молча не переедет. Молча — это самое противное. Указывайте путь всегда.

🔴 Грабля №8. Ключ Perplexity (поиск по интернету) не входит в allowlist миграции секретов — его придётся вписать руками, вытащив из старого конфига:

PK=$(jq -r '.tools.web.search.apiKey // empty' /root/openclaw-src/openclaw.json)
echo "PERPLEXITY_API_KEY=$PK" >> /root/.hermes/.env

После миграции я проверил ~/.hermes/.env (OpenAI, Telegram на месте), SOUL.md (характер бота), память и скиллы. Поиск Perplexity протестировал в одну строку — вернул свежие новости со ссылками. Живой.


Шаг 6. История переписки (это отдельный квест)

claw migrate переносит всё, кроме истории чатов. А мне хотелось сохранить полтора года диалогов с реальными датами.

OpenClaw хранит сессии как .jsonl-логи (по событию на строку). Hermes — в SQLite (~/.hermes/state.db) с полнотекстовым поиском. Форматы разные → нужна конвертация. Написал маленький скрипт, который:

  • парсит каждый .jsonl (первая строка — session, дальше message/toolResult);

  • пропускает служебные события и *.checkpoint.*;

  • делает прямой INSERT в state.db, сохраняя реальные epoch-таймстемпы (а не now());

  • полнотекстовые триггеры синхронизируются сами.

Прогнал сначала на копии базы, проверил PRAGMA integrity_check, и только потом — на боевой, при остановленном gateway. Итог: 16 сессий, 9 315 сообщений, реальные даты, поиск работает.


Шаг 7. Запускаем бота (и снова интерактив против нас)

hermes gateway install --system --run-as-user root
systemctl enable --now hermes-gateway
hermes gateway status

🔴 Грабля №9. hermes gateway install под root отказывается ставить системный сервис без флага --run-as-user root. А ещё установщик задаёт несколько Y/N-вопросов подряд — а я гонял команды не из TTY. Решение: либо yes | hermes gateway install ..., либо поставить юнит и поднять его напрямую через systemctl enable --now hermes-gateway.

И вот он — первый ответ нового бота в Telegram. Персонаж жив, память на месте. Можно выдыхать… но мы же ещё не подключили половину фишек.


Шаг 8. Голос

Голосовые я слушаю локальным faster-whisper. Он доустанавливается сам при первом голосовом. Один нюанс:

hermes config set stt.local.language ru   # фиксируем язык — не тратим время на авто-детект

🔴 Грабля №10. Первое голосовое обрабатывается ощутимо дольше — модель качается и грузится. Это разово. А фиксация языка убирает лишние полторы секунды на каждом сообщении.


Шаг 9. Google: почта, календарь, диск

Самая интерактивная часть — OAuth. Здесь Hermes молодец: есть встроенный скилл google-workspace. Но Google в 2026-м подкинул сюрпризов.

pip install --break-system-packages google-api-python-client google-auth-oauthlib google-auth-httplib2
GW=~/.hermes/skills/productivity/google-workspace
python3 $GW/scripts/setup.py --client-secret /root/.hermes/google_client_secret.json
python3 $GW/scripts/setup.py --auth-url          # ссылку открываем в браузере, даём согласие
python3 $GW/scripts/setup.py --auth-code '4/0A...'
python3 $GW/scripts/setup.py --check             # AUTHENTICATED

🔴 Грабля №11 — Google образца 2026:

  • Cloud Console заблокирован, пока на аккаунте бота не включена двухэтапная аутентификация (2SV). Включается только вручную, с телефоном.

  • Client secret больше нельзя скачать или посмотреть повторно. На Desktop-клиенте жмёшь «+ Add secret», копируешь сразу (показывается один раз) и собираешь client_secret.json руками.

  • Drive API включается отдельно. Gmail и Calendar у меня уже были включены, а Drive — нет, и он отвечал 403 accessNotConfigured, пока я не включил его в библиотеке API.

  • Аккаунт бота должен быть в Test users, иначе согласие не пройдёт.

  • После согласия браузер уйдёт на http://localhost:1 и не загрузится — это нормально, забираем code из адресной строки.

Проверка, что всё ожило:

python3 $GW/scripts/google_api.py gmail search "in:inbox" --max 2
python3 $GW/scripts/google_api.py calendar list
python3 $GW/scripts/google_api.py drive search "" --max 5

Почта вернула реальные письма, календарь и диск — ответили. Победа.


Шаг 10. Картинки: генерация и анализ

Хотел, чтобы бот и рисовал, и понимал фото. С пониманием фото оказалось проще всего — основная модель gpt-5.4-mini мультимодальная, фото она видит из коробки. А вот генерация…

hermes plugins enable image_gen/openai
hermes tools enable image_gen
hermes config set image_gen.provider openai      # ← без этого «backend не настроен»
hermes config set image_gen.model gpt-image-2

🔴 Грабля №12. Включить плагин мало — Hermes по умолчанию ждёт ключ FAL. Нужно явно назначить активного провайдера: image_gen.provider openai.

Попросил бота: «нарисуй кота-космонавта в стиле акварели». Бот гордо ответил «Вот оно:» — и не прислал ничего. Сгенерировал, но не доставил.

🔴 Грабля №13 — самая коварная. gpt-image-2 сохраняет картинку в /root/.hermes/cache/images/. А Telegram-адаптер по умолчанию не имеет этот каталог в белом списке доставки файлов (там есть cache/videos, cache/documents, screenshots, но не images). В логах честно: Skipping unsafe local file path outside allowed roots. Лечится одной строкой в .env:

echo 'HERMES_MEDIA_ALLOW_DIRS=/root/.hermes/cache/images:/root/hermes-workspace' >> /root/.hermes/.env

После этого кот-космонавт долетел. И, не скрою, вышел шикарный (он же — КДПВ в начале статьи).

Бонусом я добавил в AGENTS.md правило авто-улучшения промта: когда просишь «нарисуй кота» — бот молча превращает это в детальный английский промпт (стиль, свет, композиция, аспект) и уже им генерирует. Качество подскочило заметно.


Шаг 11. Файлы: PDF, DOCX, XLSX и все остальные

У Hermes есть встроенные скиллы file, nano-pdf, ocr-and-documents, но без библиотек и конвертеров с документами всерьёз не поработаешь. Поставил полный тулчейн:

DEBIAN_FRONTEND=noninteractive apt-get install -y 
  poppler-utils tesseract-ocr tesseract-ocr-rus pandoc antiword catdoc unrtf 
  libreoffice-writer libreoffice-calc libreoffice-impress
pip install --break-system-packages pypdf pdfplumber python-docx openpyxl pandas 
  python-pptx markdown beautifulsoup4 tabulate lxml xlrd Pillow

После этого агент уверенно работает с:

  • PDF — чтение (pdftotext/pdfplumber/pypdf), сканы → текст через OCR (tesseract);

  • DOCX/DOCpython-docx, antiword, конвертация через LibreOffice;

  • XLSX/XLS/CSV/таблицыpandas + openpyxl;

  • PPTXpython-pptx; HTMLbs4; любая конвертация — pandoc или soffice --headless.

Перезапуск не нужен — агент берёт библиотеки сразу.


Шаг 12. Сайт-витрина (бонус)

У моего бота есть публичная страничка-визитка, которую он сам обновляет. Механизм гениально простой: что агент записал в /var/www/<домен>, то и появилось на сайте — отдаёт Caddy, сертификат Let’s Encrypt он выпускает сам.

apt install -y caddy
# /etc/caddy/Caddyfile:
#   { email you@example.com }
#   example.com { root * /var/www/example.com; file_server; encode gzip }
systemctl reload caddy

Дальше меняем A-запись домена на новый IP — и всё.

🔴 Грабля №14 — DNS и сертификат. Caddy выпустит сертификат только когда DNS уже указывает на новый сервер. Старый TTL держит кэш у центра сертификации → ACME-проверка ещё стучится на старый IP и падает (tls internal error). Лечение: понизить TTL (300), дождаться распространения, при необходимости systemctl restart caddy, чтобы форсировать свежую попытку. Сайт при этом всё время живой — его пока отдаёт старый сервер, даунтайма нет.


Бонус-грабля, которую я заслужил

🔴 Грабля №15. Я попросил бота сгенерировать картинку — и пока он рисовал, перезапустил gateway ради мелкой правки конфига. Генерация оборвалась. Мораль простая и обидная: не перезапускайте агента, пока у него выполняется задача. Сначала убедись, что он ничего не делает.


Чек-лист приёмки

Прежде чем гасить старый сервер — прогоните:

  • [ ] hermes -z "PONG" → PONG (значит, провайдер OpenAI, а не OpenRouter).

  • [ ] Бот отвечает в Telegram, allowlist на месте.

  • [ ] Память и персона живые; история переписки читается, поиск работает.

  • [ ] Голосовое распознаётся; картинка генерится и приходит как фото.

  • [ ] Google: почта/календарь/диск отвечают. Perplexity ищет.

  • [ ] Файлы: PDF/DOCX/XLSX/CSV/PPTX читаются и создаются; OCR и конвертация работают.

  • [ ] Сутки наблюдения за памятью без OOM.

Когда всё зелёное — старый сервер можно остановить (но не удалять ещё недельку).


Итог

Переезд оказался не «вечерком», а полноценным днём — но в основном из-за пятнадцати мелких граблей, каждая из которых лечится одной-двумя строками. Сам по себе Hermes встал ровно: архитектура близка к OpenClaw, нативная миграция тянет 80% данных, остальное — аккуратные ручные шаги.

Что я получил в итоге: своего ИИ-агента на своём сервере, который отвечает в Telegram, помнит всю историю, ходит в Google и Perplexity, слушает голос, рисует картинки, читает PDF/Excel/Word и сам обновляет свой сайт. И всё это — на дешёвой модели, без привязки к вендору, с открытой дверью к локалке.

Если будете повторять — держите рядом список граблей. Они сэкономят вам половину дня и один нервный перезапуск.

P.S. А кота-космонавта бот всё-таки дорисовал. И знаете — оно того стоило.


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

Автор: AMLAI

Источник