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。
20 KiB
小队(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 启动第 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 节调用链逐项对应:
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 实拍(节选):
# 步骤任务:市场与技术调研,回填事实与缺口
- 角色:调研专员(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 起)与演示计划同构,
真实代码里的步骤与交付约定:
// 通用四阶段骨架:梳理 → 专项 → 成文 → 终审
{"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 的形态见意图识别 4.6 节例 5 的 catalog 实测输出。
5. 小队如何"协作"
- **黑板(Blackboard)**是协作中枢:Facts(已确认事实)/Gaps(信息缺口)/
Implications/Assumptions/Fields。每步完成后子工作区的
fields.json/gaps.json合并进黑板(squad/blackboard.go:43mergeStepArtifacts);下一成员的 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/ |