如何将控制台 AI 代理变成《办公室》里的像素风办公室
最近偶然发现了一个仓库,如果你曾经运行过 Claude Code 这样的自主控制台工具,并且觉得管理几十个打开的终端标签页非常不方便的话,这个仓库绝对值得一看。这个项目叫做 Munder Difflin。

作者们用出人意料的幽默感来处理终端代理编排。他们将控制台进程封装成一个使用 Electron 和 Pixi.js 构建的桌面应用,每个运行的代理都在像素办公室里走来走去,携带虚拟信封,通过本地文件系统与同事交流。俯瞰这一切的是你的克隆体 Michael,坐在一间独立的办公室里。
听起来像个玩笑玩具,但底层有严肃的脚手架来通过 Ollama 并行运行 Claude Code、Antigravity、OpenAI Codex、Kimi、Qwen 和本地模型。

这到底是什么
与其为每个模型发明自定义 API 客户端,Munder Difflin 直接使用你已经在终端中运行的现成 CLI 工具。应用通过 node-pty 为每个代理启动一个真正的伪终端,并通过 xterm.js 在界面中渲染它。
因此,代理在其原生环境中工作。它保留对本地文件的访问权限,运行测试、执行提交、读取构建输出,就像你在普通的 iTerm 或 Alacritty 标签页中手动启动它一样。
主要区别在于进程被统一到一个共享网络中。你给主协调代理(GOD agent)一个高级任务,它将子任务分配给专门的代理,监控它们的状态,只在危险操作前请求你的许可。
代理交互是如何工作的
整个架构建立在本地文件和 Git 协议之上,没有外部云数据库。
邮箱和共享内存
当代理需要传递上下文或工作结果时,它们不调用复杂的远程 RPC。系统使用磁盘上的邮箱架构:
- 代理将消息或产物写入其本地目录
outbox/。 - 内部路由器将文件移动到收件人的文件夹
inbox/。 - 收件人通过文件系统事件唤醒,读取消息并接收任务。
- 长期记忆以纯 Markdown 格式存储,并通过本地语义搜索建立索引,以便在会话之间快速检索上下文。
为防止并行进程阻塞 index.lock 仓库,对提交历史的写入通过单个提交者进程进行。
防止无限循环和预算超支
自主 CLI 代理的主要问题之一是循环风险,当脚本开始重复修复同一个测试或向 API 发送数百个请求时。
Munder Difflin 内置了断路器机制:
- 每个代理都有硬性令牌限制,并从日志中实时监控请求成本。
- 系统跟踪级联错误和失败命令的重试尝试。
- 当超出预算或表现出异常行为时,代理首先会收到警告和上下文限制,如果失败继续,它将被强制停止。
- 破坏性操作、范围变更和资金支出需要通过审批面板确认。
内部结构:技术栈
在架构上,应用分为两个隔离层,在 Electron 中汇聚:
┌───────────────────────────────────────────────────────────────┐
│ Electron Renderer (React) │
│ ┌──────────────────┐ ┌──────────────────────────────┐ │
│ │ Office Floor │ │ Terminal + Command Bar │ │
│ │ (Pixi.js) │ │ Files + Git tabs (xterm.js) │ │
│ └─────────▲────────┘ └────────────▲─────────────────┘ │
│ │ avatar state │ pty bytes / fs / git │
└─────────────┼──────────────────────────┼──────────────────────┘
│ IPC (contextBridge: window.cth)
┌──────┴──────────┐ ┌──────┴─────────────┐
│ Event Plane │ │ Terminal Plane │
│ hooks / hive │ │ node-pty PTYs │
│ router + GOD │ │ + fs + git │
└────────▲────────┘ └──────▲─────────────┘
│ hook payloads │ stdin / stdout
└─────────┬──────────────┘
┌──────┴──────────────┐
│ claude / agy / codex│
└─────────────────────┘
Node.js 主进程管理终端生命周期、文件路由和用于会话历史持久化的 SQLite 数据库。React 和 Pixi.js 上的渲染器通过类型化 IPC 桥接 window.cth 接收数据。
除了可视化办公室,桌面客户端还包括内置的 Monaco 编辑器、带依赖关系的任务看板、Git diff 查看器和 Slack webhook 集成。你可以将任务发送到工作聊天,Michael 会在后台创建一个临时代理来解决问题,然后将答案返回到线程中。
如何部署和试用
要运行它,你需要 Node.js 18+、用于构建原生模块 node-pty 的 C/C++ 编译器(在 macOS 上,Xcode Command Line Tools 即可),以及至少一个已安装的控制台代理。
克隆仓库并在开发模式下运行项目:
git clone https://github.com/chaitanyagiri/munder-difflin.git
cd munder-difflin
npm install
npm run dev
首次启动时会打开设置向导。在那里你可以指定二进制文件 claude、codex、copilot 的路径,或设置本地 LM Studio / Ollama / vLLM 服务器的地址。
如果系统中没有所需的二进制文件,应用可以在内置终端窗口中运行自动安装。
谁会从这个项目中受益
Munder Difflin 很难被称为轻量级日常工具——Electron 和通过 Pixi.js 的精灵渲染会消耗资源。但如果你经常尝试多代理场景、编写由多个模型驱动的复杂重构,或厌倦了在 tmux 中手动控制并行 Claude Code 启动,这里有很多值得学习的内容。通过 Markdown 文件管理进程、通过 git worktrees 进行分支隔离,以及对正在发生的事情进行人性化的可视化控制,使这个项目成为本地 AI 代理周围最原创的开源 hack 之一。仓库活跃提交,代码用清晰的 TypeScript 编写,因此深入研究内部钩子和 PTY 处理程序绝对值得。
相关项目