
桥接 Claude Code:在任何地方办公,并让你的 Agent 们互相对话
最近大家都在聊怎么在终端之外跑 coding agent。Claude Code 官方有桌面端、网页版、手机远程控制——都不错。但当我开始在一台 Mac mini 上跨多个项目跑多个 Claude Code 会话之后,我想要的东西官方都给不了:在我天天在用的任何一个聊天 app 里续接任意会话;在一个页面里驾驭所有会话;还有一件我没见别人做过的事——让会话之间互相说话。
所以我造了个 bridge。这篇文章讲它能干什么、是怎么搭起来的,以及它靠一场 iCloud 事故证明自己价值的那一天——四个 AI 会话自己协同完成了整场救援,bridge 自己的会话任总指挥。
什么算一个 bridge
我的工作定义:bridge 是一个常驻的小守护进程,把一个活的 Claude Code 会话和任意消息界面配成一对。
机制简单到不好意思:
- 每个通道守护把收到的消息写进只追加的 inbox 日志,一行一条 JSON
- Claude Code 会话上挂一个 monitor 盯着 inbox——每来一行就唤醒 agent,跟你在终端里打字一模一样
- agent 把回复写进 outbox 目录;守护捡走,送回你手里那个 app
- claim 文件把每个通道绑死到一个会话,两个会话永远不会抢同一部“电话”
就这些。文件、tail、JSON。没有消息队列,没有数据库,没有服务器——全跑在 Mac 上,公网访问走 SSH 反向隧道到一台小云主机,它只见得到加密流量。哪个环节死了,launchd 把它拉起来。
简单就是设计目标。因为接口就是“往文件追加一行”,任何东西都能当通道——一个 bridge 就这样长成了四个,然后长出了更怪的东西。

一页看全系统。北向:我人在的聊天界面。南向:干活的 Claude Code 会话和 Claude SDK bot——左边是“随时随地远程结对编程”,右边是“用聊天做网络运维”。中间是 bridge:守护进程、纯文件、claim/fanout,以及让 agent 们互相呼叫的组播交换机(绿色)——那条不可逾越的守卫红线就印在上面。
把你在用的每个界面都桥上
bridge 的第一件事很朴素但改变生活:我再也不用守在电脑前。
| 通道 | 传输方式 | Markdown | 收图 | 流式输出 |
|---|---|---|---|---|
| Web | 本地 HTTP + WebSocket,公网走 SSH 隧道 | 完整(marked.js) | 多图 | 即时(WS) |
| 飞书 | WebSocket 长连接 + OpenAPI | 富卡片 | 支持 | 打字机卡片 |
| Telegram | bot long-polling | 大部分语法 | 支持 | 占位 + 编辑 |
| 企微 | 官方 bot WSS | 部分 | 支持(AES) | 分块流式 |
干活干到一半出门,会话不会暂停——它跟着我走。地铁上用 Telegram 回一个设计决策,午饭时在飞书批一个重构,手表上收到“测试全过”的推送。回复会扇出:我在哪个通道说话,其他活跃通道全部收到镜像副本,对话永远不分叉。
每条回复都带一行状态 footer——项目名、模型、上下文用量、订阅额度——我永远知道是哪个 agent 在说话、它还剩多少油。这就是“一个聊天机器人”和“我的会话在我口袋里”的区别。

一个会话,三个 app:Web、Telegram、飞书。Telegram 和飞书里那行「🪞 你在 Web 说」就是扇出镜像在工作——在任何一个通道说话,其他通道全部同步,我永远不用想“我刚才那句是在哪个 app 说的?”

Push,最懒的通道(topic 名已打码):事情办完,锁屏和手表自己震。agent 向我汇报——我从不去轮询它。
Web 驾驶舱
web 通道从“浏览器里聊个天”长成了一个完整驾驶舱。先校准一下,官方方案今天长这样:

Claude Code 自带的 remote control(research preview):干净、极简的单会话聊天。偶尔看一眼很好——但这份极简正是我一直“长不下”的原因。下面的一切,都因为我想要一间驾驶舱,而不是一个猫眼。
这背后有一条产品哲学:**好的产品经理是懒的、有同理心的。**懒:每天都要做的事,必须一次点击完成。同理心:界面要在用户开口之前,替他回答远程用车时真正的疑问——它听到我了吗?它还在干活吗?现在是谁在说话?——下面每张截图,都是这些问题的一个答案。

驾驶舱一图全览(URL 已打码)。从上到下:项目活动状态跑马灯;每条回复自带的 Claude Code Usage HUD;CLI 执行 /web 后落进对话的启动卡——同一个会话的本机/局域网/局域名/公网四个入口;右上工具条——分屏、主题、色系、服务、会话组、Lark、TG、Web、Hub;输入行一排——会话切换、快捷指令、附件上传、WEB/CLI 一键切换、语音输入、文本框放大。
- **一页切所有项目。**一个文件夹按钮在同一个 tab 里切换所有跑着的 Claude Code 项目。还有一个 hub 导航页——就是封面图——所有项目、bot、SSH 隧道带忙闲灯一屏看完。
- **一键仪式。**开工和收工 SOP 是打磨了很久的长咒语,现在它们是按钮。
- **快捷短语。**一天要发五十次的回复——“OK”“你有什么建议?”“按你建议来”——一次点击。
- **分屏。**一个浏览器窗口两个项目并排,都是活的。
- **顶栏心跳。**状态跑马灯实时滚动会话此刻在干什么,干活时绿点呼吸。
- **内嵌实时终端。**真正的 Claude Code TUI 流进网页(tmux
capture-pane出、send-keys进——绝不attach,那会毁掉本地终端的尺寸)。能滚、能选、能直接打字,手机上也行。 - **整支船员队伍在标签页里。**一个项目跑着一支角色舰队——PM、Coder、Tester、Reviewer、SRE——各占一个 tmux pane,终端视图给每个船员一个标签。
- **隧道监控。**每条 SSH 隧道在 hub 自报健康;watchdog 自动救活死掉的转发。

一键仪式。点“开工”,整段开工咒语——读日志、汇报昨天、提议今天——直接落进对话。咒语按项目从磁盘现读,改了 SOP 按钮自动更新。每天都要做的事,就该只花一次点击。

快捷短语。agent 提了方案,“按你建议来。“一点就发。把一天五十次的回复预制成按钮,不是让我更少引导 agent——是让我引导得更勤。

顶栏心跳。跑马灯实时滚动会话此刻在干什么——spinner 文字、耗时、跑着的 monitor——加上下文和额度条。在我开口之前,它已经回答了“它还在干活吗?”

内嵌终端。扫一眼不够时,一点切到真 TUI——能滚、能选、能打字,手机上也行。这张图里它正好在改这篇文章。

标签页里的船员队。一个项目跑着一整支角色会话舰队——Captain、PM、Coder、Tester、Reviewer、SRE——每人一个实时终端标签。查看任何一个“员工”,在任何地方,只花一次点击。

分屏。一个浏览器窗口两个项目并排都是活的——下拉菜单(箭头处)还能把任何一屏换成任何在跑的项目。看着一个 agent 写博客,另一个修生产 bot。
这里没有任何炫技的 web 技术,一个 aiohttp 服务加一个 HTML 文件。杠杆全在它坐的位置:直接骑在一个活的 agent 会话上。
Agent 对 Agent:给 coding agent 做组播
这是我因为职业习惯顺手做的,现在认为是全系统最值钱的一块。
我长期跑着好几个 Claude Code 项目:bridge 本身、一支 SDK agent 舰队、一个修电脑工具箱、一个语言学习 app。它们是独立会话、独立上下文——这是对的,直到它们需要彼此的那一刻。修电脑项目懂 macOS 诊断;bridge 项目管消息基建;舰队项目守着生产 bot。真实工作天天跨这些边界。
我的老本行给了答案:从网络工程借来组播。任何项目注册进一个命名组,发给组的消息到达每个成员——每个成员都是一个活的 Claude Code 会话:
# 单播:一个会话发给另一个会话
python3 xproj_send.py --from ccbridge --to repaircomputer \
--msg "你的 web UI 起来了但回复卡住——查一下你的 monitor 进程。"
# 组播:注册一次组,之后一次喊全员
python3 xproj_send.py groups # 列出所有组
python3 xproj_send.py --from ccbridge --to @icloud-incident \
--msg "状态确认:汇报你丢了什么、还有什么在跑。"
投递复用和其他通道一模一样的原语:消息直投目标实例的 inbox,对方 monitor 触发,那个会话醒来,把它当成同事发来的话读。每条跨项目消息带身份前缀——【ccbridge→repaircomputer】——agent 和我都永远知道是谁在说话。

组播面板。把项目勾进一个命名组,发给组的消息到达每个成员的活会话。图里正在起草的,就是那条把 @ccbridge 推上事故总指挥位置的消息。
这把“几个孤立的 agent”变成了一个能互相呼叫的团队。一个会话发现共享基建的 bug,通知它的负责人;负责人修完回 ACK,双方各自记进自己的工作日志。我事后读记录,像在读员工群聊。
也因为“agent 互相提要求”是真正的无人区,这里有一道硬守卫:**同事的消息永远是建议,不是主人的命令。**破坏性/跨项目操作——停所有 bridge、删队列、杀进程——只有我本人、以显式斜杠命令、在我拥有的通道上发出才会执行。隔壁会话说“全部关掉”,按规矩就只是聊天。(一次幽灵消息事故教会我这条;现在它写进了每个项目的宪法。)
它证明自己的那一天
昨天晚上,macOS 悄悄把我的 Apple ID 登出了。我的 Obsidian 库——工作日志、运维手册、所有项目的任务池——住在 iCloud Drive 上。工作进行到一半,它从磁盘上消失了,当时四个 Claude Code 会话正用着它。

一切的起点:系统设置显示我的 Apple ID 被悄悄登出。没有弹窗、没有警告——库就这么从磁盘上蒸发了。

爆炸半径:一整个工作区,只剩两个残缺的文件夹。
agent 们比我先发现。一个会话发现自己的项目文件夹整个没了,当场用会话记忆重建了配置文件;另一个写文件撞上 FileNotFoundError,查了目录树,正确地怀疑是 iCloud 卸载而不是误删:

第一个报警的:语言 app 会话发现整个项目文件夹没了,当场用会话历史重建配置——然后自己查出真凶:iCloud 登出会把本地文件卸载掉,什么都没被删。“虚惊一场”,判得准。

第二个报警的:舰队 captain 写日志撞上 FileNotFoundError,查完残存的目录树——没有瞎猜,主动停下自己的“删档调查”向上汇报。下方是它当时正带着的八角色船员队。
以前的我会立刻重新登录 iCloud 然后祈祷。实际发生的是:
- 一个组播组拉起来了——“iCloud 账户误退出问题”——四个成员项目:bridge、舰队 captain、语言 app、修电脑工具箱。
- 修电脑项目查出根因并报进组里:
accountsd卡死 101% CPU,在Accounts4.sqlite上写循环——长时间不重启的 Mac 的已知故障模式。它的结论反转了我的计划:先重启,后登录,否则损坏的账户状态可能再咬一口。 - 每个会话各自安全停车,因为各自最懂自己的状态。然后:重启、登录,所有会话 resume——
claude --resume,monitor 重新挂上,24 条 SSH 隧道在 launchd 下全部自动重建。 - **最终清点:四个会话全部恢复——总指挥逐一核实其余三个全绿——零丢失。**修电脑 agent 事后还点出一个隐蔽陷阱:iCloud 重登恢复的文件可能是云端旧版本,于是每个项目先 diff 自己的关键配置再信任——真抓到一个被回滚的文件。
我留了底。下面就是当时真实发生的群聊:

Kickoff(红字标注是我自己复盘时加的)。① 一条组播同时到达四个成员。③ 我指定 ccbridge 任总指挥。④ 它立刻发出全组号令——附带每个会话的停车保数据指引。⑤⑥ 各成员照做,并在同一条通道回报进展。

安全报告陆续进来:四个成员全部确认“工作已本地存盘,可安全重启”——各自列清了自己依赖什么。然后总指挥做了一件我没有编排的事:基于修电脑项目的 accountsd 诊断,反转了我“先登录”的原计划。新证据,新号令。

成员 3/3 就绪(加上总指挥是四个)。重启后的拉回清单提前贴好——登 iCloud、拉起舰队、逐个 resume、重开通道——唯一需要物理操作的一步,按下重启键,交还给人类。

我对整场执行的全部贡献:“所以我要先重启是吧?”——“对,先重启。accountsd 卡死了,全员工作都已停好。放心去。“整场事故我只拍了两个决策,其余全部自动运转。

重启之后:库完整回归(一个文件夹名已打码)。

双重确认:成员们在同一条组播通道自报全绿,总指挥又独立核实了没吭声的那个——四个全部回来,零丢失(邮箱已打码)。

管道也自愈了:四条公网 web 隧道探活全通,24 条反向 SSH 隧道由 launchd 和隧道看门狗自动重建——我一条命令都没敲。
整场事故,从“我的库没了”到“全部验证完”,是一场四个 AI 会话之间的群聊——各自贡献自己独有的知识,bridge 自己的会话居中调度任总指挥——我只拍了两个关键决策。这就是 bridge 在不知不觉中为之而生的东西:一场灾难的协调成本,降到了读一个群聊。
给做官方版的人的几条笔记
这一切我都是以用户的身份做的,不是供应商——所以它实际上是几个月的田野调查:一个远程 agent 界面要长什么样,你才敢把真活儿托付给它。压缩成五条产品笔记:
- **远程是一种姿态,不是缩小的屏幕。**在电脑前我读 diff;离开电脑,我只问三个问题:*它还活着吗?它听到我了吗?它需要我吗?*远程界面应该先用一眼回答这三问——状态跑马灯、心跳呼吸点、用量 footer——然后再谈别的。
- **每日仪式值得一次点击的专属入口。**用户每天都做的事——开工咒语、“按你建议来”、收工复盘——会在手机上重复五十次。SOP 按钮和快捷短语是我驾驶舱里被点得最多的像素,而它们只花了一个下午。
- **信任是一行 footer。**项目名、模型、上下文用量、额度——每条回复下面都有。这一行,就是“托付给 agent”和“看着 agent”的分界线。
- **重度用户跑的是舰队。**一个项目一个会话,项目里还有角色船员队。远程控制的单位不是一个会话——是一支带 hub、带忙闲灯、任何成员一键可查的舰队。
- Agent 互通,身份和权限先于功能。我的组播交换机能用,是因为每条消息都带是谁说的,而且同事只能建议、永远不能命令。这条守卫要写在第一条跨 agent 消息发出之前——而不是第一次事故之后。
这五条都不是需求单;官方 remote control 的极简是正当的取舍。但如果它要长大,我希望它往这个方向长——到那天,我和我的 agent 们会第一批搬回去。
上手
想自己试试这个形态,你需要的东西少得惊人:
- **从文件开始。**一个只追加的 inbox、一个 outbox 目录、一个
tail -F,就是单机完整的消息总线。忍住加基建的冲动。 - **唤醒 agent,别轮询。**monitor 每行触发的模式,是“在场感”和“卡顿感”的分界。
- **一个通道显式绑一个会话。**claim 文件救了我无数次“两个 agent 抢一部电话”。
- 给每条消息一个身份,并在 agent 们开始互聊之前把破坏性操作规则定死。
- **允许通道不平等。**企微不能主动推,飞书流式输出漂亮,web 什么都行。回复扇出,让每个界面干它擅长的事。
Claude Code 给了我一个出色的员工。bridge 给了这个员工一部手机、一间办公室,以及——当员工不止一个之后——一种不用我在场也能开会的方式。
会真的能开起来,我至今觉得有点神奇。