Skip to content

Hermes 多智能体内网通信 — Redis 异步消息总线实战

视频演示如何在 Mac mini(Bobo)和 X230i(99)上构建基于 Redis 的异步消息总线,替代传统的 AI 群聊和 HTTP 同步模式,实现跨设备的工业级多智能体调度(Orchestrator)。Gemini 评价该系统为"工业级(Production-Ready)"。


目录


为什么群聊和 HTTP 同步不行

群聊模式的失败

把两个 AI 拉进 Telegram 群聊的典型问题:

  • AI 之间互相吹捧,形成"互吹灾难"
  • 缺乏中心化的"法官机制"控制流程
  • Token 消耗高但产出低
  • 无法做物理隔离和规则约束

"群聊是给人类用的,智能体用群聊 = 把严谨协议塞进噪声池。"

HTTP 同步模式的失败

多步任务(6 轮 Tool Call + 文件写入 + 自测 + 报告)通常需要 5-15 分钟/轮

问题 说明
客户端阻塞 requests.post(url, timeout=600) 导致调用方卡死
超时崩溃 5-10 分钟的 HTTP 超时仍不够
服务端宕机 服务 down = 客户端 deadlock
跨机通信 需要 SSH 隧道

"HTTP 同步是给人类短交互设计的,智能体长任务用它 = 自找崩溃。"


核心哲学:信箱而非电话

  电话模式(HTTP 同步)         信箱模式(Redis 队列)
  ─────────────────────        ──────────────────────
  打电话 → 必须等对方接          写信 → 扔进信箱就走
  对方忙 → 你卡在原地            对方忙 → 信在信箱等
  对方不在线 → 死锁              对方不在线 → 信还在
  通话结束 → 连接断开            信箱永不停业

解耦本质:任何人都能往任何节点的 inbox 推任务,任何人都能从任何节点的 inbox 消费。节点不需要知道其他节点是否在线。信箱本身就是协议。


系统架构

┌────────────── Mac mini (<YOUR_MAC_MINI_IP>) ──────────────┐
│ ┌─────────────┐ ┌──────────────┐ ┌───────────────────┐    │
│ │ Redis :6379 │ │ Hermes API   │ │ HTTP serve :8080  │    │
│ │ bind 0/0    │ │ :8642 (LLM)  │ │ (LaunchAgent)     │    │
│ └──────┬──────┘ └──────────────┘ └───────────────────┘    │
│        │ 0.7ms LAN, Redis shared                           │
└────────┼──────────────────────────────────────────────────┘
         │
    ┌────┴──── inbox:macmini ◄──── lpush(task) ──────┐
    └──── inbox:macmini ────► brpop(block=0) ──► worker_macmini
    ┌──── outbox:orch ────► brpop ──► orchestrator
    ┌──── inbox:99 ◄── 99 pushes ──────────────┘
         ▼
┌──── X230i / Pi 5 / Any Linux Node ────────────────────────┐
│ ~/.hermes/async_bus/                                       │
│ ├── worker_node.py      (protocol=2 for RESP3 fix)         │
│ ├── orchestrator_async.py (4-step, N-round debate)         │
│ ├── .env_common         (REDIS_HOST, API_URL, API_KEY)     │
│ └── worker_<NODE>.log    (systemd managed)                  │
│ systemd --user async_bus_worker_<NODE>.service             │
│ (Linger=yes → survives reboot / ssh logout)                 │
└───────────────────────────────────────────────────────────┘

关键特性: - Redis 监听 0.0.0.0,内网所有设备共享 - 0 SSH — 完全通过 Redis 队列通信 - 报告自动回到发起方的本地机器,无需 scp - systemd 托管,Linger=yes 保证 SSH 登出后不退出


三大核心设计

1. 隔离记忆池(Isolated Memory Pools)

每个 Agent 节点有独立的记忆空间,不共享上下文:

  ❌ 错误做法                    ✅ 正确做法
  ┌──────────────────┐          ┌──────────────────┐
  │   共享上下文       │          │ Bobo 记忆池       │
  │   Agent A 看到    │    →     │ 99 记忆池         │
  │   Agent B 的思考  │          │ Orchestrator 记忆 │
  └──────────────────┘          └──────────────────┘
  • 防止 Agent 间互相影响判断
  • Orchestrator 只看最终结果,不看中间过程
  • 各节点的 .env_common 独立配置

2. 严厉的系统提示词限制(Strict System Prompts)

限制类型 作用
角色锁定 每个 Agent 只做自己的事(编码/测试/审核)
输出格式 强制结构化输出(JSON、代码块)
Token 预算 限制每轮最大输出,防止无限展开
禁止社交 Agent 不被允许"讨论"或"协商"

3. 抢占式令牌机制(Preemptive Token Mechanism)

Orchestrator 控制任务分配和资源调度:

  Orchestrator 流程(4 步协议):
  ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
  │ 1. 分发   │───►│ 2. 执行   │───►│ 3. 审核   │───►│ 4. 汇总   │
  │   任务    │    │   任务    │    │   结果    │    │   报告    │
  └──────────┘    └──────────┘    └──────────┘    └──────────┘
       │               │               │               │
       ▼               ▼               ▼               ▼
    lpush inbox     brpop inbox     brpop outbox    写入报告
    (推到 worker)   (worker 消费)   (Orch 消费)     (发起方本地)

协议规范

任何框架实现这 3 条规则即可接入 Hermes-AgentMesh:

规则 格式 说明
队列命名 inbox:<NODE_NAME> 每个节点有独立 inbox
消息载荷 {turn: int, messages: [{role, content}]} 标准化的多轮消息格式
响应队列 outbox:orchestrator 所有节点统一回复到 Orchestrator

跨框架兼容性

框架 接入方式 推任务 消费任务
Hermes requests.post(API_URL, messages=...) 内置 内置
OpenClaw openclaw.run(inbox="my_agent", task=...) SDK SDK
LangGraph/AutoGen/CrewAI 包装 Redis client redis.lpush("inbox:node", task_json) redis.brpop("inbox:node")
自定义 Agent 任何支持 Redis + HTTP 的语言 同上 同上

实测结果

场景 结果 日期
Mac mini 模拟 macmini+99,4 轮 4.5 分钟 2026-06-09
Mac mini + X230i 真实跨机,4 轮 3.5 分钟,0 SSH 2026-06-09
99 worker 收到 Turn 999 ping 14 字 "99 在,收到 ping." 2026-06-10
Mac mini worker 收到 Turn 888 ping 65 字 "Bobo 在 Mac-mini.local 活着" 2026-06-10
99 发起 2 轮(WWDC 2026 话题) 2 分钟,报告回到 99 本地 2026-06-10

0 次失败,0 次回滚。


Bug 故事:Loopback Masking

Agent "99" 发现了 Bobo 在 orchestrator_async.py 第 6 行的一个 bug:

# Bug: if False 永远为假,else 分支总是执行
if False
    redis_host = os.getenv("REDIS_HOST", "127.0.0.1")
else:
    redis_host = "127.0.0.1"  # ← 实际总是走这里

为什么 Mac mini 上测不出:Redis 就在 localhost,127.0.0.1 恰好能连。6 轮辩论全部通过。

为什么在 99 上失败:Redis 在 Mac mini 上而非本机,连接立即失败。99 修复了 bug,加了 import os,设置了正确的回退 IP。

教训:单端测试永远抓不到"loopback masking" bug。真正的跨机测试必不可少。


部署要点

Mac mini(Redis 宿主)

# Redis 监听所有接口(内网使用)
# redis.conf: bind 0.0.0.0

# Hermes API 端口 :8642
# HTTP 服务 :8080(LaunchAgent 托管)

X230i(Worker 节点)

# ~/.hermes/async_bus/ 目录结构
# worker_node.py — 协议 2(redis-py 8 RESP3 修复)
# orchestrator_async.py — 4 步协议,N 轮辩论
# .env_common — REDIS_HOST, API_URL, API_KEY

# systemd 托管(Linger=yes)
systemctl --user enable async_bus_worker_99.service

关键配置项

配置 说明
REDIS_HOST Mac mini 的内网 IP
protocol=2 redis-py 8 的 RESP3 兼容修复
Linger=yes systemd 用户服务在 SSH 登出后继续运行
bind 0.0.0.0 Redis 监听所有网络接口

参考资料

相关笔记