在 OmniRoute 解决了智能体的 API 流量去向之后,下一个瓶颈是智能体本身的管控。这边一个 Claude Code,那边一个 OpenCode,偶尔再试用一下 Codex——各自占着一个终端窗口、停在某个分支上、握着我昨天交给它的任务的一半上下文。三个智能体乘以四个仓库,靠文件夹加标签页的方式就撑不住了。
Orca 是我用来看住这一切的桌面应用。它的模型很简单:每个任务都有自己的工作区(workspace)。我在 Mac mini 上已经用了两个月,这篇文章就是对它实际用法的盘点——是靠 Orca 自己的会话索引还原出来的(多少有点尴尬),因为我的记忆服务器里居然一条相关记录都没有。
Worktree 是工作的单位
注册一次仓库,Orca 就会盯着它。派一个任务,它就在 ~/orca/workspaces/<repo>/<task> 下创建一个真正的工作树,并配上独立分支。这周 xhs-1688-bridge 仓库的例子:
/Users/weidai/orca/workspaces/xhs-1688-bridge/w12-suppliers-reports
branch: refs/heads/weidai/w12-suppliers-reports
主检出留在 main 上,毫发无损。这个工作树有自己的终端、浏览器标签和智能体会话。每张工作区卡片还承载着我过去只能记在脑子里或备忘录里的协调状态:状态(todo / in-progress / in-review / completed)、一行评论(“修复已实现;正在跑集成测试”),以及它对应的 PR、issue、Linear 工单或 Jira key 的链接。
底层就是 git worktree(从任何普通 shell 里我都能 cd 进这些路径),但 Orca 补上了裸工作树从来没有过的记账能力。
启动智能体
每个工作树都能拉起它认识的任意智能体 CLI:claude、codex、opencode、gemini、grok、droid 等等(我这台机器的会话索引器追踪 25 种智能体类型;我真正用过的只有两种)。启动时可以钉死模型和推理力度:
orca worktree create --name fix-login --no-parent --agent codex \
--model gpt-6-astra --effort high --prompt "reproduce and fix #42" --json
按每个智能体的设置,它以聊天或 CLI 终端的形式打开,启动回执会说明是哪种。托管账号按智能体类型分开管理,所以启动可以钉到指定登录账号,而不是 shell 当前碰巧用的那个。
来自 orca search --index-status 的诚实使用统计:37 个 Claude Code 会话、34 个 OpenCode。Orca 终端里的 Claude Code 是我的日常主力,OpenCode 是第二意见。
CLI 才是真正的界面
orca agent-context 报告 321 条命令。正因为这个 CLI,我才把 Orca 当作控制平面而不是更漂亮的终端网格:智能体和我一样直接驱动它。
- 交接。 一个智能体完成自己那一段后,可以拉起下一个工作树、附上书面简报进行交接,然后停机。简报带着上下文,不需要在窗口之间复制粘贴。
- 编排。 协调者可以运行另一种智能体的 worker:我的 Claude 会话派一个 Codex worker 去做评审,带 ask/reply 消息流、任务 DAG 和决策门,而不是我在两个终端之间当传声筒。
- 终端 I/O。
terminal read --screen返回 TUI 实际显示的内容(Claude Code 不停重绘,普通的滚动回读只会得到堆叠碎片),terminal wait --for tui-idle会阻塞到智能体停止思考,terminal send则是往前推它一把。 - 会话全文搜索。 宿主机上的每一段智能体对话都有索引:写这篇文章时有 13,222 条消息。“哪个会话碰过那个函数?“一句带引号的短语就能查到——我审计这篇文章的用法数据用的正是它。
浏览器与端口
每个工作树有一个作用域限定于它的内嵌浏览器(快照、点击、填写、截图,全部可以由 CLI 脚本化),外加端口发现:orca ports --json 能找到机器上监听的 dev server,并归因到启动它们的工作区,我和智能体都不必再跑 lsof 猜端口。
定时提示
自动化(automations)就是按计划运行的提示(hourly、daily、weekdays、5 段 cron 或 RRULE),由选定的 provider 执行,可以每次在新工作树里跑,也可以在现有工作区里跑,还能挂一个 shell --precheck 门:退出码不对就跳过本次运行。我的安装里还没接任何一条;第一个候选是给 issue 流量最大的仓库配一个每周 triage 提示。
手机作为第二块屏幕
桌面应用只是运行时的一个客户端。orca serve --mobile-pairing 无头启动同一个运行时并打印配对码;手机配对之后(orca://pair 链接协议负责握手),手机就成了同一份状态的窗口:工作区卡片、活跃的 PTY、未读圆点。运行时养着终端,所以通勤路上在手机上读到的,就是我在书桌上留下运行的那个会话,包括智能体卡在哪里、以及一个能让它继续的输入框。
需要整台机器时,我已经能通过自托管的 HopToDesk web 客户端从 iPhone 连到 Mac mini 的完整桌面。多数时候我只想看一眼智能体,这种场景配对完胜:更轻、更快,而且只显示我关心的那一块。
踩过的坑
每一条都真踩过:
- 终端句柄是运行时作用域的。 重启 Orca 之后旧句柄会报
terminal_handle_stale。重新列出、改用替代句柄,不要向两个句柄同时发送。 terminal read不是屏幕。 它是剥掉转义序列的滚动缓冲,任何会重绘的东西(shell、进度条、智能体 TUI)读出来都是堆叠碎片。答案取决于终端实际显示什么时,用read --screen。- 权限菜单会吃掉提示。 智能体显示权限/信任菜单时,发送"文本+回车"会被
agent_prompt_blocked拒绝。要把文本和回车分成两条命令发,才能回答菜单。 - 每个工作树都是完整检出。 每个任务一份
node_modules,磁盘账单涨得很快;仓库 setup 脚本(--setup run)能自动化安装,但不会让磁盘账单变小。 - 会话搜索要在每台宿主机上手动打开。 开关在 Settings → Agent Session History,没有 CLI 开启方式。要趁早打开,因为它只索引之后的内容。
- 看板不喂就不真。 评论和状态不会自己更新;智能体跑完却不设置
--workspace-status in-review,卡片就在说谎。
我今天的配置
| 仓库 | 是什么 | Orca 的用法 |
|---|---|---|
personal_blog | 本 Hugo 站 | 主工作树里每天跑 Claude Code 会话——本文就是在其中一个会话里起草的 |
xhs-1688-bridge | 数据桥接 | 周报任务此刻正跑在子工作树(w12-suppliers-reports)里 |
fastapi_app | FastAPI + SQLModel 应用 | 对着注册的主检出跑 Claude Code / OpenCode 会话 |
float_bot | 机器人项目 | 已注册、已进会话索引;目前用得还少 |
外加一个已保存的 SSH 目标,等着哪天想在第二台机器上开工作树。
Orca 逼出来的那个转变:智能体不再是我在终端窗口里盯着的东西,而成了有邮箱、有状态卡、有可搜索转录的工人。现在我是看板前派活的调度员。Mac mini 正在悄悄变成一台智能体服务器,手机变成它的遥控器。