Buzz 深度拆解:Jack Dorsey 用 Nostr 重造 Slack,让 AI Agent 成为持有密钥的正式队友
一、背景:当「群聊」成为人机协作的主战场
2026 年 7 月 22 日,Block(前身 Square)正式开源了一个叫 Buzz 的项目:一个基于去中心化社交协议 Nostr 构建的团队协作平台,Apache 2.0 许可证,当前版本 0.4.22,处于早期公测阶段。Jack Dorsey 给它的定位很直接——挑战 Slack。
如果只看「又一个开源 Slack 替代品」这个标签,你大概率会划走。Mattermost、Rocket.Chat、Zulip……这条赛道上的尸体已经足够多了。但 Buzz 押的不是「更便宜的 Slack」,而是一件更激进的事:
当人类和 AI Agent 在协作基础设施中的地位完全对等时,工作流会长出全新的形态。
过去一年里,所有人都在往群聊里塞机器人:DevOps 播报机器人、代码审查机器人、日报汇总机器人。但在 Slack 的世界观里,Bot 永远是「外挂」——它靠平台发的 token 活着,权限由中心化后台定义,行为记录存在 Salesforce 的数据库里,你想审计它干过什么,得看平台愿意给你什么样的日志导出功能。
Buzz 的回答是:让 Agent 自己持有密码学密钥,用和人类一模一样的签名事件参与协作,所有行为写进同一条可验证的事件日志。
这篇文章我会从协议层、架构层、代码层把 Buzz 拆开,看看这套「Nostr + Agent」的组合拳到底是营销噱头,还是真的踩中了什么。
二、核心概念:Nostr 101,事件即一切
要理解 Buzz,得先理解 Nostr。很多程序员对 Nostr 的印象还停留在「Dorsey 站台的去中心化推特协议」,但它的本质其实简单到令人发指:
Nostr = 签名事件(Signed Event)+ 中继(Relay)。没了。
一条 Nostr 事件长这样:
{
"id": "e8b487c079b0f67c695ae6c4c2552a47f38adfa2533cc5926bd2c102942fdcb7",
"pubkey": "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93",
"created_at": 1753142400,
"kind": 1,
"tags": [
["e", "被引用事件的id"],
["p", "被提及用户的公钥"]
],
"content": "消息正文,或任意 JSON 载荷",
"sig": "908a15e46fb4d8675bab026fc230a0e3542bfade63da02d542fb78b2a8513fcd..."
}
六个字段,各司其职:
| 字段 | 含义 |
|---|---|
id | 事件规范化序列化后的 SHA-256 哈希 |
pubkey | 作者的 secp256k1 公钥(是的,和比特币同一条曲线) |
created_at | Unix 时间戳 |
kind | 整数类型号,决定这条事件「是什么」——这是整个协议唯一的分发开关 |
tags | 结构化元数据:引用、提及、频道归属等 |
sig | 对 id 的 Schnorr 签名 |
Relay 则是一个只干三件事的 WebSocket 服务器:接收事件、按订阅条件过滤、推送事件。它不管注册、不管好友关系、不管权限业务——身份就是密钥对,验证就是校验签名。
这个设计有两个被严重低估的推论:
- 身份是自主权的(self-sovereign)。没有「注册账号」这回事,生成一个密钥对你就存在了。任何能生成 secp256k1 密钥对的东西——人、脚本、AI Agent、CI 流水线——在协议眼里完全平等。
- 事件日志天然可审计。每条事件都带签名,谁在什么时候说了什么、做了什么,密码学层面不可抵赖。你不需要相信平台的日志,你只需要验签。
看到这里你应该已经嗅到 Buzz 的味道了:Nostr 这套「密钥即身份、事件即行为」的模型,恰好就是 AI Agent 协作最缺的那块地基。
三、架构拆解:一个 Relay 作为协作总线
3.1 整体结构
Buzz 的底层是一个(可自托管的)Nostr Relay。在 Buzz 的世界里,以下所有东西都是签名过的 Nostr 事件,写进同一条日志:
- 每条聊天消息
- 每个表情回应
- 每个工作流步骤的状态变更
- 每次代码评审的通过/驳回
- 每个 git 事件(push、PR 开启、合并)
- 项目管理里的任务创建、指派、关单
换句话说,Buzz 把「团队协作」建模成了一条 append-only 的签名事件流,不同的 kind 值区分事件语义,客户端按需订阅、按需渲染。聊天界面只是这条事件流的一种投影,看板是另一种投影,审计报表是第三种投影。
这是一个很「事件溯源(Event Sourcing)」的架构。做过 CQRS 的同学会立刻反应过来:这不就是把 Kafka + 事件溯源 + 数字签名揉在一起,然后用一个开放协议标准化了吗?
对,但魔鬼在于「开放协议」这四个字。Kafka 的 topic 是你公司内部的私产,Nostr 的事件是标准格式——任何客户端、任何 Agent、任何第三方工具,只要说 Nostr 这门语言,就能接入你的工作区(在你授权的前提下)。协作数据的互操作性第一次被放到了协议层解决。
3.2 Agent 即成员:与 Slack Bot 模型的本质区别
这是 Buzz 最核心的设计决策,值得掰开细讲。
Slack 模型:
人类用户 ──> Slack 账号体系(SSO/密码)──> 权限由工作区管理员配置
Bot ──> App 平台发放的 token ──> 权限由 OAuth scope 定义
│
└── 两套身份体系,两套审计逻辑,Bot 是二等公民
Buzz 模型:
人类用户 ──> secp256k1 密钥对 ──> 签名事件
AI Agent ──> secp256k1 密钥对 ──> 签名事件
│
└── 同一套身份原语,同一条事件日志,同一套审计轨迹
在 Buzz 里,你可以往群里拉一个自动检查代码提交的 DevOps Agent、一个每天汇总行业新闻的情报 Agent、一个帮你起草文档的写作 Agent。它们可以被 @提及,可以在条件触发时主动发言,可以给 PR 打上「已审查」的签名事件——每一个动作都是它用自己的私钥签出来的。
这解决了企业落地 AI Agent 时最头疼的四个问题:
- 谁授权的? Agent 的公钥被加入工作区,这本身是一条由管理员签名的事件。
- 谁看见了? Agent 的所有输出都在共享事件流里,没有私下的 side channel。
- 谁接手? Agent 掉线或被移除,它的历史事件仍然完整可查,新 Agent 接上同一条事件流就能恢复上下文。
- 谁负责? 每条事件都有签名,出了事故可以精确回放到「哪个 Agent 在哪个时间点基于哪条上游事件做了什么」。
对比之下,Slack Bot 的行为审计依赖平台日志,token 泄露后你甚至分不清是 Bot 干的还是攻击者干的——因为 token 不是身份,只是通行证。而私钥签名在密码学意义上绑定了行为与身份。
3.3 与 Goose 的关系:Block 的 Agent 版图
别忘了 Block 手里还有另一张牌:Goose——他们 2025 年初开源的 AI Agent 框架,基于 MCP(Model Context Protocol)做工具集成,能连 GitHub、Google Drive、JetBrains IDE。
把两个项目放在一起看,Block 的路线图就清晰了:
- Goose 负责「Agent 怎么干活」:模型编排、工具调用、任务执行。
- Buzz 负责「Agent 在哪干活、跟谁干活」:身份、通信、协作、审计。
Goose 是手和脑,Buzz 是工位和工牌。一个 Goose Agent 拿到 Nostr 密钥对,接入 Buzz 工作区,就成了一个有身份、有历史、有责任边界的「数字员工」。这比 OpenAI 的 GPTs 商店或者各家的 Agent 平台都更彻底——因为整个栈是开源的、自托管的、协议化的。
四、代码实战:从零写一个 Buzz 风格的 Agent
Talk is cheap。下面我们用 nostr-tools(Nostr 生态最常用的 TypeScript 库)从零实现一个最小可用的「CI 播报 Agent」,感受一下「Agent 持钥上岗」是什么体验。
注:Buzz 仍在早期公测,其自定义 kind 值和标签约定可能变动。以下代码基于 Nostr 标准协议(NIP-01)编写,接入任何 relay 都能跑,理解原理为主。
4.1 给 Agent 发一张「工牌」:生成密钥对
import { generateSecretKey, getPublicKey } from 'nostr-tools/pure'
// Agent 的私钥——这就是它的身份本体,务必安全存储
const agentSecretKey = generateSecretKey() // Uint8Array
const agentPubkey = getPublicKey(agentSecretKey) // hex string
console.log(`Agent 上岗,工牌号: ${agentPubkey}`)
就这么两行,一个「数字员工」的身份诞生了。不需要在任何平台注册,不需要谁给它发 token。管理员把这个 pubkey 加进工作区成员列表(这个动作本身也是一条签名事件),它就是正式成员了。
4.2 连接 Relay,订阅工作区事件流
import { Relay } from 'nostr-tools/relay'
const relay = await Relay.connect('wss://relay.your-company.internal')
// 订阅:监听所有 @提及本 Agent 的文本消息
const sub = relay.subscribe(
[
{
kinds: [1], // kind 1 = 文本消息
'#p': [agentPubkey], // p 标签包含本 Agent 公钥 = 被提及
since: Math.floor(Date.now() / 1000),
},
],
{
onevent(event) {
console.log(`收到提及: ${event.content} (来自 ${event.pubkey})`)
handleMention(event)
},
}
)
注意这里的思维转变:Agent 不是在轮询某个 REST API,而是订阅了一条实时事件流。工作区里发生的一切——只要匹配过滤器——毫秒级推到 Agent 面前。这和人类用户打开客户端看到新消息,走的是完全相同的链路。
4.3 签名回复:Agent 的每句话都盖章
import { finalizeEvent } from 'nostr-tools/pure'
async function handleMention(incoming: NostrEvent) {
// 假设这是个 CI 播报 Agent,被 @ 时回报最新构建状态
const buildStatus = await fetchLatestBuildFromCI() // 查你的 Jenkins/GHA
const replyEvent = finalizeEvent(
{
kind: 1,
created_at: Math.floor(Date.now() / 1000),
tags: [
['e', incoming.id], // 引用被回复的事件
['p', incoming.pubkey], // 提及提问者
],
content: `最新构建 #${buildStatus.number}: ${buildStatus.result},耗时 ${buildStatus.duration}s`,
},
agentSecretKey // 用 Agent 自己的私钥签名
)
await relay.publish(replyEvent)
}
finalizeEvent 做了三件事:计算规范化哈希得到 id、填入 pubkey、用私钥做 Schnorr 签名。发出去的这条消息,任何人在任何时间都可以离线验证它确实出自这个 Agent 之手:
import { verifyEvent } from 'nostr-tools/pure'
const isAuthentic = verifyEvent(replyEvent) // true / false,纯本地计算
不需要问服务器「这条消息是不是真的」,数学本身就是公证处。
4.4 把工作流事件也搬进来:git push 播报
Buzz 把 git 事件也建模为 Nostr 事件。我们可以模拟这个思路,用自定义 kind(Nostr 约定 30000+ 为参数化可替换事件,1000-9999 为常规事件)来承载结构化载荷:
// git 钩子触发后,CI Agent 把 push 事件写入工作区事件流
const gitPushEvent = finalizeEvent(
{
kind: 3111, // 假设的自定义 kind:git push
created_at: Math.floor(Date.now() / 1000),
tags: [
['repo', 'github.com/yourorg/backend'],
['branch', 'main'],
['t', 'git-activity'], // 主题标签,方便订阅过滤
],
content: JSON.stringify({
commits: [
{ sha: 'a1b2c3d', author: 'dev-alice', message: 'fix: 修复订单超时逻辑' },
],
pusher: 'dev-alice',
}),
},
agentSecretKey
)
await relay.publish(gitPushEvent)
然后任何客户端——聊天界面、看板、审计工具——都可以订阅 kinds: [3111] 把 git 活动渲染成自己需要的样子。数据只写一次,投影随便做。这就是「事件即一切」的工程红利。
4.5 接上大模型:一个会思考的评审 Agent
最后把 LLM 接进来,让 Agent 真的「智能」起来。伪代码骨架:
async function handleReviewRequest(event: NostrEvent) {
const { prUrl } = JSON.parse(event.content)
const diff = await fetchPRDiff(prUrl)
// 调用你的模型服务(本地 vLLM / 云端 API 均可)
const review = await llm.chat({
system: '你是资深后端评审,只关注正确性、安全性与性能,输出结构化结论。',
user: `请评审以下 diff:\n${diff}`,
})
// 评审结论作为签名事件写回工作区
const reviewEvent = finalizeEvent({
kind: 3222, // 假设的自定义 kind:代码评审
created_at: Math.floor(Date.now() / 1000),
tags: [
['e', event.id],
['pr', prUrl],
['verdict', review.approved ? 'approve' : 'request-changes'],
],
content: review.summary,
}, agentSecretKey)
await relay.publish(reviewEvent)
}
重点不在 LLM 调用本身,而在于:这个 Agent 的评审结论带着它的签名进入了永久事件日志。半年后审计「这个 PR 当时谁批的、依据是什么」,一条 verdict 事件加一个 verifyEvent 就是铁证。这在「AI 参与生产决策需要留痕」的合规语境下,价值巨大。
五、工程视角的冷思考:Buzz 要过的四道坎
吹完了优点,按惯例泼冷水。作为一个天天跟基础设施打交道的程序员,我看到至少四个硬骨头。
5.1 Relay 的扩展性与「事件风暴」
把所有东西都变成事件是优雅的,但也意味着事件量爆炸。一个 50 人 + 20 Agent 的团队,聊天、表情、工作流、git 活动全算上,一天几万条事件很正常;Agent 一旦进入「自动化互相触发」的循环(A 的输出触发 B,B 的输出触发 C……),事件量可能指数级失控——这就是分布式系统里经典的反馈风暴问题。
工程上的对策无非几类:
- 速率限制按 pubkey 施加:好在身份是密钥,限流粒度天然清晰;
- Agent 触发链深度限制:在事件 tags 里携带因果链 ID 和 hop 计数,超限即熔断;
- 冷热分层:Relay 只保留近期热数据,历史事件归档到对象存储,按需回放。
Nostr Relay 本身是很薄的(一个 WebSocket + 存储 + 过滤器引擎),单机撑十万级日事件毫无压力,但企业级场景需要的多 Relay 冗余、订阅一致性、断线补拉,都是 Buzz 需要在产品层补齐的。
5.2 密钥管理:Agent 的私钥放哪?
「Agent 持有私钥」在架构上是升维,在运维上是新的攻击面。人类可以用硬件钱包和脑子记助记词,Agent 的私钥只能落在某个运行环境里。私钥一旦泄露,攻击者就能完美冒充这个 Agent——签名反而给冒充行为镀了金。
成熟的做法是把签名操作收进 KMS/HSM 或类似 nsecbunker 的远程签名服务:Agent 进程只能请求「帮我签这条事件」,拿不到私钥本体;签名服务上再叠加策略引擎(只允许签哪些 kind、频率多少、内容过滤)。这一层做不好,「密码学审计轨迹」就是空中楼阁。
5.3 隐私模型:签名事件 ≠ 加密事件
签名解决的是「谁说的」,不解决「谁能看」。企业协作里大量内容需要访问控制,而 Nostr 的原生事件是明文广播的。生态里已有 NIP-44(加密载荷)和基于其上的私有群组方案,Buzz 自托管 Relay 本身也提供了一层网络边界(内网部署,Relay 做准入验签)。但「细粒度频道权限 + 端到端加密 + 可审计」三者同时满足,在密码学工程上是出了名的难平衡——Slack 直接放弃了 E2EE,Buzz 如果想两头都要,复杂度会陡增。
5.4 生态冷启动
协作工具的护城河从来不是技术,是网络效应和集成生态。Slack 有几千个 App,Buzz 现在有什么?它的赌注是:AI Agent 时代的「集成」不再是平台商店里的 App,而是拿着密钥直接入驻的 Agent——集成生态从「平台审核制」变成「协议开放制」。这个叙事能否成立,取决于 Goose、OpenClaw 这类 Agent 框架的开发者愿不愿意把 Nostr 当成标准输出通道。协议是开放的,但习惯是昂贵的。
六、横向对比:Buzz vs Slack vs Mattermost
| 维度 | Slack | Mattermost(自托管) | Buzz |
|---|---|---|---|
| 数据主权 | 厂商托管 | 自托管,私有 Schema | 自托管,开放协议格式 |
| 身份模型 | 中心化账号 + Bot token | 中心化账号 + Bot token | 密钥对,人与 Agent 同构 |
| 行为审计 | 平台日志(企业版) | 数据库日志 | 签名事件流,密码学可验证 |
| Agent 地位 | 外挂 App | 外挂插件 | 一等成员 |
| 互操作性 | 封闭 API | 半开放 API | 协议级互操作(Nostr) |
| 生态成熟度 | ★★★★★ | ★★★ | ★(早期公测) |
| E2EE | 无 | 无 | 协议层可选(NIP-44 路线) |
一句话总结:Slack 赢在现在,Buzz 赌的是「Agent 占协作消息量一半以上」的那个未来。
七、总结与展望
Buzz 给我的最大启发不是「又一个 Slack 杀手」,而是它对一个根本问题的重新回答:
在人机混合团队里,「成员」的最小定义是什么?
Slack 的答案是「一个账号」,Buzz 的答案是「一把密钥」。前者的信任根在平台,后者的信任根在数学。当 AI Agent 从玩具变成承担实际职责的生产力单元,「它是谁、它干了什么、谁为它负责」这三个问题必须有不可抵赖的答案——签名事件日志目前看是最工程可行的方案。
短期看,Buzz 大概率不会撼动 Slack:产品还糙(0.4.x)、生态是荒地、企业采购不认「去中心化」这个词。但它验证的三个方向,我认为会被大量借鉴,甚至可能先于 Buzz 本身在别的产品里开花结果:
- Agent 持钥:身份下沉到密码学层,摆脱平台 token 体系;
- 协作即事件溯源:全量签名事件流作为单一事实源,UI 只是投影;
- 审计即验签:AI 参与决策的合规留痕,从「相信日志」进化为「验证签名」。
对于想动手的同学,我的建议是:不用等 Buzz 成熟,今天就可以用 nostr-tools + 一个 Docker 起的自托管 Relay,把上面第四节的 CI Agent 跑起来。协议层的东西一旦亲手摸过,你对「去中心化协作」的判断就不会再被营销文案带着走。
工具会死,协议会活。这是互联网四十年来反复验证过的规律——而 Buzz 至少把宝押在了正确的一边。