跳到主要内容

第 1 章:从 Agent 工具到托管 Agent 操作系统

1.1 先回答:Multica 到底是什么

Multica 不是模型 SDK,也不在服务端自己实现一套通用 LLM Agent Loop。它做的是更上层的问题:如何把已经存在的 Coding Agent CLI 变成可被团队长期管理的执行单元

源码中的核心动作不是 model.generate(),而是:

  1. 人或自动规则产生一份工作意图。
  2. 服务端把意图冻结成持久化 Task。
  3. 某台机器上的 Daemon 证明自己具备对应 Provider 能力。
  4. Daemon 领取 Task,准备安全且可恢复的执行环境。
  5. Provider CLI 在该环境中运行,并通过 Multica CLI 回写业务动作。
  6. 服务端把状态、消息、结果和成本广播给所有相关界面。

所以更准确的定位是:

Multica 是一个面向人类与 Agent 混合团队的托管 Agent 控制系统。它把项目管理、权限、队列、执行、上下文、会话、协作和观测连成一条耐故障的闭环。

产品定位可以从根 README.md 看到;真正的执行闭环分散在 IssueServiceTaskServiceDaemon 和统一 agent.Backend 中。

1.2 为什么不能只做一个“远程运行按钮”

一条 POST /run 加一个 exec.Command 很容易做出演示,但它回答不了生产环境的问题:

  • 浏览器断开后,工作还算不算存在?
  • 两台 Daemon 同时看到任务,谁能执行?
  • Daemon 领取后崩溃,任务如何恢复?
  • 同一仓库能否同时被两个任务修改?
  • Agent 在执行时代表谁?能访问谁的外部应用?
  • 新评论到来时,是新开任务、合并任务,还是等待当前任务结束?
  • Claude、Codex、Pi、Cursor 的流式协议不一样,界面如何显示统一状态?
  • 旧 Desktop 对上新 Server,多一个字段会不会让整个页面白屏?
  • 多个 Server 实例如何把事件发到连在另一实例上的浏览器或 Daemon?

Multica 的复杂度几乎都来自这些问题,而不是来自调用模型本身。

1.3 三个平面

控制平面

控制平面以 Go Server 和 PostgreSQL 为中心,负责:

  • Workspace、Member、Issue、Comment、Agent、Squad、Skill、Project 等长期领域对象;
  • Task 的排队、Claim、租约、状态迁移、取消与重试;
  • 权限、归因、审计与任务级令牌;
  • Browser WebSocket 和 Daemon WebSocket;
  • Autopilot、Webhook、渠道连接和后台清理任务;
  • 多实例下的 Redis 实时中继。

组合入口是 server/cmd/server/main.gorouter.go

执行平面

执行平面位于运行 multica daemon 的机器:

  • 探测 Provider CLI;
  • 为每个 Workspace / Profile / Provider 注册 Runtime;
  • 通过 WebSocket 收到唤醒并优先使用 WS RPC Claim;
  • 在本地槽位空闲后才领取任务;
  • 准备 Worktree 或锁定 local_directory
  • 注入 Brief、Skills、MCP、任务令牌和 Provider 专用配置;
  • 启动 CLI,统一流式消息,监控取消、超时和语义停滞;
  • 汇报消息、用量和终态。

核心在 server/internal/daemonserver/pkg/agent

交互平面

交互平面不只有 Web:

  • Next.js Web 是完整浏览器产品;
  • Electron Desktop 复用 Core、UI、Views,同时管理本地 Daemon;
  • Expo Mobile 独立拥有 Native UI、状态、路由和实时连接;
  • CLI 同时服务于人类管理和任务内 Agent 操作;
  • Slack / Feishu 把外部对话映射成 Multica Chat 与 Task。

这解释了为什么前端包要拆成 coreuiviews:同一业务表面需要落到多个宿主上。

1.4 一次任务的最短闭环

重要的是,任何一条虚线断掉都不应立刻丢失业务事实:

  • 浏览器 WebSocket 断开,PostgreSQL 仍是事实源;
  • Daemon WebSocket 断开,可以安全回落 HTTP;
  • Daemon 崩溃,租约、Runtime 心跳与孤儿恢复会识别任务;
  • Agent CLI 失败,终态与失败分类仍被记录;
  • Server 多实例,Redis 把事件转发到持有连接的节点。

1.5 Multica 与 Pi Agent 的对应关系

参考教程里的 Pi 是“进程内 Agent Runtime”:消息、模型、工具和 Loop 在同一 SDK 内协同。Multica 把观察尺度拉到了分布式产品层。

Pi 的概念Multica 中更接近的对象关键差异
Agent LoopProvider CLI 自己的循环Multica 只统一启动、消息和终态,不重写所有 Provider 内核
Agent stateagent_task_queue + Daemon 运行态状态跨进程持久化,允许恢复与审计
Toolmultica CLI、Provider 内建工具、MCP工具既作用于文件,也作用于 Multica 业务 API
Messageagent.Messagetask_message、Comment、Chat Message运行流、业务对话和持久历史分层
SessionProvider session_id + work_dir与 Task、Issue、Chat Session 都不是一回事
ExtensionProvider adapter、Skill、MCP、Channel、VCS adapter扩展跨服务端和本地端两个进程
EventServer Bus + Browser WS + Daemon WS事件既做进程内副作用,也跨节点同步缓存

Multica 并没有取代 Pi、Claude Code 或 Codex;它把这些 Agent 当作执行引擎。

1.6 七条贯穿源码的设计原则

原则一:业务事实先持久化,再发通知

Task、Comment、Autopilot Run、Webhook Delivery 都先写数据库,再广播事件。WebSocket 是加速同步的信号,不是唯一事实来源。

这使客户端可以通过重新查询恢复,而不是依赖“从未漏过任何事件”。

原则二:执行靠近代码与凭据

服务端不要求把所有仓库和 Provider 登录态上传到中心。Daemon 在本地使用已安装 CLI、Git 凭据和工作目录。

代价是系统必须解决 Runtime 发现、心跳、唤醒、跨版本兼容、磁盘清理和本地并发锁。

原则三:控制身份与执行身份分离

Daemon 的 mdt_ 令牌证明“这台 Daemon 能管理哪些 Runtime”;任务中的 mat_ 令牌证明“这个 Agent 正在代表哪位用户、哪项任务做什么”。

任务进程不能把 Daemon Owner 的长期令牌当作写操作兜底。这是第 4、11、20 章反复出现的信任边界。

原则四:把异构协议压到最窄接口

17 类 Provider 最终都收敛成:

Execute(ctx, prompt, options) -> Session{
Messages <-chan Message
Result <-chan Result
}

差异留在 adapter 内;Daemon 只处理统一消息、用量、取消与终态。

原则五:可恢复性不是“重跑”两个字

恢复至少包含:

  • Task 失败后是否允许重试;
  • Provider Session 是否仍安全;
  • Workdir 是否存在且属于 Daemon 管理;
  • Codex rollout 是否真的可见;
  • 新评论是否已经交付;
  • 本地目录锁是否重新获得;
  • 重试的能力快照和归因是否仍正确。

所以源码把 session_idwork_dirfailure_reasonretry_of_task_idforce_fresh_session 等字段分开存储。

原则六:权限与归因不能靠 UI 猜

Agent 的调用权限由 permission_modeagent_invocation_target 决定;任务还记录 originator_user_idaccountable_user_id、证据类型与委派血缘。

UI 是否展示按钮只是体验层;服务端每个入口仍要重新验证。

原则七:兼容性要允许局部退化

安装版 Desktop 可能晚于 Server 更新。前端通过 Zod 与 parseWithFallback 把异常响应降级成空列表或保守对象,同时记录诊断,而不是让一个新增字段或坏数据击穿整个页面。

Daemon 协议也通过能力字段、版本检查、WS/HTTP 回落和可选响应字段逐步演进。

1.7 一组有用的系统类比

可以把 Multica 类比为一个小型操作系统:

操作系统概念Multica 对应物
用户与组Member、Agent、Squad、调用目标
进程控制块agent_task_queue
调度器Claim SQL、Runtime 容量、Autopilot Scheduler
设备驱动Agent Provider adapter、Channel adapter、VCS adapter
文件系统命名空间每任务 env、Worktree、Task HOME、Provider HOME
IPCEvent Bus、Browser WS、Daemon WS、Redis Stream
能力令牌PAT、Daemon Token、Agent Task Token
守护进程multica daemon、后台 sweeper、webhook worker

类比的价值不在于说两者完全相同,而在于提醒我们:任务可靠性来自大量边界协议,而不是来自某一个“聪明的 Agent 类”。

1.8 本章源码导航

1.9 本章结论

理解 Multica 的第一步,是把问题从“怎样调用一个 Coding Agent”改写为:

怎样让不同 Agent 在不同机器上,代表正确的人,携带正确的上下文与能力,在可恢复的工作区里执行,并把结果可靠地带回团队协作系统?

后面的每一章都在回答这个问题的一部分。下一章先从仓库骨架出发,确认这些责任为什么被放在不同包和不同进程中。


下一章:Monorepo 骨架与架构边界