Вебхуки Hermes: событийные агенты без гигантского универсального промпта
Уверенный7 мин чтенияАвтоматизация

Вебхуки Hermes: событийные агенты без гигантского универсального промпта

Настройте вебхуки Hermes Agent с подходящей источнику аутентификацией, проверками работоспособности на порту 8644 и небольшими именованными маршрутами, чтобы события превращались в целевые запуски агента с явно заданной целью доставки.

Что вы сможете сделать

Вебхуки лучше cron, когда что-то только что случилось. Защищайте каждый маршрут Hermes методом аутентификации, который требует его источник, проверяйте /health на порту 8644 и задавайте каждому типу события узкий промпт и настроенную цель доставки.

Сохраняется только в этом браузере.
В этой статье

Cron спрашивает: «Пора ли?». Вебхуки сообщают: «Это только что произошло, действуйте». Для работы агентов это различие имеет значение. Запланированная проверка входящих писем отличается от событий «в Stripe открыта претензия» или «создан запрос на включение изменений в ветку main».

Вебхуки агента Hermes преобразуют аутентифицированные HTTP POST-события в запуски агентов, результаты которых отправляются настроенной цели доставки. При грамотном использовании они представляют собой небольшие двери с замками и чёткими задачами. При неграмотном использовании они становятся открытым портом с одним мега-промптом, который пытается обработать любой JSON-объект, отправляемый интернетом.

В этой статье рассматриваются проектирование маршрута, подходящая источнику аутентификация, документированная проверка работоспособности и практический дымовой тест. Сопоставьте её с укреплением безопасности на первой неделе в /articles/hermes-first-week-memory-and-skills, прежде чем выставлять что-либо за пределы localhost.

Когда вебхуки являются правильным триггером

Отдавайте предпочтение вебхукам, когда:

  • важна задержка (проверка запроса на включение изменений, пока автор ещё не переключился на другую задачу);
  • исходная система уже генерирует события (GitHub, GitLab, Jira, Stripe, внутренние формы);
  • каждое событие должно становиться одной сфокусированной задачей, а не длительной разговорной сессией.

Отдавайте предпочтение cron, когда:

  • вы опрашиваете систему на наличие расхождений («есть ли сертификаты, истекающие через 14 дней?»);
  • источник не может отправлять данные;
  • вам нужен спокойный периодический отчёт, а не прерывания по каждому событию.

Официальные рекомендации Hermes соответствуют этому разделению: cron служит для запланированных проверок, а вебхуки для запусков по событиям.

Архитектура в одном изображении

Исходная система (GitHub / GitLab / n8n / собственное приложение)
        |  HTTPS POST + подходящая источнику аутентификация
        v
Адаптер вебхуков Hermes (порт по умолчанию 8644)
        |  маршрут: /webhooks/<name>
        v
Конфигурация именованного маршрута (фильтры + промпт + доставка)
        v
Запуск агента (навыки/инструменты в рамках вашей политики одобрения)
        v
Настроенная доставка (чат-канал, комментарий GitHub или журнал)

n8n может выступать слоем валидации и объединения входящих событий: проверять поля, отбрасывать лишнее, затем отправлять минимизированную полезную нагрузку POST-запросом в Hermes. Это иллюстративная архитектура из /articles/hermes-vs-n8n-choose-by-job, а не документированная готовая интеграция поставщика. Если n8n должен получить результат агента обратно в свой рабочий процесс, вызывайте отдельный API-сервер Hermes на порту 8642 по умолчанию с bearer-аутентификацией, а не считайте адаптер вебхуков синхронным обратным вызовом.

Путь настройки (проверяйте по актуальной документации)

Документация по вебхукам описывает следующий путь:

  1. Включите платформу вебхуков (hermes gateway setup или переменную окружения, такую как WEBHOOK_ENABLED=true).
  2. Настройте секрет для каждого маршрута. В зависимости от источника используйте HMAC-заголовок GitHub, заголовок GitLab с открытым токеном или общий V2 HMAC с временной меткой.
  3. Создайте именованный маршрут в конфигурации или через hermes webhook subscribe (команда согласно текущей документации).
  4. Проверка работоспособности: curl http://localhost:8644/health
  5. Укажите внешнюю систему на адрес https://your-host/webhooks/<name>
  6. Отправьте аутентифицированную тестовую полезную нагрузку; подтвердите ожидаемые маршрут, промпт, область инструментов и цель доставки.

Документированный порт по умолчанию равен 8644. По умолчанию маршрут также ограничен 30 запросами в минуту, а тела размером более 1 МБ отклоняются. Если вы изменили эти значения, тестируйте настроенные ограничения, а не полагайтесь на значения по умолчанию.

Изменения статической конфигурации могут потребовать процедуры жизненного цикла шлюза, описанной для установленного выпуска. Динамические маршруты, созданные с помощью hermes webhook subscribe, загружаются без перезапуска и получают автоматически созданный секрет. В любом случае убедитесь, что процесс шлюза видит нужный профиль и окружение; успешное выполнение команды в интерактивной оболочке не доказывает, что демон имеет ту же конфигурацию.

Аутентификация маршрута обязательна

Каждый маршрут должен наследовать или определять секрет, иначе адаптер завершится с ошибкой при запуске. Аутентификация зависит от поставщика: GitHub использует X-Hub-Signature-256, GitLab требует точного совпадения X-Gitlab-Token, а общим пользовательским отправителям следует использовать V2 HMAC с временной меткой. Аутентификация отправителя доказывает, какой владелец секрета отправил запрос, но не делает инструкции в полезной нагрузке доверенными.

Правила, которые работают в продакшене:

  • Сгенерируйте длинный случайный секрет; храните его в менеджере секретов или файле окружения с ограниченными правами, но не в markdown навыка, который агент может читать.
  • Предпочитайте маршрутные секреты, когда системы имеют разные уровни доверия (приложение GitHub против внутренней формы против партнерского вебхука).
  • Отклоняйте неподписанные или недействительные подписи на периметре; не «логируйте и продолжайте».
  • Используйте INSECURE_NO_AUTH только для временного тестирования через loopback. Адаптер отказывается запускаться, если это значение сочетается с привязкой не к loopback, например к 0.0.0.0 или адресу LAN.

Используйте текущую общую схему V2 Hermes для пользовательских отправителей: X-Webhook-Timestamp содержит секунды Unix; X-Webhook-Signature-V2 содержит шестнадцатеричный HMAC-SHA256 дайджест в нижнем регистре от <timestamp>.<raw-body>. Hermes отклоняет временные метки вне окна ±300 секунд. V1 подписывает только тело и не имеет защиты от повторного воспроизведения, поэтому не создавайте новые отправители на его основе (официальный контракт безопасности вебхуков).

Воспроизводимый дымовой тест с подписью

После создания маршрута с именем support-triage поместите нечувствительный полезный блок в payload.json. Убедитесь, что ваш утвержденный механизм внедрения секрета установил WEBHOOK_SECRET до запуска этой оболочки; не вводите производственный секрет вручную в историю команд. Приведенная ниже команда Node считывает ключ из окружения, а не раскрывает его в аргументах процесса, и подписывает точные байты файла:

: "${WEBHOOK_SECRET:?inject a disposable route secret before running this test}"
timestamp="$(date +%s)"
signature="$(TIMESTAMP="$timestamp" node -e '
  const { createHmac } = require("node:crypto");
  const { readFileSync } = require("node:fs");
  const hmac = createHmac("sha256", process.env.WEBHOOK_SECRET);
  hmac.update(`${process.env.TIMESTAMP}.`, "utf8");
  hmac.update(readFileSync("payload.json"));
  process.stdout.write(hmac.digest("hex"));
')"

curl --fail-with-body \
  -H 'Content-Type: application/json' \
  -H "X-Webhook-Timestamp: $timestamp" \
  -H "X-Webhook-Signature-V2: $signature" \
  --data-binary @payload.json \
  http://127.0.0.1:8644/webhooks/support-triage

Затем повторите запрос без обоих заголовков подписи и с временной меткой старше 300 секунд. Оба запроса должны быть отклонены. Не вставляйте реальный секретный ключ на скриншоты, в тикеты или историю командной оболочки; используйте одноразовый секрет маршрута для тестирования документации и меняйте его после завершения.

Открытый вебхук, способный передать контролируемый злоумышленником текст агенту с доступом к терминалу, создаёт риск удалённого выполнения инструментов. Аутентификация ограничивает круг отправителей событий, но даже текст аутентифицированной полезной нагрузки может быть враждебным. Используйте TLS и сетевые ограничения, минимизируйте полезные нагрузки, ограничьте или отключите инструменты терминала, файлов и исходящих действий, а выполнение изолируйте от хоста. Запросы подтверждения защищают намерение оператора, а не изолируют враждебный ввод.

Что помещать в полезную нагрузку

Отправляйте агенту контракт, а не сырой поток данных:

{
  "event_type": "github.pull_request.opened",
  "repo": "acme/api",
  "pr_number": 1842,
  "title": "Add billing retry worker",
  "author": "ada",
  "base_ref": "main",
  "html_url": "https://github.example.invalid/acme/agent-service/pull/1842",
  "task": "Summarize risk for main. List missing tests. Do not approve or merge."
}

Удаляйте неиспользуемые поля. Огромные дампы рабочих процессов расходуют контекст и провоцируют некорректное использование инструментов. «Небольшая явная полезная нагрузка с ясной задачей» является рекомендацией этой статьи по проектированию, а не утверждением об официальной интеграции n8n.

Проектирование маршрутов: много маленьких дверей

Не создавайте /webhooks/everything. Создавайте именованные маршруты с фильтрами и промптами:

Имя маршрутаИсточникЗадачаДоставка
gh-pr-openedОткрыт PR в GitHubСводка рисков + пробелы тестовТема Telegram для инженеров
stripe-disputeСоздан спор StripeЧерновик контрольного спискаSlack финансов + журнал
support-formn8n после валидацииКлассификация + черновик ответаНастроенный приватный канал Slack
uptime-alertВебхук мониторингаСбор контекста последних деплоевКанал дежурных

Каждый маршрут должен отвечать на вопросы:

  1. Какие события принимаются?
  2. Какой единственный ожидаемый результат?
  3. Какие инструменты разрешены для профиля агента этого маршрута?
  4. Куда направляется результат?
  5. Что происходит при сбое (повтор? очередь недоставленных сообщений? уведомление специалиста?)?

Полезные нагрузки вебхуков часто содержат адреса электронной почты, идентификаторы аккаунтов или тексты сообщений. Минимизируйте количество полей до их попадания в Hermes. Схема маршрута не документирует отдельный переключатель записи в память для каждого маршрута. Используйте отдельный профиль с отключённой памятью или включённым memory.write_approval и проверьте, что сохраняется. Если рассуждение агента не требуется, используйте документированный режим deliver_only вместо запуска агента.

Контроль работоспособности и эксплуатация

Документированная конечная точка для проверки состояния: http://localhost:8644/health (или ваш хост/порт). Используйте её для:

  • Локальных дымовых тестов после включения
  • Проб готовности в Docker/Kubernetes
  • Внешних проверок доступности по приватному URL состояния, а не по публичному маршруту вебхука без аутентификации

Также логируйте:

  • Ошибки проверки подписи (возможная атака или неверно настроенный секрет)
  • Ошибки валидации полезной нагрузки
  • Длительность выполнения агента и отказы в одобрении инструментов
  • Ошибки доставки на стороне получателя (например, недоступность чат-API)

Без этих сигналов фраза «агент работал нестабильно» станет вашим единственным отчётом об инциденте. Эти записи улучшают наблюдаемость, но сами по себе не образуют полный защищённый от изменений аудиторский журнал.

Пример: открытие PR в GitHub → сфокусированное выполнение

Цель: Когда PR открывается в main, Hermes формирует заметку о рисках для человека. Он не сливает, не одобряет и не комментирует код, если вы позже не добавите маршрут доставки с проверкой.

  1. Создайте маршрут gh-pr-opened. Для прямой доставки GitHub настройте общий секрет, используемый для проверки X-Hub-Signature-256; для общего ретранслятора n8n реализуйте вместо этого контракт V2 HMAC с временной меткой.
  2. Фильтруйте по событиям pull_request / opened и базовому main.
  3. Промпт с контрактом: кратко изложите цель, область возможных последствий, отсутствующие тесты и риски развёртывания; отмечайте неизвестные данные; не давайте инструкций по слиянию.
  4. Инструменты: чтение из GitHub только если настроено; оболочка (shell) отключена или требует одобрения.
  5. Доставка: публикуйте markdown во внутренний канал; человек принимает решение о дальнейших шагах.

Показана структура хорошего результата агента (иллюстративная структура; формулировки вашей модели могут отличаться):

PR #1842: Добавить воркер повторных попыток выставления счетов (из ветки ada в main)

Факты
- Внесены изменения в воркер выставления счетов и конфигурацию очереди (на основе названия и списка файлов).
- Связанный URL: `https://github.example.invalid/acme/agent-service/pull/1842` (иллюстративный)

Риски
- Возможны лавины повторных попыток при отсутствии механизма экспоненциальной задержки [inference; verify in diff]
- В названии не указаны ключи идемпотентности [unclear]

Отсутствуют тесты для подтверждения
- Поведение при дублировании доставки / возникновении «отравленных» сообщений
- Настройка оповещений при исчерпании бюджета повторных попыток

Не сливать изменения на основе данного примечания. Требуется проверка человеком.

Это выполнение агента, управляемое событиями, с правилом остановки. Это не автономный владелец кода.

Упражнение: спроектируйте три маршрута перед включением хотя бы одного

На бумаге (или в вашей книге инструкций) опишите три маршрута вебхуков для вашего стека. Для каждого укажите:

  • Имя
  • Источник + фильтр событий
  • Метод аутентификации и владелец секрета
  • Поля полезной нагрузки: начните максимум с 10 полей, чтобы намеренно ограничить бюджет упражнения
  • Промпт: начните максимум с 8 строк, затем добавляйте только то, что требуют оценки маршрута
  • Разрешённые инструменты
  • Цель доставки
  • Поведение при сбое

Сначала реализуйте маршрут с наименьшим риском, обычно внутреннее оповещение или черновик сводки PR. Выполните curl к /health, затем аутентифицированный тестовый POST-запрос и тест с недействительной аутентификацией, после чего отправьте одно реальное событие в непроизводственном репозитории или тестовом проекте.

Ожидаемые режимы сбоев

  • Несоответствие секрета после ротации: аутентификация не проходит; исправьте окружение процесса шлюза, а не только оболочку ноутбука.
  • Слишком широкий промпт: агент импровизирует с инструментами; разделите маршрут.
  • Лавина повторных попыток: источник повторяет POST-запросы. Hermes кэширует идентификаторы доставки в течение часа, но для содержательной дедупликации требуется стабильный X-GitHub-Delivery или X-Request-ID. Действия, видимые клиенту, всё равно требуют устойчивой бизнес-идемпотентности со сроком хранения, соответствующим окну повтора.
  • Загрязнение памяти: большой поток оповещений достигает долговременной памяти; используйте отдельный профиль и явные настройки памяти.
  • Открытый порт: проверки работоспособности и вебхуки доступны без предусмотренных TLS и сетевых ограничений; исправьте сеть до добавления инструментов.

Ссылки, которые стоит держать открытыми

Агенты, управляемые событиями, наиболее эффективны, когда каждый маршрут узок, аутентифицирован и наблюдаем и имеет настроенную цель доставки. Адаптер вебхуков является входной точкой событий, а не API запрос-ответ с bearer-аутентификацией. Проектируйте и тестируйте его соответственно.

Читать дальше

Продолжайте тот же учебный путь со следующими практическими статьями.

Углубиться

Тщательно подобранные внешние курсы, которые глубже раскрывают эту тему.

DeepLearning.AI

Practical Multi AI Agents and Advanced Use Cases with crewAI

João Moura (Founder, CrewAI)

Одновременно закрывает вертикали продаж и клиентской поддержки и даёт по-настоящему практичный курс по агентам: вы строите агентный пайплайн продаж (скоринг лидов, персонализированный аутрич) и пайплайн инсайтов по данным поддержки — два из пяти практических проектов, — а преподаёт основатель CrewAI. Требует базового Python, поэтому стоит рядом с другими курсами builder-трека, а не с no-code выбором.

Уверенный~2h 49m · в своём темпе (15 уроков)
Hugging Face

AI Agents Course

Hugging Face

Самое понятное открытое изложение агентных систем. Курс не привязан к одному вендору: он рассматривает фреймворки, которые инженеры реально сравнивают, включая smolagents, LlamaIndex и LangGraph.

Уверенный~25 часов
Salesforce Trailhead

Quick Start: Assemble a Service Agent with Agentforce Builder

Salesforce Trailhead

Курс по no-code сборке агентов, которого не хватало нашему среднему уровню — каждый существующий средний выбор (LangChain, LlamaIndex, LangGraph, Hugging Face) предполагает, что вы пишете на Python. Здесь вы настраиваете реального сервисного агента, описывая желаемое простым языком в Agentforce Builder — без кода — на собственной бесплатной платформе Salesforce Trailhead.

Уверенный~40 минут · в своём темпе

Все курсы в категории «Автоматизация»