并行跑多个 AI 编程 CLI 的开发者大多撞过同一堵墙:三个 Claude Code 会话同时改一个仓库,index.lock 报错此起彼伏;想让 Codex 把结论转交给另一个会话,只能靠人肉复制粘贴;每个会话的上下文彼此隔离,A 学到的东西 B 一无所知。GitHub 上一个叫 Munder Difflin 的开源项目给出了一套相当工程化的答案:它不改写任何 agent 框架,只用文件系统、原子重命名、一个单提交者的 git 仓库和 Claude Code 的 Stop 钩子,把终端里已有的 CLI 变成一个能互相收发消息、共享记忆、自主分工的团队。
项目 5 月 31 日创建,两周多时间攒到 2652 star、319 fork,日增 star 接近 800,是本周 GitHub Trending 上爆发最快的仓库之一。名字来自美剧《办公室》里的纸业公司 Dunder Mifflin 的谐音,UI 也做成了像素风的办公室楼层:每个 agent 是一个办公楼里的角色,工作时走到工位,互相发消息时有信封在工位之间飞。

它解决什么问题
Munder Difflin 的定位是 local multi-agent harness:一个跑在自己机器上的桌面应用,把 claude、agy(Antigravity)、codex、grok、kimi、qwen、opencode、crush、pi、copilot 这十个终端 agent CLI 包装成完整的 agent。每个 CLI 以真实进程跑在伪终端里,由 node-pty 托管、xterm.js 渲染,输出的每个字节都是原生的。

UI 的一角:每个角色头像对应一个真实 CLI 进程,右侧终端就是它的原生会话,底部状态栏实时显示各 agent 的忙闲与消息等待状态。这个切入点还有一个成本维度:应用本身只做协调,智能仍然来自被包装的 CLI,复用开发者已有订阅的小时级配额。
技术栈是 Electron + React + TypeScript,渲染层用 Pixi.js 画办公室楼层。视觉设计文档(DESIGN.md)明确写了美学方向是"Animal Crossing × Earthbound × SNES 菜单",15 个角色对应《办公室》的演员阵容,靠发型、肤色、衬衫配区分。
Hive:把协调层做成一个 git 仓库
整个多智能体层的核心设计是:所有协调状态都是本地一个 git 仓库里的普通文件,官方文档称之为 hive。目录结构长这样:
hive/
PROTOCOL.md # agent 侧契约:如何记忆和发消息
registry.json # 花名册:每个 agent 的角色、能力、状态、座位
board.md # 共享黑板,多人协作的计划
tasks.json # 任务账本(id、指派、规格、状态、结果引用)
log.jsonl # 只追加的事件流,驱动 UI 活动栏
agents/<agentId>/
identity.md # 我是谁,我的角色(启动时读)
memory.md # 长期记忆(启动时读,学到东西就追加)
inbox/ # 送到我这里的消息
inbox/.done/ # 处理过的消息留档审计
outbox/ # 我要发的消息,路由器来取
cursor.json # 已处理到哪条,避免重复处理这套布局背后是三条并发纪律,直接对应多 agent 系统最常见的崩溃模式:
单提交者。 所有 agent 都不碰 git,只有 Electron 主进程执行提交。这规避了多个 claude 进程并发操作同一仓库时 .git/index.lock 损坏的问题。作者考证过 GitHub Desktop 的提交队列模式和 lazygit 的重试退避策略。
单写者文件。 每个 agent 只写自己 agents/<id>/ 目录里的文件。跨 agent 的投递由主进程的路由器完成:从发送者的 outbox/ 移动到接收者的 inbox/。任何文件在任意时刻只有一个进程写。
原子写。 每条消息一个独立 JSON 文件,通过临时文件加原子 rename 落盘。共享邮箱文件在 git 下会产生合并冲突,单文件单消息从结构上消除了这个类别。
这三条规则合起来,把"多进程共享状态"这个分布式问题压缩成了"文件系统已经解决的问题"。对熟悉 Unix 哲学的工程师来说,这是整个项目最耐看的部分。
消息协议:FIPA 精简版
agent 之间的通信借了 FIPA-ACL/KQML 里唯一真正有用的概念——speech act(言语行为),丢掉了 LISP 语法。消息结构七个字段:
{
"id": "2026-05-30T14-03-11-123Z-a1b2", // 唯一且按时间排序
"conversation": "conv-7f3", // 线程分组
"in_reply_to": "<prev msgid> | null",
"from": "agent.researcher",
"to": "agent.coder | god | broadcast",
"act": "request | inform | propose | query | agree | refuse | done",
"subject": "短摘要",
"body": "自由文本或结构化负载",
"hops": 3, // 每次回复 +1,超限熔断
"requires_reply": true, // 只有 request/query/propose 必须回复
"needs_human": false, // 路由器或 god 可翻转为升级
"created_at": "ISO-8601"
}防活锁的设计藏在字段语义里:只有 request/query/propose 三种行为强制回复,inform 和 done 是终止性的,收到不用回;每条回复 hops 加一,超过上限由 god agent 介入仲裁,而不是让两个 agent 无限乒乓;消息 ID 幂等,靠 cursor.json 记录处理进度,重复投递是无害的空操作。
自主循环:Stop 钩子当发动机
agent 什么时候检查收件箱?答案是 Claude Code 的 Stop 钩子。agent 完成当前回合时钩子触发,POST 到 hive 的 Unix domain socket,主进程检查它的 inbox:有未读消息就返回 {"decision":"block","reason":...},agent 因此继续工作,读消息、干活、通过自己的 outbox 回信。无限循环由 stop_hook_active 守卫拦截。
控制流完整走一遍是这样的:agent B 任务中途需要 agent C 的数据,写一条 act:request, to:C 的消息到自己的 outbox;主进程路由器发现后投递到 C 的 inbox,同时追加到 log.jsonl 并由唯一的提交者写入 git;C 完成当前回合时 Stop 钩子触发,发现有未读消息,被 block 住继续运行,读消息、执行、回信。同一个钩子 socket 还驱动 UI:PreToolUse/PostToolUse 的事件让对应的角色在办公室楼层里走到正确的工位。
GOD 编排者与人在回路
团队里有一个常驻的特权 agent,坐在 Michael 办公室(编号 desk-ceo),标记 isGod。它本身就是一个普通的 claude 进程,智能归它,机制归主进程(git、socket、路由)。它负责花名册与路由、仲裁跨 agent 流量、作为 board.md 唯一的抄写员、维护任务账本。
升级策略刻意做得克制:例常请求(澄清、要数据、调计划)god 自己处理,系统保持完全自主运行;只有关键事项(破坏性操作、花钱、范围变更、无法解决的冲突)才升级到人。且没有独立的审批队列,人的介入点就是每个 agent 自己的工具权限弹窗,通过 /remote-control 可以从手机远程批准。
设计文档里有一个对选型很有参考价值的判断:在 5 到 15 个 agent 的规模下,重量级向量记忆层(Letta/Mem0/Zep)既没必要也不合适,因为这类方案想接管 agent 运行时,而这个项目的运行时就是 CLI 本身。所以记忆层做成 markdown 优先:每个 agent 一个 memory.md,不够用时加 SQLite FTS 全文索引。语义召回是可选项,通过包装 MemPalace CLI 实现,未安装时静默降级,默认嵌入模型用 minilm(照顾低内存 Mac),多语言场景可换 embeddinggemma。
安全边界
失控防护是一个 steer → constrain → stop 的三级断路器,针对循环、报错风暴、预算超支的 agent 逐级收紧。每个 agent 有独立的 token 预算,成本从 ~/.claude/projects/ 的 JSONL 转录文件里读真实数据核算,落在 SQLite 持久账本里,观测走 OpenTelemetry span 和工具调用瀑布图。遥测方面,官方构建发送少量匿名使用事件(应用打开、agent 生成、功能使用),不含提示词、代码、文件路径和 agent 输出,提供三种关闭方式。
版本历史上能看到这个项目的迭代速度和坦诚程度:v0.4.4 修复了一个 Windows 上的结构性 bug,cmd.exe 在第一个换行处截断多行命令,导致 Windows 上的 agent 从不知道自己可以互相发消息,各自启动、看起来健康、永远互相忽略;0.3.8 的用量限制守卫会扣住它持有的 agent 不释放,这个构建已被整体移除并建议所有用户升级。
上手与许可证
安装是标准的 Electron 项目流程:Node.js 18+、C/C++ 工具链(node-pty 原生插件需要,macOS 装 Xcode Command Line Tools)、PATH 上至少一个受支持的 agent CLI。缺的 CLI 大多能自愈,harness 会在终端里跑安装器然后接着用新装的二进制。
git clone https://github.com/chaitanyagiri/munder-difflin.git
cd munder-difflin
npm install # postinstall 会按 Electron ABI 重建 node-pty
npm run dev # 启动应用,热重载许可证有一个必须留意的分层:源代码是 MIT,但捆绑的像素美术素材(地块、地图、角色基础图)来自 LimeZu 的免费版授权,限定非商业使用,重新着色的精灵继承这个限制。想商用需要替换素材或购买付费授权。项目本身是《办公室》的善意戏仿,与 NBC 无关。
工程视角的评价
把 Munder Difflin 拆开看,它没有发明任何新算法:stigmergy(通过修改共享环境协调)、blackboard(Hearsay-II 时代的多源协作)、actor 邮箱模型、supervisor 编排(LangGraph 同款),全是经典模式。它的贡献在于组合方式:承认终端 CLI 就是当前最强的 agent 运行时,把协调层压薄到文件系统和 git 的既有保证上,用钩子机制衔接生命周期。对想在自己机器上编排多个编码订阅的开发者,这是一套可以直接抄走的设计;对做 agent 基础设施的团队,这份 HIVE 文档本身就是一份并发纪律的清单。
项目当前状态标注为 working prototype,开源 issue 55 个,路线图上排着 Telegram 集成、更多引擎模板和更完整的头像事件覆盖。Discord 社区有个细节挺能说明项目气质:PR 被合并的贡献者会获得 employee of the month(本月最佳员工)角色。
来源: