Всё вышеперечисленное, плюс постоянный Ubuntu-контейнер, где агент может выполнять apt/pip/npm install
info Что отличается от стандартной установки
Установщик curl | bash сам управляет Python, Node и зависимостями. Nix flake заменяет всё это — каждая Python-зависимость является Nix-производной, построенной с помощью uv2nix, а инструменты времени выполнения (Node.js, git, ripgrep, ffmpeg) включены в PATH бинарника. Нет pip во время выполнения, нет активации venv, нет npm install.
Для пользователей не-NixOS это меняет только шаг установки. Всё остальное (hermes setup, hermes gateway install, редактирование конфигурации) работает идентично стандартной установке.
Для пользователей NixOS-модуля весь жизненный цикл отличается: конфигурация находится в configuration.nix, секреты проходят через sops-nix/agenix, сервис является systemd-юнитом, а CLI-команды конфигурации заблокированы. Вы управляете hermes так же, как управляете любым другим NixOS-сервисом.
Предварительные требования
Nix с включёнными flakes — рекомендуется Determinate Nix (включает flakes по умолчанию)
API-ключи для сервисов, которые вы хотите использовать (как минимум: ключ OpenRouter или Anthropic)
Быстрый старт (любой пользователь Nix)
Клонирование не требуется. Nix загружает, собирает и запускает всё:
# Запуск напрямую (сборка при первом использовании, затем кэшируется)
nixrungithub:NousResearch/hermes-agent--setup
nixrungithub:NousResearch/hermes-agent--chat
# Или установить постоянно
nixprofileinstallgithub:NousResearch/hermes-agent
hermessetup
hermeschat
После nix profile install, hermes, hermes-agent и hermes-acp оказываются в вашем PATH. Отсюда воркфлоу идентичен стандартной установке — hermes setup проведёт вас через выбор провайдера, hermes gateway install настраивает launchd (macOS) или systemd user-сервис, а конфигурация хранится в ~/.hermes/.
Этот модуль требует NixOS. Для систем без NixOS (macOS, другие дистрибутивы Linux) используйте `nix profile install` и стандартный CLI-воркфлоу, описанный выше.
Вот и всё. nixos-rebuild switch создаёт пользователя hermes, генерирует config.yaml, подключает секреты и запускает gateway — долго работающий сервис, который соединяет агента с мессенджерами (Telegram, Discord и др.) и слушает входящие сообщения.
warning Требуются секреты
Строка environmentFiles выше предполагает, что у вас настроен sops-nix или agenix. Файл должен содержать как минимум один ключ LLM-провайдера (например, OPENROUTER_API_KEY=sk-or-...). Смотрите Управление секретами для полной настройки. Если у вас ещё нет менеджера секретов, вы можете использовать обычный файл в качестве отправной точки — просто убедитесь, что он не доступен для чтения всем:
tip addToSystemPackages
Установка addToSystemPackages = true делает две вещи: помещает CLI hermes в системный PATH и устанавливает HERMES_HOME общесистемно, чтобы интерактивный CLI разделял состояние (сессии, навыки, cron) с gateway-сервисом. Без этого запуск hermes в вашей оболочке создаст отдельный каталог ~/.hermes/.
CLI с поддержкой контейнера
Когда `container.enable = true` и `addToSystemPackages = true`, **каждая** команда `hermes` на хосте автоматически направляется в управляемый контейнер. Это означает, что ваша интерактивная CLI-сессия работает внутри того же окружения, что и gateway-сервис — с доступом ко всем установленным в контейнере пакетам и инструментам.
- Маршрутизация прозрачна: `hermes chat`, `hermes sessions list`, `hermes version` и т.д. все выполняются внутри контейнера
- Все CLI-флаги передаются как есть
- Если контейнер не запущен, CLI делает несколько попыток (5 с со спиннером для интерактивного использования, 10 с без вывода для скриптов), затем завершается с понятной ошибкой — без скрытого отката
- Для разработчиков, работающих над кодом hermes, установите `HERMES_DEV=1`, чтобы обойти маршрутизацию в контейнер и запускать локальную копию напрямую
Установите `container.hostUsers`, чтобы создать симлинк `~/.hermes` на каталог состояния сервиса, чтобы CLI хоста и контейнер разделяли сессии, конфигурацию и воспоминания:
Пользователи, перечисленные в `hostUsers`, автоматически добавляются в группу `hermes` для доступа к файловым разрешениям.
**Пользователи Podman:** NixOS-сервис запускает контейнер от root. Пользователи Docker получают доступ через сокет группы `docker`, но rootful-контейнеры Podman требуют sudo. Предоставьте sudo без пароля для вашей среды выполнения контейнеров:
CLI автоматически определяет, когда нужен sudo, и использует его прозрачно. Без этого вам придётся запускать `sudo hermes chat` вручную.
Проверка работоспособности
После nixos-rebuild switch проверьте, что сервис работает:
# Проверка статуса сервиса
systemctlstatushermes-agent
# Просмотр логов (Ctrl+C для остановки)
journalctl-uhermes-agent-f
# Если addToSystemPackages = true, проверьте CLI
hermesversion
hermesconfig# показывает сгенерированную конфигурацию
Выбор режима развёртывания
Модуль поддерживает два режима, управляемых через container.enable:
Нативный (по умолчанию)
Контейнер
Как работает
Защищённый systemd-сервис на хосте
Постоянный Ubuntu-контейнер с /nix/store примонтированным bind-mount
Безопасность
NoNewPrivileges, ProtectSystem=strict, PrivateTmp
Изоляция контейнера, запуск от непривилегированного пользователя внутри
Агент может сам устанавливать пакеты
Нет — только инструменты на PATH, предоставленном Nix
Да — установки apt, pip, npm сохраняются между перезапусками
Режим контейнера автоматически включает `virtualisation.docker.enable` через `mkDefault`. Если вы используете Podman, установите `container.backend = "podman"` и `virtualisation.docker.enable = false`.
Конфигурация
Декларативные настройки
Опция settings принимает произвольный attrset, который преобразуется в config.yaml. Она поддерживает глубокое слияние (deep merge) между несколькими определениями модулей (через lib.recursiveUpdate), так что вы можете разделять конфигурацию по файлам:
Оба объединяются глубоким слиянием на этапе оценки. Ключи, объявленные в Nix, всегда побеждают ключи в существующем config.yaml на диске, но ключи, добавленные пользователем, к которым Nix не прикасается, сохраняются. Это означает, что если агент или ручное редактирование добавляет ключи вроде skills.disabled или streaming.enabled, они переживают nixos-rebuild switch.
note Именование моделей
settings.model.default использует идентификатор модели, который ожидает ваш провайдер. С OpenRouter (по умолчанию) они выглядят как "anthropic/claude-sonnet-4" или "google/gemini-3-flash". Если вы используете провайдера напрямую (Anthropic, OpenAI), установите settings.model.base_url на их API и используйте их нативные идентификаторы моделей (например, "claude-sonnet-4-20250514"). Если base_url не установлен, Hermes по умолчанию использует OpenRouter.
tip Обнаружение доступных ключей конфигурации
Запустите nix build .#configKeys && cat result, чтобы увидеть каждый листовой ключ конфигурации, извлечённый из Python-DEFAULT_CONFIG. Вы можете вставить ваш существующий config.yaml в attrset settings — структура отображается 1:1.
danger Никогда не помещайте API-ключи в settings или environment
Значения в Nix-выражениях попадают в /nix/store, который доступен для чтения всем. Всегда используйте environmentFiles с менеджером секретов.
И environment (несекретные переменные), и environmentFiles (файлы с секретами) объединяются в $HERMES_HOME/.env во время активации (nixos-rebuild switch). Hermes читает этот файл при каждом запуске, поэтому изменения вступают в силу после systemctl restart hermes-agent — пересоздание контейнера не требуется.
Для платформ, требующих OAuth (например, Discord), используйте authFile для начального внесения учётных данных при первом развёртывании:
{
services.hermes-agent={authFile= config.sops.secrets."hermes/auth.json".path;# authFileForceOverwrite = true; # перезаписывать при каждой активации};}
Файл копируется только если auth.json ещё не существует (если authFileForceOverwrite = true не установлен). Обновления OAuth-токенов во время выполнения записываются в каталог состояния и сохраняются между пересборками.
Документы
Опция documents устанавливает файлы в рабочую директорию агента (рабочая директория, которую агент читает как своё рабочее пространство). Hermes ищет определённые имена файлов по соглашению:
USER.md — контекст о пользователе, с которым взаимодействует агент.
Любые другие файлы, которые вы сюда помещаете, видны агенту как файлы рабочего пространства.
Файл идентичности агента отдельный: Hermes загружает свой основной SOUL.md из $HERMES_HOME/SOUL.md, который в NixOS-модуле находится в ${services.hermes-agent.stateDir}/.hermes/SOUL.md. Помещение SOUL.md в documents создаёт только файл рабочего пространства и не заменит основной файл персоны.
{
services.hermes-agent.documents={"USER.md"=./documents/USER.md;# ссылка на путь, копируется из Nix store};}
Значения могут быть inline-строками или ссылками на пути. Файлы устанавливаются при каждом nixos-rebuild switch.
MCP-серверы
Опция mcpServers декларативно настраивает MCP (Model Context Protocol) серверы. Каждый сервер использует либо stdio (локальная команда), либо HTTP (удалённый URL) транспорт.
Транспорт Stdio (локальные серверы)
{
services.hermes-agent.mcpServers={filesystem={command="npx";args=["-y""@modelcontextprotocol/server-filesystem""/data/workspace"];};github={command="npx";args=["-y""@modelcontextprotocol/server-github"];
env.GITHUB_PERSONAL_ACCESS_TOKEN="\\${GITHUB_TOKEN}";# берётся из .env};};}
Переменные окружения в значениях `env` извлекаются из `$HERMES_HOME/.env` во время выполнения. Используйте `environmentFiles` для внесения секретов — никогда не помещайте токены напрямую в Nix-конфигурацию.
Токены хранятся в $HERMES_HOME/mcp-tokens/<имя-сервера>.json и сохраняются между перезапусками и пересборками.
Первоначальная OAuth-авторизация на серверах без головы (headless)
Первая OAuth-авторизация требует браузерного потока согласия. При headless-развёртывании Hermes выводит URL авторизации в stdout/логи вместо открытия браузера.
**Вариант A: Интерактивная начальная настройка** — выполните поток один раз через `docker exec` (контейнер) или `sudo -u hermes` (нативный режим):
# Режим контейнера
dockerexec-ithermes-agent\\hermesmcpaddmy-oauth-server--urlhttps://mcp.example.com/mcp--authoauth
# Нативный режим
sudo-uhermesHERMES_HOME=/var/lib/hermes/.hermes\\hermesmcpaddmy-oauth-server--urlhttps://mcp.example.com/mcp--authoauth
Контейнер использует `--network=host`, поэтому OAuth callback-слушатель на `127.0.0.1` доступен из браузера хоста.
**Вариант B: Предварительное внесение токенов** — выполните поток на рабочей станции, затем скопируйте токены:
Файл-маркер .managed в HERMES_HOME — устанавливается скриптом активации, виден интерактивным оболочкам (например, docker exec -it hermes-agent hermes config set ... тоже заблокирован)
Чтобы изменить конфигурацию, отредактируйте вашу Nix-конфигурацию и выполните sudo nixos-rebuild switch.
Архитектура контейнера
Этот раздел актуален только если вы используете `container.enable = true`. Пропустите его для развёртываний в нативном режиме.
Когда режим контейнера включён, hermes работает внутри постоянного Ubuntu-контейнера, при этом бинарник, собранный Nix, примонтирован read-only с хоста:
Бинарник, собранный Nix, работает внутри Ubuntu-контейнера, потому что /nix/store примонтирован bind-mount — он несёт собственный интерпретатор и все зависимости, поэтому нет зависимости от системных библиотек контейнера. Точка входа контейнера разрешается через симлинк current-package: /data/current-package/bin/hermes gateway run --replace. При nixos-rebuild switch обновляется только симлинк — контейнер продолжает работать.
Что сохраняется при каких событиях
Событие
Контейнер пересоздан?
/data (состояние)
/home/hermes
Слой записи (apt/pip/npm)
systemctl restart hermes-agent
Нет
Сохраняется
Сохраняется
Сохраняется
nixos-rebuild switch (изменение кода)
Нет (симлинк обновлён)
Сохраняется
Сохраняется
Сохраняется
Перезагрузка хоста
Нет
Сохраняется
Сохраняется
Сохраняется
nix-collect-garbage
Нет (GC root)
Сохраняется
Сохраняется
Сохраняется
Изменение образа (container.image)
Да
Сохраняется
Сохраняется
Теряется
Изменение томов/опций
Да
Сохраняется
Сохраняется
Теряется
Изменение environment/environmentFiles
Нет
Сохраняется
Сохраняется
Сохраняется
Контейнер пересоздаётся только когда изменяется его identity hash. Хеш включает: версию схемы, образ, extraVolumes, extraOptions и скрипт entrypoint. Изменения переменных окружения, настроек, документов или самого пакета hermes не вызывают пересоздание.
warning Потеря слоя записи
Когда изменяется identity hash (апгрейд образа, новые тома, новые опции контейнера), контейнер уничтожается и создаётся заново из свежего образа container.image. Все пакеты apt install, pip install или npm install в слое записи теряются. Состояние в /data и /home/hermes сохраняется (это bind-mounts).
Если агент полагается на определённые пакеты, рассмотрите возможность включения их в пользовательский образ (container.image = "my-registry/hermes-base:latest") или прописывания их установки в SOUL.md агента.
Защита GC Root
Скрипт preStart создаёт GC root в ${stateDir}/.gc-root, указывающий на текущий пакет hermes. Это предотвращает удаление работающего бинарника командой nix-collect-garbage. Если GC root по какой-то причине сломается, перезапуск сервиса воссоздаст его.
Плагины
NixOS-модуль поддерживает декларативную установку плагинов — императивный hermes plugins install не требуется.
Директориальные плагины (extraPlugins)
Для плагинов, которые представляют собой просто дерево исходников с plugin.yaml + __init__.py (например, hermes-lcm):
Плагины симлинкуются в $HERMES_HOME/plugins/ во время активации. Hermes обнаруживает их через обычное сканирование каталогов. Удаление плагина из списка и запуск nixos-rebuild switch удаляет симлинк.
Entry-point плагины (extraPythonPackages)
Для pip-пакетированных плагинов, которые регистрируются через [project.entry-points."hermes_agent.plugins"] (например, rtk-hermes):
Проверка коллизий во время сборки предотвращает перекрытие пакетов плагинов с основными зависимостями hermes. Если плагин предоставляет пакет, который уже есть в изолированном venv, `nixos-rebuild` завершится с понятной ошибкой.
Разработка
Dev Shell (оболочка разработчика)
Flake предоставляет оболочку разработчика с Python 3.12, uv, Node.js и всеми инструментами времени выполнения:
cdhermes-agent
nixdevelop
# Оболочка предоставляет:# - Python 3.12 + uv (зависимости устанавливаются в .venv при первом входе)# - Node.js 22, ripgrep, git, openssh, ffmpeg на PATH# - Stamp-file оптимизация: повторный вход почти мгновенный, если зависимости не изменились
hermessetup
hermeschat
cdhermes-agent
direnvallow# однократно# Последующие входы почти мгновенные (stamp file пропускает установку зависимостей)
Проверки Flake
Flake включает проверки во время сборки, которые выполняются в CI и локально:
# Запустить все проверки
nixflakecheck
# Отдельные проверки
nixbuild.#checks.x86_64-linux.package-contents# бинарники существуют + версия
nixbuild.#checks.x86_64-linux.entry-points-sync# синхронизация pyproject.toml ↔ Nix package
nixbuild.#checks.x86_64-linux.cli-commands# подкоманды gateway/config
nixbuild.#checks.x86_64-linux.managed-guard# HERMES_MANAGED блокирует мутации
nixbuild.#checks.x86_64-linux.bundled-skills# навыки присутствуют в пакете
nixbuild.#checks.x86_64-linux.config-roundtrip# скрипт слияния сохраняет ключи пользователя
Что проверяет каждая проверка
| Проверка | Что тестирует |
|---|---|
| `package-contents` | Бинарники `hermes` и `hermes-agent` существуют, `hermes version` работает |
| `entry-points-sync` | Каждая запись `[project.scripts]` в `pyproject.toml` имеет обёрнутый бинарник в Nix-пакете |
| `cli-commands` | `hermes --help` показывает подкоманды `gateway` и `config` |
| `managed-guard` | `HERMES_MANAGED=true hermes config set ...` выводит ошибку NixOS |
| `bundled-skills` | Каталог навыков существует, содержит файлы SKILL.md, `HERMES_BUNDLED_SKILLS` установлен в обёртке |
| `config-roundtrip` | 7 сценариев слияния: чистая установка, переопределение Nix, сохранение ключей пользователя, смешанное слияние, аддитивное слияние MCP, вложенное глубокое слияние, идемпотентность |
Справочник опций
Основные
Опция
Тип
По умолчанию
Описание
enable
bool
false
Включить сервис hermes-agent
package
package
hermes-agent
Пакет hermes-agent для использования
user
str
"hermes"
Системный пользователь
group
str
"hermes"
Системная группа
createUser
bool
true
Автоматически создавать пользователя/группу
stateDir
str
"/var/lib/hermes"
Каталог состояния (родительский для HERMES_HOME)
workingDirectory
str
"${stateDir}/workspace"
Рабочая директория агента (MESSAGING_CWD)
addToSystemPackages
bool
false
Добавить CLI hermes в системный PATH и установить HERMES_HOME общесистемно
Конфигурация
Опция
Тип
По умолчанию
Описание
settings
attrs (глубокое слияние)
{}
Декларативная конфигурация, преобразуемая в config.yaml. Поддерживает произвольную вложенность; множественные определения объединяются через lib.recursiveUpdate
configFile
null или path
null
Путь к существующему config.yaml. Полностью переопределяет settings если установлен
Секреты и окружение
Опция
Тип
По умолчанию
Описание
environmentFiles
listOf str
[]
Пути к файлам окружения с секретами. Объединяются в $HERMES_HOME/.env при активации
environment
attrsOf str
{}
Несекретные переменные окружения. Видимы в Nix store — не помещайте сюда секреты
authFile
null или path
null
Начальное внесение OAuth-учётных данных. Копируется только при первом развёртывании
authFileForceOverwrite
bool
false
Всегда перезаписывать auth.json из authFile при активации
Документы
Опция
Тип
По умолчанию
Описание
documents
attrsOf (either str path)
{}
Файлы рабочего пространства. Ключи — имена файлов, значения — inline-строки или пути. Устанавливаются в workingDirectory при активации
MCP-серверы
Опция
Тип
По умолчанию
Описание
mcpServers
attrsOf submodule
{}
Определения MCP-серверов, объединяемые в settings.mcp_servers
Метод аутентификации. "oauth" включает OAuth 2.1 PKCE
mcpServers.<name>.enabled
bool
true
Включить или отключить этот сервер
mcpServers.<name>.timeout
null или int
null
Тайм-аут вызова инструмента в секундах (по умолчанию: 120)
mcpServers.<name>.connect_timeout
null или int
null
Тайм-аут подключения в секундах (по умолчанию: 60)
mcpServers.<name>.tools
null или submodule
null
Фильтрация инструментов (списки include/exclude)
mcpServers.<name>.sampling
null или submodule
null
Конфигурация сэмплинга для LLM-запросов от сервера
Поведение сервиса
Опция
Тип
По умолчанию
Описание
extraArgs
listOf str
[]
Дополнительные аргументы для hermes gateway
extraPackages
listOf package
[]
Дополнительные пакеты, доступные агенту. Добавляются в per-user профиль пользователя hermes, так что терминальные команды, навыки и cron-задачи видят их
extraPlugins
listOf package
[]
Директориальные пакеты плагинов для симлинкования в $HERMES_HOME/plugins/. Каждый должен содержать plugin.yaml
extraPythonPackages
listOf package
[]
Python-пакеты, добавляемые в PYTHONPATH для обнаружения entry-point плагинов. Собирайте с помощью python312Packages
restart
str
"always"
Политика systemd Restart=
restartSec
int
5
Значение systemd RestartSec=
Контейнер
Опция
Тип
По умолчанию
Описание
container.enable
bool
false
Включить режим OCI-контейнера
container.backend
enum ["docker" "podman"]
"docker"
Среда выполнения контейнера
container.image
str
"ubuntu:24.04"
Базовый образ (загружается во время выполнения)
container.extraVolumes
listOf str
[]
Дополнительные монтирования томов (хост:контейнер:режим)
container.extraOptions
listOf str
[]
Дополнительные аргументы, передаваемые в docker create
container.hostUsers
listOf str
[]
Интерактивные пользователи, получающие симлинк ~/.hermes на служебный stateDir и автоматически добавляемые в группу hermes
Структура каталогов
Нативный режим
/var/lib/hermes/# stateDir (владелец hermes:hermes, 0750)├──.hermes/# HERMES_HOME│├──config.yaml# Сгенерировано Nix (глубокое слияние при каждой пересборке)│├──.managed# Маркер: мутация CLI-конфигурации заблокирована│├──.env# Объединено из environment + environmentFiles│├──auth.json# OAuth-учётные данные (внесены, затем самоуправляемы)│├──gateway.pid│├──state.db│├──mcp-tokens/# OAuth-токены для MCP-серверов│├──sessions/│├──memories/│├──skills/│├──cron/│└──logs/├──home/# HOME агента└──workspace/# MESSAGING_CWD├──SOUL.md# Из опции documents└──(файлысозданныеагентом)
Режим контейнера
Та же структура, смонтированная в контейнер:
Путь в контейнере
Путь на хосте
Режим
Примечания
/nix/store
/nix/store
ro
Бинарник Hermes + все Nix-зависимости
/data
/var/lib/hermes
rw
Всё состояние, конфигурация, рабочее пространство
/home/hermes
${stateDir}/home
rw
Постоянный HOME агента — pip install --user, кэши инструментов
/usr, /usr/local, /tmp
(слой записи)
rw
Установки apt/pip/npm — сохраняются между перезапусками, теряются при пересоздании
В режиме контейнера симлинк current-package обновляется, и агент подхватывает новый бинарник при перезапуске. Без пересоздания контейнера, без потери установленных пакетов.
Устранение неполадок
tip Пользователи Podman
Все команды docker ниже работают так же с podman. Заменяйте соответствующим образом, если вы установили container.backend = "podman".
Логи сервиса
# Оба режима используют один и тот же systemd-юнит
journalctl-uhermes-agent-f
# Режим контейнера: также доступно напрямую
dockerlogs-fhermes-agent