mirror of
https://github.com/multica-ai/multica.git
synced 2026-08-13 03:15:34 +02:00
* fix(squads): align parent issue status ownership with agent-managed model Squad leaders now open assigned parents to in_progress on first dispatch, keep them there while members work, and only move to in_review when overall completion is confirmed—matching ordinary agent status semantics without server auto-flips. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(squads): scope leader parent-status ownership to squad-assigned issues Review follow-up on the parent-status alignment change. Two boundaries were left ambiguous, both of which the change's own premise ("don't make the model resolve a contradiction in the prompt") argues should be closed in-place. 1. Status ownership was granted too widely. The leader briefing is injected on every leader path, keyed off is_leader_task — including the MUL-3724 case where an issue is assigned to a plain agent and a squad was merely @mentioned for help. The unqualified "Own the parent issue status" responsibility therefore also reached guest leaders, who could push another assignee's in-flight issue to in_review. buildSquadLeaderBriefing now takes ownsIssueStatus and selects between two variants of responsibility 6: the grant only when the issue's assignee is this squad, otherwise an explicit "do NOT change this issue's status". Quick-create passes false — no issue exists on that turn. Everything else in the protocol (roster, delegation, evaluation) is unchanged for both. 2. The comment-triggered path still contradicted itself. The runtime brief says "do not change status unless the comment explicitly asks", and a member's delivery comment never asks. Squads that dispatch by @mention create no child issues, so no child-done system comment exists to carry the explicit ask either — that parent would sit in in_progress indefinitely. writeWorkflowComment now names the protocol responsibility as the one exception for squad leaders. It is safe to state unconditionally because the grant is only present in the instructions when the server decided this squad owns the issue; for a guest leader the sentence has nothing to activate. Tests: two composition tests assemble both halves (server-side briefing + daemon-side CLAUDE.md) for one real scenario each, since asserting each half alone is how the original contradiction shipped. Plus execenv coverage that the carve-out appears only for leaders and the ordinary-agent rule stays absolute. Docs and the multica-squads skill / source map record the narrower contract. Co-authored-by: multica-agent <github@multica.ai> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: J <j@multica.ai> Co-authored-by: multica-agent <github@multica.ai>
141 lines
11 KiB
Plaintext
141 lines
11 KiB
Plaintext
---
|
||
title: 小队
|
||
description: 小队(squad)是一组智能体(可选附带成员),由一名指定的"队长"智能体(leader)领导。把 issue 分配给小队,队长来决定谁接手。
|
||
---
|
||
|
||
import { Callout } from "fumadocs-ui/components/callout";
|
||
|
||
小队(squad)是一组 [智能体](/agents) 和 [人类成员](/members-roles) 的**命名集合**,其中有一名指定的**队长(leader),必须是智能体**。小队本身是一等可分配对象——在任意 **Assignee** 选择器里直接挑它,触发会落到队长身上:队长读 issue、判断谁最合适,然后用 `@` 提及把活派给那个成员。小队让你把一组专家**一次性编好队**,之后**按主题派活,而不是按名字派活**——队伍扩展,路由不变。
|
||
|
||
## 小队的运转机制
|
||
|
||
- **一个队长,多名成员。** 队长必须是智能体;成员可以是智能体或人类成员。只有队长一个人的小队也是允许的(队长 briefing 会注明"没有其他成员"),同一个智能体也能加入多个小队。
|
||
- **任何能选人的地方都能选小队。** Assignee picker、@ 提及 picker、快速创建 modal——只要能选智能体或成员的位置,小队都会出现。
|
||
- **删除走"归档"软删除。** 归档一个小队后,它会从 picker 和列表里消失;当前分配给它的 issue 会被**自动转给队长智能体**,让工作不至于卡住。归档的小队不能再被分配新 issue。
|
||
|
||
## 什么时候用小队,什么时候用单个智能体
|
||
|
||
| 用小队的场景 | 用单个智能体的场景 |
|
||
|---|---|
|
||
| 有几个专家,但事先不知道这条 issue 该归谁 | 工作范围很明确,明确知道该谁干 |
|
||
| 想让 assignee(小队)稳定,实际响应人按 issue 变 | 希望 issue 上挂的是这个智能体的名字,责任清晰 |
|
||
| 想要一个 `@FrontendTeam` 那样的路由目标 | 一对一 `@agent-name` 就够用 |
|
||
|
||
小队不增加能力——它增加**路由**。成员还是那些智能体,队长唯一的工作是**挑对人**。
|
||
|
||
## 权限
|
||
|
||
| 操作 | 谁能做 |
|
||
|---|---|
|
||
| 创建 / 更新 / 归档小队 | 工作区 **owner** 或 **admin** |
|
||
| 增删成员、改成员角色 | 工作区 **owner** 或 **admin** |
|
||
| 把 issue 分配给小队 | 任何工作区成员(和分配给智能体一样)|
|
||
| 在评论里 `@` 小队 | 任何工作区成员 |
|
||
| 记录小队队长的 evaluation | 只有队长智能体本人(通过 CLI)|
|
||
|
||
完整角色权限对照见 [成员与权限](/members-roles)。
|
||
|
||
## 创建小队
|
||
|
||
在侧边栏打开 **Squads → New squad**,填几个字段:
|
||
|
||
- **名字(Name)** —— 例如 `Frontend Team`、`Bug Triage`。在工作区里**不要求唯一**。
|
||
- **描述(Description,可选)** —— 一句话简介,展示在小队卡片和详情页上。
|
||
- **队长(Leader)** —— 选一个已有的智能体。创建后队长会自动以 `leader` 角色加入小队。
|
||
|
||
创建完打开小队详情页可以:
|
||
|
||
- **加成员** —— 选智能体或人类成员;可以给每个成员加一句"角色描述"(例如 "owns the migrations"、"reviewer of last resort")。队长派活时会参考这些角色。
|
||
- **写 instructions** —— 小队级别的指令,队长每次执行都能看到(见下文)。
|
||
- **设头像** —— 用和智能体一样的头像选择器。
|
||
|
||
CLI 等价命令:
|
||
|
||
```bash
|
||
multica squad create --name "Frontend Team" --leader frontend-lead-agent
|
||
multica squad member add <squad-id> --member-id <agent-or-user-uuid> --type agent --role "Owns Tailwind / shadcn surface"
|
||
```
|
||
|
||
## 分配给小队的 issue 是怎么跑的
|
||
|
||
非 Backlog 状态的 issue 一旦分配给小队,Multica 会立刻给**队长智能体**入队一个 `task`(不是给每个成员都入一个)。整个流程是这样的:
|
||
|
||
1. **队长领走 task。** 队长所在的 daemon 在下次轮询时把 task 领走,和普通智能体的分配流程一样。
|
||
2. **队长拿到 briefing。** 领走的瞬间,Multica 会在队长的系统提示后面追加三段内容——详见下文 [队长每次执行看到的内容](#队长每次执行看到的内容)。
|
||
3. **队长把父 issue 推到 `in_progress`。** 和直接分配给智能体同一套 Agent-managed 状态约定:首次接单应离开 `todo`(或从 backlog 提升后的状态),进入 `in_progress`。分发成员不等于完成——小队干活期间父 issue 保持 `in_progress`。
|
||
4. **队长发一条"派活"评论。** 评论里用 roster 里给好的 mention markdown `@` 选中的成员——这个 `@` 会触发被派的成员入队新 `task`。
|
||
5. **队长记录 evaluation:** `multica squad activity <issue-id> action --reason "..."`。这一行会写进 issue 的 activity 时间线,方便人类回溯队长确实评估过这一次触发。
|
||
6. **队长停下。** 派完活,队长**不动手干活**。当被派的成员有回复——或子 issue / stage 屏障关闭——时,队长会被自动唤醒,决定下一步:继续派活、上抛给人类、在整体目标达成后把父 issue 推到 `in_review`、还是保持沉默。`done` 留给人工确认或既有集成(例如带 close intent 的 PR merge)。
|
||
|
||
如果 issue 是 **Backlog** 状态,队长不会被触发——Backlog 是停泊场,规则和直接分配给智能体一样。
|
||
|
||
### 队长每次执行看到的内容
|
||
|
||
每次队长被触发,三段内容会被附加到它的 instructions 上:
|
||
|
||
- **Squad Operating Protocol(小队工作规范)** —— 一段硬编码的规则集:读 issue → 首次接单把父 issue 推到 `in_progress` → 用 `@` 派活 → 简洁(**不要**复述 issue 内容,被派的成员自己能读)→ 每次都记 evaluation → **派完就停** → 只有整体目标达成后才把父 issue 推到 `in_review`。这段是系统管理的,不可编辑。
|
||
|
||
其中**状态那一半只对「确实分配给本小队」的 issue 生效**。如果队长是被别人 issue 里的 `@squad` 喊醒的,他照样拿到花名册和派活规则,但会被明确告知**不要碰那个 issue 的状态**——状态仍归该 issue 自己的 assignee。
|
||
- **Squad Roster(小队花名册)** —— 队长自己一行 + 每个未归档成员一行。每一行带上**确切可用**的 mention markdown(`[@Name](mention://agent/<uuid>)` 或 `[@Name](mention://member/<uuid>)`)让队长直接复制——纯文本 `@name` 是**不会**触发任何人的。
|
||
- **Squad Instructions(小队自定义指令)** —— 你为这个小队写的私货(在详情页里编辑,或用 `multica squad update --instructions`)。用来写路由规则("DB 相关派给 Alice,前端派给 Bob")、上报策略,或者任何 issue 本身不会有的背景。
|
||
|
||
## 队长什么时候会被再次触发
|
||
|
||
第一次派活完之后,**大多数后续评论**都会自动唤醒队长。具体规则:
|
||
|
||
| 事件 | 触发队长?|
|
||
|---|---|
|
||
| 非小队成员(人类 reporter、外部智能体)发评论 | **会** |
|
||
| 小队成员发"进展更新",**不带任何** `@mention` | **会**——队长重新评估是否需要下一步 |
|
||
| 任何人发的评论里**显式 `@`** 智能体 / 成员 / 小队 / `@all` | **不会**——显式 `@` 就是路由信号,队长让位 |
|
||
| 队长自己发的评论 | **不会**——硬编码防自触发 |
|
||
| 评论里只有 issue 互链 `[MUL-123](mention://issue/...)` | **会**——issue 引用不算路由 |
|
||
|
||
以上规则之上还有去重:如果队长在这个 issue 上已经有 `queued` 或 `dispatched` 的 task,新一次触发不会重复入队。
|
||
|
||
<Callout type="info">
|
||
**为什么成员发的 `@` 评论不会唤醒队长。** 小队成员一旦直接 `@` 谁,那条评论就是**有意识的交接**——再让队长唤醒一次"观察"路由,只会产出一次空回合、把时间线搞乱。智能体作者的评论是个例外:当某个智能体发出一条结果还顺手 `@` 了另一个智能体时,队长仍然会被唤醒,以便协调整条线程。
|
||
</Callout>
|
||
|
||
## 在评论里 `@` 一个小队
|
||
|
||
小队会出现在 `@` picker 里,和成员、智能体并列。点选小队会插入 `[@SquadName](mention://squad/<uuid>)`,效果等同于把这个 issue 分配给小队触发的**队长**——但**不改 assignee、不改 status**。适合"我想让小队挑个人回答一下/做一小步,但 issue 还归原来的人"这种场景。
|
||
|
||
防循环规则同样适用:队长跳过自己;同一条评论里如果还显式 `@` 了某个成员,路由会直接落到那个成员。
|
||
|
||
## 重新分配或归档一个小队
|
||
|
||
**把分配人从小队改成别的**,行为和换 assignee 完全一致:当前 issue 上所有活跃 task(包括队长的)会被取消,新的 assignee(智能体、成员、或另一个小队)被入队。没有"不改 assignee 只移除小队"的单独操作;要换就选新的 assignee。
|
||
|
||
**归档小队**(`multica squad delete <id>`,或详情页的 Archive 按钮):
|
||
|
||
1. **当前分配给这个小队的 issue 会被自动转给队长智能体**,让工作落到一个具体智能体上,避免无人接手。
|
||
2. 在 squad 表上写入 `archived_at` / `archived_by`——记录被保留下来,历史的 activity 还能解析;但从列表、picker、`@` 下拉里它都消失。
|
||
3. **拒绝后续分配**——`cannot assign to an archived squad`。
|
||
|
||
目前没有"反归档"命令;要恢复路由,重新建一个小队即可。
|
||
|
||
## CLI 命令
|
||
|
||
| 命令 | 用途 |
|
||
|---|---|
|
||
| `multica squad list` | 列出工作区里的小队 |
|
||
| `multica squad get <id>` | 查看小队的名字、队长、描述、instructions |
|
||
| `multica squad create --name "..." --leader <agent>` | 创建小队(owner / admin)|
|
||
| `multica squad update <id> [--name X] [--description X] [--instructions X] [--leader Y] [--avatar-url Z]` | 修改一个或多个字段 |
|
||
| `multica squad delete <id>` | 归档(软删除)——同时把当前分配给小队的 issue 转给队长 |
|
||
| `multica squad member list <id>` | 列出小队成员 |
|
||
| `multica squad member add <id> --member-id <uuid> --type agent\|member [--role "..."]` | 加成员(owner / admin)|
|
||
| `multica squad member set-role <id> --member-id <uuid> --member-type agent\|member --role "..."` | 不移除成员,直接修改 role |
|
||
| `multica squad member remove <id> --member-id <uuid> --type agent\|member` | 移除成员(**不能移除队长**——先换队长)|
|
||
| `multica squad activity <issue-id> <action\|no_action\|failed> --reason "..."` | 队长每次结束前由它自己调用 |
|
||
|
||
`--leader` 接受智能体名字或 UUID;其它 ID 从 `multica agent list --output json`、`multica workspace member list --output json`、`multica squad list --output json` 拿。
|
||
|
||
## 下一步
|
||
|
||
- [分配 issue 给智能体](/assigning-issues) —— 流程相同,对小队 assignee 也适用
|
||
- [在评论里 `@` 智能体](/mentioning-agents) —— `@` picker 同样能选到小队
|
||
- [智能体](/agents) —— 小队的"零件"
|
||
- [成员与权限](/members-roles) —— owner / admin / member 的完整权限对照
|