From deep-research
Pipeline A v2.2 (Internet Research) using Agent Teams — collaborative research with a Haiku scout, Sonnet specialists (adversarial peers with structured output), and an Opus sweep agent, all as teammates. EM scopes research, spawns the team, and is freed. The team works autonomously with optional iterative deepening: after Team 1 completes, the EM evaluates the gap report and may dispatch a smaller Team 2 for targeted follow-up.
npx claudepluginhub dbc-oduffy/deep-research-claude<topic># Deep Research — Pipeline A v2.2 (Internet Research) Agent Teams Driver The EM scopes the research, creates a team, spawns all teammates, and is **freed**. The team works autonomously: - **Haiku scout** (1) — executes EM-crafted search queries, builds a shared source corpus - **Sonnet specialists** (up to 5) — blocked until scout completes, then deep-read from the corpus, verify, challenge peers, output structured claims JSON + markdown summary - **Opus sweep** (1) — blocked until all specialists complete, then reads specialist outputs directly, performs adversarial coverage check, fills ...
The EM scopes the research, creates a team, spawns all teammates, and is freed. The team works autonomously:
The scout handles mechanical source discovery. Specialists self-govern their timing, actively coordinate to avoid duplication, and challenge each other's claims. The Opus sweep reads specialist outputs directly (no consolidator intermediate), checks coverage adversarially, fills gaps, and frames the final document. The EM does not monitor or broadcast WRAP_UP.
$ARGUMENTS:
<topic> — the research topic (required)--shallow — skip the deepening decision gate (force single-pass, v2.1 behavior)YYYY-MM-DD-HHhMM (current timestamp)date +%s (Unix epoch seconds — passed to teammates for timing)novel-claude-code-implementations)mkdir -p tasks/scratch/deep-research-teams/{run-id}
docs/research/YYYY-MM-DD-{topic-slug}.mddocs/research/YYYY-MM-DD-{topic-slug}-advisory.md (replace .md with -advisory.md)--shallow flag from arguments (default: false)Announce: "Running deep research (Agent Teams) on '{topic}'."
This is judgment work — the EM does it directly. Use the scoping checklist below to ensure quality.
"Research timing: default is 5-15 min with 5-source minimum. For a trivial topic, I'd suggest 3-8 min / 3 sources. For a complex topic, 5-20 min / 5 sources. What ceiling works for you?"
Cap at 5 topics (team size constraint: 1 scout + 5 specialists + 1 sweep = 7 teammates). Default 4 topics. Write scope AND search queries to {scratch-dir}/scope.md.
Quality gates derived from published guidance (OpenAI, Perplexity, Google, STORM, Anthropic):
TeamCreate(team_name: "research-{topic-slug}")
Order matters. Task IDs from earlier steps are referenced in later steps.
1. Sweep task (created first — will be blocked later):
TaskCreate(subject: "Sweep: assess coverage, fill gaps, write framing", description: "Read all specialist outputs from {scratch-dir}/, perform adversarial coverage check, fill gaps via web research, write exec summary + conclusion to {output-path}")
2. Scout task (no blockers — reads queries from disk):
TaskCreate(subject: "Build shared source corpus", description: "Read search queries from {scratch-dir}/scope.md, execute via WebSearch, vet accessibility via WebFetch, write corpus to {scratch-dir}/source-corpus.md")
3. Specialist tasks (each blocked by scout): For each topic:
TaskCreate(subject: "Analyze topic {letter}: {description}", description: "...")
TaskUpdate(taskId: "{specialist-id}", addBlockedBy: ["{scout-task-id}"])
4. Block sweep on all specialists:
TaskUpdate(taskId: "{sweep-id}", addBlockedBy: ["{specialist-A-id}", "{specialist-B-id}", ...])
Read the scout prompt template from:
${CLAUDE_PLUGIN_ROOT}/pipelines/scout-prompt-template.md
Fill in template fields: [RESEARCH_TOPIC], [PROJECT_CONTEXT], [SCRATCH_DIR], [TASK_ID], [SPAWN_TIMESTAMP].
Agent(
team_name: "research-{topic-slug}",
name: "scout",
model: "haiku",
subagent_type: "deep-research:research-scout",
prompt: <filled scout prompt>
)
TaskUpdate(taskId: "{scout-id}", owner: "scout")
For each topic area, read the specialist prompt template from:
${CLAUDE_PLUGIN_ROOT}/pipelines/specialist-prompt-template.md
Fill in ALL template fields — including [SWEEP_NAME] (use "sweep" as the teammate name). This is how specialists know who to send the DONE wake-up message to.
Agent(
team_name: "research-{topic-slug}",
name: "topic-{letter}",
model: "sonnet",
subagent_type: "deep-research:research-specialist",
prompt: <filled specialist prompt>
)
TaskUpdate(taskId: "{id}", owner: "topic-{letter}")
Spawn the sweep agent with its task (which is blocked until all specialists finish):
Agent(
team_name: "research-{topic-slug}",
name: "sweep",
model: "opus",
subagent_type: "deep-research:research-synthesizer",
prompt: <filled sweep prompt — see below>
)
TaskUpdate(taskId: "{sweep-id}", owner: "sweep")
Sweep prompt should include:
{scratch-dir}{output-path}{advisory-path} (pre-computed in Step 1)Dispatch ALL teammates in a single message (parallel).
After spawning all teammates, announce:
"Research team is running autonomously on '{topic}' with 1 scout + {N} specialists + 1 Opus sweep. Scout builds the shared corpus (~2-3 min), then specialists deep-read, verify, and challenge each other ({MIN_MINUTES}-{MAX_MINUTES} min, {MIN_SOURCES}-source minimum). After all specialists finish, the Opus sweep reads their outputs directly, checks coverage, fills gaps, and frames the final document. I'm available for other work — I'll be notified when the sweep completes."
You are now free to continue the conversation with the PM. Do not poll, do not monitor, do not broadcast WRAP_UP. The team handles everything.
When you receive a notification that the sweep task is complete:
{output-path}test -f {advisory-path} — if the file exists, read it{scratch-dir}/gap-report.mdgit add -A && git commit -m "deep-research: Team 1 complete — {topic-slug}"
TeamDelete(team_name: "research-{topic-slug}")Proceed to Step 6.5 (do NOT archive yet — deepening may add to the scratch directory).
Skip this step entirely if --shallow was passed. Proceed directly to Step 7.
Parse the gap report's YAML front-matter. Evaluate:
DEEPEN if ANY of:
- high_severity_gaps >= 2
- contested_unresolved >= 1 AND the contradiction is material to the research question
- coverage_score <= 3
- The EM judges (from reading the prose) that a gap would materially change
the document's recommendations or conclusions
DO NOT DEEPEN if ALL of:
- high_severity_gaps == 0
- coverage_score >= 4
- Remaining gaps are cosmetic (low-severity, nice-to-have, tangential)
ALSO DO NOT DEEPEN if:
- The PM's timing preference was fast/short (3-8 min ceiling) — honor the budget
If NO DEEPEN: Announce:
"Gap report reviewed — {gap_count} gaps identified, {high_severity_gaps} high-severity. Coverage score: {coverage_score}/5. Gaps are minor — proceeding with current synthesis."
Proceed to Step 7.
If DEEPEN: Announce:
"Gap report shows {high_severity_gaps} high-severity gaps and coverage score {coverage_score}/5. Recommending a deepening pass with {N} gap-specialists. Dispatching Team 2."
Proceed to Step 6.6.
Cluster gap targets: Read the Gap Targets table from the gap report. Cluster related gaps into 1-3 specialist assignments (e.g., two absent claims in the same domain → one gap-specialist). Only include HIGH and MEDIUM severity gaps.
Decide scout inclusion: If gap targets require research in new topic areas not covered by Team 1's corpus, include a Haiku scout with new search queries. If gaps are refinements (contradictions, uncorroborated claims within existing topics), skip the scout — gap-specialists will do their own targeted searches.
Record Team 2 spawn timestamp: date +%s
Create Team 2:
TeamCreate(team_name: "research-{topic-slug}-t2")
Create tasks:
Sweep task (merge mode):
TaskCreate(subject: "Merge sweep: produce deepening delta", description: "Read Team 1 gap report + Team 2 gap-specialist outputs, produce deepening-delta.md")
Scout task (if needed):
TaskCreate(subject: "Build supplementary corpus for gaps", description: "Execute new search queries for gap targets, write to {scratch-dir}/gap-corpus.md")
Gap-specialist tasks (1-3):
For each gap cluster, read the gap-specialist prompt template from:
${CLAUDE_PLUGIN_ROOT}/pipelines/gap-specialist-prompt-template.md
Fill in template fields: [GAP_ID], [GAP_DESCRIPTION], [GAP_TYPE], [GAP_SEVERITY], [SUGGESTED_QUERIES], [RELEVANT_TOPIC_LETTER], [GAP_LETTER] (use letters starting after Team 1's last letter, e.g., if Team 1 used A-D, gap-specialists use E-G), [SCRATCH_DIR], [TASK_ID], [SPAWN_TIMESTAMP], [SWEEP_NAME] = "sweep-t2", peer list, research question, project context.
TaskCreate(subject: "Fill gap {GAP_ID}: {description}", description: "...")
TaskUpdate(taskId: "{gap-specialist-id}", addBlockedBy: ["{scout-task-id}"]) # only if scout exists
Block sweep on all gap-specialists:
TaskUpdate(taskId: "{sweep-t2-id}", addBlockedBy: ["{gap-specialist-ids...}"])
Spawn all Team 2 teammates in a single message (parallel):
Scout (if needed):
Agent(
team_name: "research-{topic-slug}-t2",
name: "scout-t2",
model: "haiku",
subagent_type: "deep-research:research-scout",
prompt: <scout prompt with gap-specific queries>
)
Gap-specialists:
Agent(
team_name: "research-{topic-slug}-t2",
name: "gap-{letter}",
model: "sonnet",
subagent_type: "deep-research:research-specialist",
prompt: <filled gap-specialist prompt>
)
Sweep (merge mode):
Agent(
team_name: "research-{topic-slug}-t2",
name: "sweep-t2",
model: "opus",
subagent_type: "deep-research:research-synthesizer",
prompt: <sweep prompt with [MERGE_MODE: true], Team 1 synthesis path, gap report path, gap-specialist output paths, delta output path = {scratch-dir}/deepening-delta.md>
)
Announce:
"Deepening team (Team 2) dispatched: {scout status} + {N} gap-specialists + 1 Opus merge sweep. Gap-specialists fill targeted gaps (~3-8 min each), then the sweep produces a delta. I'll be notified when complete."
EM is freed again. Do not poll.
When you receive a notification that the Team 2 sweep task is complete:
Read the delta document at {scratch-dir}/deepening-delta.md
Verify it has substantive content
Read Team 2's advisory if it exists
Merge delta into the Team 1 synthesis at {output-path}:
[CONTESTED] markers.[UNFILLED GAP] markers where applicable.[DEEPENING ADDITION] and [SWEEP ADDITION] markers from the final document — provenance served its purpose during merge. The final document should read seamlessly.Write the merged document back to {output-path} and {scratch-dir}/synthesis-merged.md
Commit:
git add -A && git commit -m "deep-research: Team 2 deepening merged — {topic-slug}"
Shut down Team 2: TeamDelete(team_name: "research-{topic-slug}-t2")
Proceed to Step 7.
mkdir -p docs/research/archive/YYYY-MM-DD-{topic-slug}
cp -r {scratch-dir}/* docs/research/archive/YYYY-MM-DD-{topic-slug}/
rm -rf {scratch-dir}
git add -A && git commit -m "deep-research: archive + cleanup — {topic-slug}"{output-path}."{output-path}."{advisory-path}."| Failure | Action |
|---|---|
| Scout fails (no corpus written) | Specialists fall back to self-directed discovery (existing behavior) — the corpus is optional, not required |
| Scout times out (partial corpus) | Specialists use what's there + supplement with own searches |
| Specialist hits ceiling and self-converges | Normal — specialist writes what it has and marks task complete |
| Sweep doesn't wake after all specialists complete | Verify specialists sent DONE messages to sweep; if not, send manual nudge via SendMessage. If still stalled after 5 min, EM reads raw specialist outputs for PM |
| All specialists fail | TeamDelete, report to PM |
| Agents stuck in idle loops | Known platform issue — agents may enter idle loops that resist shutdown. Commit and archive results before attempting TeamDelete. If TeamDelete fails ("active" agents), wait for timeout. Do NOT block on stuck agents — read available outputs and present to PM |
| Team creation fails | Fall back to relay pattern or manual research |
| Team 2 sweep fails | EM reads raw gap-specialist outputs from {scratch-dir}/D-*-claims.json and manually integrates into Team 1 synthesis |
| All Team 2 gap-specialists fail | TeamDelete Team 2, proceed to Step 7 with Team 1 synthesis as-is. Note: deepening failure is non-blocking — Team 1's output is already a complete document |
| Gap report has no YAML front-matter | Treat as coverage_score: 4, high_severity_gaps: 0 — skip deepening (the sweep may be running an older version) |