ccai40359-wq/multiagents-workflow/web-research-fanout
Claude Code and agent skill by ccai40359-wq/multiagents-workflow
- community
Checking that the SKILL.md file is still in the repository.
Web research orchestration protocol — split lanes (sub-question × source type) → dispatch researchers in parallel → structured claims table (assertion + source URL + date + primary/secondary) → independent arbitration only for conflicts. MUST USE for web research, multi-source verification, vendor/market research, cross-checking — triggers include "research this", "verify across sources", "全网查", "多源核对". Not for single-fact lookups or reading local documents (use dual-read in this pack).
Install
npx vskill@latest install ccai40359-wq/multiagents-workflow/web-research-fanoutSKILL.md
Web Research Fanout
Core principle: coverage comes from independent sources, not from the number of agents. The lane count equals the number of genuinely independent lines (sub-question × source type), not a fixed number you feel like dispatching. N researchers asked the same question will pick the same pages from the same search results → correlated errors reinforce each other and produce "confident mistakes".
0. First: decide whether to fan out
- Single fact (one number, one link) → dispatch nothing, or one agent; the main session searches directly.
- You need "a map" (breadth, multi-source corroboration, conflicting claims) → fan out.
- Reading local documents/PDFs → use
dual-read, not this skill.
1. Firepower tiers (lane count by stake, not by mood)
| Tier | Size | When | |
|---|---|---|---|
| Quick | 2-3 | One claim needs 2-3 independent sources | |
| Standard (default) | 5-8 | One full research pass, cut into 5-8 lanes by source type | |
| Heavy | 10-20 | Only if you can list ≥10 genuinely independent sources/sub-questions (multi-language, multi-platform, multi-category); if you can't, you don't get to open it |
Lane examples (cut by source type): official announcements/docs | code repos & issues | benchmarks/review sites | community reports (Reddit/HN/V2EX) | Chinese sources | pricing pages/terms | regulators/primary documents. Every lane's researcher must get a different seed (wording / language / site restriction — at least one must differ), otherwise it's a clone.
Quality formula: quality = independent sources × adversarial verification × arbitration; raw numbers are just an amplifier. Before adding a lane, ask: in which dimension is it independent from the existing ones — source type, language, stance, model family? If none, it's a clone and will only amplify correlated error.Model assignment: lanes are standardized work — mid-tier models are enough (in practice: contract compliance is fine; failures happen in the channels, not the thinking). Judgment-heavy steps are only three: the main session's planning/merging, the adversarial lane, and arbitration. Different family ≠ more expensive: the point of cross-family is uncorrelated blind spots; any mid-tier model from a different family will do.
2. Dispatch (one message, parallel; batch if heavy)
- Send multiple Agent calls (subagent_type:
researcher) in one message — do not serialize. - ≤6 per batch; heavy tier dispatches in batches (avoid gateway rate limits).
- Validate channels before writing them into tasks: the main session verifies one working channel first, then writes the complete command into the task template — sub-agents have no Skill tool and cannot load other manuals, so commands must be self-contained. Common channels: search APIs (Exa etc., via mcporter/MCP or curl) | search-engine result pages (Bing/Brave) | r.jina.ai for page reading |
gh|yt-dlp; verify social-platform channels before using them. - Every task must be self-contained (sub-agents cannot see the main session). A dispatch has two parts — keep them apart:
- Invariant brief — frozen the moment the lane is dispatched: question, scope, seeds, output contract below. Never edit it afterwards; a changed brief invalidates the lane's evidence. Gaps are handled by adding lanes (see the two-round rule), never by re-sending an edited brief.
- Parameter block — the tunable knobs (budget, model, tier), recorded in the dispatch ledger, not embedded in the brief:
node <pack-root>/tools/ledger/dispatch-ledger.mjs append --params-file <params.md> .... Every conclusion is traceable to the parameter set it was produced under — change a knob and you know exactly which conclusions are invalidated.
Template (invariant part):
Parameter block (recorded via the dispatch ledger, not embedded in the brief): budget: ≤8 searches + ≤10 page fetches; stop once a claim has 2 independent sources. · model: <as dispatched> · tier: <Quick|Standard|Heavy>
Big topics (heavy tier / decision-grade conclusions): two rounds, don't one-shot
- Recon round (main session, 5-10 min): search 3-6 times yourself to learn the key entities, where the primary sources live, and where accounts disagree → use that to cut lanes and seeds. (For high-cost tasks you may add a "plan gate": show the plan to the user before starting.)
- Collection round: dispatch researchers per lane in parallel (≤6 per batch).
- Gap round: dispatch 1-2 additional lanes with fresh task-ids, targeting exactly three things — the "not found" list, conflicts, and counter-evidence for load-bearing claims. The round-1 briefs stay frozen: never re-send an edited brief, because that re-opens (and re-pays for) every conclusion round 1 already settled. Gaps are new lanes, not patched ones.
The cost of one-shotting: lanes burn their budget guessing keywords (measured).
3. Mechanical merge in the main session (don't read every report)
- Gate every lane report before merging:
node <pack-root>/tools/gates/claims-lint.mjs <lane-output.md>must exit 0. It mechanically fails any row missing a public URL, date, primary/secondary marker, or counter-evidence — and conflicts that never made it into an arbitration section. A lane that fails the gate goes back to that lane; do not hand-merge around it. - Deduplicate by assertion: same assertion from multiple sources → one row, note the source count.
- Mechanically flag two things: ① load-bearing assertions with a single source ② assertions with conflicting conclusions → into the "conflict list".
- Keep only the merged table + conflict list; never stuff all raw reports into context.
- Log each lane's outcome in the dispatch ledger (
tools/ledger/dispatch-ledger.mjs) — a lane that returned nothing usable isfailed-protocolorfailed-definition, not a silent shrug (see the failure taxonomy in the Appendix).
4. Verification & arbitration (default: primary sources + adversarial + cross-family)
For every load-bearing assertion (an assertion the conclusion rests on), do all three by default at standard tier and above; quick tier does at least ①:
- Primary-source trace: the assertion must be traceable to a primary source (official page / official repo / original document). Secondary-only → mark "pending primary verification" and do not treat as settled.
- Adversarial lane: dispatch one researcher whose job is to find counter-evidence — search "X is wrong / not recommended / complaints / scam", find primary documents that contradict. Finding none is itself a result (write one line: "no counter-evidence found").
- Cross-family arbitration: the verifier/arbiter uses a model from a different family than the lanes — the point is uncorrelated blind spots, not a smarter model. Feed it only the conflict list + adversarial results, and require verbatim quotes from the originals as grounds.
- Arbitration output uses the match/addition/conflict tri-classification (same as dual-read) + for each conflict: each side's sources, dates, primacy, recommended resolution or "disputed".
- Majority vote ≠ truth: independent-source count > vote count; primary > secondary; newer > older.
5. Output format
Lane reports and the final merged deliverable both follow the pack-wide five-section shape (REPORT-CONTRACT.md): Conclusion / Findings / Verified / Not covered / Skipped. For this skill:
- Findings = the merged conclusions table (assertion | sources | date | confidence — a merge view over the lanes; the per-lane claims tables feeding it keep the full five-column contract that
claims-lint.mjschecks) + the disputed list with both sides and their sources. - Verified = load-bearing assertions traced to primary sources (each with its URL).
- Not covered =
blocked: <site> <status>items — tried, wall hit. - Skipped = sources deprioritized by the parameter block — chose not to, with the reason.
- Disputed items must be explicitly surfaced — never silently dropped. Enforce mechanically:
node <pack-root>/tools/gates/report-lint.mjs <report.md>.
Pre-delivery self-check (all must pass):
- What evidence would overturn this conclusion? Where is the adversarial lane's output row?
- Do all load-bearing assertions trace to primary sources? Are secondary-only ones marked "pending primary verification"?
- Freshness: key numbers ≤7 days, background ≤30 days; flag anything older as "stale" with a note.
- Is the "not found" list preserved verbatim? Was anything quietly deleted?
6. Anti-scrape escalation ladder (escalate in order; never retry the same rung)
On any 403/block: go up one level; do not retry the same level. Retrying is meaningless against a real block — measured: Reddit returned 403 to plain curl+UA, headless browsers, r.jina, and WebFetch alike = exit-IP-level ban; no stronger scraper gets in.
| Level | Channel | Works for | How | |
|---|---|---|---|---|
| L0 | Official API / public JSON | Sites with an API (HN Algolia, GitHub, Reddit OAuth, any .json endpoint) | Use directly. Never blocked — always first choice | |
| L1 | Index layer (bypasses live requests) | Blocked live but indexed by search engines (measured on Reddit) | The search API's site: syntax (e.g. exa.web_search_exa(query: "site:reddit.com keywords")) → titles/authors/dates/body highlights without touching the site | |
| L2 | Direct fetch / chained degradation | Ordinary static pages, light anti-bot | The fetch-hard script (real UA direct fetch → HTML-to-text → r.jina fallback) or WebFetch | |
| L3 | Change exit IP | IP-banned sites (datacenter IPs blacklisted) | Main session only: switch the proxy exit node and retry | |
| L4 | Real browser | Heavy JS rendering, login-gated material | Main session only: host browser tooling or the user's real browser (cookies intact) → save fetched content to disk and hand the text to sub-agents |
- Researchers may only use L0-L2; escalate at most one level; if still blocked → stop and mark
blocked: <site> <status>in the lane report, hand it to the main session. Never burn budget forcing it. - Channels differ per site (measured):
fetch-hardsucceeds on ordinary sites; on hard sites (Reddit, Zhihu) direct fetch and r.jina both return 403 — jina only works on ordinary sites. The cure for hard sites is the L1 index layer, not more effort at L2. - L1 returns an index snapshot (may be stale): verify key assertions via L0/L2, or mark the date column as "index time".
- Sub-agents usually have no browser tools — hard sites always go "main session fetches → saves to disk → sub-agents read".
Appendix: budget and known pitfalls (measured)
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/web-research-fanout/SKILL.md
Popularity
- Repository stars
- 54
- Repository forks
- 3
- 7-day trend score
- 20
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/ccai40359-wq/multiagents-workflow/web-research-fanout)