sidebar_position: 3 title: "Nix & NixOS Setup" description: "Install and deploy Hermes Agent with Nix — from quick nix run to fully declarative NixOS module with container mode" lang: ru


Настройка Nix и NixOS

Агент Hermes поставляет версию Nix с тремя уровнями интеграции:

Уровень Для кого это Что вы получаете
nix run / nix profile install Любой пользователь Nix (macOS, Linux) Предварительно созданный двоичный файл со всеми параметрами — затем используйте стандартный рабочий процесс CLI
Модуль NixOS (родной) Развертывание серверов NixOS Декларативная конфигурация, усиленная служба systemd, управляемые секреты
Модуль NixOS (контейнер) Агенты, нуждающиеся в самомодификации Все вышеперечисленное, а также постоянный контейнер Ubuntu, где агент может apt/pip/npm install

ℹ️ Info

Чем отличается стандартная установка Установщик `curl | bash` сам управляет Python, Node и зависимостями. Все это заменяет флейк Nix — каждая зависимость Python является производным от Nix, созданным [uv2nix](https://github.com/pyproject-nix/uv2nix), а инструменты времени выполнения (Node.js, git, ripgrep, ffmpeg) заключены в PATH двоичного файла. Нет ни пакета времени выполнения, ни активации venv, ни `npm install`. **Для пользователей, отличных от NixOS**, это меняет только этап установки. Все после (`hermes setup`, `hermes gateway install`, редактирования конфигурации) работает идентично стандартной установке. **Для пользователей модуля NixOS** весь жизненный цикл отличается: конфигурация находится в `configuration.nix`, секреты проходят через sops-nix/agenix, служба является модулем systemd, а команды конфигурации CLI блокируются. Вы управляете Hermes так же, как и любой другой службой NixOS.

Предварительные условия


Быстрый старт (любой пользователь Nix)

Клон не нужен. Nix извлекает, собирает и запускает все:

# Run directly (builds on first use, cached after)
nix run github:NousResearch/hermes-agent -- setup
nix run github:NousResearch/hermes-agent -- chat

# Or install persistently
nix profile install github:NousResearch/hermes-agent
hermes setup
hermes chat

После того, как nix profile install, hermes, hermes-agent и hermes-acp находятся в вашем PATH. Отсюда рабочий процесс идентичен стандартной установкеhermes setup помогает вам выбрать поставщика, hermes gateway install настраивает пользовательскую службу launchd (macOS) или systemd, а конфигурация находится в ~/.hermes/.

<подробности>

Сборка из локального клона
git clone https://github.com/NousResearch/hermes-agent.git
cd hermes-agent
nix build
./result/bin/hermes setup

</подробнее>


Модуль NixOS

Флейк экспортирует nixosModules.default — полноценный сервисный модуль NixOS, который декларативно управляет созданием пользователей, каталогами, генерацией конфигурации, секретами, документами и жизненным циклом службы.

:::примечание Для этого модуля требуется NixOS. Для систем, отличных от NixOS (macOS, другие дистрибутивы Linux), используйте nix profile install и стандартный рабочий процесс CLI, описанный выше.

Добавляем входные данные Flake

# /etc/nixos/flake.nix (or your system flake)
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    hermes-agent.url = "github:NousResearch/hermes-agent";
  };

  outputs = { nixpkgs, hermes-agent, ... }: {
    nixosConfigurations.your-host = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        hermes-agent.nixosModules.default
        ./configuration.nix
      ];
    };
  };
}

Минимальная конфигурация

# configuration.nix
{ config, ... }: {
  services.hermes-agent = {
    enable = true;
    settings.model.default = "anthropic/claude-sonnet-4";
    environmentFiles = [ config.sops.secrets."hermes-env".path ];
    addToSystemPackages = true;
  };
}

Вот и все. nixos-rebuild switch создает пользователя hermes, генерирует config.yaml, подключает секреты и запускает шлюз — долгоработающую службу, которая подключает агента к платформам обмена сообщениями (Telegram, Discord и т. д.) и прослушивает входящие сообщения.

:::предупреждение Требуются секреты Строка environmentFiles выше предполагает, что у вас настроен sops-nix или agenix. Файл должен содержать хотя бы один ключ поставщика LLM (например, OPENROUTER_API_KEY=sk-or-...). См. Управление секретами для полной настройки. Если у вас еще нет менеджера секретов, вы можете использовать простой файл в качестве отправной точки — просто убедитесь, что он не доступен для чтения всем:

echo "OPENROUTER_API_KEY=sk-or-your-key" | sudo install -m 0600 -o hermes /dev/stdin /var/lib/hermes/env
services.hermes-agent.environmentFiles = [ "/var/lib/hermes/env" ];

:::совет addToSystemPackages Установка addToSystemPackages = true делает две вещи: помещает hermes CLI в PATH вашей системы и устанавливает HERMES_HOME для всей системы, чтобы интерактивный CLI делился состоянием (сессии, навыки, cron) со службой шлюза. Без него запуск hermes в вашей оболочке создаст отдельный каталог ~/.hermes/.

ℹ️ Info

Интерфейс командной строки с поддержкой контейнеров Когда `container.enable = true` и `addToSystemPackages = true`, **каждая** команда `hermes` на хосте автоматически направляется в управляемый контейнер. Это означает, что ваш интерактивный сеанс CLI выполняется в той же среде, что и служба шлюза, с доступом ко всем пакетам и инструментам, установленным в контейнере. - Маршрутизация прозрачна: `hermes chat`, `hermes sessions list`, `hermes version` и т. д. все выполняется в контейнере под капотом. - Все флаги CLI пересылаются как есть. - Если контейнер не запущен, CLI кратковременно повторяет попытку (5 секунд со счетчиком для интерактивного использования, 10 секунд в автоматическом режиме для сценариев), а затем завершается с ошибкой — без автоматического возврата - Для разработчиков, работающих с кодовой базой Hermes, установите `HERMES_DEV=1`, чтобы обойти маршрутизацию контейнера и запустить локальную проверку напрямую. Задайте `container.hostUsers`, чтобы создать символическую ссылку `~/.hermes` на каталог состояния службы, чтобы CLI хоста и контейнер совместно использовали сеансы, конфигурацию и память:
services.hermes-agent = {
  container.enable = true;
  container.hostUsers = [ "your-username" ];
  addToSystemPackages = true;
};
Пользователи, перечисленные в `hostUsers`, автоматически добавляются в группу `hermes` для доступа к файлам. **Пользователи Podman:** Служба NixOS запускает контейнер от имени пользователя root. Пользователи Docker получают доступ через групповой сокет `docker`, но корневые контейнеры Podman требуют sudo. Предоставьте sudo без пароля для среды выполнения вашего контейнера:
security.sudo.extraRules = [{
  users = [ "your-username" ];
  commands = [{
    command = "/run/current-system/sw/bin/podman";
    options = [ "NOPASSWD" ];
  }];
}];
CLI автоматически определяет, когда требуется sudo, и использует его прозрачно. Без этого вам придется запускать `sudo hermes chat` вручную.

Убедитесь, что это работает

После nixos-rebuild switch проверьте, что служба запущена:

# Check service status
systemctl status hermes-agent

# Watch logs (Ctrl+C to stop)
journalctl -u hermes-agent -f

# If addToSystemPackages is true, test the CLI
hermes version
hermes config       # shows the generated config

Выбор режима развертывания

Модуль поддерживает два режима, управляемых container.enable:

Собственный (по умолчанию) Контейнер
Как это работает Усиленная служба systemd на хосте Постоянный контейнер Ubuntu с /nix/store, смонтированным привязкой
Безопасность NoNewPrivileges, ProtectSystem=strict, PrivateTmp Изоляция контейнера, запускается внутри от имени непривилегированного пользователя
Агент может самостоятельно устанавливать пакеты Нет — только инструменты, предоставляемые Nix PATH Да — установки apt, pip, npm сохраняются при перезапуске
Поверхность конфигурации То же То же
Когда выбирать Стандартное развертывание, максимальная безопасность, воспроизводимость Агенту требуется установка пакета среды выполнения, изменяемая среда, экспериментальные инструменты

Чтобы включить режим контейнера, добавьте одну строку:

{
  services.hermes-agent = {
    enable = true;
    container.enable = true;
    # ... rest of config is identical
  };
}

:::информация Режим контейнера автоматически включает virtualisation.docker.enable через mkDefault. Если вместо этого вы используете Podman, установите container.backend = "podman" и virtualisation.docker.enable = false.


Конфигурация

Декларативные настройки

Опция settings принимает произвольный набор атрибутов, который отображается как config.yaml. Он поддерживает глубокое слияние нескольких определений модулей (через lib.recursiveUpdate), поэтому вы можете разделить конфигурацию по файлам:

# base.nix
services.hermes-agent.settings = {
  model.default = "anthropic/claude-sonnet-4";
  toolsets = [ "all" ];
  terminal = { backend = "local"; timeout = 180; };
};

# personality.nix
services.hermes-agent.settings = {
  display = { compact = false; personality = "kawaii"; };
  memory = { memory_enabled = true; user_profile_enabled = true; };
};

Оба глубоко объединены во время оценки. Объявленные Nix ключи всегда перевешивают ключи в существующем config.yaml на диске, но добавленные пользователем ключи, к которым Nix не прикасается, сохраняются. Это означает, что если агент или ручное редактирование добавляет ключи типа skills.disabled или streaming.enabled, они сохраняются nixos-rebuild switch.

:::примечание Именование модели 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`, чтобы увидеть каждый конечный ключ конфигурации, извлеченный из `DEFAULT_CONFIG` Python. Вы можете вставить существующий `config.yaml` в `settings` attrset — структура отображается 1:1.

<подробности>

Полный пример: все часто настраиваемые настройки
{ config, ... }: {
  services.hermes-agent = {
    enable = true;
    container.enable = true;

    # ── Model ──────────────────────────────────────────────────────────
    settings = {
      model = {
        base_url = "https://openrouter.ai/api/v1";
        default = "anthropic/claude-opus-4.6";
      };
      toolsets = [ "all" ];
      max_turns = 100;
      terminal = { backend = "local"; cwd = "."; timeout = 180; };
      compression = {
        enabled = true;
        threshold = 0.85;
        summary_model = "google/gemini-3-flash-preview";
      };
      memory = { memory_enabled = true; user_profile_enabled = true; };
      display = { compact = false; personality = "kawaii"; };
      agent = { max_turns = 60; verbose = false; };
    };

    # ── Secrets ────────────────────────────────────────────────────────
    environmentFiles = [ config.sops.secrets."hermes-env".path ];

    # ── Documents ──────────────────────────────────────────────────────
    documents = {
      "USER.md" = ./documents/USER.md;
    };

    # ── MCP Servers ────────────────────────────────────────────────────
    mcpServers.filesystem = {
      command = "npx";
      args = [ "-y" "@modelcontextprotocol/server-filesystem" "/data/workspace" ];
    };

    # ── Container options ──────────────────────────────────────────────
    container = {
      image = "ubuntu:24.04";
      backend = "docker";
      hostUsers = [ "your-username" ];
      extraVolumes = [ "/home/user/projects:/projects:rw" ];
      extraOptions = [ "--gpus" "all" ];
    };

    # ── Service tuning ─────────────────────────────────────────────────
    addToSystemPackages = true;
    extraArgs = [ "--verbose" ];
    restart = "always";
    restartSec = 5;
  };
}

</подробнее>

Escape Hatch: используйте свою собственную конфигурацию

Если вы предпочитаете управлять config.yaml полностью вне Nix, используйте configFile:

services.hermes-agent.configFile = /etc/hermes/config.yaml;

Это полностью обходит settings — ни слияния, ни генерации. Файл копируется как есть на $HERMES_HOME/config.yaml при каждой активации.

Памятка по настройке

Краткий справочник наиболее распространенных вещей, которые пользователи Nix хотят настроить:

Я хочу... Вариант Пример
Изменить модель LLM settings.model.default "anthropic/claude-sonnet-4"
Использовать конечную точку другого поставщика settings.model.base_url "https://openrouter.ai/api/v1"
Добавить ключи API environmentFiles [ config.sops.secrets."hermes-env".path ]
Придайте агенту индивидуальность ${services.hermes-agent.stateDir}/.hermes/SOUL.md управлять файлом напрямую
Добавить серверы инструментов MCP mcpServers.<name> См. Серверы MCP
Монтировать каталоги хоста в контейнер container.extraVolumes [ "/data:/data:rw" ]
Передать доступ к графическому процессору контейнеру container.extraOptions [ "--gpus" "all" ]
Используйте Podman вместо Docker container.backend "podman"
Совместное использование состояния между CLI хоста и контейнером container.hostUsers [ "sidbin" ]
Сделайте дополнительные инструменты доступными для агента extraPackages [ pkgs.pandoc pkgs.imagemagick ]
Использовать собственное базовое изображение container.image "ubuntu:24.04"
Переопределить пакет Hermes package inputs.hermes-agent.packages.${system}.default.override { ... }
Изменить каталог состояния stateDir "/opt/hermes"
Установить рабочий каталог агента workingDirectory "/home/user/projects"

Управление секретами

🚨 Danger

Никогда не помещайте ключи API в `settings` или `environment`. Значения в выражениях Nix попадают в `/nix/store`, который доступен для чтения всем. Всегда используйте `environmentFiles` с менеджером секретов.

И environment (несекретные переменные), и environmentFiles (секретные файлы) объединяются в $HERMES_HOME/.env во время активации (nixos-rebuild switch). Hermes читает этот файл при каждом запуске, поэтому изменения вступают в силу с systemctl restart hermes-agent — пересоздание контейнера не требуется.

сопс-никс

{
  sops = {
    defaultSopsFile = ./secrets/hermes.yaml;
    age.keyFile = "/home/user/.config/sops/age/keys.txt";
    secrets."hermes-env" = { format = "yaml"; };
  };

  services.hermes-agent.environmentFiles = [
    config.sops.secrets."hermes-env".path
  ];
}

Файл секретов содержит пары ключ-значение:

# secrets/hermes.yaml (encrypted with sops)
hermes-env: |
    OPENROUTER_API_KEY=sk-or-...
    TELEGRAM_BOT_TOKEN=123456:ABC...
    ANTHROPIC_API_KEY=sk-ant-...

агеникс

{
  age.secrets.hermes-env.file = ./secrets/hermes-env.age;

  services.hermes-agent.environmentFiles = [
    config.age.secrets.hermes-env.path
  ];
}

OAuth/Раздача аутентификации

Для платформ, требующих OAuth (например, Discord), используйте authFile для ввода учетных данных при первом развертывании:

{
  services.hermes-agent = {
    authFile = config.sops.secrets."hermes/auth.json".path;
    # authFileForceOverwrite = true;  # overwrite on every activation
  };
}

Файл копируется только в том случае, если auth.json еще не существует (если только authFileForceOverwrite = true). Обновления токена OAuth во время выполнения записываются в каталог состояния и сохраняются при перестроениях.


Документы

Опция documents устанавливает файлы в рабочий каталог агента (workingDirectory, который агент считает своим рабочим пространством). Hermes ищет определенные имена файлов по соглашению:

Файл идентификации агента является отдельным: 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;  # path reference, copied from Nix store
  };
}

Значения могут быть встроенными строками или ссылками на пути. Файлы устанавливаются на каждый nixos-rebuild switch.


MCP-серверы

Опция mcpServers декларативно настраивает серверы MCP (Model Context Protocol). Каждый сервер использует транспорт stdio (локальная команда) или HTTP (удаленный URL-адрес).

Stdio Transport (локальные серверы)

{
  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}"; # resolved from .env
    };
  };
}

:::совет Переменные среды в значениях env разрешаются из $HERMES_HOME/.env во время выполнения. Используйте environmentFiles для внедрения секретов — никогда не помещайте токены непосредственно в конфигурацию Nix.

HTTP-транспорт (удаленные серверы)

{
  services.hermes-agent.mcpServers.remote-api = {
    url = "https://mcp.example.com/v1/mcp";
    headers.Authorization = "Bearer \${MCP_REMOTE_API_KEY}";
    timeout = 180;
  };
}

HTTP-транспорт с OAuth

Установите auth = "oauth" для серверов, использующих OAuth 2.1. Hermes реализует полный поток PKCE — обнаружение метаданных, динамическую регистрацию клиентов, обмен токенами и автоматическое обновление.

{
  services.hermes-agent.mcpServers.my-oauth-server = {
    url = "https://mcp.example.com/mcp";
    auth = "oauth";
  };
}

Токены хранятся в $HERMES_HOME/mcp-tokens/<server-name>.json и сохраняются при перезапусках и перестройках.

<подробности>

Первоначальная авторизация OAuth на автономных серверах

Первая авторизация OAuth требует потока согласия на основе браузера. При автономном развертывании Hermes печатает URL-адрес авторизации в стандартный вывод/логи вместо открытия браузера.

Вариант A: Интерактивная загрузка — запустите поток один раз через docker exec (контейнер) или sudo -u hermes (собственный):

# Container mode
docker exec -it hermes-agent \
  hermes mcp add my-oauth-server --url https://mcp.example.com/mcp --auth oauth

# Native mode
sudo -u hermes HERMES_HOME=/var/lib/hermes/.hermes \
  hermes mcp add my-oauth-server --url https://mcp.example.com/mcp --auth oauth

Контейнер использует --network=host, поэтому прослушиватель обратного вызова OAuth на 127.0.0.1 доступен из хост-браузера.

Вариант Б: Предварительная раздача токенов — завершите процесс на рабочей станции, затем скопируйте токены:

hermes mcp add my-oauth-server --url https://mcp.example.com/mcp --auth oauth
scp ~/.hermes/mcp-tokens/my-oauth-server{,.client}.json \
    server:/var/lib/hermes/.hermes/mcp-tokens/
# Ensure: chown hermes:hermes, chmod 0600

</подробнее>

Выборка (запросы LLM, инициированные сервером)

Некоторые серверы MCP могут запрашивать у агента завершение LLM:

{
  services.hermes-agent.mcpServers.analysis = {
    command = "npx";
    args = [ "-y" "analysis-server" ];
    sampling = {
      enabled = true;
      model = "google/gemini-3-flash";
      max_tokens_cap = 4096;
      timeout = 30;
      max_rpm = 10;
    };
  };
}

Управляемый режим

Когда Hermes запускается через модуль NixOS, следующие команды CLI блокируются с описательной ошибкой, указывающей на configuration.nix:

Заблокированная команда Почему
hermes setup Конфигурация является декларативной — отредактируйте settings в конфигурации Nix
hermes config edit Конфигурация генерируется из settings
hermes config set <key> <value> Конфигурация генерируется из settings
hermes gateway install Служба systemd управляется NixOS
hermes gateway uninstall Служба systemd управляется NixOS

Это предотвращает расхождение между тем, что объявляет Никс, и тем, что находится на диске. Обнаружение использует два сигнала:

  1. HERMES_MANAGED=true переменная среды — устанавливается службой systemd и видна процессу шлюза.
  2. .managed файл маркера в HERMES_HOME — устанавливается скриптом активации, видимый для интерактивных оболочек (например, docker exec -it hermes-agent hermes config set ... тоже блокируется)

Чтобы изменить конфигурацию, отредактируйте конфигурацию Nix и запустите sudo nixos-rebuild switch.


Контейнерная архитектура

:::информация Этот раздел актуален только в том случае, если вы используете container.enable = true. Пропустите его для развертываний в основном режиме. Когда режим контейнера включен, Hermes запускается внутри постоянного контейнера Ubuntu со встроенным Nix двоичным файлом, смонтированным с помощью привязки и доступным только для чтения с хоста:

Host                                    Container
────                                    ─────────
/nix/store/...-hermes-agent-0.1.0  ──►  /nix/store/... (ro)
~/.hermes -> /var/lib/hermes/.hermes       (symlink bridge, per hostUsers)
/var/lib/hermes/                    ──►  /data/          (rw)
  ├── current-package -> /nix/store/...    (symlink, updated each rebuild)
  ├── .gc-root -> /nix/store/...           (prevents nix-collect-garbage)
  ├── .container-identity                  (sha256 hash, triggers recreation)
  ├── .hermes/                             (HERMES_HOME)
     ├── .env                             (merged from environment + environmentFiles)
     ├── config.yaml                      (Nix-generated, deep-merged by activation)
     ├── .managed                         (marker file)
     ├── .container-mode                  (routing metadata: backend, exec_user, etc.)
     ├── state.db, sessions/, memories/   (runtime state)
     └── mcp-tokens/                      (OAuth tokens for MCP servers)
  ├── home/                                ──►  /home/hermes    (rw)
  └── workspace/                           (MESSAGING_CWD)
      ├── SOUL.md                          (from documents option)
      └── (agent-created files)

Container writable layer (apt/pip/npm):   /usr, /usr/local, /tmp

Бинарный файл, созданный Nix, работает внутри контейнера Ubuntu, поскольку /nix/store монтируется по привязке — он имеет собственный интерпретатор и все зависимости, поэтому нет необходимости полагаться на системные библиотеки контейнера. Точка входа в контейнер разрешается через символическую ссылку 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) сохраняется сохраняется сохраняется
Изменение изображения (container.image) Да сохраняется сохраняется Потерян
Изменение объема/опций Да сохраняется сохраняется Потерян
environment/environmentFiles изменить Нет сохраняется сохраняется сохраняется

Контейнер создается заново только при изменении его хэша идентификации. Хэш охватывает: версию схемы, изображение, extraVolumes, extraOptions и сценарий точки входа. Изменения переменных среды, настроек, документов или самого пакета Hermes не вызывают воссоздание.

⚠️ Warning

Потеря записываемого слоя При изменении хэша идентификатора (обновление образа, новые тома, новые параметры контейнера) контейнер уничтожается и создается заново из новой версии `container.image`. Любые пакеты `apt install`, `pip install` или `npm install` на записываемом уровне теряются. Состояние `/data` и `/home/hermes` сохраняется (это привязка). Если агент использует определенные пакеты, рассмотрите возможность включения их в собственный образ (`container.image = "my-registry/hermes-base:latest"`) или сценарий их установки в SOUL.md агента.

Защита корня GC

Скрипт preStart создает корень GC по адресу ${stateDir}/.gc-root, указывающий на текущий пакет Hermes. Это не позволяет nix-collect-garbage удалить работающий двоичный файл. Если корень GC каким-то образом сломается, перезапуск службы создаст его заново.


Плагины

Модуль NixOS поддерживает декларативную установку плагинов — императив hermes plugins install не требуется.

Плагины каталогов (extraPlugins)

Для плагинов, которые представляют собой просто дерево исходного кода с plugin.yaml + __init__.py (например, hermes-lcm):

services.hermes-agent.extraPlugins = [
  (pkgs.fetchFromGitHub {
    owner = "stephenschoettler";
    repo = "hermes-lcm";
    rev = "v0.7.0";
    hash = "sha256-...";
  })
];

Плагины имеют символическую ссылку $HERMES_HOME/plugins/ во время активации. Hermes обнаруживает их посредством обычного сканирования каталогов. Удаление плагина из списка и запуск nixos-rebuild switch удаляет символическую ссылку.

Плагины точки входа (extraPythonPackages)

Для плагинов в пакете pip, которые регистрируются через [project.entry-points."hermes_agent.plugins"] (например, rtk-hermes):

services.hermes-agent.extraPythonPackages = [
  (pkgs.python312Packages.buildPythonPackage {
    pname = "rtk-hermes";
    version = "1.0.0";
    src = pkgs.fetchFromGitHub {
      owner = "ogallotti";
      repo = "rtk-hermes";
      rev = "v1.0.0";
      hash = "sha256-...";
    };
    format = "pyproject";
    build-system = [ pkgs.python312Packages.setuptools ];
  })
];

site-packages пакета добавляется в PYTHONPATH в оболочке Hermes. importlib.metadata обнаруживает точку входа в начале сеанса.

Объединение обоих

Плагин каталога со сторонними зависимостями Python требует обоих вариантов:

services.hermes-agent = {
  extraPlugins = [ my-plugin-src ];          # plugin source
  extraPythonPackages = [ pkgs.python312Packages.redis ];  # its Python dep
  extraPackages = [ pkgs.redis ];            # system binary it needs
};

Использование наложения

Внешние флейки могут напрямую переопределить пакет:

{
  inputs.hermes-agent.url = "github:NousResearch/hermes-agent";
  outputs = { hermes-agent, nixpkgs, ... }: {
    nixpkgs.overlays = [ hermes-agent.overlays.default ];
    # Then: pkgs.hermes-agent.override { extraPythonPackages = [...]; }
  };
}

Конфигурация плагина

Плагины по-прежнему необходимо включить в config.yaml. Добавьте их через декларативные настройки:

services.hermes-agent.settings.plugins.enabled = [
  "hermes-lcm"
  "rtk-rewrite"
];

:::примечание Проверка коллизий во время сборки не позволяет пакетам плагинов скрывать основные зависимости Hermes. Если плагин предоставляет пакет, уже находящийся в запечатанном венве, nixos-rebuild завершается с ошибкой.


Развитие

Оболочка для разработчиков

Flake предоставляет оболочку разработки с Python 3.11, uv, Node.js и всеми инструментами времени выполнения:

cd hermes-agent
nix develop

# Shell provides:
#   - Python 3.11 + uv (deps installed into .venv on first entry)
#   - Node.js 20, ripgrep, git, openssh, ffmpeg on PATH
#   - Stamp-file optimization: re-entry is near-instant if deps haven't changed

hermes setup
hermes chat

direnv (рекомендуется)

Включенный .envrc автоматически активирует оболочку разработки:

cd hermes-agent
direnv allow    # one-time
# Subsequent entries are near-instant (stamp file skips dep install)

Чешуйчатые чеки

Флейк включает проверку во время сборки, которая выполняется в CI и локально:

# Run all checks
nix flake check

# Individual checks
nix build .#checks.x86_64-linux.package-contents   # binaries exist + version
nix build .#checks.x86_64-linux.entry-points-sync  # pyproject.toml ↔ Nix package sync
nix build .#checks.x86_64-linux.cli-commands        # gateway/config subcommands
nix build .#checks.x86_64-linux.managed-guard       # HERMES_MANAGED blocks mutation
nix build .#checks.x86_64-linux.bundled-skills      # skills present in package
nix build .#checks.x86_64-linux.config-roundtrip    # merge script preserves user keys

<подробности>

Что проверяет каждая проверка
Проверить Что он тестирует
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 Каталог Skills существует, содержит файлы SKILL.md, HERMES_BUNDLED_SKILLS установлен в обертке
config-roundtrip 7 сценариев слияния: новая установка, переопределение Nix, сохранение пользовательских ключей, смешанное слияние, аддитивное слияние MCP, вложенное глубокое слияние, идемпотентность

</подробнее>


Справочник по опциям

Ядро

Вариант Тип По умолчанию Описание
enable bool false Включить службу гермес-агента
package package hermes-agent Используемый пакет агента Hermes
user str "hermes" Пользователь системы
group str "hermes" Системная группа
createUser bool true Автоматическое создание пользователя/группы
stateDir str "/var/lib/hermes" Каталог состояний (HERMES_HOMEparent)
workingDirectory str "${stateDir}/workspace" Рабочий каталог агента (MESSAGING_CWD)
addToSystemPackages bool false Добавьте hermes CLI в системный PATH и установите HERMES_HOME для всей системы

Конфигурация

Вариант Тип По умолчанию Описание
settings attrs (глубокое слияние) {} Декларативная конфигурация отображается как config.yaml. Поддерживает произвольную вложенность; несколько определений объединяются через lib.recursiveUpdate
configFile null или path null Путь к существующему config.yaml. Полностью переопределяет settings, если установлено

Секреты и окружающая среда

Вариант Тип По умолчанию Описание
environmentFiles listOf str [] Пути к env-файлам с секретами. Объединен с $HERMES_HOME/.env во время активации
environment attrsOf str {} Несекретные переменные окружения. Видимо в магазине Nix — не размещайте здесь секреты
authFile null или path null Начальное значение учетных данных OAuth. Копируется только при первом развертывании
authFileForceOverwrite bool false Всегда перезаписывать auth.json с authFile при активации

Документы

Вариант Тип По умолчанию Описание
documents attrsOf (either str path) {} Файлы рабочей области. Ключи — это имена файлов, значения — встроенные строки или пути. Устанавливается в workingDirectory при активации

MCP-серверы

Вариант Тип По умолчанию Описание
mcpServers attrsOf submodule {} Определения серверов MCP, объединенные в settings.mcp_servers
mcpServers.<name>.command null или str null Команда сервера (транспорт stdio)
mcpServers.<name>.args listOf str [] Аргументы команды
mcpServers.<name>.env attrsOf str {} Переменные среды для серверного процесса
mcpServers.<name>.url null или str null URL-адрес конечной точки сервера (транспорт HTTP/StreamableHTTP)
mcpServers.<name>.headers attrsOf str {} HTTP-заголовки, например. Authorization
mcpServers.<name>.auth null или "oauth" null Метод аутентификации. "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 [] Дополнительные пакеты доступны агенту. Добавлено в индивидуальный профиль пользователя Hermes, чтобы все команды терминала, навыки и задания cron видели их
extraPlugins listOf package [] Пакеты плагинов каталога для символической ссылки на $HERMES_HOME/plugins/. Каждый из них должен содержать plugin.yaml
extraPythonPackages listOf package [] Пакеты Python добавлены в PYTHONPATH для обнаружения плагинов точки входа. Сборка с помощью python312Packages
restart str "always" системная политика 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 [] Дополнительные тома монтируются (host:container:mode)
container.extraOptions listOf str [] Дополнительные аргументы переданы docker create
container.hostUsers listOf str [] Интерактивные пользователи, которые получают символическую ссылку ~/.hermes на сервис stateDir и автоматически добавляются в группу hermes

Макет каталога

Основной режим

/var/lib/hermes/                     # stateDir (owned by hermes:hermes, 0750)
├── .hermes/                         # HERMES_HOME
   ├── config.yaml                  # Nix-generated (deep-merged each rebuild)
   ├── .managed                     # Marker: CLI config mutation blocked
   ├── .env                         # Merged from environment + environmentFiles
   ├── auth.json                    # OAuth credentials (seeded, then self-managed)
   ├── gateway.pid
   ├── state.db
   ├── mcp-tokens/                  # OAuth tokens for MCP servers
   ├── sessions/
   ├── memories/
   ├── skills/
   ├── cron/
   └── logs/
├── home/                            # Agent HOME
└── workspace/                       # MESSAGING_CWD
    ├── SOUL.md                      # From documents option
    └── (agent-created files)

Контейнерный режим

Тот же макет, установленный в контейнере:

Путь контейнера Путь к хосту Режим Заметки
/nix/store /nix/store ro Бинарный файл Hermes + все версии Nix
/data /var/lib/hermes rw Все состояние, конфигурация, рабочая область
/home/hermes ${stateDir}/home rw Постоянная домашняя страница агента — pip install --user, кэши инструментов
/usr, /usr/local, /tmp (записываемый слой) rw Установка apt/pip/npm — сохраняется при перезапуске, теряется при восстановлении

Обновление

# Update the flake input
nix flake update hermes-agent --flake /etc/nixos

# Rebuild
sudo nixos-rebuild switch

В режиме контейнера символическая ссылка current-package обновляется, и агент получает новый двоичный файл при перезапуске. Никакого воссоздания контейнера, никакой потери установленных пакетов.


Устранение неполадок

:::совет пользователям Podman Все приведенные ниже команды docker работают одинаково с podman. Замените соответствующим образом, если вы установили container.backend = "podman".

Журналы обслуживания

# Both modes use the same systemd unit
journalctl -u hermes-agent -f

# Container mode: also available directly
docker logs -f hermes-agent

Проверка контейнеров

systemctl status hermes-agent
docker ps -a --filter name=hermes-agent
docker inspect hermes-agent --format='{{.State.Status}}'
docker exec -it hermes-agent bash
docker exec hermes-agent readlink /data/current-package
docker exec hermes-agent cat /data/.container-identity

Принудительное воссоздание контейнера

Если вам нужно сбросить записываемый слой (свежая Ubuntu):

sudo systemctl stop hermes-agent
docker rm -f hermes-agent
sudo rm /var/lib/hermes/.container-identity
sudo systemctl start hermes-agent

Проверка загрузки секретов

Если агент запускается, но не может пройти аутентификацию у провайдера LLM, убедитесь, что файл .env был правильно объединен:

# Native mode
sudo -u hermes cat /var/lib/hermes/.hermes/.env

# Container mode
docker exec hermes-agent cat /data/.hermes/.env

Корневая проверка GC

nix-store --query --roots $(docker exec hermes-agent readlink /data/current-package)

Распространенные проблемы

Симптом Причина Исправить
Cannot save configuration: managed by NixOS Охранники CLI активны Изменить configuration.nix и nixos-rebuild switch
Контейнер неожиданно воссоздан extraVolumes, extraOptions или image изменено Ожидается — сброс записываемого слоя. Переустановите пакеты или используйте собственный образ
hermes version показывает старую версию Контейнер не перезапущен systemctl restart hermes-agent
Разрешение отклонено на /var/lib/hermes Государственный каталог: 0750 hermes:hermes Используйте docker exec или sudo -u hermes
nix-collect-garbage удалил Гермеса Корень GC отсутствует Перезапустите службу (preStart воссоздает корень GC)
no container with name or ID "hermes-agent" (Подман) Корневой контейнер Podman не виден обычному пользователю Добавьте sudo без пароля для podman (см. раздел Container Mode)
unable to find user hermes Контейнер все еще запускается (точка входа еще не создала пользователя) Подождите несколько секунд и повторите попытку — CLI повторит попытку автоматически
Инструмент, добавленный через extraPackages, не найден в терминале Требуется nixos-rebuild switch для обновления профиля каждого пользователя Пересобрать и перезапустить: nixos-rebuild switch && systemctl restart hermes-agent