Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • OpenClaw

  • Hermes-Agent

    • Hermes Agent 概述
    • Hermes Agent 实战 01|架构总览:用一个 Agent 管一整个机房
    • Hermes Agent 实战 02|多 Profile 与超管模型:一个 Agent 安全地管十几台机器
    • Hermes Agent 实战 03|Gateway 运维:systemd、裸进程,和一个 Telegram token 撞车
    • Hermes Agent 实战 04|模型路由实战:config 全解、thinking 注入与 401/503 源码级根因
    • Hermes Agent 实战 05|技能工程:写、去重、pin,与每周自我审计
    • Hermes Agent 实战 06|让 Agent 自己上班:cron 驱动的无人值守巡检
    • Hermes Agent 实战 07|数据库实战:可直接抄走的 SQL Server 巡检脚本
    • Hermes Agent 实战 08|量化交易助手:持仓盈亏、网格减仓,与「没开单」的真相
    • Hermes Agent 实战 09|接入 OpenWebUI:把每个 Profile 暴露成一个「模型」
    • Hermes Agent 实战 10|升级不翻车,与给上游提 PR:一个被冲掉三次的修复
    • Hermes Agent 实战 11|踩坑合集:当「手动 rm」从来不是真正的修复
    • Hermes Agent 实战 12|工具链外延:用 AI 运维 AI,与这个系列的诞生
    • Hermes Agent 实战 13|旗舰篇:让 Agent 从零部署并灾难恢复一个 7 节点生产集群
    • Hermes Agent 实战 14|跨 Profile 消息路由与自托管服务巡检:两个被忽略的边界
      • 1. 事件一:跨 Profile 发消息的「身份 confusion」
        • 1.1 场景与操作
        • 1.2 踩坑:Bot vs Profile,我混淆了分层
        • 1.3 另一个坑:Gateway vs Skill 的边界
      • 2. 事件二:RSSHub 与 wg-easy 的健康巡检
        • 2.1 场景
        • 2.2 RSSHub 巡检实战
        • 2.2 wg-easy 巡检实战
        • 2.3 踩坑:429 误报恐慌 & 流量统计误解
      • 3. 可复用要点
        • 3.1 Profile 与 Gateway 的分层心智模型
        • 3.2 自托管服务巡检清单
        • 3.3 无人值守巡检的「沉默即异常」原则
      • 4. Agent 可直接解析的元数据块
  • Claude-Code

  • AI-Agent
  • Hermes-Agent
Carry の Blog
2026-06-27
目录

Hermes Agent 实战 14|跨 Profile 消息路由与自托管服务巡检:两个被忽略的边界原创

# 跨 Profile 消息路由与自托管服务巡检:两个被忽略的边界

系列第 14 篇。这篇从两个真实的日常操作切入:一是让 superdba Profile 给 <INTERNAL_BRAND> 发消息时踩到的「Bot vs Profile」概念坑;二是对 RSSHub 和 wg-easy 做健康巡检时遇到的「429 误报」和「流量统计误解」。两个问题看似不相关,但核心都是边界认知偏差——对架构分层理解不清,导致排查路径错误。

# 1. 事件一:跨 Profile 发消息的「身份 confusion」

# 1.1 场景与操作

我想让 superdba Profile(一个专注 DBA 场景的 Hermes Profile)给同事 <USER> 发一条 Telegram 测试消息,验证跨 Profile 的消息路由是否通畅。

第一步:定位目标。通过检索 supermemory_search 和配置文件读取,定位到 channel_directory.json,提取出目标用户的 Telegram chat_id(已脱敏处理)。

第二步:确认身份状态。检查 gateway_state.json,确认 superdba 的 Telegram 网关状态为 connected。

第三步:发送。执行:

hermes send -t telegram:CHAT_ID_PLACEHOLDER
1

消息成功送达。但过程中我踩了一个概念坑。

# 1.2 踩坑:Bot vs Profile,我混淆了分层

症状:我最初以为需要找一个叫 <INTERNAL_BRAND> 的独立实体,甚至去翻有没有独立的 bot 配置。

原因:对 Hermes 的架构分层理解偏差。在 Hermes 中,Profile 本身就是身份的载体——superdba 这个 Profile 已经在其配置中绑定了 Telegram Bot Token,它就是那个 Bot。不存在一个独立的、与 Profile 平行的「Bot 对象」。

解药:

Profile = 身份 + 配置 + 网关的集合体。当你听到某个 Profile 名时,就应该意识到它已经包含了该身份的所有通信能力。

这种混淆在 multi-tenant 架构里很常见:用户习惯了「账号 → 多个 Bot」的模型,但 Hermes 是「Profile → 自带所有配置」的一体式设计。

# 1.3 另一个坑:Gateway vs Skill 的边界

这次我只用了 hermes send 这条 CLI 命令,它走的是 Gateway 层(系统级消息路由)。但 superdba 其实还有一个专属的 Skill(<SKILL_NAME>),用于格式化 DBA 日报、处理群组广播等业务逻辑。

两者的区别:

层级 用途 调用方式 特点
Gateway 系统通知、私聊测试、基础路由 hermes send 简单、直接、无业务逻辑
Skill 业务报告、格式化输出、群组管理 skill_invoke / prompt 调用 可复用、带模板、可组合

可复用要点:

普通私聊测试用 Gateway;正式业务通知(如 DBA 日报、告警广播)必须调用专属 Skill。不要把「能发消息」当成「正确地发了消息」。


# 2. 事件二:RSSHub 与 wg-easy 的健康巡检

# 2.1 场景

对自托管的 RSSHub(RSS 聚合服务)和 wg-easy(WireGuard 管理面板)进行定期健康巡检,排查潜在问题。

# 2.2 RSSHub 巡检实战

容器状态:rsshup 和 rsshup-browserless 均处于 Up 24h (healthy)。

核心指标验证:

# 健康端点检查
curl -s -o /dev/null -w "%{http_code}" http://localhost:1200/health
# 预期输出: 200

# Redis 缓存状态
redis-cli info keyspace
dbsize
# 预期输出: db0:keys=262,expires=262,avg_ttl=8280000 (约 2.3 小时)
1
2
3
4
5
6
7
8

性能测试:

time curl -s http://localhost:1200/cryptoslate > /dev/null
# 预期输出: 0.05s - 0.1s (缓存命中)
1
2

日志分析:观察到 JavBus 路由出现 429 Rate Limit 警告:

[2026-06-26T08:31:42] WARN: JavBus route returned 429, retrying (1/3)...
[2026-06-26T08:31:45] INFO: Retry successful, returning 200
1
2

这是一个典型的**「警告≠故障」**场景。RSSHub 内置了自动重试机制,429 触发重试后最终返回 200,用户侧无感知失败。

# 2.2 wg-easy 巡检实战

服务状态:容器运行 4 周,内存占用 32.71 MB,UDP 51820 端口正常。

客户端监控:列出所有客户端状态:

docker exec wg-easy wg show
# 预期输出(示例):
# peer: xxx...
#   endpoint: x.x.x.x:port
#   allowed ips: 10.x.x.x/32
#   latest handshake: 1 minute, 36 seconds ago
#   transfer: 12.45 MiB received, 244.32 GiB sent
1
2
3
4
5
6
7

这里遇到了两个认知坑。

# 2.3 踩坑:429 误报恐慌 & 流量统计误解

坑 1:429 警告引发的不必要恐慌

症状:日志中出现 429 Rate Limit,第一反应是「服务出问题了」。

原因:目标源(JavBus)触发了频率限制,但 RSSHub 的重试机制已覆盖此场景。

解药:

健康检查不能只看「有没有警告」,要看「最终是否成功」以及「缓存是否生效」。

坑 2:244GB 流量被误以为近期突发

症状:看到某个客户端 transfer: 244.32 GiB sent,以为是短时间内的大量上传。

原因:wg-easy 默认显示的是客户端创建以来的累计流量,不是实时速率,也不是近期统计。

解药:

WireGuard 统计口径 = 累计值(持久化到接口重启)。如需监控实时速率,需自行计算差分(如 Prometheus + node_exporter),或定期清零(重建客户端或重启 WG 接口)。

坑 3:握手延迟 ≠ 离线

症状:某客户端显示 latest handshake: 1 minute, 36 seconds ago,担心它已离线。

原因:WireGuard 协议的 Keepalive 间隔较长,3 分钟内无数据交互仍视为在线。

解药:

离线判定要结合「状态」字段和实际业务逻辑,不能仅看握手时间戳。


# 3. 可复用要点

# 3.1 Profile 与 Gateway 的分层心智模型

┌─────────────────────────────────────────┐
│             Skill 层                    │  ← 业务逻辑、格式化、模板
│        (<INTERNAL_BRAND> Skill)             │
├─────────────────────────────────────────┤
│           Gateway 层                     │  ← 系统路由、基础消息
│     (hermes send, telegram)              │
├─────────────────────────────────────────┤
│           Profile 层                     │  ← 身份 + 配置 + Token
│   (superdba: token + gateway_state)      │
└─────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10

Profile 不是「使用 Bot」,Profile 就是 Bot。

# 3.2 自托管服务巡检清单

RSSHub 巡检维度:

  1. 容器状态(Up/Down/Healthy)
  2. 健康端点(HTTP 200)
  3. Redis 缓存:key 数量 + TTL 分布(理想:所有 key 带 TTL)
  4. 关键路由响应时间(<100ms 为优)
  5. 日志警告:429/500 等是否被重试机制覆盖

wg-easy 巡检维度:

  1. 容器资源占用(内存、CPU)
  2. 端口监听(UDP 51820)
  3. 客户端列表:在线/离线状态
  4. 握手时间(<3min 视为在线)
  5. 累计流量(识别异常高流量设备)

# 3.3 无人值守巡检的「沉默即异常」原则

如前一篇文章所述,任何无人值守任务都应发送心跳,即使一切正常:

✅ rsshup-health clean (24h uptime, 262 cached keys, p99 51ms)
⚠️  wg-easy: <DEVICE> accumulated 244GB traffic, review needed
1
2

让「群里没消息」本身成为可检测的异常信号。


# 4. Agent 可直接解析的元数据块

{
  "_meta": {
    "doc_version": "2026-06-27",
    "article_id": "hermes-14-routing-inspection",
    "profile_context": "any",
    "estimated_setup_time": "20min"
  },
  "quick_start": {
    "step_1": "检查 Profile 网关状态: cat ~/.hermes/profiles/<name>/gateway_state.json",
    "step_2": "发送测试消息: hermes send -t telegram:<chat_id>",
    "step_3": "RSSHub 健康检查: curl -s http://localhost:1200/health",
    "step_4": "wg-easy 客户端状态: docker exec wg-easy wg show"
  },
  "safety_rules": [
    "区分 Gateway 层(系统路由)与 Skill 层(业务逻辑),正式通知走 Skill",
    "RSSHub 429 警告≠故障,需确认重试机制和缓存状态",
    "wg-easy 流量统计为累计值,非实时速率",
    "WireGuard 离线判定阈值为 3 分钟无握手"
  ],
  "verification": {
    "profile_connected": "cat ~/.hermes/profiles/<name>/gateway_state.json | grep connected",
    "rsshub_healthy": "curl -s -o /dev/null -w '%{http_code}' http://localhost:1200/health",
    "wg_clients": "docker exec wg-easy wg show | grep -c 'peer:'",
    "redis_cache": "redis-cli dbsize"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

AI Agent 使用指南:

  • 当用户说「让 X Profile 给某用户发消息」→ 执行 quick_start.step_1 确认网关状态,然后 quick_start.step_2(替换 chat_id)
  • 当用户说「巡检 RSSHub」→ 执行 quick_start.step_3 + verification.rsshub_healthy,配合 verification.redis_cache
  • 当用户说「检查 WireGuard 客户端」→ 执行 quick_start.step_4,注意对照 safety_rules[2] 和 safety_rules[3] 解释统计值

下一篇:实战旗舰:XX

#AI Agent#Hermes#Profile#Gateway#巡检#RSSHub
上次更新: 6/26/2026

← Hermes Agent 实战 13|旗舰篇:让 Agent 从零部署并灾难恢复一个 7 节点生产集群 Claude Code 概述→

最近更新
01
Hermes Agent 实战 13|旗舰篇:让 Agent 从零部署并灾难恢复一个 7 节点生产集群 原创
06-22
02
Hermes Agent 实战 12|工具链外延:用 AI 运维 AI,与这个系列的诞生 原创
06-22
03
Hermes Agent 实战 11|踩坑合集:当「手动 rm」从来不是真正的修复 原创
06-22
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式