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"
}
}
规则:
- 每个路由应有一个预期结果,或一个明确的结果枚举。
- 将持久应用键保留在 n8n 或业务系统中。正文字段可用于关联日志,但 Hermes 不将其视为 Webhook 去重键。
- 对于相同交接的重试,请发送稳定的
X-Request-ID。Hermes 会缓存 Webhook 交付 ID 一小时,并在此窗口内跳过重复的运行或交付。 - 明确说明智能体_不得_执行的操作,例如发送、退款或删除。
- 优先使用摘录而非完整附件。将原始文件或二进制对象存储在其他位置,并仅传递 Hermes 被授权获取的引用。
为每类工作流(如
support-triage、ops-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 |
| URL | https://<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-ID 或 X-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 → 人工关卡
示例理想路径,不涉及任何部署或性能声明:
- 网站表单通过 POST 请求发送到 n8n 的 webhook
/support-intake。 - n8n 验证电子邮件、消息长度和来源枚举,然后持久认领
ticket-<uuid>。 - 如果政策要求,n8n 对字段进行脱敏,并构建边界明确的任务。
- HTTP 请求调用 Hermes 的
/v1/responses接口,使用端口8642,并携带 bearer 凭证和一个短期有效的Idempotency-Key。 - Hermes 将智能体结果返回给 n8n。
- n8n 验证必填字段并将草稿存储在持久工单键下。
- 审批人接受或拒绝存储的草稿。
- 仅被接受的草稿会传递到 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 结果路径:
- 在环回或私有接口上启用 API 服务器并设置
API_SERVER_KEY。 - 从 n8n 运行时网络验证需要身份验证的
/v1/models,并发起一次测试用的/v1/responses调用。 - 添加响应 schema 验证和一个持久的 n8n 应用键。
- 在任何面向客户的连接器之前添加人工审批关卡。
- 测试五分钟 API 缓存期内和缓存期外的重试。
对于事件 Webhook 路径:
- 启用 webhook 适配器,并配置一条路由、密钥、范围收窄的提示词、受限能力和交付目标。
- 验证
/health,并从 n8n 运行时网络发送一个带 V2 签名的测试事件。 - 发送一个稳定的
X-Request-ID并检查已交付与重复的适配器状态。 - 将测试触发器替换为经过验证的真实事件和持久的 n8n 键。
- 测试速率限制、正文大小、签名、时钟、交付以及服务停止失败情况。
生产流量前的验收测试
对于 API 接口,应保留以下证据:缺少或提供错误的 Bearer 密钥会被拒绝;测试请求返回预期 schema;使用相同 Idempotency-Key 立即重试不会启动第二次智能体执行;五分钟缓存期后的重试仍会被持久应用键阻止或对账;Hermes 停止时会进入可见的暂存状态;被拒绝的草稿绝不会到达发送连接器。
对于 webhook 接口,应保留证据证明未签名请求、签名后被修改的正文,以及超出 300 秒时间窗口的时间戳都会被拒绝。确认已签名的示例事件能到达配置的交付目标。在一小时内使用相同的 X-Request-ID 重复发送并验证重复状态,确保不会出现第二次智能体运行或交付。然后确认速率限制、正文过大、目标不可用和 Hermes 停止等失败对 n8n 可见。
只有当相关接口通过其验收测试且所有权明确时,集成才具备试点条件。Bearer 身份验证和 HMAC 只在各自文档定义的契约内确认调用方身份。五分钟 API 缓存和一小时 Webhook 交付 ID 缓存只是有时限的重试辅助机制。持久的应用幂等性、授权、审批状态和业务恢复仍由 n8n 或业务系统负责。



