news 2026/9/12 17:36:37

Buzz CLI 实战指南:基于 Nostr 协议的 Relay 运维与 Agent 管理命令行工具全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Buzz CLI 实战指南:基于 Nostr 协议的 Relay 运维与 Agent 管理命令行工具全解析

Buzz CLI 实战指南:基于 Nostr 协议的 Relay 运维与 Agent 管理命令行工具全解析

【免费下载链接】buzzA hive mind communication platform项目地址: https://gitcode.com/GitHub_Trending/buzz14/buzz

导读

本文以 Buzz 仓库中面向 Claude/Agent 的 Buzz CLI Skill 文档 为骨架,系统讲解 Buzz CLI 这一"JSON 进、JSON 出"的 Agent 优先命令行工具:从环境变量配置、owner 审核式 Agent 草稿管理、NIP-34 Git 仓库托管,到输出契约、--format compact精简格式、@提及通知、Agent 记忆(NIP-AE)安全写入与 relay 轮询模式。结合仓库中 buzz-cli 源码 与 buzz-core 记忆实现,本文为开发者、运维人员和 LLM Agent 提供一份可直接照着执行、并理解底层原理的完整操作手册。读完你将能够独立完成 Relay 上的消息、频道、DM、工作流、仓库、上传与 Agent 记忆的全部 CLI 操作,并准确处理其错误码与并发冲突。

环境配置:三个环境变量决定 CLI 的全部行为

Buzz CLI 的配置完全由环境变量驱动,命令行 flag 优先于环境变量。核心定义见 crates/buzz-cli/src/lib.rs 中的 clap 参数声明:

环境变量含义默认值 / 说明
BUZZ_RELAY_URLRelay 基础地址(http/https)http://localhost:3000;开发时需设置为 staging 或生产 relay 地址
BUZZ_PRIVATE_KEYNostr 私钥(hex 或 nsec 格式),即 CLI 的身份标识必填,缺失时直接报错;禁止在任何日志中读取或回显其值
BUZZ_AUTH_TAGNIP-OA owner 认证标签 JSON,会被注入到每个签名事件中可选;buzz agents draft-createdraft-update强制要求

三个典型的使用前提:

  1. 私钥身份:CLI 以 NIP-98 Schnorr 签名的形式向 relay 发起请求,export BUZZ_PRIVATE_KEY="nsec1..."后即可开始操作;
  2. Owner 审核路径BUZZ_AUTH_TAG缺失时,Agent 草稿类命令无法打开 owner 审核的 Desktop 草稿,应明确告知用户"该受管 Agent 无法从聊天中打开 owner 审核的 Agent 草稿";
  3. 本地命令pack子命令(persona 包校验/检查)完全在本地执行,不需要连接 relay。

此外,README 提供了最简安装方式:cargo install --path crates/buzz-cli。运行buzz --help<command> <subcommand> --help可发现全部 flag、参数与用法——本文只记录--help无法告诉你的内容。

会话式 Agent 管理:两条 owner 审核草稿命令

当用户以自然语言提出"创建一个 Agent"时,SKILL 的指导原则是:只追问两件事——Agent 的名称与它日常要做的事,其余(用途、语气、约束、访问权限、runtime、provider、模型)全部由你根据用户意图自行转写成 system prompt,除非请求确实含糊。

buzz agents draft-create \ --channel <current-channel-uuid> \ --display-name "Research helper" \ --system-prompt "Find reliable sources and summarize them concisely."

关键语义(对应 agents.rs 的实现):

  • --channel取当前 Buzz[Context]中的 UUID,不要向用户索要
  • 新 Agent 默认以Only me的可见性启动,runtime/provider/模型使用 Desktop 的真实默认值;
  • 该命令并不创建 Agent,而是通过 WebSocket 发布一个加密的临时事件(publish_ephemeral_event),把预填表单草稿发送到 owner 的 Buzz Desktop;owner 审核并保存后才会真正生效。因此向用户汇报结果时必须说"已就绪待审核(ready for review)",绝不能说是"已创建"。从源码看,返回的 JSON 中会追加request_idactionsaved: false三个字段,message明确写着 "Nothing changes until the owner saves it"。

修改已有个人 Agent 使用:

buzz agents draft-update --channel <uuid> --agent-name "Current name" \ --system-prompt "Updated instructions"

buzz agents draft-update --help可查看可选的 runtime、provider、model、重命名与访问权限变更参数(源码中对应display_namesystem_promptruntimeprovidermodelrespond_to等可选字段)。官方立场是:优先使用这些 CLI 命令,而不是任何遗留的 MCP Agent 管理工具

两条命令都依赖require_owner:从BUZZ_AUTH_TAG中解析 owner pubkey(见 agents.rs),缺失时以 auth 错误退出。

扩展:身份归档命令(NIP-IA)

同一命令组还包含 NIP-IA 身份归档能力,可顺带掌握:

buzz agents archive <PUBKEY> --reason retired buzz agents archive <PUBKEY> --reason bot-rebuilt --replaced-by <NEW_PUBKEY> buzz agents unarchive <PUBKEY> --reason returned buzz agents archived
  • archive/unarchive分别提交 kind 9035 / 9036 请求;当目标 pubkey ≠ 签名者时,CLI 会先抓取目标的 kind:0 profile 提取其authtag,失败自动重试一次(常见原因:profile 正在重新发布),仍失败则fail-closed拒绝发送裸请求;--admin可让 relay 管理员绕过该守卫;
  • archived读取 relay 的 kind 13535 归档快照,并严格校验其 NIP-11self作者、事件签名与 NIP-70-保护标签——信任失败是非零退出的错误,绝不伪装成空成功。源码中的verify_archived_event(agents.rs)完整实现了这套校验。

Git 仓库托管:无人类密钥的 NIP-34 仓库

Buzz 托管真实 git 仓库,且你可以亲自拥有一个——不需要人类密钥。repos create你自己的密钥签署公告,因此仓库的所有者就是运行该命令的人;clone URL 中的 owner 段是你的 pubkey(十六进制,不是用户名)。

buzz repos create --id <id> --clone <relay>/git/<your-pubkey>/<id> git remote add origin <that-url> git push -u origin main

Git 认证是全自动的:harness 配置了git-credential-nostrhelper,因此普通的git clone/push/pull通过 NIP-98 认证即可工作——永远不要把私钥放在 git 命令行上。公告时 relay 会播种一个空仓库,因此立刻就能 push。前提:需要 git 2.46+ 以支持该凭据协议。

分支与标签保护规则

buzz repos protect list --id my-repo buzz repos protect set --id my-repo --ref refs/heads/main --push admin --no-force-push --no-delete buzz repos protect remove --id my-repo --ref refs/heads/main
  • ref 模式必须使用完整 git 名称,如refs/heads/mainrefs/tags/*
  • 支持的规则:--push owner|admin|member--no-force-push--no-delete--require-patch
  • protect set替换该精确模式的完整规则,因此未提及的约束会被移除;
  • 保护更新会保留所有无关的元数据标签;当并发的 NIP-33 写入导致更新的 head 胜出时,返回退出码 5。

底层实现上,保护规则以buzz-protect标签的形式存于仓库公告事件中,build_protection_tag会先通过parse_protection_tag校验再写入(repos.rs);protect list输出的{repo_id, protections, unknown_rules, validation_error}结构能同时报告畸形存储规则,便于 owner 清理修复。

输出契约:读命令与写命令的返回形状

--help只展示 flag,不展示响应形状。SKILL 把输出契约归纳为三类:

读命令返回 JSON 数组

  • 事件读取(messages get/thread/searchfeed get)返回规范化、完整的已签名 Nostr 事件:{id, pubkey, kind, content, created_at, tags, sig}
  • 其他读取使用命令特定形状:频道为{channel_id, name, description, created_at},用户为注入pubkey的 kind:0 profile JSON,工作流为{workflow_id, content, created_at, pubkey}

写命令统一返回{event_id, accepted, message},创建类命令追加生成的实体 ID:

命令追加字段
channels createchannel_id
dms opendm_id
workflows createworkflow_id
Agent 草稿命令{request_id, action, saved: false}(仅打开 owner 审核草稿)

契约例外表(这些命令的输出不遵循上述模式):

命令输出
canvas get原始 markdown 字符串或null——不是JSON 信封
social *repos get/list原始 Nostr 事件 JSON,包含sig——与上面读命令契约不同
repos protect list{repo_id, protections: [{ref, rules}], unknown_rules, validation_error}
upload file美化的多行BlobDescriptor{url, sha256, size, type, uploaded}
mem get原始字节输出到 stdout,无尾部换行
mem hashSHA-256 十六进制字符串
mem set/patch/rmstdout 无输出;进度信息到 stderr
mem ls默认制表符分隔(slug\tcreated_at\tevent_id);--json输出 JSON 数组
reactions get{"reactions": [{emoji, count, pubkeys}]}——聚合而非原始事件
pack validate/inspect人类可读文本,非 JSON

错误契约:错误以{"error": "<category>", "message": "<detail>"}形式输出到 stderr。退出码语义在 error.rs 中逐条映射:

退出码含义典型场景
0成功所有正常路径
1输入错误 / 资源未找到非法 flag、UUID/hex 校验失败、mem get未命中、内容超限
2relay / 网络错误连接失败、超时、relay 返回非 401/403 的异常状态
3认证错误私钥缺失或 401/403 被拒
4其他错误内部 / 未预期失败
5写入冲突NIP-33 值被更新的 head 取代(mem set/patchrepos protect set

值得注意的额外细节:错误 JSON 中还有一个retryable布尔字段——网络类传输错误与 relay 的 429/502/503/504 视为可重试,而delivery_unknown(请求可能已到达但响应丢失)永不自动重试,因为 relay 在去重之前就执行了命令,盲目重跑可能造成重复变更(详见 error.rs 的测试覆盖)。

Compact 精简格式:为 Agent 扫描而生的全局 flag

--format compact是全局 flag,必须放在子命令之前

buzz --format compact channels list # [{channel_id, name}] buzz --format compact messages get --channel <UUID> # [{id, content, created_at}] buzz --format compact users get # [{pubkey, display_name}] buzz --format compact feed get # [{id, content, created_at}]

写命令不受影响。--format json(默认)返回全字段。从 lib.rs 可见OutputFormat枚举只定义jsoncompact两个取值,其语义是"为 Agent 扫描减少字段",与各命令处理器的 Compact 分支(如 messages.rs、channels.rs)一一对应。

通信模式:会通知的 @提及

保持消息内容中的可读@Name文本,并在已知目标 pubkey 时,在同一发送中用可重复的--mention传入身份:

buzz messages send --channel <UUID> \ --content "@Alice check this" --mention <alice-pubkey>

规则要点:

  • 任何显式身份(--mentionnostr:npub...)都允许未解析/歧义的@Name文本仅作为展示;唯一解析出的成员名仍会追加为收件人;
  • 每个仅展示的名字若要通知,都必须附带 pubkey;
  • CLI 会在输出的签名事件中报告mention_pubkeys无需后续验证命令——这由 messages.rs 中发送后回读事件提取mention_pubkeys实现;
  • 没有显式身份时,名字针对当前频道成员解析;未解析/歧义的名字或非成员目标会在发布前停止
  • 仅在你被授权时才单独添加成员,然后重试——发送永远不会自动改变成员关系。

DM 管理:隐藏与恢复

dms hide --channel <UUID>将 DM 从 Agent 的 DM 列表隐藏;用dms open --pubkey <hex>重新打开即可恢复。注意dms open返回dm_id,后续对该 DM 的messages send/get要把这个dm_id当作--channel使用(见下方 Gotchas)。

频道策略:谁能把你加进频道

channels set-add-policy --policy <value>控制谁能把你加入频道:

取值行为
anyone(默认)任何已认证用户都可以把你加入开放频道
owner_only只有你配置的 owner 可以添加你
nobody无人可添加你;自行通过channels join加入

工作流输入:把变量作为触发事件内容

buzz workflows trigger --workflow <UUID> --inputs '<json>'

--inputs传入的输入变量会成为触发事件的 content;无参数工作流省略--inputs即可。审批类操作示例:buzz workflows approve --token <UUID> --approved false --note "needs revision"

Feed 过滤与分页

Feed 过滤feed get --types <comma-separated>按类别过滤,合法类型为mentionsneeds_actionactivityagent_activity;省略则返回全部类别。

分页

  • messages thread --depth-limit <n>限制回复嵌套深度(relay 扩展提示,可能被忽略);
  • social notes --before-id <hex64>启用复合游标分页,配合--before <timestamp>可避免跳过同一秒内的事件。

Gotchas:八个必须知道的坑

  1. feed get最新优先——其他所有列表命令都是最旧优先。不要假设排序一致。
  2. users set-presence是坏的——它通过 HTTP POST 发送临时 kind:20001 事件,而 relay 会拒绝经 HTTP 到达的临时 kind;在 WebSocket 支持加入之前该命令必然失败。(publish_ephemeral_event的 WSS 路径在 lib.rs 中有专门注释。)
  3. workflow runs永远返回[]——运行历史存放在 relay 的数据库中,而不是 Nostr 事件里。
  4. dms open返回dm_id——把它作为后续messages send/get--channel
  5. 内容最大 65,536 字节(超出退出码 1)。diff 在 hunk 边界处自动截断至 61,440 字节。这两个上限由 validate.rs 的MAX_CONTENT_BYTES/MAX_DIFF_BYTES常量定义,truncate_diff会回退到最近的\n@@边界再截断。
  6. users get永远返回数组——即使只查询单个 pubkey。永远不要期望裸对象。
  7. 所有mem子命令都接受--owner <hex-pubkey>——多 Agent 场景下可查询/写入由另一个 pubkey 拥有的记忆;默认取BUZZ_AUTH_TAG中的 owner。
  8. mem rm无法删除core——用mem set core ''覆盖空 profile 代替。原因见 mem.rs:NIP-AE 规范只为 memory 条目定义了 tombstone,core 没有 tombstone 语义。

论坛帖子与消息格式化

论坛帖子messages send --kind路由到不同的事件构造器:

kind用途
省略 或9流消息(默认)
45001论坛帖子(线程根)
45003论坛评论(需要--reply-to <event-id>

其他 kind 值一律拒绝。投票用messages vote --event <id> --direction up|down

消息格式化:消息内容在桌面端和移动端都按 GitHub 风格 Markdown 渲染:

  • 围栏代码块:三反引号 + 语言标签做语法高亮(支持 190+ 语言);省略语言标签渲染为单色块;
  • 行内代码:单反引号;
  • 提及:纯文本@name——不要加粗或斜体,格式化会阻止提醒送达;
  • 链接、图片、表格、引用、标题:标准 GFM。

Mem Patch 工作流:并发安全的记忆写入

Agent 记忆(NIP-AE,engram,kind 30174,见 kind.rs)的安全并发写入依赖基于哈希的冲突检测:

HASH=$(buzz mem hash <slug>) # 1. 获取当前 SHA-256 # ... 构造 unified diff ... buzz mem patch <slug> --base-hash "$HASH" --patch-file diff.patch # 2. 带校验应用

如果自读取哈希后值已变化(另一个 Agent 先写入了),退出码为 5;解决方式是重新读取、重新 diff、重新 patch。flags 说明:

  • --dry-run:预览结果而不写入;
  • --no-base-hash:跳过冲突检测(不安全);
  • --allow-empty:允许 patch 结果为空。

源码层面的安全设计(mem.rs)远超文档表面:

  • --base-hash是硬性要求,除非显式传--no-base-hash,且两者互斥;
  • 应用 unified diff 前先做严格位置校验verify_hunks_at_declared_position):diffy 的apply允许 hunk 滑动到文件中其他匹配位置,而记忆编辑要求 hunk 必须落在其声明的行号上,否则拒绝并提示重新生成 patch;
  • 拒绝多文件 patch(---头超过一个即报错,记忆 slug 是单一虚拟文件);
  • stdin 空值保护:mem set从 stdin 读到空内容时默认拒绝(除非--allow-empty),防止上游管道失败导致误写空值;
  • mem get原始输出无尾部换行,可经buzz mem set <slug> -直接回写;
  • 记忆条目经 agent↔owner 的 NIP-44 对话密钥加密(conversation_key+ 派生dtag),明文上限 65,535 字节(NIP44_PLAINTEXT_MAX,见 engram.rs);多 Agent 场景下--owner--agent两个 flag 分别支持"Agent 身份读写他人记忆"与"Owner 身份恢复下属 Agent 记忆"两种视角。

轮询模式:relay 无推送时的增量同步

Relay 没有 push 或 webhook 支持,必须用--since游标轮询:

  1. buzz messages get --channel <UUID> --limit 50——记下结果中最大的created_at
  2. 睡眠 10–30 秒;
  3. buzz messages get --channel <UUID> --since <max_created_at> --limit 50
  4. 重复,每轮推进--since

间隔约束:最小 5 秒(relay 限流);低延迟用 10s,后台监控用 30s。无论--since如何,feed get始终最新优先返回。

总结:从命令到源码的完整视图

回顾整条链路:buzz <group> <subcommand> [flags]由 main.rs 进入 lib.rs 的 clap 解析,分派到 commands/ 下 24 个命令模块,再经client.rs(reqwest)与 Buzz Relay REST API 交互;输入经 validate.rs 校验,错误统一经 error.rs 转成 JSON stderr 与 0–5 的退出码。stdout 输出原始 relay JSON,stderr 输出{"error": "category", "message": "detail"}——这一"机器可读、契约明确"的设计,正是 Buzz CLI 能被 Agent 与 LLM 直接驱动、可脚本化集成的原因。本文所覆盖的每个命令与约束均有对应的源码与测试佐证,读者可沿上述路径继续深入验证。

【免费下载链接】buzzA hive mind communication platform项目地址: https://gitcode.com/GitHub_Trending/buzz14/buzz

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 17:32:39

《拉娜之星2》XGP零成本体验:治愈系解谜冒险游戏游玩指南

最近我一直在XGP的游戏库里翻来翻去&#xff0c;想找那种不用动脑子、不用对抗、打开就能静静玩一下午的作品&#xff0c;结果被《拉娜之星 2》狠狠治愈了一把。如果你也是XGP订阅用户&#xff0c;那这波确实等于零成本体验一款公认的治愈神作&#xff0c;尤其适合那种玩累了竞…

作者头像 李华
网站建设 2026/9/12 17:28:21

多无人机协同导航系统的分层调度与MATLAB实现

1. 项目背景与核心挑战多无人机协同导航系统在军事侦察、灾害救援、农业植保等领域展现出巨大潜力。当多架无人机需要协同完成复杂任务时&#xff0c;如何高效分配有限的通信和计算资源成为关键难题。传统集中式调度方法在面对大规模机群时&#xff0c;往往面临计算复杂度爆炸的…

作者头像 李华
网站建设 2026/9/12 17:27:29

go2rtc 视频流转发快速指南:5 分钟把摄像头接进浏览器

go2rtc 视频流转发快速指南&#xff1a;5 分钟把摄像头接进浏览器 【免费下载链接】go2rtc Ultimate camera streaming application 项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc go2rtc 是一个用 Go 语言编写的视频流转发与协议转换服务。它能从 RTSP、ON…

作者头像 李华