Multica Docs

项目资源

为项目关联 GitHub 仓库或本地目录,让后续执行获得稳定的工作上下文。

项目资源告诉智能体这组工作会用到哪些代码,以及在哪里执行。资源会持续关联在项目上,不必在每条任务中重复粘贴仓库地址或本地路径。

目前支持两种资源:

资源适用场景执行位置
GitHub 仓库团队共享的代码库,希望由运行时管理 checkout运行时管理的工作目录
本地目录已经存在的 checkout、很大的仓库,或需要直接查看本地改动指定电脑上的原目录

资源进入执行的方式

当智能体处理项目内的任务时,Multica 会把项目名称、项目描述和资源列表加入执行上下文,并在工作目录中写入 .multica/project/resources.json

工作区关联的仓库列表始终包含在执行上下文中。项目关联的仓库在此基础上指明这组工作使用的代码和默认 ref。

本地目录只对绑定它的守护进程有效。本次执行所在的守护进程有匹配的本地目录时,智能体直接进入该目录工作;其他电脑仍使用项目中的 GitHub 仓库或工作区仓库。

添加 GitHub 仓库

打开项目,在 资源 中选择"添加资源"。可以选择已关联到工作区的仓库,也可以粘贴 Git URL。工作区仓库在 设置 → 代码仓库 中维护;连接 GitHub 后,可在同一页面通过 从 GitHub 选择 导入 App 已授权的仓库。

仓库不限于 GitHub:任何运行时能访问的 Git URL 都可以作为仓库资源。自部署的 Multica 还可以在 设置 → 集成 → Git 代码托管 连接自托管的 Forgejo、Gitea 或 GitLab,见自托管 Git 代码托管

创建项目时,也可以直接在 Repos 中选择仓库。一个项目可以关联多个 GitHub 仓库。

资源中的 ref 可以指定后续 checkout 默认使用的分支、tag 或 commit。default_branch_hint 只向智能体提供默认分支提示,不会强制切换分支。

添加本地目录

添加本地目录的界面只在 Desktop 中提供,因为浏览器不能选择电脑上的文件夹。

这是逃生舱,不是更方便的默认项。 local_directory 是给那些"不得不这么开发"的人准备的 —— 典型是一个 checkout 就几十 GB 的游戏项目,不可能每来一条 task 就重新 clone 一份。

如果你的目录只是一个能正常 clone 的普通 git 仓库,请用 github_repo:它默认走 worktree 模式,同一个仓库上的 task 可以无限并发。local_directory 默认一次只跑一条 task;如果这个目录本身是 git 仓库,可以主动开启 worktree 模式把并发拿回来(见“task 如何共享这个目录”)。先看上面的两种资源对照再决定。

  1. 确认 Desktop 的本地守护进程在线。
  2. 打开项目的 资源,或者创建项目对话框里的 本地目录 标签页 —— 项目还没建出来时也能做同样的选择。
  3. 选择"添加本地目录",再选择要使用的文件夹。
  4. 选择 task 如何使用它 —— 原地 还是 并行,两者的区别见"task 如何共享这个目录"。如果这个文件夹是 git 仓库、并且那台机器上的运行时能做隔离,Desktop 会预选 并行,否则预选 原地。当场可以改,之后也可以在 资源 里点目录旁边的铅笔图标改。

预选只作用于你此刻正在关联的目录。之前关联好的目录仍然保持保存时的模式 —— 已有的配置不会在你不知情的情况下被切换。

目录必须是绝对路径,已经存在,并且当前守护进程可以读取和写入。以下路径会被拒绝:系统根目录和盘符根(/C:\)、用户主目录本身及各主目录的上级(如 /Users/home/root),以及 /etc/var/tmp/usr/opt 等系统目录。如果所选路径是符号链接,会先解析为真实路径再按同样的规则校验一次,串行锁也按真实路径生效。

每个项目在同一台守护进程上最多关联一个本地目录。团队中的不同电脑可以分别为同一个项目关联各自的目录。

在默认的 in_place 模式下,本地目录不是隔离环境:智能体会直接看到并修改当前分支和未提交的文件,Multica 也不会自动切换分支、stash、commit、push 或创建 PR。worktree 模式会改变这一点 —— 见下面的“task 如何共享这个目录”。

Task 如何共享这个目录

本地目录有两种执行模式,按资源逐个设置。在资源面板里可以直接切换,CLI 用 --execution-mode。Desktop 里这两种模式显示为 原地并行;API、CLI 和本页其余部分都使用标识符。

in_place(默认)—— “原地”

智能体直接在你的目录里工作,task 一次只跑一条。两条 task 使用同一个真实目录时,后到的 task 进入 waiting_local_directory,等前一条释放目录后继续。两个路径经不同符号链接指向同一目录时,同样串行。

等待不会修改目录。等待中的 task 可以取消,否则会一直等到目录可用。

worktree —— “并行”

每条 task 拿到你仓库的一个独立 git worktree,建在运行时自己的工作区目录里。同一目录上的 task 并发执行,谁都不用排队,并且都不会写你的工作副本。

要求这个目录是一个至少有一次提交的 git 仓库。如果不是,task 会明确报错,而不是悄悄退回串行。那台机器上的运行时也必须实现了该模式。运行时在连接时会声明这项能力,Multica 判断的是这个声明而不是版本号 —— 一个开发构建完全可能带着看起来足够新的版本号,却根本没有对应的实现。这个声明会被检查两次:只要那台机器的运行时没有声明该能力,保存资源就会被拒绝,并提示去升级那台机器上的 App;每条 task 在被真正领取时还会再按领取它的运行时检查一次 —— 所以资源保存之后才降级的机器,其 task 会被带原因取消,而不是悄悄原地跑掉。选择 worktree 就是在要求隔离,把它换成“直接改你的工作副本”永远不是兜底方案。

智能体看到什么、你拿回什么:

  • 智能体从你眼前的状态开始,而不是从 HEAD 开始。 你未提交的改动和未跟踪的文件会被回放进 worktree,所以它不会去 review 一份你已经不用的代码。你自己的工作副本、暂存区和 stash 列表都不会被动到。如果这个状态无法忠实还原 —— 包括未跟踪内容超出回放上限(2000 个文件 / 200 MiB)—— task 会直接失败,而不是从一棵你认不出来的树开始。通常的解决办法是把还没被忽略的构建产物加进 gitignore 或清理掉。
  • 结果是你仓库里的一个分支,按任务而不是按每次执行来分:agent/<agent>/<issue>(chat 则是 agent/<agent>/chat-<session>)。执行记录的运行详情面板里会显示分支名(可直接复制),也可以用 git branch 找到它。用 git log / git diff review,然后自己决定 merge 还是 cherry-pick。Multica 不会替你合并。中途失败的 task 同样会报告它的分支,因为它已经把智能体做出来的部分提交进去了。
  • 后续对话接着上一轮继续。 同一个任务的下一条评论会重新 check out 这个分支,智能体站在自己刚交付的成果上继续做,而不是从 HEAD 重新开始、把上一轮的改动落在另一个分支上。只有你在上一轮之后改动的部分会被重放上去 —— 其余部分分支里已经有了。把分支 merge 掉之后,下一轮又会从你的 HEAD 重新开始。同一个任务上有两次执行重叠时,后一个会从前一个的成果分叉到 agent/<agent>/<issue>-<task>,因为 git 规定一个分支只能有一棵 worktree。
  • 你的改动和智能体的成果冲突时,由智能体来解决。 如果你重写了智能体也重写过的那几行,git 无法判断谁对,这一轮就会在一棵带冲突的 worktree 上启动,并被要求先把 merge 做完(在那棵 worktree 里 git status 会列出未合并的文件)。只要还有文件没合完,这一轮就什么都不交付:task 失败、worktree 保留,下一轮会再次把同样的改动送上来,所以你的修改不会被悄悄丢掉。
  • 只有 Multica 自己的分支才会被续接。 是否续接由归属记录决定,而不是看名字:记录里既写了属于哪个会话,也写了这条分支当时停在哪个 commit。你自己建的、恰好叫 agent/<agent>/<issue> 的分支永远不会被 check out、被追加提交,也不会被当成上一轮的成果读取;已经不包含记录中那个 commit 的分支同样如此 —— 所以你把 Multica 的分支删掉再自己建一条同名的,或者把它 force-move 到别的历史上,都是安全的,task 会改用 agent/<agent>/<issue>-<id>。在已交付的分支上继续提交则是正常用法,续接照常,你的提交下一轮就在那里。每条分支还会以一个属于自己的 baseline commit 开头,标记第一轮开始时的目录状态 —— 后续正是靠这个 commit 来辨认这条分支,同时 git diff <baseline>..<branch> 恰好就是智能体做的改动。如果某一轮没能记录它的分支 —— 中途失败、记录写不进去,或者把 worktree reset 到了「把你的改动带进分支的那个 commit」之前 —— 这一轮会报失败并保留 worktree,后续几轮会另起一条分支,而不是去续接一条无法证明归属的分支。
  • 不会静默丢东西。 智能体留下的未提交改动,会在 worktree 被移除前提交到那个分支上,task 中途失败时同样如此。极少数情况下连这次提交都做不了 —— 例如仓库开了 commit.gpgSign 而运行时拿不到签名密钥 —— worktree 会被刻意保留而不是删除,task 标记为失败,并且在你仓库里执行 git worktree list 就能看到存放这些改动的目录。
  • 没有产生改动的 task 不留下任何东西。 它的分支会被删除,而不是作为一个空条目留在 git branch 里;但如果这是承载了之前几轮成果的任务分支,它一定会保留。

由于 worktree 位于运行时的工作区目录内,它会按正常的清理周期回收。留在你仓库里的有两样东西:分支,以及每条分支对应的一个隐藏 ref(在 refs/multica/local-state/ 下),记录这条分支归谁所有、以及上次续接时你目录里的内容。隐藏 ref 不会出现在 git branch 里,可以用 git for-each-ref refs/multica 查看。Multica 删除分支时会一并删掉它;你自己删掉的分支所对应的 ref,会在下一次该仓库上有 task 运行时被清理 —— 也可以用 git for-each-ref --format='%(refname)' refs/multica | xargs -n1 git update-ref -d 一次性清掉。

自托管运维注意: 该模式的隔离由服务端强制(保存资源时检查一次,运行时领取每条 task 时再检查一次),所以无论何时降级运行时都会被拦住。唯一拦不住的组合是:把服务端回滚到本功能之前的版本,同时还连着没有实现该模式的运行时 —— 旧服务端没有这道门禁,而这样的运行时会忽略 execution_mode、直接在原目录里跑 task。只要还存在 worktree 资源,就不要把服务端回滚到本版本之前,除非那些机器上的运行时全部升级到位。

worktree 模式面向 git 仓库。普通的非 git 目录仍然串行执行 —— 这正是 in_place 的用途。

执行期间写入的内容

除了智能体产生的代码改动,运行时还可能在目录中写入当前 AI 编程工具所需的说明文件,以及 .multica/project/resources.json。不希望它们进入版本控制时,加入 .gitignore 即可。

Multica 清理执行环境时不会删除关联的本地目录。智能体对该目录的改动,与你在终端中直接运行 AI 编程工具的改动性质相同,需要同样的审查。

使用 CLI 管理资源

# 创建项目时关联仓库
multica project create \
 --title "Agent UX" \
 --repo https://github.com/multica-ai/multica

# 查看和添加资源
multica project resource list <project-id>
multica project resource add <project-id> \
 --type github_repo \
 --url https://github.com/multica-ai/multica \
 --ref main

# 关联指定守护进程上的本地目录
multica project resource add <project-id> \
 --type local_directory \
 --local-path /absolute/path/to/repo \
 --daemon-id <daemon-id>

# 关联一个本地 git 仓库,并让 Task 在各自的 worktree 中并发执行
multica project resource add <project-id> \
 --type local_directory \
 --local-path /absolute/path/to/repo \
 --daemon-id <daemon-id> \
 --execution-mode worktree

# 为已有的本地目录切换模式
multica project resource update <project-id> <resource-id> --execution-mode worktree
multica project resource update <project-id> <resource-id> --execution-mode in_place

# 移除资源
multica project resource remove <project-id> <resource-id>

资源变更会影响之后创建的 task,不会改写已经结束的执行记录。

接下来

  • 项目 — 了解项目上下文、进度和负责人。
  • 守护进程与运行时 — 了解 task 由哪台电脑领取。
  • Task — 查看 waiting_local_directory 等执行状态。