Интеграция с ACP-хостами

Команды для зависимостей Python на этой странице рассчитаны на чекаут исходников, подготовленный через PM. После изменения зависимостей заново активируйте чекаут и перезапустите Hermes.

Hermes Agent умеет работать как ACP-сервер: совместимые хосты общаются с ним по stdio. Редакторы при этом рисуют:

  • сообщения чата
  • активность инструментов
  • диффы файлов
  • команды терминала
  • запросы на подтверждение
  • потоковые фрагменты размышлений и ответа

Другие хосты используют тот же протокол, чтобы заводить в Hermes события совместной работы. ACP подходит, когда вы хотите сохранить за Hermes его личность, настройки провайдеров, память, навыки и инструменты, а транспортом разговора пусть заведует другое приложение.

Что Hermes даёт в режиме ACP

В этом режиме запускается отобранный набор инструментов hermes-acp, заточенный под работу в редакторе. В него входят:

  • файловые инструменты: read_file, write_file, patch, search_files
  • терминальные инструменты: terminal, process
  • веб- и браузерные инструменты
  • память, todo, поиск по сессиям
  • навыки
  • execute_code и delegate_task
  • зрение (vision)

Намеренно за бортом остаётся то, что плохо ложится на типичный редакторский UX, — например, доставка сообщений и управление cron-задачами.

Набор инструментов разрешается так же, как в шлюзе мессенджеров при той же конфигурации платформы. Сюда входят и добавки, которые шлюз кладёт поверх списка, например включённые наборы инструментов плагинов, — их получают и сессии ACP. platform_toolsets.acp заменяет умолчание hermes-acp, а agent.disabled_toolsets убирает наборы из каждой сессии ACP. MCP-серверы из mcp_servers подчиняются тем же правилам. По умолчанию ACP получает все включённые серверы. Если перечислить имена серверов в platform_toolsets.acp, войдут только они, а no_mcp убирает их все. В hermes tools пункта для ACP нет, так что правьте config.yaml напрямую:

platform_toolsets:
  acp: [file, web, skills, github]   # только MCP-сервер github
agent:
  disabled_toolsets: [code_execution]

MCP-серверы, которые редактор передаёт с session/new, — отдельная история. Клиент запрашивает их для каждой сессии, и они добавляются всегда.

Установка

Поставьте Hermes как обычно, а затем добавьте ACP-экстру из каталога установки:

cd ~/.hermes/hermes-agent && python -c "import pm; pm.sync_venv(['acp'], explicit=True)"

Так подтянется зависимость agent-client-protocol и включатся команды:

  • hermes acp
  • hermes-acp
  • python -m acp_adapter

Запуск ACP-сервера

Hermes стартует в режиме ACP любой из команд:

hermes acp
hermes-acp
python -m acp_adapter

Логи Hermes пишет в stderr, чтобы stdout оставался свободным под трафик ACP JSON-RPC.

Для неинтерактивных проверок:

hermes acp --version
hermes acp --check

Браузерные инструменты (опционально)

Браузерные инструменты (browser_navigate, browser_click и прочие) зависят от npm-пакета agent-browser и Chromium, а они не входят в Python-wheel. Поставьте их так:

hermes acp --setup-browser           # интерактивно (спросит перед загрузкой ~400 МБ)
hermes acp --setup-browser --yes     # принять загрузку без вопросов

Это отдельная команда. Поток терминальной авторизации (hermes acp --setup) тоже предлагает развернуть браузер — отдельным вопросом уже после выбора модели, так что напрямую --setup-browser большинству вообще не понадобится.

Что под капотом:

  • ставит Node.js 26 в ~/.hermes/node/, если его там нет
  • выполняет npm install -g agent-browser @askjo/camofox-browser в этот префикс (sudo не нужен — --prefix у npm указывает на доступный пользователю Node под управлением Hermes)
  • ставит Playwright Chromium или подхватывает найденный системный Chrome/Chromium, если он есть

Запуск идемпотентный: повторный прогон проходит быстро и пропускает уже сделанную работу.

Настройка хоста

Каналы Buzz (мост через релей)

Buzz — платформа совместной работы людей и агентов на базе Nostr. Её обвязка buzz-acp соединяет каналы Buzz с любым ACP-агентом по stdio:

Buzz relay <-- WebSocket --> buzz-acp <-- ACP over stdio --> Hermes Agent

Это интеграция транспорта, а не вторая установка Hermes. Подпроцесс, который запускает buzz-acp, использует ту же конфигурацию, учётные данные, память, навыки и состояние, что и hermes на этом хосте.

(Не путайте с управляемым рантаймом Buzz Desktop, который запускает Hermes локально как предустановленную обвязку. Мост через релей нужен, чтобы заходить в каналы Buzz отдельной личностью агента, как правило, на сервере.)

Что потребуется:

  • Пройти установку ACP и проверку hermes acp --check выше.
  • Собрать buzz-acp и CLI buzz из репозитория Buzz (cargo build --release -p buzz-acp).
  • Выпустить для Hermes отдельную пару ключей Nostr (buzz-admin generate-key) и зарегистрировать её участником релея (buzz-admin add-member). Каждому агенту нужна своя личность — не переиспользуйте человеческие ключи.
  • Добавить эту личность в нужные каналы Buzz.

Запуск моста:

export BUZZ_RELAY_URL="wss://community.example.com"
export BUZZ_PRIVATE_KEY="..."
export BUZZ_API_TOKEN="..."
export BUZZ_ACP_AGENT_COMMAND="hermes"
export BUZZ_ACP_AGENT_ARGS="acp"

buzz-acp

BUZZ_API_TOKEN нужен, только если релей требует аутентификацию по токену. Приватный ключ и токен API не коммитьте и никуда не вставляйте.

Для постоянного развёртывания на сервере запускайте buzz-acp под менеджером служб от того же пользователя ОС, которому принадлежит нужный домашний каталог Hermes. Настройка, генерация ключей, обнаружение каналов и параметры отдельных агентов описаны в README buzz-acp.

Мост сам находит все каналы Buzz, где личность Hermes состоит участником, и подписывается автоматически, когда её добавляют в очередной канал. Границей доступа остаётся членство в каналах Buzz — отдельный список каналов в конфигурации Hermes не нужен.

Чтобы активность Hermes через ACP была видна в Buzz Desktop у владельца, добавьте:

export BUZZ_ACP_RELAY_OBSERVER="true"

Так публикуются зашифрованные наблюдательские кадры вида 24200, адресованные владельцу агента (NIP-AO в Buzz). Desktop рисует живой поток жизненного цикла, инструментов, ответов и расхода в журнале активности агента. Релей считает эти кадры эфемерными, поэтому Desktop должен быть онлайн до начала хода; долговременной историей на стороне владельца остаётся его локальный архив наблюдателя.

Headless-мосты отвечают на ACP-запросы разрешений сами, потому что редактора с диалогами подтверждения рядом нет, — см. держите агентов Buzz только для владельца. Относитесь к мосту как к привилегированной автоматизации: заведите отдельную учётную запись ОС, ограничьте круг пользователей Buzz, которые могут обращаться к агенту (в buzz-acp есть шлюз ответа только владельцу через BUZZ_ACP_AGENT_OWNER), и давайте членство только в тех каналах, где Hermes действительно должен работать.

VS Code

Поставьте расширение ACP Client.

Чтобы подключиться:

  1. Откройте панель ACP Client с боковой панели активности.
  2. Выберите Hermes Agent из встроенного списка агентов.
  3. Подключитесь и начинайте переписку.

Если хочется задать Hermes вручную, добавьте его через настройки VS Code в раздел acp.agents:

{
  "acp.agents": {
    "Hermes Agent": {
      "command": "hermes",
      "args": ["acp"]
    }
  }
}

Zed

Пропишите Hermes кастомным сервером агента в настройках Zed:

  1. Откройте панель агента (Agent Panel).
  2. Добавьте кастомный сервер агента с такой конфигурацией:
{
  "agent_servers": {
    "hermes-agent": {
      "type": "custom",
      "command": "hermes",
      "args": ["acp"]
    }
  }
}
  1. Откройте новый тред внешнего агента Hermes.

Что нужно заранее:

  • Сначала задайте учётные данные провайдера Hermes командой hermes model либо пропишите их в ~/.hermes/.env / ~/.hermes/config.yaml.

JetBrains

Возьмите ACP-совместимый плагин и направьте его на hermes acp или hermes-acp.

Buzz Desktop

Buzz поставляется с Hermes Agent как с предустановленным рантаймом. Установите Hermes обычным способом — Buzz найдёт его сам: откройте Settings → Runtimes, и Hermes появится среди рантаймов.

Если обнаружение не сработало (на старых установках), убедитесь, что лаунчер ACP резолвится в PATH login-шелла:

command -v hermes-acp || command -v hermes

Свежие установки кладут в ~/.local/bin оба лаунчера — hermes и hermes-acp; на старых установках лаунчер hermes-acp добавляет hermes update. Как запасной вариант, задайте в Buzz команду агента hermes с аргументами ["acp"].

Выбор модели

Buzz Desktop (v0.5.1+) рисует полное меню моделей Hermes в настройках рантайма агента. Список приходит от самого Hermes по ACP: в нём каждая модель тех провайдеров, к которым вы авторизовались в Hermes (тот же перечень, что стоит за hermes model и командой /model). Значит, отсутствие модели в меню означает, что у её провайдера на стороне Hermes не настроены учётные данные.

Идентификаторы записей имеют вид provider:model (например, openrouter:z-ai/glm-5.1) либо custom:<name>:<model> для кастомных OpenAI-совместимых эндпоинтов из config.yaml. Выбор модели действует на сессию этого агента и не меняет ваше умолчание для Hermes целиком — для этого есть hermes model.

Держите агентов Buzz только для владельца

Buzz создаёт каждого агента с настройкой Who can talk to this agent в значении Owner only. Оставьте её как есть, если рантайм — Hermes.

На этом пути складываются два поведения. В набор инструментов hermes-acp входят terminal и execute_code, а ACP-мост Buzz отвечает на запросы разрешений Hermes сам, выдавая allow_once вместо того, чтобы их показать. Поэтому агент Hermes в Buzz выполняет команды оболочки на хосте, ничего не спрашивая. Я попросил одного выполнить rm -rf по временному каталогу — он его удалил, и никакого запроса нигде не появилось.

Значение Anyone раздаёт тот же доступ к оболочке любому автору, который дотянется до канала. Buzz при этом не предупреждает.

approvals.mode: manual не помогает: Hermes выдаёт запрос разрешения, но Buzz подтверждает его автоматически, и команда всё равно выполняется. Чтобы отобрать оболочку, сузьте набор инструментов: задайте в platform_toolsets.acp список без terminal и code_execution или добавьте их в agent.disabled_toolsets. Даже пустой platform_toolsets.acp: [] всё равно добавляет включённые наборы инструментов плагинов, так что каждый ненужный набор плагина перечислите в agent.disabled_toolsets.

Команда !shutdown от владельца останавливает агента в любом режиме, а от всех остальных Buzz её игнорирует.

Конфигурация и учётные данные

Режим ACP берёт ту же конфигурацию Hermes, что и CLI:

  • ~/.hermes/.env
  • ~/.hermes/config.yaml
  • ~/.hermes/skills/
  • ~/.hermes/state.db

Провайдер определяется обычным рантайм-резолвером Hermes, так что ACP наследует текущего настроенного провайдера и его учётные данные. Кроме того, Hermes объявляет метод терминальной авторизации (--setup) для ACP-клиентов при первом запуске — он открывает интерактивную настройку модели и провайдера.

Интеграция со стороны хоста

Эти переменные выставляет процесс ACP-хоста — редактор или другая обвязка агента — тому подпроцессу Hermes, который он запускает. Это не пользовательская конфигурация: руками их в .env или config.yaml прописывать не нужно.

ПеременнаяЗначениеЧто делает
HERMES_ACP_SKIP_CONFIGURED_MCP1Не запускать глобально настроенные MCP-серверы из config.yaml перед началом цикла ACP JSON-RPC.

Обычно Hermes поднимает каждый MCP-сервер из config.yaml до входа в цикл ACP JSON-RPC. Хосту, который сам владеет MCP и передаёт серверы сессии явно через session/new, этот глобальный запуск не нужен, а посторонний медленный или интерактивный MCP-сервер иначе задержит initialize. Значение ровно 1 позволяет такому хосту его пропустить.

Пропускается только обнаружение по глобальному config.yaml. MCP-серверы, переданные ACP-сессией через session/new, регистрируются по-прежнему, так что хост не теряет ничего из запрошенного. Любое другое значение — не задано, пусто, 0, false — сохраняет поведение по умолчанию, поэтому посторонняя похожая на «истину» строка молча MCP не отключит.

Поведение сессий

Пока сервер работает, ACP-сессиями заведует встроенный менеджер сессий ACP-адаптера, хранящий их в памяти.

В каждой сессии лежат:

  • идентификатор сессии
  • рабочий каталог
  • выбранная модель
  • текущая история диалога
  • событие отмены (cancel event)

Разговоры сохраняются в базу сессий Hermes, и после перезапуска ACP-сервера их по-прежнему можно перечислить, загрузить, возобновить или разветвить. Новая сессия, открытая без промпта, остаётся только в памяти: пробы для определения модели пустых строк истории не создают. Непустая ветка сохраняется сразу, а метаданные существующей сессии можно обновлять даже тогда, когда её текущая история пуста.

Пустые строки, оставшиеся от прежних версий, автоматически не удаляются. Открытая ACP-строка сама по себе не доказывает, что её клиент отключился. Закройте соответствующие сессии в редакторе, посмотрите на ненужные строки через hermes sessions show <id> и удаляйте только те, в которых уверены: hermes sessions delete <id>.

Поведение рабочего каталога

ACP-сессия привязывает cwd редактора к идентификатору задачи Hermes, чтобы файловые и терминальные инструменты работали относительно рабочего пространства редактора, а не cwd серверного процесса.

Подтверждения

Опасные команды терминала можно вернуть в редактор как запросы на подтверждение. Набор вариантов в ACP проще, чем в CLI:

  • разрешить однократно
  • разрешить всегда
  • запретить

При тайм-ауте или ошибке мост подтверждений отклоняет запрос. Время ожидания — approvals.timeout из config.yaml (по умолчанию 300 с), та же настройка, что и у запросов в CLI и шлюзе; увеличьте её, если ваш редактор дольше держит карточки подтверждения открытыми.

Автоподтверждение правок в пределах сессии

В ACP есть третий уровень между разрешить однократно и разрешить всегда — Разрешить для сессии. Если выбрать его в запросе разрешения внутри редактора, согласие запоминается только для текущей ACP-сессии: каждая следующая подходящая команда в этой сессии пройдёт без вопроса, но новая ACP-сессия (или перезапуск редактора) обнуляет всё, и в первый раз вопрос появится снова.

ВариантПодпись в редактореОбластьСохраняется между перезапусками
allow_onceAllow onceТолько этот вызов инструментаНет
allow_sessionAllow for sessionВсе подходящие вызовы в этой ACP-сессииНет — стирается с концом сессии
allow_alwaysAllow alwaysВсе будущие сессииДа (пишется в постоянный список разрешений Hermes)
denyDenyТолько этот вызов инструментаНет

allow_session — разумный выбор по умолчанию для работы в редакторе, когда вы доверяете агенту на время одной задачи, но не хотите заводить долгоживущую запись в списке разрешений. Компромисс по безопасности прост: чем шире область, тем реже редактор вас дёргает — и тем больше успеет натворить сбойнувший агент (или внедрённый промпт), пока вы не заметите. Незнакомым командам выдавайте allow_once; повышайте до allow_session, когда пару раз увидели, что агент верно прогоняет один и тот же шаблон; а allow_always приберегите для по-настоящему идемпотентных команд, которым доверяете навсегда (скажем, git status).

ACP-мост раскладывает эти варианты на внутреннюю семантику подтверждений Hermes: allow_always пишет постоянную запись в список разрешений ровно так же, как это делает CLI, а allow_session затрагивает только внутрипроцессный кэш согласий текущей ACP-сессии.

Некоторые хосты отвечают на запрос разрешения программно, вместо того чтобы показать его вам: тогда эти варианты существуют на уровне протокола, но до человека не доходят. Так поступает Buzz Desktop, поэтому считайте этот путь необслуживаемым выполнением независимо от ваших настроек approvals.

Решение проблем

ACP-агент не появляется в редакторе

Проверьте:

  • Для ручной или локальной разработки убедитесь, что команда хоста указывает на hermes acp.
  • Hermes установлен и доступен в PATH.
  • Установлена ACP-экстра (cd ~/.hermes/hermes-agent && python -c "import pm; pm.sync_venv(['acp'], explicit=True)").

ACP стартует, но тут же падает с ошибкой

Прогоните эти проверки:

hermes acp --version
hermes acp --check
hermes doctor
hermes status

Нет учётных данных

Режим ACP опирается на уже настроенного провайдера Hermes. Задайте учётные данные командой:

hermes model

или правкой ~/.hermes/.env. Поток терминальной авторизации (hermes acp --setup) тоже запускает интерактивную настройку провайдера и модели.

Смотрите также

перевод и редактура:

обновлено

⌕ ESC