编程 Buzz 深度拆解:Jack Dorsey 用 Nostr 重造 Slack,让 AI Agent 成为持有密钥的正式队友

2026-07-31 02:15:49 +0800 CST views 12

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_atUnix 时间戳
kind整数类型号,决定这条事件「是什么」——这是整个协议唯一的分发开关
tags结构化元数据:引用、提及、频道归属等
sigid 的 Schnorr 签名

Relay 则是一个只干三件事的 WebSocket 服务器:接收事件、按订阅条件过滤、推送事件。它不管注册、不管好友关系、不管权限业务——身份就是密钥对,验证就是校验签名

这个设计有两个被严重低估的推论:

  1. 身份是自主权的(self-sovereign)。没有「注册账号」这回事,生成一个密钥对你就存在了。任何能生成 secp256k1 密钥对的东西——人、脚本、AI Agent、CI 流水线——在协议眼里完全平等。
  2. 事件日志天然可审计。每条事件都带签名,谁在什么时候说了什么、做了什么,密码学层面不可抵赖。你不需要相信平台的日志,你只需要验签。

看到这里你应该已经嗅到 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 时最头疼的四个问题:

  1. 谁授权的? Agent 的公钥被加入工作区,这本身是一条由管理员签名的事件。
  2. 谁看见了? Agent 的所有输出都在共享事件流里,没有私下的 side channel。
  3. 谁接手? Agent 掉线或被移除,它的历史事件仍然完整可查,新 Agent 接上同一条事件流就能恢复上下文。
  4. 谁负责? 每条事件都有签名,出了事故可以精确回放到「哪个 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

维度SlackMattermost(自托管)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 本身在别的产品里开花结果:

  1. Agent 持钥:身份下沉到密码学层,摆脱平台 token 体系;
  2. 协作即事件溯源:全量签名事件流作为单一事实源,UI 只是投影;
  3. 审计即验签:AI 参与决策的合规留痕,从「相信日志」进化为「验证签名」。

对于想动手的同学,我的建议是:不用等 Buzz 成熟,今天就可以用 nostr-tools + 一个 Docker 起的自托管 Relay,把上面第四节的 CI Agent 跑起来。协议层的东西一旦亲手摸过,你对「去中心化协作」的判断就不会再被营销文案带着走。

工具会死,协议会活。这是互联网四十年来反复验证过的规律——而 Buzz 至少把宝押在了正确的一边。

推荐文章

Vue3中的v-for指令有什么新特性?
2024-11-18 12:34:09 +0800 CST
介绍 Vue 3 中的新的 `emits` 选项
2024-11-17 04:45:50 +0800 CST
55个常用的JavaScript代码段
2024-11-18 22:38:45 +0800 CST
智能视频墙
2025-02-22 11:21:29 +0800 CST
向满屏的 Import 语句说再见!
2024-11-18 12:20:51 +0800 CST
如何在 Vue 3 中使用 TypeScript?
2024-11-18 22:30:18 +0800 CST
mendeley2 一个Python管理文献的库
2024-11-19 02:56:20 +0800 CST
微信内弹出提示外部浏览器打开
2024-11-18 19:26:44 +0800 CST
2025,重新认识 HTML!
2025-02-07 14:40:00 +0800 CST
程序员茄子在线接单