- BrainTools - https://www.braintools.ru -

Как я «переезжал» своего ИИ-агента с OpenClaw на Hermes и собрал все грабли (чтобы Вы не собирали)

Формат: туториал + личный опыт [1]. Сложность: средняя. Время чтения: ~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. Растёт со временем. Персистентная память [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 — конфликт [3] токена. У 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 и сам обновляет свой сайт. И всё это — на дешёвой модели, без привязки к вендору, с открытой дверью к локалке.

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

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


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

Автор: AMLAI

Источник [5]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/31388

URLs in this post:

[1] опыт: http://www.braintools.ru/article/6952

[2] память: http://www.braintools.ru/article/4140

[3] конфликт: http://www.braintools.ru/article/7708

[4] повторять: http://www.braintools.ru/article/4012

[5] Источник: https://habr.com/ru/articles/1044574/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1044574

www.BrainTools.ru

Rambler's Top100