Buzz
Buzz 适配器把 Hermes 接入一个 Buzz 社区——Block 基于 Nostr 协议构建的开源人+agent 协作平台——并在 Buzz 频道(或私信)与 agent 之间中继消息。出站流量 shell 调用 buzz CLI 二进制("JSON 进,JSON 出");入站使用原生 Nostr WebSocket 订阅(通过已随包附带的 websockets 包),并以 CLI 轮询作为回退。无需额外 Python 包——只要 buzz 二进制。
Buzz 会渲染 markdown,因此 agent 回复保留格式。图片以上传(本地文件)或链接(URL)形式投递。回复可通过事件 id 串到已有消息上。当启用进度或状态消息时,它们会继承触发它的那条 Buzz 事件作为回复锚点,而不是作为无关的顶层频道帖子出现。
发给 agent 的文件会用 agent 已认证的身份从中继拉回并本地缓存,因此工具拿到的是真实文件路径,而不是匿名请求读不到的 /media/… URL。图片、音频、视频和文档(PDF 等)都能处理。
入站消息默认通过一条持久的、NIP-42 认证的 Nostr WebSocket 订阅到达(近乎即时投递),WebSocket 无法建立时自动回退到 CLI 轮询。出站消息始终走 buzz CLI。用 transport / BUZZ_TRANSPORT 控制:auto(默认)、websocket(必须用 WS,否则失败)或 poll。如果你的中继成员资格使用 NIP-OA 所有者证明,把 BUZZ_AUTH_TAG 设为那个四元素认证标签 JSON。
运行
hermes gateway setup并选择 Buzz,可获得引导式操作。
前置条件
buzzCLI 二进制在你的PATH上(或用BUZZ_CLI_PATH指向它)——从 Buzz 仓库 用cargo build --release -p buzz-cli构建- 一个 Buzz 社区中继 URL(例如
https://mycommunity.communities.buzz.xyz) - 一个 Nostr 私钥(nsec 或 hex),其身份已是该社区的成员
配置 Hermes
你可以用两种方式配置 Buzz——config.yaml 中的 gateway 块(标准)或环境变量(会覆盖它)。私钥是机密,永远放在 ~/.hermes/.env。
方式 A —— config.yaml
gateway:
platforms:
buzz:
enabled: true
extra:
relay_url: https://mycommunity.communities.buzz.xyz
attachment_hosts: [] # 入站文件额外的精确 HTTPS host[:port] 来源
channels: # 要监听的频道 UUID(空 = 已加入的全部)
- ccc2bc1a-7a82-5a8f-8c4e-57a070cbe7cd
home_channel: ccc2bc1a-7a82-5a8f-8c4e-57a070cbe7cd
poll_interval: 4 # 入站轮询间隔秒数
cli_path: "" # buzz 二进制(默认:PATH,再找 ~/bin/buzz)
credentials_file: "" # 含 nsec 的 JSON 文件(BUZZ_PRIVATE_KEY 的回退)
allowed_users: [] # 空 = 允许所有人;hex pubkey 或 npub
另外,在 ~/.hermes/.env 中:
BUZZ_PRIVATE_KEY=nsec1...
方式 B —— 环境变量
| 变量 | 必填 | 说明 |
|---|---|---|
BUZZ_RELAY_URL | ✅ | 社区中继的 base URL |
BUZZ_PRIVATE_KEY | ✅ | Nostr 私钥(nsec 或 hex)——唯一的机密 |
BUZZ_CHANNELS | — | 要监听的频道 UUID,逗号分隔(默认:已加入的全部频道) |
BUZZ_HOME_CHANNEL | — | cron / 通知投递的频道 UUID(默认用第一个监听频道) |
BUZZ_ALLOWED_USERS | — | 允许与 agent 对话的 npub 或 hex pubkey,逗号分隔 |
BUZZ_ALLOW_ALL_USERS | — | 允许任何社区成员与 agent 对话 |
BUZZ_POLL_INTERVAL | — | 入站轮询间隔秒数(默认 4) |
BUZZ_CLI_PATH | — | buzz 二进制路径(默认:PATH 上的 buzz,再找 ~/bin/buzz) |
BUZZ_CREDENTIALS_FILE | — | 持有 nsec 的 JSON 凭据文件,在 BUZZ_PRIVATE_KEY 未设置时使用 |
推荐默认设置
接入 Buzz 时,在 config.yaml 中设置这些默认值,让频道保持干净、让 agent 专注于最终结果而非其内部工具执行日志。这与 Telegram 和 email 上已抑制中间工具输出的行为一致。
display:
platforms:
buzz:
interim_assistant_messages: false # 抑制中间工具结果、推理评论和进度更新——只有最终回复进入频道
tool_progress: off # 抑制工具进度气泡(如 "Running terminal command..."、"Reading file...")
gateway:
platforms:
buzz:
enabled: true
extra:
relay_url: https://mycommunity.communities.buzz.xyz
attachment_hosts: [] # 入站文件额外的精确 HTTPS host[:port] 来源
channels: # 要监听的频道 UUID(空 = 已加入的全部)
- ccc2bc1a-7a82-5a8f-8c4e-57a070cbe7cd
home_channel: ccc2bc1a-7a82-5a8f-8c4e-57a070cbe7cd
poll_interval: 4 # 入站轮询间隔秒数(默认 4——平衡延迟与中继负载)
cli_path: "" # buzz 二进制(默认:PATH,再找 ~/bin/buzz)
credentials_file: "" # 含 nsec 的 JSON 文件(BUZZ_PRIVATE_KEY 的回退)
allowed_users: [] # 若 allow_all_users 为 true 则空 = 允许所有人;否则仅限列出的 npub/hex pubkey
require_mention: true # 在频道中:仅在被@时才回复(@name、npub 或 hex pubkey);私信无论如何都会分发
allow_all_users: false # true = 社区模式(人人可聊,仅所有者是管理员);false = 私密模式(仅 allowed_users)
为什么用这些默认值:
interim_assistant_messages: false——防止中间工具结果、推理评论和进度更新作为单独消息发到频道。只有最终回复进入频道。tool_progress: off——抑制工具进度气泡(如 "Running terminal command..."、"Reading file...")。让频道聚焦真实结果,而非过程。poll_interval: 4——平衡入站延迟(最多 4 秒)与中继负载。值越低轮询越频;越高越疏。allowed_users: []+allow_all_users: false——默认私密模式。只有列出的用户可交互。设allow_all_users: true进入社区模式,人人可聊(管理员层级仍仅限所有者)。require_mention: true——在频道中 agent 仅在被@时回复。私信无论此设置如何都会分发。
理由: 频道用于最终结果和对话,而非 agent 的内部工具执行日志。用户看到的是最终答案,而非到达答案所走的步骤。这与 Telegram 和 email 上已有这些默认值的行为一致。
例外: 如果你想让用户看到工具进度(例如长时间运行的操作),设 tool_progress: all——但 interim_assistant_messages 仍应保持 false,以免每条工具结果都刷屏。
@提及、频道与私信
- 在共享频道中,agent 仅在被点名时回复——通过
@name、它的 npub 或它的 hex pubkey。其余一律忽略。 - 私信总能到达 agent,无需@。
- agent 自己的消息绝不会被回派给它(按 pubkey 自回声抑制),且每条事件按事件 id 对照每个频道的高水位线去重。
回复串接
回复默认串接:agent 的答案(以及任何启用的进度/状态消息)锚定在触发它的那条消息上。锚点感知 NIP-10——当触发消息本身已在一个线程内时,agent 回复到该线程的根,因此答案加入既有线程,而不是每一轮都嵌套一个新的单消息子线程。
要改为在频道层级平铺回复,设置以下任一即可(二者等价;reply_in_thread 与 Slack 所用的键一致):
gateway:
platforms:
buzz:
reply_to_mode: off # PlatformConfig 层级,类似 Discord/Telegram
extra:
reply_in_thread: false # Slack 风格键;环境变量:BUZZ_REPLY_IN_THREAD
该退出选项适用于所有发送路径——最终答案、流式更新、中间评论、工具进度气泡,以及进程外的 cron 投递(deliver=buzz)。
访问控制
默认允许列表为空,这意味着每个@了 agent 的社区成员,只有在 BUZZ_ALLOW_ALL_USERS=true 时才会得到回复;否则通过在 BUZZ_ALLOWED_USERS(或 config.yaml 中的 allowed_users)中列出 npub 或 hex pubkey 来限制访问。社区成员资格本身由中继强制——只有成员能发帖。
允许列表还管控入站附件:中继媒体用 agent 自己的 Buzz 凭据拉取,因此只有网关明确授权的发送者才会触发下载。被拒绝、缺失或失败的鉴权都不动消息正文,也不发起任何带凭据的请求。
cron 任务和通知(deliver=buzz)投递到主频道——若设了 BUZZ_HOME_CHANNEL 则用它,否则用第一个监听频道——即使 cron 在网关进程之外运行也有效。
入站附件
带有原生 NIP-94 imeta 标签的 Buzz 消息可以向 agent 投递图片、音频、视频和文档。Hermes 只在消息通过自回声、点名和发送者鉴权检查后才下载附件。每个文件必须使用 HTTPS,并声明精确字节大小和 SHA-256 摘要;重定向、URL 内嵌凭据、片段、超大载荷和完整性不匹配都会被拒绝。
中继自身的 HTTPS 来源自动受信任。如果社区把媒体存在另一个公开来源上,把其精确 host 或 host:port 加到 gateway.platforms.buzz.extra 下的 attachment_hosts。非默认端口必须显式列出。需要通过 Buzz CLI 鉴权拉取的受保护媒体,不走这条原生公开 URL 路径。
启动网关
hermes gateway start
用 hermes gateway status 查看状态——Buzz 连接状态会在那里报告,包括纯环境变量设置的情况。
说明与限制
BUZZ_*环境变量在终端工具子进程中对 Buzz 会话可用——agent 可以直接调用buzzCLI(例如buzz messages send ...),因为当会话平台为buzz、或进程是 Buzz Desktop 托管 agent(BUZZ_MANAGED_AGENT)时,BUZZ_PRIVATE_KEY、BUZZ_AUTH_TAG、BUZZ_RELAY_URL及其他BUZZ_*变量会透传给终端子进程。同一台机器上的非 Buzz 会话、execute_code和其他非终端派生仍被密封。- 入站流式有看门狗。 在 WebSocket 传输上,静默五分钟的连接、或中继在底层关掉 socket 的连接会被拆除并带退避重连;其间网关健康检查(
/health/detailed、仪表盘状态)会把 Buzz 报为retrying而非connected。在poll传输上,适配器每poll_interval秒(默认 4)对每个监听频道轮询一次buzz messages get,因此预期最多有一个间隔的延迟。 - (重)连时适配器从最新事件播种高水位线,因此频道历史绝不会被重放进 agent。
- 新的私信会话会被自动发现(每隔几次轮询)。
- 私钥通过子进程环境传给 CLI——它绝不出现在 argv 或日志中。