在线阅读:https://hanqing.github.io/multica-notes/
本站使用 Docusaurus 构建。首次本地运行:
npm install
npm run start生产构建:
npm run build
npm run serve以
refs/dg-ai-notes拆解 Pi Agent 的方法为参照,沿真实源码路径系统讲清multica-0.4.10:一个任务怎样从 Issue、Chat、Webhook 或定时计划进入控制平面,怎样被本地 Daemon 领取并交给 17 类 Agent CLI,怎样把结果、事件、状态和成本重新汇回多人协作界面。
只看 Multica 的产品 README,容易把它理解为“给 Coding Agent 套了一层项目管理界面”。源码呈现的是更完整的系统:它把 Agent 变成可分配、可授权、可调度、可恢复、可观测的团队成员,并将真正执行代码的进程放在用户机器或云 Runtime 上。
因此,Multica 的核心不是一个孤立的 Agent Loop,而是三组系统共同维持的闭环:
- 控制平面:Go Server、PostgreSQL、任务状态机、事件总线、WebSocket、调度器和集成服务。
- 执行平面:
multica daemon、Runtime 注册、任务抢占、隔离环境、仓库 Worktree、Agent CLI 适配和恢复机制。 - 交互平面:Web、Electron Desktop、Expo Mobile、CLI,以及 Slack / Feishu 等外部渠道。
本教程不逐文件翻译,而是沿用参考教程的三个问题:
- 是什么:这个模块在整套系统里承担什么责任?
- 怎么做:一次真实请求经过哪些对象、状态、协议和持久化记录?
- 为什么:为什么不用更直接的实现?它在防什么故障或权限问题?
- 目标源码:
multica-ai/multica@v0.4.10 - 写法参考:本地
refs/dg-ai-notes对 Pi Agent 的拆解方法 - 参考项目源码:本地
refs/pi-0.82.0快照 - 目标目录标签:
0.4.10 - Go 基线:
1.26.1 - Node CI 基线:
22 - pnpm:
10.28.2
目录名代表本次分析的源码快照。根 package.json 的内部版本仍为 0.2.0,不能拿它覆盖快照标签;这类版本漂移正是文档必须说明“事实来自哪个注册表”的原因。
文档遵循五条证据规则:
- 关键结论尽量链接到源码文件,并注明重要类型或函数名。
- 优先链接文件而不是易漂移的行号。
- README 中的宣传数字只作为产品描述;Provider 注册表、数据库模型和路由源码才作为当前静态事实。
- “源码明确写出”与“从结构可以推断”分开表述。
- 数量只描述本地快照,不视为未来版本承诺。
flowchart LR
A["第 1~4 章\n定位、骨架、数据、服务入口"] --> B["第 5~8 章\n工作触发、任务状态、Daemon、执行环境"]
B --> C["第 9~11 章\nAgent 协议、上下文、Skills 与 MCP"]
C --> D["第 12~15 章\n事件一致性、前端、多端、消息渠道"]
D --> E["第 16~18 章\nSquad、Autopilot、代码托管集成"]
E --> F["第 19~21 章\nCLI、安全工程、完整旅程"]
第一次阅读建议按顺序。若目标是排障或二次开发,可以直接按后面的专题路线跳转。
| 章 | 主题 | 你会得到什么 |
|---|---|---|
| 01 | 开篇:从 Agent 工具到托管 Agent 操作系统 | 产品问题、三平面全景与核心设计原则 |
| 02 | Monorepo 骨架与架构边界 | Go、Web、Desktop、Mobile 与共享包的责任边界 |
| 03 | 领域模型、PostgreSQL 与 sqlc | 82 个模型背后的领域簇、弱引用与事务不变量 |
| 04 | 服务启动、路由、中间件与认证 | Server 组合根、四类令牌、工作区隔离和关闭顺序 |
| 05 | Issue、Comment 与工作触发 | 任务如何由分配、@提及、线程、聊天和快速创建产生 |
| 06 | 任务队列与状态机 | Claim、Prepare Lease、取消、重试、合并评论和故障恢复 |
| 07 | Daemon、Runtime 与任务抢占 | 注册、心跳、WS-first Claim、槽位控制和孤儿恢复 |
| 08 | 执行环境、仓库、本地目录与 GC | 每任务隔离、Bare Cache、Worktree、路径锁与回收策略 |
| 09 | Agent 后端与协议适配 | 统一 Backend/Session 契约如何容纳 17 类 CLI 协议 |
| 10 | Prompt、上下文与会话连续性 | 短 Prompt、长 Brief、Session/Workdir 恢复和失败降级 |
| 11 | Skills、Runtime 能力、MCP 与 Connected Apps | 服务端 Skill 包、本地发现、内容寻址缓存与任务级能力快照 |
| 12 | 事件总线、WebSocket 与实时一致性 | 同步事件顺序、浏览器/Daemon 双通道、Redis 中继和去重 |
| 13 | Frontend Core、状态与缓存 | ApiClient、Zod 降级、React Query、Zustand 与 Workspace 命名空间 |
| 14 | Web、Desktop、Mobile 多端适配 | 共享 Views、NavigationAdapter、Electron 主进程和独立 Mobile 架构 |
| 15 | Chat、Inbox、通知与外部渠道 | Chat 会话、取消收尾、两阶段去重、Slack/Feishu 入站流水线 |
| 16 | Squad 与多 Agent 协作 | Leader/Worker 分工、委派血缘、回环抑制和延迟升级 |
| 17 | Autopilot、调度器与 Webhook | Run-only/Create-issue、DB 租约 Cron、投递队列和归因快照 |
| 18 | GitHub、VCS 与代码托管闭环 | GitHub App 特化路径与 Forgejo/Gitea/GitLab 通用适配 |
| 19 | CLI、配置与控制协议 | Cobra 命令树、Profile、任务内 CLI、Daemon HTTP/WS 控制面 |
| 20 | 安全、部署、观测、测试与发布 | 信任边界、Compose/Helm、多实例、Prometheus、CI 和发布链 |
| 21 | 一次任务的完整旅程 | 把前 20 章连接成可调试的端到端调用链 |
| 附录 A | 源码导航与阅读路线 | 按问题定位入口文件、类型、查询和测试 |
| 附录 B | 术语、状态机与不变量速查 | 高频概念、状态迁移与不可破坏的约束 |
flowchart TB
subgraph Clients["交互平面"]
WEB["Next.js Web"]
DESK["Electron Desktop"]
MOB["Expo Mobile"]
CLI["multica CLI"]
IM["Slack / Feishu"]
end
subgraph Control["控制平面"]
API["Go HTTP API / Chi"]
BUS["同步事件总线"]
BWS["Browser WebSocket Hub"]
DWS["Daemon WebSocket Hub"]
SCHED["DB-backed Scheduler"]
PG[("PostgreSQL")]
REDIS[("Redis Relay,可选")]
end
subgraph Execution["执行平面"]
DAEMON["Local / Cloud Daemon"]
ENV["每任务执行环境"]
REPO["Bare Cache + Worktree\n或 local_directory"]
BACKEND["统一 Agent Backend"]
AGENTS["Claude / Codex / Pi / ..."]
end
Clients --> API
IM --> API
API <--> PG
API --> BUS --> BWS
BUS --> DWS
SCHED <--> PG
BWS <--> REDIS
DWS <--> REDIS
DWS <--> DAEMON
API <--> DAEMON
DAEMON --> ENV --> REPO
ENV --> BACKEND --> AGENTS
AGENTS --> API
最容易混淆的五个概念:
- Agent:工作区里的长期协作者配置,包含身份、说明、Provider、Runtime、模型、权限、Skill 和环境配置。
- Runtime:某个工作区中可运行某类 Provider 的具体执行能力;同一台机器通常注册多个 Runtime。
- Daemon:机器级常驻进程,发现 CLI、注册 Runtime、领取任务并管理本地执行。
- Task:一次持久化执行尝试。重试会创建新的 Task,并保留父子和归因血缘。
- Session:Provider 原生会话标识及其可恢复上下文,不等同于 Multica 的 Task,也不等同于 Chat Session。
把它们压成一个“Agent Run”会看不懂后面的并发、恢复和权限设计。
| 维度 | 当前快照 |
|---|---|
| Go 源文件 | 942 |
| TypeScript 文件 | 863 |
| TSX 文件 | 859 |
| 向上数据库迁移 | 262 |
| sqlc 模型结构体 | 82 |
| SQL 查询文件 | 42 |
| 非测试 Handler 源文件 | 86 |
*Handler 方法(含内部辅助方法) |
546 |
| Agent Provider 标识 | 17 |
总行数包含生成代码、测试、迁移和前端资源,容易夸大“手写核心逻辑”;本教程更关注责任边界、状态机和跨层不变量。
| Pi 教程主干 | Multica 对应章节 | Multica 增加的观察维度 |
|---|---|---|
| 三层架构 | 01~04 | 控制平面、执行平面、多客户端、数据库组合根 |
| Agent Loop | 06~10 | 持久化 Task 状态、远程 Daemon、CLI 子进程协议 |
| 模型调用 | 09 | Multica 不直连模型,而是适配 Provider CLI |
| 工具系统 | 08、11、19 | CLI 工具、MCP、Skills、仓库与任务令牌 |
| 消息与事件 | 05、12、15 | Issue/Comment、双 WebSocket、外部 IM 渠道 |
| 上下文工程 | 10、11 | Provider 原生 Brief、任务快照、本地能力发现 |
| 上下文压缩 | 10 | 主要委托给 Provider,会话毒化时强制新开 |
| 会话管理 | 06、10、15 | Task、Provider Session、Chat Session 三层分离 |
如果只有一小时:
- 读第 1 章看全景。
- 读第 6 章理解任务状态机。
- 读第 7、8 章理解执行平面。
- 读第 9、10 章理解 Agent CLI 如何接入。
- 读第 21 章把链路串起来。
如果要增加一个 Agent Provider:读 02 → 07 → 08 → 09 → 10 → 11 → 20。
如果要排查“任务卡住”:读 06 → 07 → 08 → 12 → 20,再按附录 A 的排障入口定位。
如果要增加一个 IM 渠道:读 04 → 12 → 13 → 15 → 20。
如果要理解多 Agent 协作:读 05 → 06 → 10 → 16 → 17。
如果要改前端缓存:读 12 → 13 → 14,并先记住“WebSocket 是失效信号,不是唯一事实源”。