AT Protocol 详解:支撑 Bluesky 的联邦式社交协议
Bluesky 这款应用的背后,是一套被有意设计成独立存在的协议层。AT Protocol(Authenticated Transfer Protocol)将**账号可迁移性**与**应用层去中心化**作为核心设计目标,通过基于 Merkle Search Tree 的签名仓库、以 DID 为基础的身份体系,以及职责分明的一组基础设施角色来实现这一目标。本文详细介绍其设计思路,以及实际运营中暴露出的问题。
AT Protocol 是什么:账号可迁移性与应用层去中心化
AT Protocol(Authenticated Transfer Protocol)起源于 Twitter 内部一个关于去中心化社交网络的研究项目,自 2021 年起由独立机构 Bluesky PBC 持续开发。同名应用「Bluesky」只是构建在这一协议之上的众多客户端之一,协议本身的设计目标是让其他应用也能够使用它。其设计的核心是两大理念:账号可迁移性(account portability)与应用层去中心化(application-level decentralization)。前者是指用户在技术上不会被某一家托管服务商锁定,可以在保留粉丝和发帖历史的前提下迁移到另一台服务器;后者是指多个相互独立、彼此竞争的应用(时间线客户端、自定义 feed、审核工具等)可以共存于同一套数据基础设施之上。与联邦式架构的普遍目标一致,AT Protocol 试图通过这两大理念,实现「没有任何一家公司能够单方面关闭整个网络」的愿景。
身份体系:DID 与基于 DNS 的 handle
AT Protocol 中的每个用户都拥有一个持久且可加密验证的DID(去中心化标识符,Decentralized Identifier)。Bluesky 默认使用的 DID 方法是 did:plc:由 Bluesky PBC 运营的一个仅追加、可审计的目录服务(PLC Directory)保存每个 DID 文档(包含签名密钥、当前所在 PDS 等信息)的更新历史。如果希望自行运营这一目录功能,也可以改用 did:web,将 DID 文档托管在自己的域名之下。由于原始 DID 不便于人类使用,每个 DID 还会关联一个人类可读的handle(例如 @alice.example.com)。handle 本身就是一个域名或其子域名,通过在 DNS 中添加 TXT 记录(_atproto.<domain>)或在域名根目录放置 .well-known 文件来证明域名归属,从而建立 handle 与 DID 之间的对应关系。这一机制把「用户住在哪台 PDS 上」与「用户是谁」两个问题分离开来,同时复用了 DNS 这一成熟稳定的基础设施作为信任起点。更多细节可参阅DID 详解。
仓库:带签名的 Merkle Search Tree
每个用户的数据(帖子、点赞、关注关系、个人资料等)都以记录的形式,存放在该用户专属的签名仓库(repository)中。记录按集合(collection)分类,集合名即 Lexicon 的 schema 名称(例如 app.bsky.feed.post),整个仓库则存放于Merkle 树详解中 MST 一节所介绍的Merkle Search Tree(MST)之中。用户每新增、更新或删除一条记录,都会重新计算出一个新的 MST 根哈希,并将包含该根哈希的commit用用户的签名密钥进行签名。这一结构使得任何人都能够低成本地证明「某条记录确实存在于该用户的仓库中」,也让多个 relay 之间只需同步仓库版本之间存在差异的子树即可完成复制,这正是 MST 最初被设计来解决的副本同步问题。除签名密钥外,权限更高的rotation 密钥负责更新 DID 文档本身(更换签名密钥、变更账号所指向的 PDS),即便签名密钥泄露或与 PDS 服务商发生纠纷,账号依然能够得到保护。
支撑网络运转的基础设施:PDS、Relay、AppView、Feed Generator、Labeler
AT Protocol 并非由单一服务器承担全部职责,而是把功能拆分给多个职责各异的组件。正是这种拆分,才使「应用层去中心化」在技术上成为可能。
- PDS(Personal Data Server,个人数据服务器)
- 实际托管用户仓库的服务器,负责身份验证以及记录的读写。既可以使用 Bluesky 运营的 PDS,也可以自行搭建。
- Relay(firehose)
- 爬取并订阅大量 PDS,把全网范围内的仓库更新事件汇聚成一条统一的流(firehose,通过
subscribeRepos接口)再重新广播出去。Bluesky PBC 运营着一个规模庞大的默认 Relay。 - AppView
- 消费 firehose,为特定应用聚合、索引数据,社交图谱的构建、时间线的生成、通知的产生等工作都在这一层完成。
- Feed Generator
- 一个独立于 AppView 的小型服务,实现自定义的排序算法,只返回帖子 URI 的列表(骨架),具体内容由 AppView 负责填充。
- Labeler
- 同样独立于 AppView 的服务,负责为内容或账号打上审核标签。用户可以按自己的意愿分别订阅多个 Labeler。
这里容易产生一个误解:仓库会被复制到多个 Relay 与 AppView,并不意味着数据本身(在理念上)是分散存放的。真正的正本(source of truth)始终只有一份,即用户签名的PDS 上的仓库;Relay 与 AppView 保存的只是从 firehose 接收到的副本或索引。如果 PDS 删除某条记录,这一删除操作会经由 firehose 传播到全网,下游的副本也理应随之更新。这种「正本唯一」的设计,也让违法内容的法律责任归属变得清晰:多数司法辖区通常要求托管方删除违法数据,而在 AT Protocol 中,承担这一责任的正是持有正本的PDS 运营方。
这些组件之间的交互都由Lexicon这一 schema 定义语言严格定型。Lexicon 用反向域名风格的 NSID(例如 app.bsky.feed.post)为每种记录类型和 API 端点命名空间化,并在此基础上生成 XRPC,一套基于 HTTP 的简单 RPC 约定(查询对应 GET,操作对应 POST)。只要由不同开发者实现的 PDS、AppView、客户端都遵守 Lexicon 这份共同的「契约」,彼此之间就能够互操作,这正是这种分离式设计的用意所在。
设计理念的落地与尚存的课题
这种职责分离支撑了两个理念性的主张。其一是算法的可选择性(algorithmic choice):时间线该按什么算法排序,并非由协议本身决定,用户可以自由选择并订阅自己喜欢的 Feed Generator。其二是可叠加的审核机制(stackable moderation):「什么内容应被判定为不当」这一判断权不再由单一运营方独占,每个用户都可以按自己的标准,组合来自多个独立 Labeler 的标签。这两点都得益于把相应功能从协议核心中剥离出来。
- Relay 与 AppView 的运营成本分布不均:firehose 需要处理全网范围的更新,所需的带宽、存储与计算能力都不小。结果是,实际流量大多集中在 Bluesky PBC 运营的默认 Relay 与 AppView 上,这也招致了「号称联邦式,实际上接近中心化」的批评。相比之下,自行搭建 PDS 已经变得相对容易,但自行运营 Relay 或 AppView 的第三方仍属少数。
- 联邦化的实际落地仍不成熟:多个相互独立、彼此竞争的 AppView 共存的图景目前更多停留在理念层面,实际被广泛使用的 AppView 基本上仍然是 Bluesky PBC 自己提供的那一个。
- 与 ActivityPub 之间没有直接互操作性:由于数据模型与协议本身都和 ActivityPub 不同,Bluesky 无法与以 Mastodon 为代表的 Fediverse 直接联邦。Bridgy Fed 等桥接服务通过在两者之间转换、中继消息,实现了有限程度的互通。详见ActivityPub 详解。
不过,中心化隐忧并非 AT Protocol 的全貌。2026 年 4 月,Bluesky PBC 的服务器遭受 DDoS 攻击,宕机长达十余小时,这一事件也在现实中证明了「官方应用宕机」与「协议本身宕机」是两回事。在 Bluesky 自家基础设施瘫痪期间,自行运营 Relay 与 AppView 的兼容网络(例如Blacksky与Eurosky)不受影响、持续运转,据报道还承接了大量无处可去的用户。这一事件揭示出 AT Protocol 各层去中心化程度并不均衡:PDS 足够轻量,个人也能自行运营;而 Relay、AppView 则需要相当的运营能力,因而更容易走向集中。
把 AT Protocol 与追求类似去中心化目标的其他协议放在一起比较,其特点会更加清晰。
| 维度 | ActivityPub | AT Protocol | Nostr |
|---|---|---|---|
| 身份 | 与 actor 名称及实例域名绑定的 URI(例如 @user@instance.tld) | DID(did:plc/did:web)与基于 DNS 的 handle 相互分离 | 公钥(npub)本身即为身份,不与任何服务器绑定 |
| 数据存放位置 | 数据保存在所属实例上,通过 inbox/outbox 进行投递 | 签名仓库(MST)托管于 PDS,但与 DID 相互解耦(正本仅存于 PDS,Relay/AppView 只是索引副本) | 签名事件被冗余地广播到多个 relay,不存在单一的「正本」存放处 |
| 账号可迁移性 | 跨实例迁移时,粉丝与历史记录通常只能有限地保留 | DID 与 handle 独立于托管方,迁移 PDS 时数据与关系按设计应可保留 | 密钥对本身就是身份,「迁移」实质上只是改为向另一批 relay 发布 |
| 发现与分发机制 | 基于服务器间 inbox 投递的推送式联邦 | Relay(firehose)汇聚全部更新,AppView 再按应用重新组织 | 客户端分别连接并订阅多个 relay 的拉取式模型 |
| 审核机制 | 以实例管理员的封禁与断开联邦(defederation)为主 | 通过 Labeler 实现可叠加的审核,用户可分别订阅多个 Labeler | 主要依赖客户端过滤与 relay 端的屏蔽名单,协议内建机制较为薄弱 |
相关页面
AT Protocol 在本站介绍的多项技术中都可以找到具体的应用场景:支撑仓库完整性的 Merkle Search Tree,详见Merkle 树详解;多个运营方协作运行同一网络的通用思路,见联邦式架构;追求相似目标但采用不同设计路径的协议,可参阅ActivityPub 详解与Nostr 详解;支撑整个身份体系的底层技术,则在DID 详解中详细展开。