社交文件系统 AT 协议技术分析一、概述1. 文章信息A. 标题A Social Filesystem（社交文件系统）B. 作者Dan AbramovC. 来源overreacted.ioD. 发布时间2026 年 1 月 18 日2. 核心主题本文探讨了如何将传统文件系统的理念应用到社交网络中，介绍了 AT 协议（Authenticated Transfer Protocol）如何实现数据与应用的分离，让用户数据真正归属于用户而非平台。二、背景分析1. 传统文件系统的优势A. 数据归属文件不属于创建它的应用程序，而是属于用户。用户可以检查文件、发送给朋友、用其他应用打开。B. 文件格式的作用文件格式就像一种语言，应用可以"说"多种格式，同一种格式可以被多个应用理解。应用和格式是多对多的关系。C. 应用无关性我们的记忆、思想、设计应该比创建它们的软件更持久。应用无关的存储（文件系统）强制实施这种分离。2. 社交应用的现状问题A. 数据被困在 Instagram、Reddit、Tumblr、GitHub、TikTok 等社交应用中，用户数据被困在应用内部，无法自由迁移。B. 应用主导传统模式是应用主导，用户的数据存储在应用的服务器上，由应用控制。C. 缺乏互操作性不同社交平台之间数据无法互通，用户需要重复创建内容。三、核心理念：社交文件系统1. 万物文件夹概念假设有一个文件夹包含你的在线角色所有发布过的内容：你的帖子、点赞、音乐播放记录、食谱等，可以称为"万物文件夹"。在这个世界中：在 Tumblr 发帖会在你的文件夹中创建一个"Tumblr 帖子"文件在 Instagram 关注会在你的文件夹中放入一个"Instagram 关注"文件在 Hacker News 投票会在你的文件夹中添加一个"HN 投票"文件2. 文件作为真实来源文件是真实来源，应用只是反映文件夹中的内容。对文件夹的任何写入都会同步到相关应用。删除"Instagram 关注"文件与应用中取消关注效果相同。3. 应用反应式设计在这个范式下，应用对文件是反应式的。每个应用的数据库主要成为派生数据——应用特定的缓存物化视图，反映所有人的文件夹。四、AT 协议架构1. 系统组成graph TB User[用户] --> owns[拥有] owns --> Repo[Repository 仓库] Repo --> contains[包含] contains --> Collection[Collection 集合] Collection --> containsRecord[包含] containsRecord --> Record[Record 记录] Repo --> hostedBy[托管于] hostedBy --> PDS[Personal Data Server] PDS --> syncWith[同步] syncWith --> Relay[Relay 中继] App1[App 1] --> subscribes[订阅] subscribes --> Relay App2[App 2] --> subscribes App3[App 3] --> subscribes2. 核心概念A. Record（记录）记录是社交文件系统的基本单位，是一个 JSON 文件。例如一条推文记录：{ "text": "no", "createdAt": "2008-09-15T17:25:00.000Z" }关键原则：只包含用户创建的数据不包含派生数据（如点赞数、转发数）可以独立验证和解析B. Collection（集合）集合是包含特定词表类型记录的文件夹。命名规则采用反向域名表示法：com.twitter.post：Twitter 帖子com.instagram.follow：Instagram 关注fm.last.scrobble：Last.fm 播放记录io.letterboxd.review：Letterboxd 影评graph LR subgraph Collections A[com.twitter.post] B[com.instagram.follow] C[fm.last.scrobble] D[org.schema.recipe] end App1[App 1] --> defines[定义] defines --> A App2[App 2] --> defines defines --> B App3[App 3] --> defines defines --> CC. Repository（仓库）仓库是用户的"万物文件夹"，由 DID 标识，包含集合，集合包含记录：graph TD DID[DID:did:plc:xxx] --> Repo[Repository] Repo --> Collection1[com.twitter.post] Repo --> Collection2[fm.last.scrobble] Repo --> Collection3[com.ycombinator.news.vote] Collection1 --> Record1[记录1] Collection1 --> Record2[记录2] Collection2 --> Record3[记录3]D. Lexicon（词表）词表是记录格式的定义，类似于 TypeScript 类型定义，但更丰富：{ "lexicon": 1, "id": "com.twitter.post", "defs": { "main": { "type": "record", "key": "tid", "record": { "type": "object", "required": ["text", "createdAt"], "properties": { "text": { "type": "string", "maxGraphemes": 300 }, "createdAt": { "type": "string", "format": "datetime" } } } } } }词表特点：可以表达约束（如字符串长度、格式）易于解析，便于构建工具可以生成多种语言的类型定义和验证代码E. DID（去中心化标识符）DID 是账户的永久标识符，支持多种方法：graph TD DID[DID 标识符] --> Methods[方法类型] Methods --> did_web[did:web - 域名] Methods --> did_plc[did:plc - 注册表] Methods --> did_future[did:bla - 未来方法] did_web --> Example1[did:web:wint.co] did_plc --> Example2[did:plc:6wpkkitfdkgthatfvspcfmjo]DID 解析过程：给定 DID，获取其文档（包含当前托管、句柄、公钥）文档指向数据的实际托管位置从托管位置获取记录五、技术实现细节1. 记录键命名使用时间戳加随机性混合的编码：posts/ ├── 34qye3wows2c5 ├── 34qye3wows2k3 └── 34qye3wows3k3优点：可以本地生成，几乎不会冲突按字母排序即按时间排序ls -r 可以得到按时间倒序的时间线2. at:// URIat:// URI 是指向记录的永久链接，可以经受托管和句柄变更：at://did:plc:6wpkkitfdkgthatfvspcfmjo/com.twitter.post/34qye3wows2c5 └─────────── who ──────────────┘ └─ collection ─┘ └── record ─┘解析流程：解析 DID 获取托管位置从托管位置获取指定集合中的记录3. 记录间关系通过 at:// URI 实现记录间的引用：graph TD Post[Post 记录] --> hasLikes[有点赞] hasLikes --> Like1[Like 记录] hasLikes --> Like2[Like 记录] hasLikes --> Like3[Like 记录] Like1 --> references[引用] references --> Post Post --> hasReplies[有回复] hasReplies --> Reply1[Reply 记录] Reply1 --> parentField[parent 字段] parentField --> references示例：点赞记录：{ "subject": "at://did:plc:xxx/com.twitter.post/34qye3wows2c5" }回复记录：{ "text": "yes", "parent": "at://did:plc:xxx/com.twitter.post/34qye3wows2c5" }六、数据完整性验证1. 哈希树结构仓库结构化为哈希树（Merkle Tree）：graph TD Root[Root Hash] --> Commit[签名 Commit] Commit --> Tree[Tree Delta] Tree --> contains1[包含] contains1 --> Record1[记录 1] Tree --> contains2[包含] contains2 --> Record2[记录 2] Tree --> contains3[包含] contains3 --> Record3[记录 3]每次写入都是包含新根哈希的签名提交，这使得：可以验证记录与原作者公钥的匹配中继可以只重传证明，不存储内容降低中继运行成本2. 数据流订阅除了将仓库视为文件系统（列出和读取），还可以将其视为流，通过 WebSocket 订阅。sequenceDiagram Repo as Repository Relay as Relay 中继 App as 应用缓存 Repo->>Relay: 提交新记录 Relay->>App: 推送事件 + 树证明 App->>App: 验证证明 App->>App: 更新本地缓存七、实际应用案例1. Sidetrail 应用作者创建的 Sidetrail 应用演示了数据真实来源于仓库的概念：export async function handleEvent(db: IngesterDb, evt: JetstreamEvent): Promise<void> { if (evt.kind !== "commit") return; const { commit } = evt; const { collection, rkey } = commit; if (commit.operation === "delete") { switch (collection) { case "app.sidetrail.walk": await deleteWalk(db, uri); break; } return; } const record = commit.record as Record<string, unknown>; switch (collection) { case "app.sidetrail.trail": await upsertTrail(db, uri, commit.cid, evt.did, rkey, record); break; } }用户在 pdsls 中删除 app.sidetrail.walk 记录，Sidetrail 应用中的对应 walk 会自动消失。2. teal.fm 演示一个展示最近播放曲目的演示：graph LR Users[用户] --> Scrobble[Scrobble 记录] Scrobble --> creates[创建] creates --> fm_teal[fm.teal.alpha.feed.play] fm_teal --> indexed[被索引] indexed --> Relay[中继] Relay --> GraphQL[lex-gql GraphQL] GraphQL --> Demo[演示网站]关键点：teal.fm API 实际上不存在teal.fm 产品也只是着陆页任何人都可以开始通过在仓库中放入记录来记录播放演示只索引 fm.teal.alpha.feed.play 记录八、词表生态系统1. 词表发现通过以下工具发现现有词表：pdsls.dev：词表目录服务Lexicon Garden：词表展示平台UFOs：词例浏览器2. 词表发布词表可以作为记录发布：graph TD Lexicon[词表定义] --> publish[发布到] publish --> com_atproto[com.atproto.lexicon.schema] com_atproto --> contains[包含] contains --> io_overreacted[io.overreacted.comment]需要通过 DNS 设置证明域名所有权。3. 词表验证原则应用始终将记录视为不受信任的输入在读取时验证，就像文件一样演进词表时不能改变哪些记录被认为是有效的可以添加新的可选字段，但不能改变字段的可选性九、信任模型1. PLC 目录PLC（Permissionless Concatenatable Log）目录的特点：graph TD User[用户] --> creates1[创建账户] creates1 --> Generate[生成密钥对] Generate --> Sign[签名操作] Sign --> Hash[哈希] Hash --> DID[DID 标识符] User --> updates[更新] updates --> NewOp[新操作] NewOp --> Prev[prev 指向前一个] Prev --> Chain[操作链]验证过程：检查签名有效prev 字段匹配前一个操作的哈希验证整个更新链到第一个操作第一个操作的哈希就是标识符2. 中继信任中继不存储私钥数据、完全开源、操作日志可审计。理想情况下会独立成为法律实体。十、优势与挑战1. 优势A. 数据主权用户真正拥有自己的数据，可以自由迁移托管B. 应用创新任何人都可以为现有数据创建新应用C. 互操作性不同应用可以共享和理解相同的数据格式D. 可验证性数据可以验证真实性，无需信任中继2. 挑战A. 派生数据计算应用需要计算派生数据（如点赞数）而无需额外开销B. 中继信任如何确保他人的中继不撒谎C. 用户体验密钥管理对大多数用户来说很复杂十一、总结AT 协议通过将文件系统理念引入社交网络，实现了：数据与应用的真正分离用户数据归属于用户应用可以自由创新，不被锁定数据可验证、可迁移、可互操作这种范式转变可能重新定义社交网络的基础架构，让社交计算回归个人计算的本质。参考资料A Social Filesystem - overreacted.ioAT Protocol 官方网站Bluesky 社交网络Lexicon Garden - 词表展示平台pdsls - AT Protocol 文件管理器