並行執行階段:多 Agent 同時處理不同視角/任務
Map Phase 是多 Agent 工作流的核心階段,透過 Task API 啟動多個並行 Agent,每個 Agent 負責一個視角的專門工作。
此為共用模組,被以下 skill 引用:
skills/research/- 多視角研究skills/plan/- 多視角規劃skills/implement/- 監督式實作skills/review/- 多視角審查skills/verify/- 多視角驗證
根據需求選擇不同執行模式,平衡速度與品質。
| 模式 | 並行 Agent 數 | 模型 | 適用場景 |
|---|---|---|---|
express |
1 | haiku | 快速實驗、原型開發 |
default |
4 | 混合 | 標準開發流程(預設) |
quality |
4 | opus | 關鍵功能、安全敏感 |
// 載入執行模式配置
const profiles = loadConfig('shared/config/execution-profiles.yaml');
const profile = profiles.profiles[profileMode] || profiles.profiles.default;→ 完整配置:../config/execution-profiles.yaml
每個視角根據任務複雜度使用不同的模型,最大化效率和品質。
# 配置來源:shared/config/model-routing.yaml
視角類型 模型 原因
─────────────── ──────── ─────────────────────
深度分析類 sonnet 需要複雜推理與洞察
流程整理類 haiku 較機械性任務/快速反應
關鍵決策類 opus 最高品質要求/複雜決策1. 檢查是否有 profile 的 model_override
↓
2. 如有 override → 使用指定模型(忽略 model-routing.yaml)
↓
3. 如無 override(null)→ 讀取 model-routing.yaml
↓
4. 根據 STAGE + perspective 類型查找推薦模型
↓
5. 如未找到配置,使用預設 sonnet
↓
6. 如遇錯誤 2 次以上(timeout、rate-limit),
自動升級到更強模型(sonnet → opus)
// 載入配置
const profiles = loadConfig('shared/config/execution-profiles.yaml');
const modelRouting = loadConfig('shared/config/model-routing.yaml');
const profile = profiles.profiles[profileMode];
// 決定模型:profile override > routing > default
const model = profile.model_override
|| modelRouting.routing[STAGE][perspective]
|| 'sonnet';
Task({
description: `${perspective} 視角分析`,
model: model, // 指定模型
prompt: perspectivePrompt
});→ 完整配置:../config/model-routing.yaml
┌─────────────────────────────────────────────────────────────────┐
│ 準備階段 │
│ 1. 載入視角配置(由各 skill 提供) │
│ 2. 載入執行模式(express/default/quality) │
│ 3. 為每個視角生成專屬 prompt(直接注入必要資訊) │
│ 4. 準備 Task API 呼叫 │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 並行啟動 │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Task #1 Task #2 Task #3 Task #4 │ │
│ │ (視角 A) (視角 B) (視角 C) (視角 D) │ │
│ │ │ │
│ │ 各 Agent 獨立運作,互不干擾 │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 同步檢查點(可選) │
│ S1 (50%): 確認方向正確 │
│ S2 (80%): 驗證初步成果 │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 收集結果 │
│ 等待所有 Task 完成,收集視角報告 │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 保存視角報告(重要!) │
│ 將每個視角的報告寫入檔案: │
│ .claude/memory/{type}/{id}/perspectives/{perspective_id}.md │
└─────────────────────────────────────────────────────────────────┘
⚠️ 關鍵:真正的並行需要在單一訊息中發送多個 Task 工具呼叫
錯誤做法(順序執行):
Message 1: Task({...}) → 視角 A
[等待完成]
Message 2: Task({...}) → 視角 B
[等待完成]
Message 3: Task({...}) → 視角 C
[等待完成]
Message 4: Task({...}) → 視角 D
正確做法(並行執行):
Message 1 同時包含:
- Task({description: "架構視角", prompt: "...", subagent_type: "Explore", model: "sonnet"})
- Task({description: "認知視角", prompt: "...", subagent_type: "Explore", model: "sonnet"})
- Task({description: "工作流視角", prompt: "...", subagent_type: "Explore", model: "haiku"})
- Task({description: "業界視角", prompt: "...", subagent_type: "Explore", model: "haiku"})
[所有 Task 並行執行]
// JavaScript 偽代碼(僅供理解概念)
const tasks = perspectives.map(perspective => ({
description: `${perspective.name} 處理 ${topic}`,
prompt: generatePrompt(perspective, topic, config),
subagent_type: selectAgentType(perspective),
model: selectModelForPerspective(perspective)
}))
// 並行執行所有 Task
await Promise.all(tasks.map(task => executeTask(task)))實際執行:Claude 需要在單一回應中發送多個 Task 工具呼叫,而非依序發送。
1. 讀取 shared/config/model-routing.yaml
↓
2. 根據 STAGE + perspective 類型查找推薦模型
↓
3. 如未找到配置,使用預設 sonnet
↓
4. 如遇錯誤 2 次以上(timeout、rate-limit),
自動升級到更強模型(sonnet → opus)
↓
5. 將選定的模型傳入 Task
自動升級邏輯:
- 第 1 次失敗:重試相同模型
- 第 2 次失敗:升級到更強模型 + 重試
- 第 3 次失敗:升級至 opus(最高層)或標記失敗
| 視角類型 | subagent_type | 適用場景 |
|---|---|---|
| 探索型 | Explore |
需要搜尋程式碼/檔案 |
| 分析型 | general-purpose |
深度思考分析 |
| 規劃型 | Plan |
需要設計實作計劃 |
## 任務
你是一位 {角色描述}。
### 目標
{topic}
### 背景
{previous_stage_summary}
### 聚焦領域
{focus_points}
### 相關檔案
以下檔案可能有用,請使用 Read 工具讀取:
{relevant_file_paths}
### 輸出要求
請產出一份結構化報告:
1. **核心發現/建議**(3-5 點)
2. **詳細分析**
3. **建議與洞察**
4. **風險/注意事項**(如適用)
### 輸出路徑
{output_path}原則:直接注入必要資訊,Agent 需要更多內容時自己用 Read 讀取。
目的:確保方向正確
檢查項目:
- Agent 正在處理正確的主題
- 深度符合預期
- 沒有偏離核心問題
如果偏離:
- 終止該 Agent
- 調整 prompt
- 重新啟動
目的:確認初步成果的品質
檢查項目:
- 發現/建議有足夠支持
- 結論合理
- 可以進入整合階段
如果 Agent 超過預期時間:
1. 記錄已有的部分結果
2. 標記為「部分完成」
3. 繼續整合流程(降級處理)
如果 Agent 回報錯誤:
1. 記錄錯誤類型
2. 嘗試一次重啟(相同配置)
3. 如仍失敗,使用備用視角或跳過
| 模式 | 並行 Agent 數 | 適用場景 |
|---|---|---|
| quick | 2 | 快速處理 |
| normal | 4 | 標準處理 |
| deep | 6 | 深度處理 |
| Profile | 視角數 | 模型 | 並行度 |
|---|---|---|---|
| express | 1/階段 | haiku | 1 |
| default | 4/階段 | 混合 | 4 |
| quality | 4/階段 | opus | 4 |
每個 Agent 獨立運作,不共享上下文。這確保:
- 視角獨立性(不互相影響)
- 資源隔離(一個失敗不影響其他)
- 可擴展性(可輕易增加視角數)
參考 GSD (Get-Shit-Done) 設計簡化
Task = Fresh Context
Claude Code 的 Task API 每次呼叫都是獨立的 context window。不需要額外的「快照檔案」機制,因為:
- 沒有共享的 context 需要「重置」
- 直接在 Task prompt 中注入必要資訊更簡單、更可靠
- 驗證方式:Task 能完成 = 上下文足夠
Context 使用量 品質
0-30% Peak(最佳)
30-50% Good
50-70% Degrading
70%+ Poor
每個 Task 從 0% 開始,自動保持在最佳品質區間。
不需要保存快照檔案,直接在 Task prompt 中注入必要資訊:
Task({
prompt: `
## 任務
你是一位 ${role_description}。
### 目標
${task_objective}
### 背景(精簡)
${previous_stage_summary} // 1-3 句即可
### 相關檔案
以下檔案可能有用,請使用 Read 工具讀取:
${relevant_file_paths}
### 輸出路徑
${output_path}
`,
model: model,
subagent_type: "general-purpose"
})| 直接注入 | Agent 自己讀取 |
|---|---|
| 角色描述 | 完整視角報告 |
| 任務目標 | 檔案內容 |
| 背景摘要(1-3 句) | 詳細分析 |
| 相關檔案路徑 | 對話歷史 |
| 輸出路徑 | - |
Task 能正常完成
↓
輸出檔案被正確寫入
↓
報告內容符合要求
↓
✓ 上下文新鮮機制正常運作
不需要額外的驗證步驟 — Task 完成本身就是驗證。
→ 完整配置:../config/context-freshness.yaml
各 skill 可透過配置客製化 Map Phase:
map_config:
parallelism: 4 # 並行度
timeout_minutes: 10 # 單一 Agent 超時
checkpoints:
enabled: true # 是否啟用同步檢查點
s1_threshold: 0.5 # S1 觸發點
s2_threshold: 0.8 # S2 觸發點
retry:
max_attempts: 2 # 最大重試次數
on_failure: skip # 失敗策略:skip | abort | fallback重要:每個 Agent 完成後,必須將其報告寫入檔案,而非只保留在記憶體中。
.claude/memory/{type}/{id}/perspectives/{perspective_id}.md
範例:
.claude/memory/research/user-auth/perspectives/architecture.md
.claude/memory/plans/user-auth/perspectives/risk-analyst.md
.claude/memory/reviews/user-auth/perspectives/code-quality.md
每個 Agent 完成時:
↓
1. 確認輸出目錄存在
mkdir -p .claude/memory/{type}/{id}/perspectives/
↓
2. 將報告寫入檔案
Write → perspectives/{perspective_id}.md
↓
3. 記錄指標(如啟用)
<!-- METRICS: record_agent perspective_id={id} output_path={path} -->
↓
4. 繼續等待其他 Agent
每個視角 Agent 的 prompt 結尾必須包含以下指令:
-
確保目錄存在:
Bash: mkdir -p .claude/memory/{type}/{id}/perspectives/ -
將報告寫入指定路徑:
Write → .claude/memory/{type}/{id}/perspectives/{perspective_id}.md -
報告必須包含:
# {視角名稱} 報告標題## 核心發現section(至少 3 點)## 詳細分析section- 最少 50 行(確保分析深度)
- 無上限(REDUCE 階段會智能處理大報告)
不執行 Write 操作 = 任務失敗
視角 Agent 不應該開啟 Task:
| 允許的操作 | 說明 |
|---|---|
| ✅ Read | 讀取檔案 |
| ✅ Glob/Grep | 搜尋檔案和內容 |
| ✅ Explore agent | 輕量級探索 |
| ✅ Bash | 執行命令 |
| ✅ WebFetch | 抓取網頁 |
| ✅ Write | 寫入報告 |
| ❌ Task | 開子 Agent |
原因:
- 複雜度爆炸(Task 開 Task 開 Task...)
- Token 成本失控
- 難以追蹤和除錯
- 違反單一職責原則
當需要抓取網頁時,使用以下順序:
-
優先使用 WebFetch
- 快速、輕量
- 適合靜態網頁
-
如果 WebFetch 失敗,使用 Chrome:
a. mcp__claude-in-chrome__tabs_create_mcp → 建立新分頁 b. mcp__claude-in-chrome__navigate → 導航到 URL c. 等待頁面載入 d. mcp__claude-in-chrome__get_page_text → 讀取內容 -
如果仍然失敗,記錄 URL 供人工處理
每個視角報告應包含:
# {視角名稱} 報告
**視角 ID**: {perspective_id}
**執行時間**: {timestamp}
**主題**: {topic}
## 核心發現
1. ...
2. ...
3. ...
## 詳細分析
...
## 建議
...
## 信心度
高 / 中 / 低
---
*由 {perspective_name} 視角產出*報告長度無上限,REDUCE 階段會根據總量自動選擇處理策略。
| 總量情況 | REDUCE 策略 | 說明 |
|---|---|---|
| 總量 < 500 行 | 策略 A:直接讀取 | 一次讀取所有報告 |
| 總量 ≥ 500 行 | 策略 B:並行子 Agent | 每個視角由獨立 Agent 完整處理 |
建議的報告結構(非強制):
### 輸出要求
請產出一份結構化報告:
1. **核心發現**(3-5 點,精煉摘要)
2. **詳細分析**(深入分析,長度不限)
3. **建議與洞察**
4. **風險/注意事項**(如適用)
5. **附錄**(補充資料,可選)
報告長度以分析完整性為優先,無需刻意精簡。策略 B 處理流程(超過 500 行時):
REDUCE 階段偵測到大報告
↓
啟動並行子 Agent(每個負責一個視角)
↓
子 Agent 完整讀取報告 → 產出結構化摘要
↓
主 Agent 收集摘要 → 進行交叉驗證和匯總
詳見:reduce-phase.md 策略 B 說明
- 可追溯性:可以回頭查看每個視角的原始分析
- 除錯:匯總有問題時可以檢查個別視角
- 復用:其他工作流可以引用特定視角的報告
- 透明度:使用者可以看到完整的分析過程
Map Phase 完成並保存視角報告後,視情況觸發 CP4 Task Commit。
注意:通常 CP4 在 Reduce Phase 完成後觸發(整個 skill 階段完成時)。Map Phase 只負責保存視角報告,不單獨觸發 commit。
如需在 Map Phase 後立即 commit(例如中斷恢復需求),可選擇性執行:
optional_intermediate_commit:
condition: "需要中間保存點"
action:
- stage: ".claude/memory/{type}/{id}/perspectives/"
- message: "wip({skill}): save perspectives for {topic}"Map Phase 完成後,進入 Reduce Phase 進行整合。