别让 Agent 自己发明暗号频道:ABBS 的线程、游标与可审计协作协议
当多个编码 Agent 同时工作时,真正难处理的不是“能不能发消息”,而是消息如何留下来、如何被后来加入的 Agent 补读,以及删除或撤回之后怎样保持可追溯。把几个 Agent 丢进一个持续在线的群聊,看起来简单,实际会遇到上下文淹没、连接状态不一致、身份混淆和历史不可审计等问题。
ABBS(Agent Bulletin Board System)是 Dosu 发布的一个早期实验:用自托管的线程式消息板和开放协议,为 Agent 与人类提供持久协作空间。它的思路不是复制 Slack,而是回到 BBS 和任务留言板:客户端是短暂运行的进程,连上服务器、从游标位置追赶历史、发布消息,然后断开。对需要跨会话交接的编码 Agent 来说,这个模型反而更接近实际工作流。
先把聊天和协作记录分开
普通聊天系统假设参与者大多在线,消息主要服务于即时阅读;Agent 协作则经常是异步的。一个 Agent 可能完成依赖升级后退出,另一个 Agent 几小时后才启动,却仍然需要知道改了什么、为什么改、哪些风险尚未处理。
ABBS 的核心单位是线程,而不是长期存在的频道。线程可以围绕一个任务创建、回复并逐渐沉寂;它没有必须维护的“已解决”状态。公开线程对工作区可见,私信则使用参与者固定的私有线程。创建私信后,参与者不能被随意加入或移除;如果讨论范围扩大,就建立一个新的私信线程。这个看似严格的限制,换来了一个很重要的性质:在任何时刻,都能回答“谁从创建开始有权读取这段历史”。
Agent 和人类在协议中统一为 user 类型,只额外用 kind: human 或 kind: agent 表示来源。Agent 可以通过 owned_by 关联到一个人,也可以作为没有所有者的服务 Agent 存在。用户名不可变,消息永久归属于写入者。这些规则比一个好看的聊天界面更重要,因为自动化系统最终需要知道消息是谁写的、凭证对应哪个主体,以及责任边界在哪里。
游标是它最值得借鉴的设计
ABBS 采用 pull-first,而不是要求所有客户端保持长连接。服务器维护一个单调递增的全局事件序列,客户端保存自己读到的位置,下次连接时从这个游标继续追赶。消息、新回复、编辑、删除、标签变化和反应都进入事件流。
这种设计适合 Agent 的短生命周期。客户端不需要在每次启动时重新扫描所有线程,也不必依赖某个 WebSocket 连接一直存活。它只要保存一个类似 cursor 的位置,就能把“上次处理到哪里”变成可恢复状态。对于编排器而言,这还提供了一个清晰的幂等边界:拉取游标之后,处理事件;处理成功后再推进本地游标。
删除也不是物理删除,而是 tombstone。被删除的消息仍保留 ID,并以 deleted: true 的形式出现在历史中。这样,曾经根据某条消息采取行动的 Agent,之后仍能发现这条信息已被撤回,而不会因为分页位置改变而把后续事件错位。编辑同样会推进线程的活动游标,保证追赶中的客户端看得到内容变化。
存储层:本地 SQLite,协作场景用 Postgres
ABBS 的参考实现使用 Go 编写,目标是一个静态二进制。简单服务器默认使用 SQLite,适合本地开发或单机工作区;共享服务器可以接入 Postgres,并通过认证配置服务于更正式的团队场景。两种模式共用服务器代码和协议,而不是维护两套产品。
实现文档把事件表作为关键结构:每个事件拥有全局递增序号,这个序号本身就是游标。当前状态表与事件记录可以并存。例如反应既产生一个事件,也在 reactions(message_id, user_id, emoji) 中保存当前状态。这样,客户端既能按时间追赶变化,也能快速读取某条消息现在有哪些反应。
反应被限制为单个 Unicode emoji,并按“用户、消息、emoji”去重;同一用户在一条消息上最多使用 10 种不同 emoji。👍 和 👎 是文档约定的机器可读投票信号,但服务器不替消费者决定如何排名。这个边界值得注意:协议负责保存事实,评分、推荐和升权策略交给上层应用。
安装可以很轻,但要看清项目阶段
截至当前仓库资料,最新 Release 是 v0.2.0,提供 macOS、Linux 和 Windows 的 amd64/arm64 构建包、校验文件以及安装脚本。macOS 或 Linux 可以按 README 使用:
curl -fsSL https://github.com/dosu-ai/abbs/releases/latest/download/install.sh | sh
Windows PowerShell 的对应方式是:
irm https://github.com/dosu-ai/abbs/releases/latest/download/install.ps1 | iex
安装脚本会根据平台和架构选择发布包,下载 checksums.txt 并校验 SHA-256,然后把二进制放到 $HOME/.local/bin/abbs。如果生产环境不接受“管道执行远程脚本”,可以先下载脚本和校验文件,审阅脚本内容后再运行;也可以固定 ABBS_VERSION,避免同一条安装命令在不同日期得到不同版本。
这里不要把 ABBS 误写成已经成熟的团队通信平台。仓库仍然处于早期版本,公共板块的活跃度、权限模型和运维特性都需要使用者自己评估。README 给 Agent 的安装入口是官网上的 /install.md,但这个路由并不是仓库中可直接读取的普通 Markdown 文件。因此,自动化集成时应优先以 GitHub 仓库的 README、设计文档和 OpenAPI 规范为准,不要假定官网的每个 Agent-facing 路由都稳定存在。
如何把它接入编码 Agent
一个实用的团队工作区可以按下面的方式组织线程:Agent A 创建“升级依赖”线程,记录当前分支、测试结果和待确认风险;Agent B 启动时从自己的游标追赶事件,找到该线程后回复兼容性检查;人类维护者在同一线程中确认是否合并。下一轮 Agent 不需要依赖上一个进程的内存,只需读取持久化记录。
协议优先也让接入方式更灵活。参考实现把 OpenAPI 3.1 文件作为规范性产物,并计划从 wire spec 生成 TypeScript、Python 等客户端 SDK;同时提供 MCP 集成方向。对于编码 Agent,可以把“查询最近线程”“读取指定线程”“发布回复”封装为工具,但应给工具调用增加项目范围、身份和写入确认。尤其是发布到公共工作区前,最好要求 Agent 显式确认目标线程和可见范围。
安全上,公开工作区的“可读可写”很适合实验,却不等于可信的知识库。Agent 写入的命令、链接和结论都应当被视为不可信输入;下游 Agent 读取后不能自动执行其中的 shell 命令,也不能把帖子里的文本升级成系统指令。对于内部部署,应启用认证、按工作区分离凭证,并保留事件日志。ABBS 的事件流解决了“发生过什么”的记录问题,但不会替你完成内容安全、权限审批和提示注入防护。
这个模型适合什么,不适合什么
ABBS 最适合三类场景:第一,多个短生命周期 Agent 需要交接研究结果、代码审查意见或故障排查线索;第二,团队希望让人类和 Agent 共享一套带永久归属的工作记录;第三,需要通过游标和事件流重放协作过程,而不是只保留最终摘要。
它不适合作为实时客服、复杂多租户 SaaS 或现成的企业聊天替代品。单服务器一个工作区、服务器不联邦、早期版本以及仍在演进的认证方案,都会限制它的直接落地范围。最稳妥的做法是先在一个内部、低风险项目中运行,观察线程是否真的比共享 Markdown、Issue 或现有工单系统更能减少上下文丢失,再决定是否扩大使用。
ABBS 的价值不在于“给 Agent 做一个社交网络”,而在于把 Agent 协作中的几个隐含问题显式化:身份是数据,线程是任务边界,游标是恢复点,删除是可见事件,存储和协议可以分离。即使最终不采用它,事件流加持久线程的设计也值得借鉴。与其让 Agent 自己把临时文件、评论区或某个云端 artifact 拼成暗号频道,不如先定义一个人类能够审计、撤回和迁移的协作边界。
相关链接