Files
Agent-System-Documents/docs/guides/squad-mechanics.md
T
weichen 4ce8155161 Expand guides with worked examples for intents, runs, and squads
Why: 补充实例让导览可对照实操:意图打分/填槽/多意图裁决给出
intentctl explain 实测轨迹(含样例意图、歧义、优先级 tie-break、
能力目录),任务执行给出工具清单与典型回合走查(含 ClaimGate
三类拦截),小队给出 agent-squad demo 全流程实测与真实工作区
目录树/TASK.md 实拍;并修正事实:默认意图目录为空、插件 overlay
与 registry loader 两种文件形态不同。

Evidence: intentctl explain/catalog 与 agent-squad demo 为 2026-10-08
本地实测输出(命令见各节);锚点仍为 Dev R0 218fc4b1;git diff
--check 通过;五篇互链全部可解析。SRC=SELF。

Impact: 仅文档增补(02/03/04/05 四篇),无代码影响。

Refs: Dev 任务分支 feature/architecture-guides。
2026-10-08 09:33:13 +00:00

227 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 小队(Squad)工作机制:拆解、执行、汇总的完整调用链
> 基准:Agent-System-Dev 组合 `218fc4b1ba00b0a03b5bb79f292b3eba6c987a58`(R0,2026-10-08 锚点核验)。
> 行号为该提交下的函数入口位置(个别内部区段为约略范围),随代码演进漂移;文件与函数名是稳定锚点。
> `internal/` 指 `modules/backend/internal/`;`squad/` 指 `deps/agent-squad/squad/`。
---
## 1. 一句话结论
小队是 run 内的一种**编排执行模式**:由 agent-squad 引擎(`deps/agent-squad`)把目标
拆成**角色化步骤 DAG**(规则规划器或蓝图模板),每一步交给一个"成员"执行——成员是
按角色装配的 **agent-native 内核 agent**(独立执行循环;legacy 的 agent-system 子 run
压缩路径已退役),无写集冲突的步骤并行推进,产出落子工作区并经**黑板**共享,收口时做
六维质检与自动修复,交付物聚合回主 run。
触发时机(何时启动):settings `runtime.entry=squad`(对话即小队)、模型调用
`squad_orchestrate` 工具、演示消息 `#squad`——详见[小队与子 Agent 启动](squad-and-subagents.md)第 3 节。
---
## 2. 概念模型(类型全部在 `deps/agent-squad/squad/models.go`)
| 类型 | 位置 | 含义 |
|---|---|---|
| `RoleSpec` 角色 | models.go:25 | role/name、绑定执行后端 `Backend`(stub/llm/agent-native/…)、角色级 Model、工具白名单 Tools、技能 Skills、**BashPermission 三态 allow/ask/deny**、Keywords(规则规划器匹配用)、Instructions、HITL 策略、`MaxConcurrentTasks` 并发限流 |
| `Goal` | models.go:48 | 目标文本 + Materials 附件 + Constraints + HITL 覆盖 |
| `Blueprint` | models.go:64 | 任务模板:关键词命中即走基线步骤 |
| `StepSpec` 步骤 | models.go:86 | Role、Targets(期望交付物文件,缺省 output.md)、`Writes` 写集(写集相交强制串行)、`Needs` 依赖、`Parallel`、`Critical`(失败即终止)、`MinScore` 质检门槛、`RequiresApproval`、`IntentID/IntentSlots`(系统功能步,不走智能体)、Attempts |
| `WorkflowPlan` + `SquadConfig` | models.go:168, 179 | 拆解结果(与产品 squad workflow.json / squad.json 兼容) |
| `BlackboardState` 黑板 | models.go:225 | Facts/Gaps/Implications/Assumptions/Fields —— 成员间协作的共享状态载体 |
**小队成员 ≠ 常驻 agent**:成员 = 角色(RoleSpec)。每条步骤由
`BackendResolver.Resolve`(`squad/backend.go`)解析出一个 Executor 并调用一次
`Execute`。产品侧**只注册 agent-native 后端**(`internal/squadadapter/adapter.go:292`
`BuildBackends`;`deps/agent-squad/adapters/native/register.go:61` `RegisterFull`),
每步构造一个独立内核 agent 执行循环(模型/工具/搜索/MCP/技能根按 RoleSpec 装配)。
---
## 3. 小队 Run 状态机
`squad/models.go:284` 起(`RunStatus`):
```
created → planning → (awaiting_clarification | awaiting_confirmation) ← HITL 挂起
→ executing → (waiting_human | quality_review) ← HITL 挂起
→ completed | degraded | failed | cancelled ← 终态
```
- 挂起态判定与适配:适配器 `isHoldStatus`(`internal/squadadapter/adapter.go:221`)据此进 HITL。
- 挂起上下文 `HitlGate`(Request+Plan+PrevStatus)落盘 `pending.json`;`Respond`
(`squad/engine.go:637`)按多种 Kind 分派恢复:Clarification 答案并入 Goal 重新规划、
Confirmation、Gap、Escalation、Adjustment、Permission、QualityReview;执行态恢复走
`Resume`(`squad/engine.go:1127`)。
**事件体系**:引擎 `squad.Event` 13 类(`squad/progress.go:10-24`:run_started /
phase / step_started / completed / failed / skipped / detail / deliverable /
human_input_required / human_responded / run_completed / failed / cancelled)。
产品侧不直连 bus:`onSquadEvent`(`internal/squadadapter/adapter.go:185`)把 step_* 映射为
`core.EvAgentProgress`,计划经 `mapPlan`(`adapter.go:200`)映射为 `rc.UpdatePlan` →
`core.EvPlanUpdate`,成员子 run 发 `core.EvAgentSpawn` —— 统一进事件流,**前端可看到
小队进展**(`modules/frontend/src/store.ts`、`contracts.ts` 消费 agent.spawn/plan.update/agent.progress)。
**运行状态持久化(磁盘即权威)**:`workspace.json / workflow.json / squad.json /
blackboard.json / pending.json / runstate.json / usage.json`
(`squad/runstate.go:13` 注释、`:81` `persist`);崩溃恢复 `Resume → recoverInterrupted`
(产物已齐判完成防副作用翻倍)。支持运行中 Steering 与黑板字段注入自动唤醒 `SweepWakeups`。
---
## 4. 端到端调用链(以 `squad_orchestrate` 工具路径为主线)
| # | 步骤 | 位置 |
|---|---|---|
| 1 | 触发:`llm_direct.go:479` case toolSquad → `squadadapter.Orchestrate` | `internal/runtime/llm_direct.go:479` → `internal/squadadapter/adapter.go:47` |
| 2 | 编排进度卡(可选):创建 `CardKindProgress` 卡,终态置态 | adapter.go `Orchestrate` 内(CardSink 端口 `:40`) |
| 3 | 注册内置角色 `builtinRoles()`(`adapter.go:306`):规划员/调研员/撰稿员/审校员,**全部 Backend=agent-native**;工具白名单按角色最小化(全员含 write_file,步骤须自己落盘交付物);撰稿员 `BashPermission=ask` + docx/xlsx/pptx-author 技能,其余角色 Bash=deny;指令来源 `RoleInstructions`(:303,接提示词库 `agent.squad.<kind>`) | |
| 4 | 组装后端 `BuildBackends`(`adapter.go:292`):只注册 `"agent-native"` 内核工厂(组合根 `AgentNativeOptions`,`internal/app/app.go:196`);legacy `"agent-system"` 已退役;工厂缺席 fail-closed | |
| 5 | 组装引擎 `squad.NewEngine(Options{…})`:Planner=RulePlanner、Checker=quality.Checker、RepairBudget、HitlPolicy、Sink=ProgressFunc(onSquadEvent);引擎默认 `DefaultBackend="stub"`(`squad/engine.go:169-170`)、单步超时默认 10 分钟(Options 注释 `:32`) | `adapter.go` Orchestrate 内;`squad/engine.go` |
| 6 | `SquadEngine.Run`(`squad/engine.go:234`):生成 `run_<UTC时间戳>` ID → `acquire`(`:213`,进程内 mutex + flock 文件锁,单 run 单控制操作)→ `EvRunStarted` → 可选**意图闸门**一次裁决(GuardHit→Reject;命中 blueprint→定向模板;否则不干预;实现 `deps/agent-squad/adapters/intent/gate.go`) | |
| 7 | **任务拆解(规划)** `planAndExecute`(`squad/engine.go:335`):先 Router 分诊;未 direct 则蓝图匹配 + `Planner.Plan`(`squad/planner_rule.go:20`)。产品用 **RulePlanner(确定性规则,非 LLM)**:命中 Blueprint 直接用模板步骤/编制(`fromBlueprint`,planner_rule.go:27);未命中走四阶段骨架 **梳理(organizer)→专项(specialist)→成文(writer)→终审(leader)**(planner_rule.go:85 起),注册表缺角色时 `Registry.Derive` 现场派生并置 `NeedsConfirmation`。LLM 规划器已实现(`squad/planner_llm.go`,严格 JSON+重试+Fallback)但产品未接。拆解结果持久化 `runs/<run_id>/workflow.json + squad.json`(`squad/runstate.go:81` `persist`) | |
| 8 | 澄清/确认挂起:规划歧义 → `awaiting_clarification`;派生编制 → `awaiting_confirmation`(leader 模式豁免)。适配器驱动循环(`adapter.go` Orchestrate 内):hold 态 → `askHuman`(`adapter.go:150`,HumanRequest→core.HITLCard→`rc.AskHITL`)→ `engine.Respond`(`engine.go:637`);执行态 → `engine.Resume`(`engine.go:1127`)。每次推进后 `mapPlan`(`adapter.go:200`)把 WorkflowPlan 映射为右栏计划快照 | |
| 9 | **工作区物化**:`PrepareWorkspace`(`squad/workspace.go:27`)+ `BuildSubWorkspaces`(workspace.go:127):每步建 `tasks/NN_<role>/` 子工作区,把 `context/`(goal.md、材料原文 + textextract 抽取文本、index.json)与 template.md 快照进去(`snapshotContextInto` workspace.go:160),并写 **TASK.md**(`writeTaskFile` workspace.go:182:黑板快照、权威等级资源表、产出要求——成员靠它读前序产出)与 **AGENTS.md**(`writeAgentsFile` workspace.go:224:角色指令) | |
| 10 | **调度执行** `flowDriver.advance`(`squad/workflow.go:25`):每轮从权威 Steps 现场编译调度图 `compileGraph`(`squad/graph.go:23`:Needs 依赖或相邻 Parallel 同层,环 fail-closed)→ 分并行/串行层 → **无写集冲突的步骤并行**(`runParallel` workflow.go:216,goroutine+WaitGroup,关键失败 cancel 全组),写集冲突按声明序串行 → `gateBeforeRun`(workflow.go:175:bash ask 角色授权 / 步骤审批的 HITL 门)→ `runOneStep` | |
| 11 | **单步执行** `runOneStep`(`squad/workflow.go:262`):置 running、Attempts++ → 写 TASK.md → 组装 ExecRequest(ToolAllowlist/Skills/SessionScope/Budget/OnEvent 过程帧)→ 后端 `Execute`(系统功能步改走 IntentRunner)→ 瞬态失败重试并注入重试提示 → **交付物落盘校验** `missingTargets`(workflow.go:1071)→ 完成:`mergeStepArtifacts` 把子工作区 `fields.json/gaps.json` 并入黑板(`squad/blackboard.go:43`)→ `checkBlockingGaps`(workflow.go:652:interactive 挂 HitlGap 卡、auto 记兜底假设继续)→ 每步后可动态调整(评估器加步/跳步)。superstep 边界写检查点快照,Resume 时校验图指纹防形态漂移 | |
| 12 | **成员执行(统一 agent-native)**:`RegisterFull`(`adapters/native/register.go:61`)按角色构造独立内核 agent(模型/工具/搜索/MCP/技能根按 RoleSpec+BashPermission 装配),过程帧经 eventTap 桥为 `EvDetail`。内核里的 `delegate_task` 经 `SubagentFactory`(`adapter.go:234`,SpawnBackground `:266` / SpawnSubagent `:273`)桥回产品 SpawnSubagent,**深度恒为 1,子 run 不再嵌套小队** | |
| 13 | **Leader 委派模式**(entry=squad 的 plan 分诊):`RunOptions.Mode="leader"`(`squad/engine.go:99-105` Options 注释;轮次上限 `MaxLeaderTurns` 默认 8,`squad/leader.go:48` `DefaultMaxLeaderTurns`)——规划被委派循环取代:每轮重写 leader 的 TASK.md(目标+黑板+委派历史)与 AGENTS.md(协调契约),leader 后端执行产出 **delegation.json**(action=delegate/escalate/close/failed);delegate:临时建 StepSpec、跑 runOneStep、交付快照进 leader 的 `inbox/<stepID>/`、再唤醒 leader 评估(一轮只委派一个成员);escalate → HitlEscalation 挂起;超限按现有产出降级收口。核心状态与提示词装配:`LeaderState`(leader.go:57)、`DelegationRecord`(:81)、`delegation`(:91)、`leaderPrompt`(:126)、`leaderExecRequest`(:16) | |
| 14 | **汇总与质检(收口)** `finalize`(`squad/workflow.go:784`):最后 completed 步骤的主产出复制为 `output.md` → `Checker.Check`(`internal/quality/checker.go:16` 附近 → `score.go`:六维启发式评分——结论先行/结构/完整性/证据/可执行性/可读性;**Passed = 总分≥70 且无单维<40**,score.go:28,72;docx 走段落提取;可选 housestyle lint)→ 未过写 `quality-feedback.md`(checker.go:29)并自动修复 `rerunForRepair` 重跑交付步骤(workflow.go:913)→ 仍不过:interactive 转 `quality_review` 人工裁决(approve=manualPass、retry 追加预算但受上限 `MaxRepairGranted`,`squad/termination.go:14`)→ 写 `manifest.json`(全文件 sha256 防篡改)→ `EvRunCompleted` | |
| 15 | **聚合回主 run**:`Orchestrate` 返回 summary,交付物经 `rc.WriteArtifact("squad-<runID>.md")` 登记为主 run 工件;`RunEntry` 返回 `EntryResult{Summary, Body}`(`entry.go:34`),SquadRunner 做**虚假交付检查**(`internal/runtime/squad_runner.go:95` 附近 `claimsFalseDeliverable`)后落工件并 `SetAssistantParts`(squad_runner.go:107)。所有 usage 按角色聚合进 `RunResult.Usage` | |
---
## 4.5 实测:离线小队演示(真实输出)
`deps/agent-squad` 自带离线演示(`cmd/agent-squad demo -keep`,stub 脚本成员 + 规划脚本 +
自动应答 HITL,无需 LLM/网络),以下为其 2026-10-08 实测输出摘录。**引擎机制与产品完全
同一套**,差异只有三处:成员后端是脚本(产品是 agent-native 内核)、规划器是 MockPlanner
(产品默认 RulePlanner)、HITL 自动应答(产品走 HITL 卡片)。
```
═══ agent-squad 离线演示(stub 智能体 + mock 规划器 + HITL)═══
[1] 注册角色(手动注册,backend=demo 脚本智能体)
+ researcher 调研专员 + writer 撰写专员 + reviewer 审核专员
[2] 发起运行:调研便携式超声诊断仪并产出报告
✔ step_01_research researcher 市场与技术调研,回填事实与缺口
step_02_draft writer 汇总调研产出,撰写报告初稿
step_03_review reviewer 一致性终审并产出终版
[3] ⏸ HITL 挂起(gap):发现 1 个阻塞缺口,需要人工补充信息后才能继续:
- [gap_1] 目标年产量未提供,影响成本测算(owner=agent)
→ 自动回应:choice="resolved" answer="年产量 10 万套"
✔ step_01_research ✔ step_02_draft ✔ step_03_review
[4] 运行终态:completed
步骤 3 个(完成 3/跳过 0/失败 0)。质检得分 100。
交付物: <dataDir>/runs/run_20261008T090457.882598947/output.md
黑板字段: {"annual_volume":"100000","budget":"15万","device_class":"二类",
"review":"passed","target_market":"中国"}
```
对应真实落盘的工作区(`runs/<run_id>/`)——与第 4 节调用链逐项对应:
```text
runs/run_20261008T090457.882598947/
├── context/goal.md, context/index.json # 9. 目标与材料快照
├── tasks/01_researcher/ # 9. 每步一个子工作区
│ ├── TASK.md # 步骤任务书(角色、期望产出、资源权威等级、黑板快照、产出要求)
│ ├── AGENTS.md # 角色指令
│ ├── context/ # 快照进来的目标/材料
│ ├── notes.md fields.json gaps.json # 成员产出(黑板来源)
│ └── execution.log
├── tasks/02_writer/{TASK.md,AGENTS.md,context/,output.md,...}
├── tasks/03_reviewer/{TASK.md,AGENTS.md,context/,output.md,fields.json,...}
├── blackboard.json # 11. 黑板(字段在步骤间累积)
├── workflow.json squad.json runstate.json # 7. 拆解结果与运行态(磁盘即权威)
├── checkpoints/{001,002,latest}.json # 11. superstep 检查点
├── output.md manifest.json # 14. 聚合交付物 + sha256 清单
└── .lock # 6. acquire 的 flock 文件锁
```
`tasks/01_researcher/TASK.md` 实拍(节选):
```markdown
# 步骤任务:市场与技术调研,回填事实与缺口
- 角色:调研专员(researcher)
- 期望产出:[notes.md fields.json gaps.json]
## 任务上下文资源与权威等级(已快照到本目录,只引用本地路径)
| 资源路径 | 权威等级 | 用途说明 |
| `context/goal.md` | **authoritative** | 运行目标 | 不可推翻 |
## 黑板快照(共享状态)
## 产出要求
1. 按期望产出文件名落盘到本子目录;
2. 结构化事实回填 `fields.json`(字符串键值);
3. 发现信息缺口且无法假设时写 `gaps.json`([{"item":"…","blocking":true}])。
```
产品的默认拆解(RulePlanner 四阶段骨架,`squad/planner_rule.go:79` 起)与演示计划同构,
真实代码里的步骤与交付约定:
```go
// 通用四阶段骨架:梳理 → 专项 → 成文 → 终审
{"step_01_organizer", "梳理目标背景与输入材料,产出事实与缺口", "organizer"},
{"step_02_specialist", "围绕目标开展专业分析与推演", "specialist"},
{"step_03_writer", "汇总各角色产出,撰写交付物初稿", "writer"},
{"step_04_leader", "一致性终审与交付把关", "leader"},
// 非末步 targets = ["notes.md","fields.json"](事实经黑板传给后步);末步 = ["output.md"]
```
注册表缺角色时 `Registry.Derive` 现场派生(名为"organizer 专员"等)并置
`NeedsConfirmation` → `awaiting_confirmation` 挂起等用户确认编制。意图目录注入规划器/
Leader 的形态见[意图识别](intent-recognition.md) 4.6 节例 5 的 catalog 实测输出。
---
## 5. 小队如何"协作"
- **黑板(Blackboard)**是协作中枢:Facts(已确认事实)/Gaps(信息缺口)/
Implications/Assumptions/Fields。每步完成后子工作区的 `fields.json`/`gaps.json`
合并进黑板(`squad/blackboard.go:43` `mergeStepArtifacts`);下一成员的 TASK.md 带
黑板快照,据此读前序产出。字段注入可自动唤醒挂起的 run(`SweepWakeups`)。
- **材料溯源**:输入材料经 `deps/agent-squad/textextract/` 提取纯文本并注入页码锚点,
成员引用材料时可标注出处。
- **防失控上限**:`squad/termination.go` 集中管理修复预算、Leader 轮数等终止条件。
---
## 6. 与 runmgr / workflow 的关系
- 小队**不是独立的一层**:它是 conversation run 内的一种执行模式/入口(`runtime.entry`)
或 run 内 LLM 的一次工具调用,在 runCtx 上同步驱动。
- 成员执行的子 run 经产品 `SpawnSubagent` 进任务树(仅限内核 `delegate_task` 桥接);
工作流(`run_workflow` → wfcompile 编译执行)是另一条平行机制——注意 wfcompile 执行时
**也装配到 squad 引擎上步进**,entry=squad 时不再提供 `run_workflow` 声明(互斥,
`internal/runtime/llm.go:266-268`)。
- 依赖方向:agent-squad 核心只依赖 error-code-system(不感知内核);依赖由 adapters
层单向引入——`agent-squad/adapters/native` 同时依赖 agent-native 与 agent-squad;
backend require 两者并 replace 到自己 `deps/` 下的库副本。
---
## 7. 关键文件清单
| 职责 | 文件 |
|---|---|
| 全部类型与状态机 | `deps/agent-squad/squad/models.go`(RoleSpec :25、StepSpec :86、BlackboardState :225、RunStatus :284) |
| 门面(Run/Respond/Resume/Inspect/Steer) | `deps/agent-squad/squad/engine.go`(Run :234、acquire :213、planAndExecute :335、Respond :637、Resume :1127) |
| 调度/单步/收口 | `deps/agent-squad/squad/workflow.go`(advance :25、gateBeforeRun :175、runParallel :216、runOneStep :262、checkBlockingGaps :652、finalize :784、rerunForRepair :913、missingTargets :1071) |
| DAG 编译与图指纹 | `deps/agent-squad/squad/graph.go`(compileGraph :23) |
| Leader 委派 | `deps/agent-squad/squad/leader.go`(DefaultMaxLeaderTurns :48、LeaderState :57、leaderPrompt :126) |
| 规划器(规则/LLM/端口) | `squad/planner_rule.go`(Plan :20、fromBlueprint :27)、`planner_llm.go`、`planner.go` |
| direct/plan 分诊 | `squad/router.go`(applyRoute :29、directAssistantPlan :55) |
| 状态持久化(磁盘即权威) | `squad/runstate.go`(persist :81) |
| 工作区/TASK.md/AGENTS.md | `squad/workspace.go`(PrepareWorkspace :27、BuildSubWorkspaces :127、writeTaskFile :182、writeAgentsFile :224) |
| 黑板合并 | `squad/blackboard.go`(mergeStepArtifacts :43) |
| 事件 | `squad/progress.go`、`store/eventsink.go` |
| 后端解析器 / 防失控上限 | `squad/backend.go`、`termination.go` |
| backend 工具路径适配 | `internal/squadadapter/adapter.go`(Orchestrate :47、askHuman :150、onSquadEvent :185、mapPlan :200、isHoldStatus :221、SubagentFactory :234、BuildBackends :292、builtinRoles :306) |
| backend 入口路径适配 | `internal/squadadapter/entry.go`(RunEntry :42、kernelRoles :177) |
| 对话入口 Runner + LLM 分诊 | `internal/runtime/squad_runner.go`(Execute :26、Route :146) |
| 质检打分(六维) | `internal/quality/checker.go`、`score.go` |
| 内核接成小队执行器 | `deps/agent-squad/adapters/native/register.go`(RegisterFull :61) |
| 意图闸门/能力目录 | `deps/agent-squad/adapters/intent/gate.go`、`catalog.go` |
| 独立 CLI(serve/run/demo) | `deps/agent-squad/cmd/agent-squad/` |