Multica 的 Context
是怎么做的
按 Slock artifact 的方式拆:先看系统边界,再追 issue、subscriber、prompt 和 runtime 拉起链路,最后落到 agent 到底用哪些 CLI 工具取回上下文。
一句话模型
Multica 的 context 设计不是“把所有信息预先打包成一个巨大 prompt”,而是
薄启动 prompt + 本地 brief/context 文件 + CLI 按需取回 + session/workdir 复用。
服务器负责把任务、安全边界和高信号指针给 daemon;真正的 issue 详情、评论历史、repo 内容由 agent 在运行中用 multica CLI 读取。
只存任务事实和指针
Issue、comment、workspace、project、skill、prior session/workdir 都在 DB 里。任务入队时通常不做大 context snapshot。
启动前注入 brief
Daemon claim 到任务后,创建或复用隔离 workdir,写入 CLAUDE.md / AGENTS.md / .agent_context/issue_context.md 等文件。
运行中主动读取
Prompt 明确要求先跑 multica issue get、multica issue comment list、multica repo checkout,把上下文从平台拉到本轮模型里。
从 issue 到 agent 的启动链路
真正重要的是 claim 阶段。入队时 Multica 只创建 queue row;daemon claim 时才把 agent instructions、skills、workspace context、project resources、trigger comment、prior session/workdir 拼进响应。
agent_task_queue。
源码注释直说:issue task 不存 context snapshot,agent 运行时用 CLI 拉取所需数据。
/api/daemon/runtimes/:id/tasks/claim。
claim response 里带 agent identity、skills、workspace_id、repos、project resources、trigger comment、chat message、autopilot payload、quick-create prompt。
(agent, issue) 的后续任务会复用 prior workdir;assignment 任务还可 resume prior session,comment-triggered follow-up 通常只复用 workdir,不 resume 旧对话,避免回答新评论时继承旧的“Done”。
CLAUDE.md,Codex/OpenCode/Cursor/Kimi/Kiro 等写 AGENTS.md,Gemini 写 GEMINI.md。同时写 .agent_context/issue_context.md 和 provider-native skills 目录。
MULTICA_TOKEN、MULTICA_WORKSPACE_ID、MULTICA_AGENT_ID、MULTICA_TASK_ID。Agent 通过本地 multica CLI 读写平台。
Issue 数据流:你提出一个 issue 后发生什么
最常见路径是:用户创建 issue 并分配给 agent;server 写 issue、广播事件、判断 agent 是否可运行;如果可运行,就写入 agent_task_queue 并唤醒对应 runtime 的 daemon。Daemon claim 成功后才真正启动本地 agent。
创建时触发
CreateIssue 成功后发布 issue:created。如果 assignee 是 ready agent 且不是 backlog,调用 EnqueueTaskForIssue。
从 backlog 拉出来
用户把已分配 agent 的 issue 从 backlog 改到活动状态时,也会入队。done 和 cancelled 不会触发新工作。
评论触发
成员评论会按 shouldEnqueueOnComment 判断是否触发 assignee agent;@agent 走 EnqueueTaskForMention,使用触发 comment id 作为本轮入口。
task:queued,再通过 runtime wakeup 让 daemon 来 claim。
Subscribe 数据流:谁会收到后续变化
Subscriber 是 notification 和 issue 关注状态的核心表。它既有手动订阅,也有事件驱动的自动订阅。Multica 在 server 启动时先注册 subscriber listeners,再注册 notification listeners,确保同一次事件里先写订阅关系,再基于订阅表发 inbox。
| 来源 | 写入 reason | 作用 |
|---|---|---|
issue:created |
creator / assignee / mentioned |
创建者、被分配者、description 中的 mention 成为 subscriber。随后 notification listener 可以直接基于表发 inbox。 |
issue:updated |
assignee / mentioned |
新 assignee 和新增 mention 被自动订阅;assignee change 还会触发相关通知。 |
comment:created |
commenter |
评论者进入 subscriber 表。system comment 被跳过,避免平台系统评论制造无意义订阅和通知。 |
| Quick-create completion | creator |
quick-create issue 由 agent 创建,但 task service 会把发起 quick-create 的 human requester 订阅进去。 |
| Manual subscribe | manual |
SubscribeToIssue / CLI multica issue subscriber add 写表并发布 subscriber:added。 |
Prompt 与 runtime 拉起流程图
Agent 真正开始行动前,会先经历 claim response、workdir 准备、brief 写入、per-turn prompt 生成、环境变量注入、provider CLI 启动。它受到的约束分布在 runtime brief、per-turn prompt、skills、env 和 server-side guard 里。
提示词约束从哪里来
Runtime brief
AGENTS.md / CLAUDE.md / GEMINI.md 写入 agent identity、workspace context、可用命令、workflow、metadata 规则、mentions 规则和输出规则。
Per-turn prompt
BuildPrompt 根据 assignment、comment、quick-create、chat、autopilot 切模板。新评论会直接嵌入 trigger comment 并要求先读 thread。
Skills
Agent 绑定的 skills 写入 provider-native 目录。它们是团队知识和专门流程,不一定塞进主 prompt。
Server guard
server 还会在 API 层强制某些规则,例如 comment-triggered task 回复同一 issue 时 parent_id 必须等于 trigger comment id。
检索上下文会用哪些工具
multica issue get <id> --output json | 读取 issue 标题、描述、状态、assignee、附件等主上下文。 |
multica issue metadata list <id> --output json | 读取 agent 钉住的高信号 KV,如 PR、deploy、blocker。 |
multica issue comment list ... | assignment 读全历史;comment task 先 --thread <comment-id> --tail 30,再按需 --recent 和 cursor 翻页。 |
multica repo checkout <url> [--ref] | 按 project/workspace repo 指针 checkout 代码,不在 prompt 里直接塞 repo 内容。 |
multica attachment download <id> | 读取 issue、comment、chat 附件,避免直接访问短 TTL URL。 |
multica workspace member list / agent list / squad list | quick-create 解析用户提到的 assignee 时使用。 |
multica autopilot get <id> --output json | run-only autopilot 需要完整配置时使用。 |
multica issue subscriber list <id> --output json | 需要确认谁在关注 issue 时使用;默认 workflow 不强制读取。 |
Context 存储位置速查
| Context 类型 | 持久化位置 | 进入 agent 的方式 |
|---|---|---|
| Issue 主体、状态、assignee、project | issue rows |
prompt 只给 issue id,agent 用 multica issue get 拉取完整内容。 |
| 评论历史和触发评论 | comment rows;触发评论 id 存在 agent_task_queue.trigger_comment_id |
触发评论内容会在 claim/prompt 中直注入;历史由 multica issue comment list 分页读取。 |
| 任务队列事实 | agent_task_queue:agent_id、runtime_id、issue_id、context JSONB、session_id、work_dir |
claim response 转成 daemon 的 Task,再生成 prompt、env 和 workdir。 |
| Workspace 背景 | workspace.context |
claim 时加载,写进 runtime brief 的 ## Workspace Context。 |
| Project resources | project_resource rows |
brief 里给摘要,同时写入 .multica/project/resources.json;repo 资源用 multica repo checkout 打开。 |
| Agent skills | agent_skill / skill_file |
daemon 写入 .claude/skills、CODEX_HOME、.opencode/skills 等 provider-native 目录。 |
| 执行现场 | 本地 workdir;完成或失败后把 session_id 和 work_dir 回写 task row |
未来同一 agent/issue 的任务可以复用 workdir,部分任务可 resume provider session。 |
| 订阅关系和通知 | issue_subscriber、inbox_item |
subscriber 关系驱动 inbox;前端通过 subscriber:added / subscriber:removed 失效缓存后重新读取。 |
Context 分层表
| 层 | 来源 | 注入方式 | 设计意图 |
|---|---|---|---|
| Workspace Context | workspace.context |
claim response → brief 中 ## Workspace Context |
所有 agent、所有 task kind 都能看到同一份 workspace 级系统背景。 |
| Requesting User | runtime owner 的 profile description | brief 中 ## Requesting User,用户描述用 blockquote 包起来 |
让 agent 知道“替谁工作”,但明确低于实际任务指令。 |
| Agent Identity | agent name / id / instructions | brief 中 ## Agent Identity |
persona、职责、skill 使用习惯等稳定行为。 |
| Task Entry | issue id / chat message / quick-create prompt / autopilot payload | per-turn prompt + .agent_context/issue_context.md |
告诉 agent 本轮为什么被唤醒,以及第一步该跑什么命令。 |
| Trigger Comment | 触发本轮的 comment row | 直接嵌入 comment-triggered prompt | 防止复用 workdir 时 agent 被旧输出带偏,先盯住这条新评论。 |
| Comment History | issue comments | agent 运行中用 multica issue comment list 分页读取 |
长 issue 不一次性塞满,按 thread / recent / cursor 渐进恢复。 |
| Project Resources | project_resource table | brief 中摘要 + .multica/project/resources.json |
项目级 repo / 资源只作为指针,任务相关时再打开。 |
| Skills | agent_skill + skill_file | 写入 Claude/Codex/OpenCode 等 provider-native skill 目录 | 复用团队能力,不把所有技能正文都塞进 prompt 主体。 |
| Execution Memory | prior session_id + work_dir | daemon 复用 workdir;部分任务 resume CLI session | 把 repo checkout、临时文件、模型对话连续性留在本地执行现场。 |
| Issue Metadata | issue metadata KV | brief 要求 entry read / exit write | 只钉高信号事实,如 pr_url、deploy_url、waiting_on,避免评论考古。 |
Prompt 不是一份,而是按任务形态切换
Multica 的 BuildPrompt 会按 task kind 走不同模板。共同点是:prompt 很短,主要告诉 agent 入口、优先读取方式和回复规则。
新分配 issue
You are running as a local coding agent...
Your assigned issue ID is: ...
Start by running `multica issue get ... --output json`
For comment history, follow the runtime workflow file...
assignment 任务会强制读 issue、metadata、完整评论历史,然后更新状态、工作、评论汇报。
新评论触发
[NEW COMMENT] A user just left a new comment.
Focus on THIS comment...
Read triggering thread first:
multica issue comment list ... --thread ... --tail 30
新评论内容直接进 prompt;历史读取先 thread 后 cross-thread,避免长 issue 噪声。
自然语言创建 issue
There is NO existing issue.
Create a well-formed issue with a single
`multica issue create` command.
这里 agent 是“issue 整理器”,把用户一句话变成 title/description/assignee/project,不允许读不存在的 issue。
对话或自动化运行
Chat: user message + attachment IDs
Autopilot: run id + title + trigger payload
No assigned issue for run-only autopilot.
chat 使用最新用户消息和附件 ID;autopilot 使用 trigger payload 和 autopilot description,不默认读 issue。
本地 workdir 才是 context 的载体
Daemon 准备的目录不只是临时 cwd。它把 platform context、skills、project resources、provider config 都写进去,让不同 CLI 用自己原生的方式发现。
{workspacesRoot}/{workspaceID}/{taskShort}/
├── workdir/
│ ├── CLAUDE.md | AGENTS.md | GEMINI.md
│ ├── .agent_context/
│ │ ├── issue_context.md
│ │ └── skills/.../SKILL.md # fallback / partial providers
│ ├── .multica/project/resources.json # project resources, when present
│ ├── .claude/skills/.../SKILL.md # Claude
│ ├── .opencode/skills/.../SKILL.md # OpenCode
│ ├── .cursor/skills/.../SKILL.md # Cursor
│ └── checked-out repos via `multica repo checkout`
├── output/
├── logs/
└── codex-home/ # Codex provider only
为什么要复用 workdir
同一 issue 的后续任务可以继承已经 checkout 的 repo、生成的文件、构建缓存和局部调查结果。它比每次从零拉 repo 更像真实工程师的工作台。
为什么不总是 resume session
comment-triggered follow-up 会跳过旧 session resume,只复用 workdir。原因是旧 session 的最后一句可能是“Done”,会污染对新评论的理解。
和 Slock 的核心差异
消息协作控制面
Slock 更像 Slack 风格的人-AI 协作入口。Context 主要围绕 channel/thread/message、daemon wake、system prompt、slock CLI 通信规则来恢复。
典型问题:收到 IM 消息后,agent 怎么知道该读哪个 thread、怎么避免多 agent 抢答、怎么回到同一上下文。
Issue / runtime / workdir 执行面
Multica 更像 agent-native issue tracker。Context 以 issue/task/project/workdir/session 为主,消息只是触发和汇报的 timeline。
典型问题:一个 issue 分给哪个 agent、在哪个 runtime 执行、如何复用工作目录、如何按需拉 repo 和评论历史。
这套 context 设计的收益和风险
收益
scalable
长 issue 不会每次把全量 comment dump 进 prompt;project resources 也只是指针,只有相关时才 checkout / fetch。
recoverable
Workdir 和 session_id 能让 agent 在后续任务里恢复执行现场,尤其适合代码修改和长调查。
provider-neutral
Claude、Codex、OpenCode、Cursor、Gemini 等通过不同文件名和 skills 目录接入,但 platform brief 的语义是一致的。
风险
retrieval discipline
设计依赖 agent 真的按 brief 去读 issue/comment/metadata。漏读时,context 并不会自动出现在模型窗口里。
stale local state
复用 workdir 是优势,也可能保留过期文件、旧分支、旧调查结果。Multica 用 trigger comment 直注入和 metadata 规则缓解,但不能完全消除。
workspace trust
workspace.context 被当作 workspace owner/admin 设定的高权限共享背景,直接进入 brief。用户 profile description 则用 blockquote 包起来并降低优先级。
证据路径
下面这些路径是本页结论的主要依据。源码快照来自 GitHub multica-ai/multica main 分支,commit fd0fe1d,抓取时间为 2026-05-24。
issue:created / issue:updated。subscriber:added / subscriber:removed 广播。.agent_context/issue_context.md、skills、.multica/project/resources.json 的写入方式。CLAUDE.md / AGENTS.md / GEMINI.md 注入内容、workspace context、requesting user、workflow、issue metadata 规则。subscriber:added / subscriber:removed 后 invalidates issueKeys.subscribers(issue_id)。