1. 为什么要把 GitHub/GitLab/Jenkins 事件接进 Hermes AgentWebhook 这个词听起来像运维黑话其实一句话就能说清它是「反向 API」。平时是你去问 GitHub「有新 PR 吗」问十次九次空手而归Webhook 是 GitHub 在 PR 合并那一刻主动往你的服务器 POST 一条 JSON。Hermes Agent 的网关能暴露 HTTP 端点把这条 JSON 当成一条「用户消息」塞进新的 Agent 会话于是代码审查、构建分析、告警通知这些动作就能被事件自动触发。我把它用在三个场景GitHub PR 合并后自动跑一遍代码审查、GitLab push 到 release 分支时检查提交规范、Jenkins 构建失败时让 Agent 读日志给出可能原因。这三个场景的共同点是——事件发生的时间点不确定轮询要么浪费请求要么延迟高Webhook 刚好补上这块。但真正落地时卡人的往往不是 Webhook 本身而是 Agent 背后要调用大模型。GitHub、GitLab、Jenkins 三个系统各配一套 Key轮换、额度、审计全是麻烦。这篇的做法是Webhook 链路照常搭模型调用统一走 TaoToken 的 API 通道一个 Key 覆盖 Hermes Agent 里所有需要推理的环节。下面从配置到验证一步步来命令和 JSON 都能直接复制。适合谁看已经装好 Hermes Agent、想让外部系统事件驱动 Agent 的开发者正在被多套模型 Key 管理折磨的运维以及想搞明白 Webhook 从触发到 Agent 响应整条链路的人。核心检索词就三个Webhook 订阅、Hermes Agent、统一 Key。2. TaoToken 前置准备统一 Key 与 Hermes 的模型通道Hermes Agent 处理 Webhook 时真正消耗资源的是「Agent 处理」这一步——它要把 Webhook 的 JSON 理解成任务、决定调哪些工具、生成审查报告。这一步背后是模型推理。如果 GitHub 事件走一套 Key、Jenkins 事件走另一套时间一长你自己都记不清哪个 Key 对应哪个系统。TaoToken 在这里的角色是「统一模型入口」Hermes Agent 的模型配置指向一个 Base URL所有 Webhook 触发的会话都用同一个 Key 去请求。官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 注意 API 地址不带查询参数配置时别把 UTM 拼进去。你需要准备三样东西我把它叫「三件套」后面每个集成场景都会用到配置项值说明Base URLhttps://taotoken.net/apiHermes 模型请求的根地址API Key在控制台创建形如sk-开头的一串Model ID按控制台可用列表填例如claude-sonnet-4-5这类标识Key 的创建入口在控制台的 API Keys 页面登录后新建即可建议给 Hermes 单独建一个 Key方便按用途区分额度。模型 ID 不要凭记忆写去模型对话页面确认当前可用的标识复制过来最稳。Hermes Agent 侧的模型配置通常写在它的配置文件里不同版本路径略有差异常见是~/.hermes/config.toml或项目根目录的hermes.toml。核心就是让 provider 指向 TaoToken# ~/.hermes/config.toml [model] provider openai-compatible base_url https://taotoken.net/api api_key sk-你的Key model claude-sonnet-4-5这里用openai-compatible是因为 TaoToken 的 API 兼容 OpenAI 风格的请求格式Hermes 只要支持自定义 Base URL 就能接。配完之后先别急着配 Webhook用一条最简请求确认模型通道是通的curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-你的Key \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-5, messages: [{role: user, content: 回复 ok}] }返回里能看到choices数组且内容正常说明模型通道没问题。这一步很关键——如果模型通道本身不通后面 Webhook 触发了你也只会看到 Agent 报错排查方向会被带偏。我试过先跳过这步直接配 Webhook结果 GitHub 那边显示 200Agent 这边静默失败查了半天才发现是 Key 写错了。如果你后续要做长期编码类 Agent比如让 Webhook 触发的会话持续跑多轮工具调用可以了解下 Coding Plan 这类按周期计费的方案比按量更适合高频事件场景。入口在 https://taotoken.net/api 对应的控制台里能找到这里不展开。3. 可复制配置GitHub/GitLab/Jenkins 三套 Webhook 片段这一节是全文最实操的部分。Hermes Agent 创建 Webhook 路由的命令是hermes webhook subscribe NAMENAME 就是路由名最终端点路径是/webhooks/NAME。三个系统各建一个路由互不干扰。先建路由hermes webhook subscribe github-pr-merge hermes webhook subscribe gitlab-push hermes webhook subscribe jenkins-build建完用hermes webhook list确认应该能看到三条记录和各自的路径。接下来是三个系统各自的配置片段。GitHub 侧进入仓库 Settings → Webhooks → Add webhook。Payload URL 填你的公网地址加路径Content type 选application/jsonSecret 填一个随机字符串后面 Hermes 端要对应验证事件选 Let me select individual events 后勾 Pull requests。对应的配置等价 JSON 如下方便你用 API 批量建{ name: web, active: true, events: [pull_request], config: { url: https://your-server/webhooks/github-pr-merge, content_type: application/json, secret: your-github-secret, insecure_ssl: 0 } }GitLab 侧进入项目 Settings → Webhooks。URL 填https://your-server/webhooks/gitlab-pushSecret token 同样填随机串Trigger 勾 Push events 和 Merge request events。GitLab 的签名头是X-Gitlab-Token和 GitHub 的X-Hub-Signature-256不一样Hermes 端验证逻辑要区分。Jenkins 侧稍微绕一点因为 Jenkins 原生 Webhook 支持不如前两者直接。常见做法是装 Generic Webhook Trigger 插件或者用构建后步骤发一个 POST。用 curl 模拟 Jenkins 构建完成通知curl -X POST https://your-server/webhooks/jenkins-build \ -H Content-Type: application/json \ -H X-Jenkins-Token: your-jenkins-secret \ -d { job: order-service-build, build_number: 128, status: FAILURE, log_url: https://jenkins.example.com/job/order-service-build/128/console }三个路由建好后还要告诉 Agent 收到事件后干什么。Hermes 的做法是在工作目录的AGENTS.md里定义处理逻辑Agent 每次新会话都会读它## Webhook 处理规则 ### github-pr-merge 收到 GitHub PR 合并事件时 1. 从 body 提取 pull_request.title、merge_commit_sha、changed_files 2. 对变更文件做代码审查重点看空指针、边界条件、日志泄露 3. 发现问题则整理成清单发送到配置的通知频道 ### gitlab-push 收到 GitLab push 事件时 1. 检查 commit message 是否符合 Conventional Commits 2. 不符合则列出违规条目 ### jenkins-build 收到 Jenkins 构建事件时 1. status 为 FAILURE 时读取 log_url 内容 2. 归纳最可能的失败原因给出排查建议这里有个细节AGENTS.md里的规则越具体Agent 处理越稳定。只写「处理 Webhook」这种模糊描述模型容易自由发挥。把字段名、判断条件、输出格式都写清楚相当于给 Agent 一份操作手册。安全方面三个系统都支持 Secret 签名。Hermes 端验证失败会返回 401/403这是好事——说明伪造请求被挡住了。公网暴露的端点一定要开 Secret 验证否则任何人都能 POST 一条假事件消耗你的模型额度。如果服务器不方便暴露公网可以在 Nginx 层做 IP 白名单只放行 GitHub/GitLab 的官方 IP 段或者干脆把端点放在内网、通过内网 Jenkins 触发。4. 验证请求用一次真实推送确认订阅生效配置写完不验证等于没配。验证分两层先确认 Webhook 端点能收到请求再确认 Agent 真的处理了。第一层用 Hermes 自带的测试命令hermes webhook test github-pr-merge它会往本地端点发一个测试 POST返回 200 且日志里能看到请求体被接收说明路由是活的。这一步不消耗模型额度适合快速排错。第二层是真实事件。去 GitHub 仓库随便提一个 PR 然后合并或者直接对已有 PR 点 merge。合并后回到 GitHub Webhook 页面点进刚建的 webhook看 Recent Deliveries 标签页——应该有一条记录Response 是 200。如果显示红色失败点开看 Response body通常是签名不匹配或路径写错。同时看 Hermes 这边的日志正常会看到类似这样的会话记录[Webhook: github-pr-merge] 新会话创建 Body: {action:closed,pull_request:{title:Refactor order service,merged:true,...}} Agent 开始处理...Agent 处理完后按AGENTS.md的规则审查结果会发到你配置的通知频道。如果用的是 Telegram检查对应 bot 有没有收到消息。到这一步整条链路就算通了GitHub 合并 PR → Webhook POST → Hermes 网关 → 创建 Agent 会话 → 模型推理走 TaoToken 统一 Key→ 输出审查报告。GitLab 和 Jenkins 的验证同理。GitLab 在 Webhooks 页面有「Test」按钮可以选 Push events 发测试Jenkins 用上面那条 curl 手动发一次看 Hermes 日志有没有收到。三个都验证过你的事件驱动自动化才算真正落地。验证时有个容易忽略的点模型返回的choices字段。如果 Agent 日志里出现reading choices相关报错说明模型通道返回格式不对多半是 Base URL 或 Model ID 写错了。回到第 2 节的 curl 测试重新确认。5. 本篇常见错排查401、local proxy failed、reading choicesWebhook 链路的报错有个特点错误可能出现在四个位置——发送方GitHub、网络层、Hermes 网关、模型通道。定位错位置会浪费大量时间。下面按真实遇到的报错逐个拆。401 UnauthorizedHermes 网关返回最常见。原因通常是 Secret 不匹配。GitHub 的签名算法是 HMAC-SHA256用 Secret 对请求体签名后放在X-Hub-Signature-256头里Hermes 端要用同样的 Secret 和算法验证。检查两边 Secret 是否完全一致注意别把 GitHub 的 Secret 填到 GitLab 路由上。另一个可能是请求体被中间层改过比如 Nginx 做了 body 转换导致签名对不上。local proxy failed这个报错指向网络层。Hermes 网关在验证或转发时连不上目标常见于 Nginx 反向代理配置错误比如proxy_pass地址写错、端口不通。检查 Nginx 配置里location /webhooks/的转发目标是否指向 Hermes 实际监听的端口。如果 Hermes 跑在容器里确认端口映射正确。reading choices 报错这个出现在模型通道。Agent 拿到模型响应后要读choices[0].message.content如果返回结构不对就会报这个。原因一般是 Base URL 少了/v1或多了斜杠。TaoToken 的请求路径是https://taotoken.net/api/v1/chat/completions配置里 Base URL 填https://taotoken.net/apiHermes 会自动补/v1。如果你手动填了https://taotoken.net/api/v1可能变成/v1/v1就会出问题。OAuth 相关报错如果你在 Hermes 里配了需要 OAuth 的模型 provider又同时想用统一 Key会冲突。解决办法是把 provider 切成openai-compatible用 API Key 认证不走 OAuth 流程。Codex 的auth.json那套是另一条路径和这里的统一 Key 不混用。Webhook 返回 200 但 Agent 没反应最隐蔽。GitHub 显示成功但通知频道没消息。检查AGENTS.md是否在正确的工作目录、Agent 会话是否真的创建了。有时候是 Webhook 路由建了但没绑定处理逻辑Agent 收到消息后不知道干什么就静默结束了。在AGENTS.md里补上对应路由的处理规则即可。排查顺序建议先看发送方的 Delivery 记录确认请求发出去了再看 Hermes 日志确认收到了再看模型通道 curl 测试确认推理正常最后看通知频道。按这个顺序走基本不会绕路。6. 把统一 Key 用在长期事件流上Webhook 是事件驱动的事件频率决定了模型调用量。PR 合并、push、构建失败这些事件在活跃仓库里一天几十上百次很正常如果每个事件都触发一次 Agent 推理按量计费的 Key 月底账单会很难看。我的做法是分两层高频但轻量的事件比如 push 检查 commit 规范用便宜快速的模型低频但重的事件比如 PR 合并代码审查用能力强的模型。Hermes 支持按路由指定不同模型在AGENTS.md或路由配置里区分即可。这样统一 Key 管的是「入口」模型选择管的是「成本」。如果你打算把 Webhook 触发的 Agent 做成长期跑的服务比如让它在构建失败后持续跟进、多轮调用工具排查那按周期计费的 Coding Plan 会比按量更划算。入口在控制台里按你的实际调用频率算一下就知道哪种合适。最后留一个实用技巧给每个 Webhook 路由的 Agent 会话加一个「事件指纹」——把X-GitHub-Delivery或 GitLab 的X-Gitlab-Event-UUID记进日志。这样当同一个事件被重复投递网络重试很常见时你能快速识别并去重避免 Agent 对同一个 PR 审查两遍。这个头在请求里就有AGENTS.md里加一行提取规则即可。整条链路跑通后你会发现 Webhook 真正的价值不是「自动」而是「及时」。轮询模式下你永远慢半拍事件驱动下 Agent 在 PR 合并的下一秒就开始工作。把 GitHub、GitLab、Jenkins 三个源头都接进来再配上统一 Key 管住模型调用这套组合能覆盖大部分研发流程里的自动化需求。