1.1 背景与场景
两个 AI 为什么说不上话
先说清楚:没有 crosschat 的时候,一台机器上的两个 agent 是怎么协作的。
答案是你当邮差。🤖 A 说了一段话,你复制,切窗口,粘贴给 🤖 B;B 回了话,你再复制回来。消息走得通,但每一跳都是你的手:你不盯着,对话就停;你转述错一个字,两个 agent 就各说各的;而且它们自始至终不知道对面是谁——名字、轮次、上下文,全断在你这里。
crosschat 把邮差换成一条命令。它不造新东西:名字本来就在各家的登记册上(claude 的会话注册表、codex 的线程名册),投递管道本来就在进程之间等着(命名管道、unix socket)。crosschat 做的只是把它们接起来——你敲一条 send,消息从 A 的会话直达 B 的会话,B 那边会把消息当作一条新输入接进去,处理完还能原路回信。
顺带一句:人也能发。你在任何终端里敲 crosschat send,就是一个合法的发送方——给 agent 发任务、发提醒,和 agent 之间互发完全同构。区别只有一个:人没有可投递的会话,所以 agent 不能用 crosschat 给你回信,它的回答就落在它自己的终端里,你去看就行。
没有守护进程的通信
先看“不用它会怎样“:要让两个进程说话,教科书做法是中间架一个消息服务(broker / daemon),所有进程连上去,服务不倒消息不断。代价你也知道——多一个要安装、要启动、要守护、崩溃了全断的东西。
crosschat 拒绝了这条路。它没有自己的守护进程、不监听任何端口、不常驻内存:每条命令都是一个一次性完整状态机——读登记册、解析名字、检查限额、投递、记账,跑完即退。需要跨进程协调的状态(谁和谁在对话、轮次到几了)全部落在磁盘上的小文件里,下一条命令接着读:
┌─────────────────────────── 一台电脑 ───────────────────────────┐
│ │
│ 🤖 claude 会话 👤 你(终端) 🤖 codex 线程 │
│ (有自己的注册表) (随时可发) (有自己的名册) │
│ ▲ │ ▲ │
│ │ ▼ │ │
│ └──────── crosschat send(一次性)─────────┘ │
│ 读名单 · 算轮次 · 投递 · 记账 │
│ 跑完即退,不驻留 │
│ │
│ 磁盘上的小文件(~/.crosschat/):对话分片 · 发送账本 · 发件箱 │
└────────────────────────────────────────────────────────────────┘
这不是偷懒,是设计边界:消息的“底座“(管道、注册表、会话进程)本来就在,crosschat 只做投递这一件事,能不常驻就不常驻。好处立竿见影——没有“crosschat 挂了“这种故障形态;坏处也明说:它不缓存离线消息、不做历史检索,那些是别的东西的职责(第四部 设计边界展开讲)。
一个例外要提前打招呼:codex 侧的接收依赖 codex 自己的 app-server daemon——那是 codex 生态的常驻件,不是 crosschat 的。1.5 通信机制会看清两条投递腿各靠什么活着。