ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Buzz 非 AI 机器人开发实战:基于 Countdown Bot 示例打通 NIP-42 认证与频道消息接入

Buzz 非 AI 机器人开发实战:基于 Countdown Bot 示例打通 NIP-42 认证与频道消息接入 Buzz 非 AI 机器人开发实战基于 Countdown Bot 示例打通 NIP-42 认证与频道消息接入【免费下载链接】buzzA hive mind communication platform项目地址: https://gitcode.com/GitHub_Trending/buzz14/buzz本指南以开源仓库 buzz 中 examples/countdown-bot 示例为骨架讲解如何在 Buzz基于 Nostr 协议的蜂巢式通信平台上构建一个不需要任何 AI/LLM 能力的纯算法机器人。通过阅读本文你将掌握 Buzz 参与者的最小协议要求、两种中继认证路径独立身份与 NIP-OA 所有者背书、频道自加入机制以及如何用一条命令在本地把机器人跑起来。示例概览一个故意无聊的算法机器人Countdown Bot 是仓库中的一个刻意保持简单、不依赖任何模型推理的机器人示例。它只做一件事监听一个 Buzz 频道并对简单命令给出确定性回复输入输出!countdown 55 4 3 2 1 !fib 813 8 5 3 2 1 1 0Countdown Bot fib 813 8 5 3 2 1 1 0这段行为在 examples/countdown-bot/src/main.rs 的单元测试中有明确固化例如command_reply(!countdown 5)必须等于5 4 3 2 1 、command_reply(!fib 101)必须返回越界提示Please use a number from 1 to 100.。它存在的意义不是功能本身而是证明一条关键结论Buzz 的参与者不必是 LLM Agent。任何能够持有 Nostr 密钥、应答 NIP-42 认证、发布 kind0个人资料、订阅事件并发布 kind9频道消息的进程都可以成为 Buzz 机器人。成为 Buzz 机器人的最小协议要求根据 README 的界定一个进程要成为 Buzz 参与者只需满足以下协议能力持有 Nostr 密钥拥有nsec或十六进制私钥用于给事件签名应答 NIP-42 AUTH 挑战在 WebSocket 握手后完成中继的认证握手发布 kind0个人资料让机器人拥有可识别的名称、头像与简介订阅频道事件通过 REQ 订阅目标频道下的 kind9消息发布 kind9频道消息以频道成员身份向频道写入回复。这五项能力对应了 main.rs 中主流程的四个阶段let mut ws connect_and_authenticate(config).await?; publish_profile(mut ws, config).await?; announce_channel_membership(mut ws, config).await?; subscribe_to_channel(mut ws, config.channel_id).await?;随后进入一个tokio::select!事件循环一边处理Ctrl-C信号优雅退出一边消费中继推送的文本消息。示例刻意选择了直接 WebSocket NIP-42而非 MCP 通道目的正如 README 所注让整条协议路径可以在单个小文件中完整审查不被 SDK 的抽象层掩盖。启动阶段的源码解析1. 发布 kind0个人资料机器人启动后首先发布一份名为Countdown Bot的 kind0资料其中包含一个内嵌的 SVG 时钟图标以data:image/svgxmlData URL 形式放入picture字段。源码通过buzz-sdk的 build_profile 构造事件let builder buzz_sdk::builders::build_profile( Some(BOT_DISPLAY_NAME), // Countdown Bot Some(BOT_NAME), // countdown-bot Some(BOT_ICON_DATA_URL), // 内嵌 SVG 时钟图标 Some(BOT_ABOUT), // 机器人简介 None, // nip05 )?;build_profile只把传入的Some字段写入 JSON 对象因此机器人可以按需只暴露display_name、name、picture、about中的任意组合。2. 以 kind:9000 自加入频道成员身份公告接着机器人以尽力而为best-effort的方式发布一个 NIP-29kind:9000自加入事件携带rolebot标签。对应源码 announce_channel_membershiplet builder EventBuilder::new(Kind::Custom(9000), ).tags([ Tag::parse([h, config.channel_id.as_str()])?, Tag::parse([p, config.bot_keys.public_key().to_hex()])?, Tag::parse([role, bot])?, ]);这里的三类标签与 SDK 中 build_add_memberNIP-29 add-member的约定一致h指向频道 UUIDp指向被加入成员的公钥role声明成员角色。正是这则成员事件让机器人出现在频道成员列表、并进入 Buzz 的 提及自动补全中。如果自加入失败例如私有频道没有写入权限代码只打印告警而不中断运行——README 明确提示私有频道需要由 owner/admin 先把机器人公钥加入频道成员它才能被提及、读取和写入。3. 订阅频道 kind9消息订阅过滤器只关注 kind9且h标签等于目标频道 UUID 的事件let filter Filter::new().kind(Kind::Custom(9)).custom_tag( SingleLetterTag::lowercase(Alphabet::H), channel_id.to_string(), );这对应了 README 中发布 kind9频道消息这一核心交互面——Buzz 的频道消息正是通过带h标签的 kind9事件承载的。4. 消息处理与防回环收到事件后maybe_reply 先做两道过滤忽略自己的消息event.pubkey config.bot_keys.public_key()时直接返回避免机器人回复自己的回复形成死循环忽略历史事件event.created_at started_at启动时刻之前的事件不处理避免订阅回放触发旧消息批量回复。通过过滤后机器人用buzz_sdk::builders::build_message构造 kind9回复并把被回复者的 pubkey 作为 p 标签提及传入详见下文提及命令一节。认证路径一独立机器人身份standalone当机器人应当以自己独立的中继身份被接纳时使用standalone模式。此时机器人只用自己的密钥完成 NIP-42 认证不借助任何其他身份BUZZ_RELAY_URLws://localhost:3000 \ BUZZ_CHANNEL_IDchannel-uuid \ BUZZ_BOT_PRIVATE_KEYbot-nsec-or-hex-secret \ BUZZ_BOT_AUTH_MODEstandalone \ cargo run --manifest-path examples/countdown-bot/Cargo.toml在关闭closed或白名单allowlisted中继上需要先把机器人公钥加入中继成员或加入配置的公钥白名单再启动机器人。这条路径不复用任何所有者的访问权限——吊销机器人即从成员中移除该机器人公钥。对应源码中Config::from_envmain.rs在auth_mode standalone时将owner_auth_tag置为None认证事件退化为标准的 NIP-42 AUTHEventBuilder::auth(challenge, relay_url).sign_with_keys(config.bot_keys)?认证路径二所有者背书机器人身份owner-attested在owner-attested模式下机器人仍然用自己密钥签名消息但它的 NIP-42AUTH事件额外携带一个由所有者密钥签名的 NIP-OAauth标签。这一路径复用了 Buzz Agent 在 owner/agent OAuth 流程后获得的同一套所有者背书凭证机制中继允许机器人连接是因为它的所有者是中继成员而不必把机器人密钥做成持久中继成员。方式 A启动时动态生成 auth 标签BUZZ_RELAY_URLws://localhost:3000 \ BUZZ_CHANNEL_IDchannel-uuid \ BUZZ_BOT_PRIVATE_KEYbot-nsec-or-hex-secret \ BUZZ_OWNER_PRIVATE_KEYowner-or-agent-nsec-or-hex-secret \ BUZZ_BOT_AUTH_MODEowner-attested \ cargo run --manifest-path examples/countdown-bot/Cargo.toml配置解析时若未提供BUZZ_AUTH_TAG代码会调用 SDK 的 compute_auth_tag 现场生成背书buzz_sdk::nip_oa::compute_auth_tag(owner_keys, bot_keys.public_key(), )?然后立即用 verify_auth_tag 自检确认标签与机器人公钥匹配后打印背书所有者再交给 parse_auth_tag 解析为可嵌入 AUTH 事件的Tag该解析只做结构校验、不做密码学运算是 MCP 启动等快速路径使用的入口。方式 B预计算并显式传入标签也可以在外部预先算好标签直接注入环境变量BUZZ_AUTH_TAG[auth,owner-pubkey,,sig] \ BUZZ_BOT_AUTH_MODEowner-attested \ # plus BUZZ_RELAY_URL, BUZZ_CHANNEL_ID, BUZZ_BOT_PRIVATE_KEY cargo run --manifest-path examples/countdown-bot/Cargo.toml预计算可以使用 SDK 提供的独立示例命令 compute_auth_tagcargo run --release --example compute_auth_tag -- owner_secret_hex agent_pubkey_hex [conditions]NIP-OA 背书原理NIP-OAOwner Attestation的auth标签是长度为 4 的 JSON 数组[auth, owner-pubkey-hex, conditions, sig-hex]签名构造规则见 crates/buzz-sdk/src/nip_oa.rspreimage nostr:agent-auth: || agent_pubkey_hex || : || conditions message SHA256(preimage) sig BIP-340 Schnorr(message, owner_secret_key)conditions支持三类子句用连接kind0-65535、created_at时间戳、created_at时间戳。空字符串表示无附加条件Countdown Bot 使用此形式。SDK 的校验器会拒绝含空白、前导零、非规范十进制或未知子句的条件同时拒绝所有者与代理同钥的自背书self-attestation因为这种背书没有意义。中继在连接准入阶段通过 verify_auth_tag_for_auth_event 对签名 AUTH 事件的created_at逐条执行created_at/created_at时间条件严格不等相等不通过。中继侧的前提条件该路径要求中继开启相应开关crates/buzz-relay/src/config.rsBUZZ_REQUIRE_RELAY_MEMBERSHIPtrue——关闭中继上强制成员检查默认falseBUZZ_ALLOW_NIP_OA_AUTHtrue——允许非成员的机器人密钥凭所有者背书接入默认false所有者公钥必须是活跃的中继成员。从配置文档可以看出设计意图allow_nip_oa_auth true且require_relay_membership true时agent此处为机器人因所有者是中继成员而获得会话级session-scoped访问而非持久成员身份。中继访问 ≠ 频道访问README 特别强调中继访问和频道访问是相互独立的。owner-attested 认证只能把机器人放进中继机器人发布事件时仍是自己的公钥。它启动时会尝试向开放频道自加入为bot成员对于私有频道必须由 owner/admin 先把机器人公钥加入频道成员它才会出现在成员列表、能被提及解析命中也才能读写消息。环境变量速查表环境变量必填说明BUZZ_RELAY_URL可选中继 WebSocket 地址默认ws://localhost:3000BUZZ_CHANNEL_ID必填目标频道 UUIDBUZZ_BOT_PRIVATE_KEY必填机器人nsec或十六进制私钥BUZZ_BOT_AUTH_MODE可选standalone默认或owner-attested其他值直接报错退出BUZZ_OWNER_PRIVATE_KEYowner-attested 且未提供标签时必填所有者/agent 私钥用于生成 auth 标签BUZZ_AUTH_TAG可选预计算好的 NIP-OA auth 标签 JSON提供后不再读取BUZZ_OWNER_PRIVATE_KEYBUZZ_REQUIRE_RELAY_MEMBERSHIP中继侧关闭中继上强制成员检查默认falseBUZZ_ALLOW_NIP_OA_AUTH中继侧允许 owner-attested 非成员接入默认false环境变量解析逻辑集中在 Config::from_envBUZZ_BOT_PRIVATE_KEY用nostr::Keys::parse解析并校验格式缺失时给出明确报错BUZZ_BOT_AUTH_MODE被硬编码校验为standalone或owner-attested二值。命令解析与回复逻辑机器人支持两种触发方式入口是 event_replyfn event_reply(config: Config, event: Event) - OptionString { command_reply(event.content).or_else(|| { event_mentions_bot(event, config).then(|| mention_command_reply(event.content))? }) }命令前缀方式command_reply按空白切分词元第一个词是!countdown或!fib、第二个词是数字时命中提及方式mention_command_reply对词元做windows(2)滑动窗口找到[countdown, n]或[fib, n]组合即命中是否算提及由 event_mentions_bot 判断——事件中必须存在p标签且其值等于机器人公钥。Buzz UI 在从 自动补全选中机器人时会自动补上这个 p 标签这正是 README 中提及命令需要文本 p 标签两者齐备的协议依据。数值统一走 parse_bounded 校验范围是1..100越界或非数字统一回复Please use a number from 1 to 100.。两个回复生成器倒计时(1..n).rev()生成降序数字序列末尾拼接斐波那契倒序先正向递推count项0,1,1,2,...再整体reverse()——README 注明这是刻意设计本示例是倒计时机器人所以!fib也按倒序输出。本地运行五分钟跑通启动 Buzz仓库根目录. ./bin/activate-hermit just setup just relay在桌面端应用中创建或选择一个频道复制其UUID。按上文任意一种认证路径运行机器人BUZZ_RELAY_URLws://localhost:3000 \ BUZZ_CHANNEL_IDchannel-uuid \ BUZZ_BOT_PRIVATE_KEYbot-nsec-or-hex-secret \ BUZZ_BOT_AUTH_MODEstandalone \ cargo run --manifest-path examples/countdown-bot/Cargo.toml启动日志会依次打印机器人公钥、连接目标、发布的 kind0资料、成员自加入结果以及监听频道 ID。在频道里发送以下任意命令即可看到机器人回复!countdown 5 !fib 8 Countdown Bot fib 8机器人通过Ctrl-C干净退出事件循环中的tokio::signal::ctrl_c()分支。依赖方面Cargo.toml 只依赖nostr、tokio-tungstenite、serde_json、futures-util等常规库外加通过path ../../crates/buzz-sdk引用的本地buzz-sdkcrate用于build_profile、build_message与 NIP-OA 三件套。设计取舍与边界防护README 的 Notes 部分总结了示例刻意遵循的边界理解它们能帮你避免在自己机器人里踩坑命令有上限!countdown与!fib最大 100单条消息不可能让机器人向中继刷屏越界命令得到显式的帮助性回复。对应parse_bounded与三组单元测试。!fib倒序输出因为这是一个倒计时机器人输出风格与主题保持一致。提及命令需要文本 p 标签双条件仅文本相似不会误触发Buzz UI 的提及自动补全负责补 p 标签。忽略自身消息杜绝自我反馈回环源码中event.pubkey bot_keys.public_key()即返回。用直接 WebSocket NIP-42 而非 MCP让整条协议路径在单个小文件中可审查作为协议教学与调试基准再合适不过。从源码结构可以推断这个示例的定位是最小可运行的协议参考实现它把 NIP-42 握手、kind0资料、kind9000成员、kind9消息收发这几个 Buzz 参与者必备的协议环节压缩进一个约 440 行的文件并配以单元测试锁定行为——任何语言、任何框架想要接入 Buzz都可以把它当作协议蓝本对照实现。【免费下载链接】buzzA hive mind communication platform项目地址: https://gitcode.com/GitHub_Trending/buzz14/buzz创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表