Hermes Agent 一旦接到 webhook,玩法就开始从会聊天的代理升级成能被外部事件唤醒的自动工人。比如 GitHub PR 来了,触发代码审查;GitLab push 了,触发通知;JIRA、Stripe 或其他系统 POST 事件过来,再把结果回投到 Telegram、Discord 或 GitHub comment。听起来很香,实际排障时也很容易让人发狂。因为 webhook 出问题时,表面症状往往只有一句:它怎么就是没反应?真正的根因却可能埋在端口、路径、签名、路由、deliver、CLI 权限甚至公网可达性里。
Hermes 官方的 Webhooks 文档其实已经把这些坑写得很明确,只是大家一碰 webhook 就容易本能地往 AI 没响应那个方向想,结果把最基础的 HTTP 链路问题忘得一干二净。
先把机制说清楚
Hermes 的 webhook adapter 本质上是一个 HTTP server,用来接收外部服务的 POST 请求,校验签名,把 payload 转成 prompt,再把结果路由回原服务或另一个平台。官方 Quick Start 给的第一步很明确:可以用 hermes gateway setup 启用 webhook,也可以手动在 ~/.hermes/.env 里设置:
WEBHOOK_ENABLED=true
WEBHOOK_PORT=8644
WEBHOOK_SECRET=...
这意味着 webhook 不是你在 config.yaml 里写个 route 它就自己活了,而是 Gateway 里真的要有一个 HTTP 服务在监听。服务没活,你 route 再漂亮也只是摆设。
一、最常见的第一坑:你以为它已经在收事件,其实 HTTP 服务压根没起来
Hermes 官方 Webhooks 文档把验证服务器是否真的在运行,写成了一个非常简单的健康检查:
curl http://localhost:8644/health
预期返回是:
{"status":"ok","platform":"webhook"}
如果这一步过不了,那后面 GitHub、GitLab、JIRA、Stripe 发什么事件都没有意义。很多人会先去看 route、看 payload、看签名,结果根本没意识到 webhook server 还没活。别笑,这类错误比签名错还常见。因为人类很容易把我配置过了理解成服务正在运行。现实世界的服务器并不懂这套心理学。
所以 webhook 排障的第一步永远是:先确认 Gateway / webhook adapter 真的在跑,/health 真的能回。如果这一步不通,别继续往上猜。你猜得越远,离问题越远。
二、8644 端口和 URL 路径是最土但最容易错的地方
Hermes 官方明确写了,webhook 默认端口是 8644,URL 路径格式是:
http://your-server:8644/webhooks/<route-name>
官方在 Troubleshooting 里对 Webhook not arriving 的排查也很直白:先确认端口是否暴露、是否可被 webhook source 访问、firewall 是否放行、URL path 是否写对。注意,是 <route-name>,不是你自己随便编的某个路径,也不是 gateway 的 home page。
很多 webhook 故障说到底就是一个普通的网络可达性问题,只不过因为前面套了个 AI Agent 的壳,大家总爱把它想得很高深。特别是把 Hermes 放在家宽、云主机、NAT 后面或者反向代理后面跑的人,更要注意这一点。我本地 curl 能通和 GitHub 能从公网打到你,是两码事。
官方文档说得非常直白:检查 firewall rules,确认端口 8644 或你的自定义端口必须开放。你要是服务器根本没暴露这口子,Webhook 当然只能在宇宙里默默消失。
三、签名校验失败,是第二大高频问题,而且每个平台的玩法还不一样
Hermes 的 webhook adapter 默认不是裸奔收包,它会做签名校验。官方文档把规则写得很细:
| 平台 | Header | 校验方式 | |------|--------|---------| | GitHub | X-Hub-Signature-256 | sha256= 前缀的 HMAC-SHA256 | | GitLab | X-Gitlab-Token | plain secret match | | 通用 | X-Webhook-Signature | 按配置 |
官方还特别强调:每条 route 都必须有 secret,要么自己写,要么继承全局 secret。没有 secret 的 route 会在启动时直接失败;如果为了开发测试想跳过校验,只能把 secret 设成 INSECURE_NO_AUTH,而且官方明确说这只建议测试使用。
这就意味着,签名问题别乱查。你得先问清楚自己面对的是谁。GitHub 和 GitLab 的校验逻辑就不一样,你拿 GitHub 的思路去看 GitLab,或者反过来,自然越看越乱。
Hermes 官方对 Signature validation failing 的建议也很实用:
- 确保 route config 里的 secret 和 webhook source 端配置完全一致
- 再看 gateway logs 里有没有 Invalid signature
所以这类问题本质不是 Agent 没响应,而是 HTTP 请求已经到了,但被安全层拦下来了。
四、事件进来了却被忽略,很多时候是 events 列表根本没匹配上
这是 webhook 场景最容易被忽略的一种逻辑错误。Hermes route 支持写 events 列表,用来限定接收哪些事件。如果这个列表不包含当前进来的事件类型,Agent 就会忽略它。
官方文档明确说:
- GitHub 常见值:pull_request、push、issues
- GitLab 常见值:merge_request、push
- 如果 events 为空或没设置,才表示全部接受
这意味着一种非常经典的伪故障:
- 路由存在
- 端口通
- 签名也对
- 结果 webhook 就是不触发
最后一查,发现你 route 里只接 pull_request,但发进来的是 push。这时候不是 Hermes 装傻,而是你自己把准入条件写死了。
这个坑尤其容易出现在你从一个 GitHub 示例复制 route,然后去接 GitLab 或别的系统时。不同平台头部事件名就不一样,别指望系统替你脑补。
五、Agent 其实响应了,只是 deliver 目标压根没配置对
Webhook 处理完事件后,还要把结果投出去。Hermes 的 docs 把这一步叫 deliver。官方列出的 deliver 类型包括:
- log(默认,只写日志)
- github_comment
- telegram
- discord
- slack
- signal
- sms
默认是 log,也就是只把结果写到 gateway log 里,适合测试。如果你以为它应该自动回到 GitHub PR 评论,但 route 里没写 deliver: github_comment,或者没补 deliver_extra.repo、deliver_extra.pr_number,那当然不会如你所愿。
这一点特别容易让人误判成 Agent 没处理。其实 Agent 可能早处理完了,只是 deliver 方式还是默认 log,结果全躺在日志里,没人通知你。
对 Telegram、Discord、Slack 这些 deliver 也是一样。官方文档说得很明白,这些 deliver 会优先走 home channel,或者你可以在 deliver_extra.chat_id 里明确指定。你要是连回投位置都没讲清楚,还要求系统把结果精准送回某个群聊,那属于把 AI 当算命先生用了。
六、GitHub comment 回投失败,通常不是 Hermes 的锅,而是 gh CLI 根本没准备好
这个坑非常工程化。Hermes Webhooks 文档专门给了 gh CLI 错误的 troubleshooting:
- 要在 gateway host 上执行 gh auth login
- 确保当前 GitHub 用户对目标仓库有写权限
- 确认 gh 已安装并且在 PATH 上
也就是说,你 route 里就算写了 deliver: github_comment,Webhook 就算进来了,签名就算过了,Agent 也就算跑完了,如果 gh CLI 没认证或没权限,评论还是发不出去。
这类问题最烦的地方,是它会让你误以为 webhook 主流程失败了。实际上前半段可能都正常,坏的是最后一步出站投递。所以一旦你碰到日志里像是处理了,但 GitHub 上没看到评论,优先去查 gh auth login、仓库写权限和 PATH,而不是回头重配 webhook route。前后链路要分清,不然你会在错误方向上循环劳动。
七、Webhook 路由写对了,Agent 还是不响应,官方给的排法其实很直接
Hermes 官方对 Agent not responding 这类 webhook 故障给的建议很少废话,核心就三条:
- 前台跑网关看日志 - 因为你一旦把 Gateway 挂成后台服务,很多其实已经报错的细节就容易被你错过
- 检查 prompt template 是否正确渲染 - 确认 payload 被正确解析
- 确认 deliver target 配置是否真的连通 - 验证回投链路
前台运行也很好理解,日志才是 webhook 场景里最诚实的东西,它不会替你顾面子。
另外,官方还提醒了一个更隐蔽的风险:prompt injection risk。Webhook payload 里很多字段,比如 PR title、commit message、issue description,本质上都是 attacker-controlled data。官方明确建议,面向公网暴露时要把 gateway 放在 sandboxed environment 里,比如 Docker 或 VM。
这个提醒虽然偏安全,但也和排障有关。因为你要是为了省事把 webhook gateway 暴露在极其宽松的环境里,后面看到奇怪行为时就很难判断:这到底是配置错了,还是有人拿 payload 在搞提示注入。
八、最省时间的排查顺序
如果你现在就遇到 Hermes Webhook 收不到事件或看起来不处理,建议直接照这个顺序来:
第一步:查 server 是否活着
curl http://localhost:8644/health
没返回 {"status":"ok","platform":"webhook"},别继续。
第二步:查端口和路径
- 确认 8644 或你的自定义端口已开放
- URL 是 http://your-server:8644/webhooks/<route-name>
- 不是自己想当然写的路径
第三步:查签名
- 确认 route secret 和 webhook source 配的一致
- 按 GitHub / GitLab / Generic 不同规则检查 header
第四步:查 events
- 确认当前进来的事件类型在 route 的 events 列表里
第五步:查 deliver
- 到底是默认 log,还是要投 GitHub comment / Telegram / Discord / Slack
- 对应的 deliver_extra 是否补全
第六步:如果是 GitHub 评论失败
- 直接查 gh auth login
- 仓库权限和 PATH
结语
Hermes Webhook 这类故障,最容易让人误判成 AI 没反应。但官方文档其实已经告诉你了,真正高频的问题大多都在更底层:
- 服务没起
- 端口没开
- 路径写错
- 签名没过
- 事件不匹配
- deliver 没配置
- gh 没登录
说白了,AI 只是坐在 webhook 流程后半段,前面的 HTTP 链、鉴权链和回投链要是没通,它根本轮不到出场。
所以,别一看到没响应就急着怀疑 Agent 本身。很多时候,最不性感、最土、最像传统后端排障的那部分,反而才是真问题。AI 再热闹,也逃不过端口、路径、日志和权限这几位老祖宗。
问题求助
没能解决你的问题?直接问我
如果你遇到任何技术问题无法解决,可以在这里提交求助。我会尽快查看并回复你。
支持作者
如果这篇文章帮到了你,可以支持我
扫码打赏,支持我持续更新原创排障文章。

