n8n → Hermes:选择 API 调用还是事件 Webhook
中级10 分钟阅读自动化

n8n → Hermes:选择 API 调用还是事件 Webhook

将确定性的状态管理留在 n8n:当 n8n 需要智能体结果时调用 Hermes API;当一个事件应触发 Hermes 按配置完成交付时,则使用 webhook 适配器。

您应该能够做到的事情

当 n8n 需要智能体结果时,使用带 Bearer 身份验证的 Hermes API 服务器;对于经过身份验证的事件入口和由 Hermes 管理的交付目标,使用单独配置的 webhook 适配器。两种有时限的缓存都不能替代 n8n 中持久的应用幂等性。

仅在此浏览器中保存。
本文内容

n8n 在可预测的自动化方面表现强劲:接收事件、验证字段、调用 API、等待人工操作,并写入结果。当下一步需要解释时,例如对语言进行分类、起草回复、使用工具进行调查,或在上下文中确定“紧急”的含义时,Hermes Agent 就非常有用。

有两种清晰的模式,它们使用不同的契约。如果 n8n 需要取回智能体结果,以便继续验证、存储、审批或发送,应调用 Hermes API 服务器。如果 n8n 只是发出事件,而 Hermes 应把结果发送到已配置的 Slack、Telegram、GitHub、电子邮件或其他受支持目标,则应调用 webhook 适配器。

请使用 官方 Hermes API 服务器文档官方 webhook 文档NousResearch 仓库。此处没有记录任何第一方的 Hermes 特定 n8n 节点;n8n 使用其通用的 HTTP 请求节点。

通用的 n8n 发送方应使用 Hermes V2 HMAC 协议。其他提供商可以有特定于适配器的认证方式,例如 GitHub 的签名或 GitLab 的令牌。每条路由都需要其文档中说明的密钥。INSECURE_NO_AUTH 仅用于回环测试;当前 Hermes 拒绝在非回环绑定上启动它。

何时交接(以及何时不该交接)

留在 n8n

  • schema 验证与脱敏
  • 幂等键与去重(幂等与人工审批关卡
  • 带显式凭证的 CRM/邮件/Slack 连接器
  • 对外发送前的人工审批队列
  • Cron 与 webhook 触发

交给 Hermes

  • 需要文档或仓库上下文的模糊分类
  • 在 Hermes 运行时和经批准的能力策略下,使用工具进行多步骤调查
  • 应使用持久记忆或技能完成的起草任务
  • 基于智能体已有权限访问的私有语料库开展研究

不要交接

  • 可以通过 Switch 节点表达的纯 if/then 路由
  • 应该首先通过更便宜的分类器处理的高吞吐量生成循环
  • n8n 绝对不应该转发的机密信息(不要为了方便将令牌粘贴到 Hermes 中)

如果整个工作流由智能体驱动并从聊天触发,你可能需要网关式用户体验。参见 OpenClaw 与 Hermes 的工作流对比。如果要先在不使用 Hermes 的情况下构建 n8n 智能体,参见 n8n 中的第一个 AI 智能体

在构建之前选择契约

n8n 需要取回结果:
事件 → n8n 验证 + 持久键原子认领
     → HTTP 请求(Bearer)→ Hermes :8642/v1/responses 或 /v1/runs
     → n8n 验证结果 → 人工审批关卡 → 连接器

由 Hermes 交付结果:
事件 → n8n 验证 + 持久键原子认领
     → HTTP 请求(V2 HMAC)→ Hermes :8644/webhooks/<name>
     → Hermes 智能体运行 → 已配置的 Hermes 交付目标

API 服务器默认使用 127.0.0.1:8642,需要 API_SERVER_KEY,并提供兼容 OpenAI 的 /v1/chat/completions/v1/responses 以及 Runs API。持有该密钥的调用方可以使用 Hermes 的完整智能体工具集,包括终端和文件操作,因此应保持私有绑定并严格限制调用者。

Webhook 适配器默认使用端口 8644;健康检查地址是 http://localhost:8644/health ,路由位于 /webhooks/<name> 下。Webhook 运行会把结果发送到该路由配置的 deliver 目标。文档列出的目标包括聊天平台、GitHub 评论、电子邮件、Home Assistant 和 log,但没有定义通用 HTTP 回调目标。

n8n 仍然负责 SaaS 连接器和人工审批关卡的持久状态。Hermes 仍然只是边界明确的推理步骤。

Webhook 事件契约:小巧且明确

不要把整个 n8n 条目树全部倒入请求。应发送一个让智能体无需猜测就能执行的任务对象。

示意契约:

{
  "application_key": "ticket-18422",
  "task": "Classify severity and draft a support reply. Do not send email.",
  "customer": {
    "name": "Example GmbH",
    "plan": "business"
  },
  "message": "VPN drops every morning around 09:00.",
  "constraints": {
    "output": "json",
    "fields": ["severity", "rationale", "draft_reply"],
    "language": "en"
  }
}

规则:

  1. 每个路由应有一个预期结果,或一个明确的结果枚举。
  2. 将持久应用键保留在 n8n 或业务系统中。正文字段可用于关联日志,但 Hermes 不将其视为 Webhook 去重键。
  3. 对于相同交接的重试,请发送稳定的 X-Request-ID。Hermes 会缓存 Webhook 交付 ID 一小时,并在此窗口内跳过重复的运行或交付。
  4. 明确说明智能体_不得_执行的操作,例如发送、退款或删除。
  5. 优先使用摘录而非完整附件。将原始文件或二进制对象存储在其他位置,并仅传递 Hermes 被授权获取的引用。

为每类工作流(如 support-triageops-alert)创建专用的 Hermes Webhook 路由,并分别配置提示词、过滤器、密钥、技能和交付设置。把载荷中的每个字段都视为不可信内容。将运行时放入沙箱,缩小提示词模板范围,移除不必要的工具,并始终要求对破坏性或对外操作进行审批。

Hermes V2 的精确 HMAC 协议

对于通用的 n8n 发送方,当前 Hermes 文档规定使用 V2:

  • 请求头 X-Webhook-Timestamp:Unix 时间戳(秒);
  • 请求头 X-Webhook-Signature-V2:小写十六进制 HMAC-SHA256 值;
  • 签名字节:<timestamp>.<raw-request-body>
  • 重放窗口:时间戳必须在 Hermes 时钟的 ±300 秒范围内。

V1 的 X-Webhook-Signature 仅基于正文的格式仍然兼容,但没有重放保护机制。请勿在新工作流中使用。有关上游安全协议的详细信息,请参阅 上游安全协议

自托管的 n8n 签名节点

仅将 HERMES_WEBHOOK_SECRET 存储在 n8n 进程的密钥或环境变量机制中。不要将其放入 Set 节点或提交的流程 JSON 中。在 Code 节点中,仅当 n8n 配置允许该模块并允许节点访问环境时,才使用内置的 Node crypto 模块。

const { createHmac } = require('crypto');

const timestamp = Math.floor(Date.now() / 1000).toString();
const body = JSON.stringify($json.hermes_payload);
const secret = $env.HERMES_WEBHOOK_SECRET;

if (!secret) throw new Error('HERMES_WEBHOOK_SECRET is not configured');

const signature = createHmac('sha256', secret)
  .update(`${timestamp}.${body}`, 'utf8')
  .digest('hex');

return [{ json: { body, timestamp, signature } }];

对于自托管的 n8n,请根据当前的 Code 节点模块配置,只允许所需的内置模块,不要启用任意外部模块。使用外部 Task Runner 时,应把 NODE_FUNCTION_ALLOW_BUILTIN=crypto 作为 env-override 写入 /etc/n8n-task-runners.json,而不能只在 n8n 主容器中设置。能否访问 $env 还取决于 N8N_BLOCK_ENV_ACCESS_IN_NODE。如果安全策略禁止这种做法,请使用组织批准的签名服务,或从密钥存储读取凭据的自定义节点。不要把密钥粘贴进工作流。

配置以下 HTTP 请求节点:

字段
方法POST
URLhttps://<hermes-host>/webhooks/support-triage
正文内容类型原始 / application/json
正文{{ $json.body }}(发送时保持字符串不变)
请求头X-Webhook-Timestamp: {{ $json.timestamp }}
请求头X-Webhook-Signature-V2: {{ $json.signature }}
请求头X-Request-ID: ticket-18422:handoff-v1(同一次交接重试时保持稳定)
超时/重试有界;只按照持久键策略重试此次交接

签名后不要再使用 HTTP 节点的结构化 JSON 编辑器,因为重新序列化可能改变字节。遇到非 2xx 响应时必须拒绝继续处理。根据路由和交付 ID,200 响应可能表示已经交付,也可能表示重复请求;它不是返回给 n8n 的结构化智能体结果。不能仅因 Hermes 接收或交付了事件,就把 n8n 中的持久键标记为 completed

对于仅限局域网的 Hermes Webhook,仍需使用文档中说明的身份验证方式。网络位置在本地不等于已经完成身份验证。当前默认设置还限制每个 Webhook 路由每分钟最多 30 次请求,拒绝超过 1 MB 的请求体,并缓存 X-Request-IDX-GitHub-Delivery 的值一小时。这些是有明确边界的传输控制,而非持久的业务保证。

Webhook 请求体通常包含客户消息。请将 Hermes 和 n8n 保留在私有网络或受控加密覆盖网络中。当内容必须保留在你批准的边界内时,请优先使用本地 OpenAI 兼容模型的 base URL;详见 n8n 的本地端点。HMAC 用于验证发送方,而非消息体中业务字段的作者。

返回什么,以及谁发送

所用接口决定谁会收到结果。

A. 由 Hermes 管理交付的 Webhook 事件

该路由运行智能体,并把响应发送到已配置的 Hermes 交付目标。n8n 收到的是适配器状态,而不是智能体的结构化答案。当目标是 Slack、Telegram、GitHub、电子邮件或其他文档支持的交付目标,并且后续 n8n 步骤不需要响应内容时,使用这种方式。

B. API 结果返回给 n8n

当 n8n 必须接收结果时,调用 POST http://127.0.0.1:8642/v1/responses 并提供 Authorization: Bearer <API_SERVER_KEY>。如果智能体步骤应作为一次运行提交并接受观察,而不是占用一个同步 HTTP 请求,请使用 /v1/runs。API 默认仅监听环回地址,但即便如此也必须提供 bearer 密钥。

{
  "model": "hermes-agent",
  "input": "Classify severity and draft a reply. Return the agreed JSON fields."
}

调用完成后,n8n 验证响应 schema,把结果关联到持久应用键,并进入人工审批关卡。Hermes API 的五分钟 Idempotency-Key 响应缓存可以降低立即重试的风险,但不能替代 n8n 的持久认领、唯一性约束或业务状态转换。

失败模式

失败缓解措施
Hermes API 或 Webhook 停止仅在持久 n8n 键下重试;将项目存入 awaiting_agent;通知所有者
API Bearer token 被拒绝修复对应配置的密钥或路由;绝不绕过身份验证
Webhook 签名不匹配修复密钥、时间戳或精确字节编码;在网络绑定时绝不切换到 INSECURE_NO_AUTH
Webhook 载荷过大存储文档并传递授权引用;保留所需上下文并记录截断
重复的 Webhook 交付在一小时缓存内对相同重试使用相同的 X-Request-ID,并在 n8n 中保留持久键
重复的 API 请求仅在五分钟缓存内对立即重试使用 Idempotency-Key,并在 n8n 中保留持久键
智能体越权操作将运行时放入沙箱;限制工具和提示字段;要求审批破坏性或对外操作
网关环境漂移检查网关配置文件和服务环境,而不是假设交互式 shell 证明了运行时配置

仅当 Hermes 确实需要检查或操作 n8n 工作流时,才使用 Hermes MCP。如果实际契约只是 HTTP API 调用或事件 Webhook,直接使用相应接口更简单。

示例:支持表单 → Hermes API → 人工关卡

示例理想路径,不涉及任何部署或性能声明:

  1. 网站表单通过 POST 请求发送到 n8n 的 webhook /support-intake
  2. n8n 验证电子邮件、消息长度和来源枚举,然后持久认领 ticket-<uuid>
  3. 如果政策要求,n8n 对字段进行脱敏,并构建边界明确的任务。
  4. HTTP 请求调用 Hermes 的 /v1/responses 接口,使用端口 8642,并携带 bearer 凭证和一个短期有效的 Idempotency-Key
  5. Hermes 将智能体结果返回给 n8n。
  6. n8n 验证必填字段并将草稿存储在持久工单键下。
  7. 审批人接受或拒绝存储的草稿。
  8. 仅被接受的草稿会传递到 n8n 的电子邮件或 CRM 连接器。

在这条路径中,不应向 Hermes 提供具备发送能力的工具。提示可以写明“不要发送”,但真正防止不可信内容诱导智能体改向的控制措施,是移除发送能力,并只让 n8n 的受控连接器执行发送。

对于不返回到 n8n 的内部 Slack 汇总,应使用 webhook 接口:配置 deliver: slack,对事件进行签名,发送一个稳定的 X-Request-ID,并将适配器响应仅视为投递状态。

签名与时钟偏差

对于 Webhook 路径:

  • 将 JSON 序列化一次,使用这些精确的字节进行签名,并发送这些精确的字节。
  • 保持 n8n 和 Hermes 的时钟同步;否则,即使 V2 签名有效,但超出 300 秒窗口范围的签名将被拒绝。
  • 当前第一方文档未定义同时使用当前和之前的 Webhook 密钥。为已部署的版本使用受控切换或文档化的密钥轮换流程。
  • 使用路由名称和不含机密信息的关联标识符记录签名失败。绝不要记录密钥。

如果 n8n 在 Docker 中运行,而 Hermes 在主机上运行,请使用从 n8n 进程网络命名空间可路由的稳定地址。localhost 在该拓扑中指的是不同的命名空间。

自定义回调是一个独立的集成

当前 Hermes Webhook 文档没有列出通用 HTTP 回调交付目标。如果你的部署通过自定义代码或工具添加了该目标,应把它作为独立集成记录,并配置固定目标允许列表、身份验证、schema 验证、SSRF 边界、持久幂等性和验收测试。不要暗示入站 Webhook 正文中的 callback 字段会启用 Hermes 内置功能。

决策速查表

问题推荐
该步骤是否是固定的集成序列?仅 n8n
n8n 是否需要智能体返回的内容?Hermes API 在 :8642
Hermes 是否应处理事件并转发到其他位置?Hermes Webhook 在 :8644
出站电子邮件是否必须经过一个审批队列?API 结果 → n8n 验证 → 人工审批 → n8n 发送
用户是否已经在支持的 Hermes 聊天频道中?考虑直接与 Hermes 聊天频道交互,而不是通过 n8n 进行往返操作

最小构建顺序

对于 API 结果路径:

  1. 在环回或私有接口上启用 API 服务器并设置 API_SERVER_KEY
  2. 从 n8n 运行时网络验证需要身份验证的 /v1/models,并发起一次测试用的 /v1/responses 调用。
  3. 添加响应 schema 验证和一个持久的 n8n 应用键。
  4. 在任何面向客户的连接器之前添加人工审批关卡。
  5. 测试五分钟 API 缓存期内和缓存期外的重试。

对于事件 Webhook 路径:

  1. 启用 webhook 适配器,并配置一条路由、密钥、范围收窄的提示词、受限能力和交付目标。
  2. 验证 /health,并从 n8n 运行时网络发送一个带 V2 签名的测试事件。
  3. 发送一个稳定的 X-Request-ID 并检查已交付与重复的适配器状态。
  4. 将测试触发器替换为经过验证的真实事件和持久的 n8n 键。
  5. 测试速率限制、正文大小、签名、时钟、交付以及服务停止失败情况。

生产流量前的验收测试

对于 API 接口,应保留以下证据:缺少或提供错误的 Bearer 密钥会被拒绝;测试请求返回预期 schema;使用相同 Idempotency-Key 立即重试不会启动第二次智能体执行;五分钟缓存期后的重试仍会被持久应用键阻止或对账;Hermes 停止时会进入可见的暂存状态;被拒绝的草稿绝不会到达发送连接器。

对于 webhook 接口,应保留证据证明未签名请求、签名后被修改的正文,以及超出 300 秒时间窗口的时间戳都会被拒绝。确认已签名的示例事件能到达配置的交付目标。在一小时内使用相同的 X-Request-ID 重复发送并验证重复状态,确保不会出现第二次智能体运行或交付。然后确认速率限制、正文过大、目标不可用和 Hermes 停止等失败对 n8n 可见。

只有当相关接口通过其验收测试且所有权明确时,集成才具备试点条件。Bearer 身份验证和 HMAC 只在各自文档定义的契约内确认调用方身份。五分钟 API 缓存和一小时 Webhook 交付 ID 缓存只是有时限的重试辅助机制。持久的应用幂等性、授权、审批状态和业务恢复仍由 n8n 或业务系统负责。

继续阅读

通过下一篇文章继续沿着相同的学习路径进行学习。