Install
$ agentstack add skill-nraford7-deep-research-deep-research ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ● Shell / process execution Used
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Deep Research
Five-model parallel deep research (Claude + ChatGPT + Perplexity + Gemini + Grok) with domain scoping, adversarial cross-validation, mechanical citation verification, and optional iterative deepening. Each model gets the same topic but a differentiated research strategy matching its strengths. Produces a single, fact-checked, fully-cited reference document — a "Research Bible."
Prerequisites
API keys — set whichever you have. The dispatcher auto-detects available keys and only calls models you've configured:
ANTHROPIC_API_KEY # Claude Opus (claude-opus-4-20250514)
OPENAI_API_KEY # OpenAI GPT-4.1
PERPLEXITY_API_KEY # Perplexity Deep Research (sonar-deep-research)
GOOGLE_API_KEY # Gemini 2.5 Pro
XAI_API_KEY # Grok 3 (grok-3-latest)
SEMANTIC_SCHOLAR_KEY # Optional — raises rate limit for lit_search.py
CONTACT_EMAIL # Optional — joins OpenAlex/Crossref "polite pool"
No key = that model is skipped with a notice. At least one key required. More models = better cross-validation.
Providers can also be defined in TOML (see [Provider/Agent Config](#provideragent-config-toml)) for arbitrary OpenAI-compatible endpoints — without touching your environment.
Python packages:
pip install -r requirements.txt
Provider/Agent Config (TOML)
The dispatcher uses two independent axes of configuration:
- Providers — LLM engines. Each provider has
api_type(openai/anthropic/gemini),api_key(inline key) orapi_key_env(name of an environment variable holding the key — use this to avoid embedding secrets in TOML),base_url(for OpenAI-compatible endpoints),model,max_tokens,capabilities(e.g.["web_search"]),pricing,fallback_models, andmax_concurrency. - Agent types — Research strategies. Five are built-in (
academic,practitioner,real-time,grey-literature,contrarian). Each has astrategyprompt and an optionalprovideroverride. Agent types are remappable and extensible.
Config discovery order (later overrides earlier):
~/.config/deep-research/config.toml./deep-research.toml
TOML config augments ~/.env — built-in providers still activate automatically when their env-var API key is set. TOML entries add new providers or override existing ones; you do not need to re-specify built-ins unless you want to change their model or settings.
Inline API keys are supported in TOML — see config.toml.example at the repo root. Copy it to ./deep-research.toml or ~/.config/deep-research/config.toml and fill in your keys. Both paths are gitignored.
[defaults] table — names providers for one-off, non-strategy calls. Currently used by Round 0 scoping (scope.py --use-llm):
[defaults]
utility = "claude-sub" # provider for one-off calls (scoping)
# synthesis = "claude-sub" # reserved for future reasoning/synthesis rounds
Resolution order (config.pick_provider): [defaults]. provider if configured → first available of claude-sub, claude, chatgpt → any configured provider → fall back to rule-based. Prefer a cheap or subscription provider here; a web-search provider (e.g. Perplexity) would spend its per-search budget on a trivial JSON call.
config.py is the single control point for provider resolution in the shipped pipeline scripts: both Round 1 dispatch (dispatch.py, via load_config + the agent-type assignment) and Round 0 scoping (scope.py, via pick_provider on the [defaults].utility role) load their providers through it. The [defaults] role-resolution above is used for the one-off scope.py call, not by dispatch.py (which maps agent types to providers). Note: Rounds 2–4 reasoning runs on the Claude Code session's own subagents and is outside these scripts.
> Model-ID drift warning: Provider model IDs change. For example, DeepSeek legacy IDs deepseek-reasoner and deepseek-chat retire 2026-07-24 in favour of deepseek-v4-*; GLM model IDs also shift. Always verify the current ID in the provider's docs. max_tokens must stay within each model's output cap — exceeding it causes a 400 error.
CLI / subscription providers (api_type = "cli")
Providers can run a local CLI tool — claude -p or codex exec — that authenticates via your SSO subscription (Claude Pro/Max, ChatGPT) rather than a paid API key. No per-token cost.
Config fields:
| Field | Required | Notes | |---|---|---| | api_type | yes | "cli" | | command | yes | Binary name or path ("claude", "codex"). Provider is skipped if the binary is not on PATH. | | model | no | Passed as --model to the CLI. Omit to use the CLI's own default. | | extra_args | no | List of extra flags passed verbatim to the CLI (e.g. ["--allowedTools", "WebSearch", "WebFetch"] to enable read-only live web search). | | capabilities | no | Same as other providers — set ["web_search"] only if the CLI can deliver live results (see caveat below). | | max_concurrency | no | Throttle concurrent invocations. |
No api_key or api_key_env is needed or used.
Auth — key scrubbing: call_cli removes ANTHROPIC_API_KEY and OPENAI_API_KEY from the subprocess environment before invoking the binary, so the CLI falls back to subscription auth rather than charging a metered API key.
How each CLI is invoked:
claude:claude -p --system-prompt [--model M] [extra_args...], prompt via stdin.codex:codex exec [--model M] [extra_args...], system prompt prepended to stdin (codex has no dedicated system-prompt flag).- Any other binary:
[extra_args...], system prompt prepended to stdin.
Tool-use caveat (real-time agent type): claude -p blocks tools by default — a live run shows "WebSearch is blocked in the current permission mode". A cli provider mapped to the real-time agent type will therefore return knowledge-cutoff results, not live web search, unless you explicitly opt in via extra_args.
Recommended — read-only web search:
extra_args = ["--allowedTools", "WebSearch", "WebFetch"]
capabilities = ["web_search"]
This enables live web search without Bash/Edit/Write access. Combined with capabilities = ["web_search"], the provider becomes eligible for the real-time agent type — so you can run the real-time pass using a Claude Pro/Max subscription at $0 API cost instead of Perplexity.
Nuclear option (not recommended for unattended subprocesses):
extra_args = ["--dangerously-skip-permissions"]
This also enables live web search, but additionally enables Bash, Edit, Write, and other tools in your current working directory. Avoid for an automated subprocess you don't want touching your filesystem.
Perplexity's sonar-deep-research model is still stronger for live research; the subscription route is the tradeoff of cost ($0) against depth.
Cost display: cli providers show subscription — no metered API cost in the pre-flight estimate; their contribution to the Round 1 total is $0.
Example:
[providers.claude-sub]
api_type = "cli"
command = "claude"
# model = "claude-opus-4-20250514"
extra_args = ["--allowedTools", "WebSearch", "WebFetch"] # read-only web; no Bash/Edit/Write
capabilities = ["web_search"] # makes it real-time-eligible
[agents.academic]
provider = "claude-sub" # route academic agent through subscription, saving API cost
[agents.real-time]
provider = "claude-sub" # live web search at $0 — Perplexity sonar-deep-research is
# stronger, but this is a free alternative
When to Use
- User asks for deep research, comprehensive analysis, or evidence-based report on a topic
- User says
/deep-research [topic] - User needs a literature review, state-of-knowledge summary, or authoritative reference
- Any research task where accuracy, citation quality, and completeness matter more than speed
Architecture: Six Rounds
Round 0 DOMAIN SCOPING (rule-based + optional LLM)
↓
Round 1 MULTI-MODEL RESEARCH (parallel)
┌─ Claude ── Academic deep dive
├─ ChatGPT ── Practitioner & explainer
├─ Perplexity ── Real-time web + citations
├─ Gemini ── Grey literature & primary sources
└─ Grok ── Contrarian & cross-disciplinary
↓
Round 2 ADVERSARIAL COMPARISON + citation-laundering detection
↓
Round 3 INTEGRATION (3-planner section reconciliation, then parallel section agents)
↓
Round 4 MECHANICAL VERIFICATION (Crossref/OpenAlex resolver) + adversarial fact-check + fix pass
↓
Round 5 (optional) ITERATIVE DEEPENING — rerun weak sections, cap 2 iterations
↓
EXPORT BibTeX + claims.jsonl + refresh project-wide semantic index
↓
OUTPUT Hub-and-spoke Research Bible + BibTeX + claims.jsonl
+ project-wide semantic index spanning every topic
Round 0: Domain Scoping (NEW)
Before any models are called, run the scoping agent. It classifies the topic into a domain (medicine, law, economics, geopolitics, technology, physical sciences, social sciences) and proposes domain-specific source priorities (which databases, journals, repositories, regulatory filings to weight).
python3 scripts/scope.py \
--topic "Your topic" \
--scope "Your scope" \
--output research/[topic-slug]/round0/scope.md \
--use-llm # optional — refines with the configured utility provider
--use-llm resolves the provider via config.py: it reads [defaults].utility from your TOML, falls back to the first available of claude-sub, claude, chatgpt, then any configured provider, and falls back silently to rule-based scoping if none are available or the call fails. Previously this was hardcoded to the Anthropic API; it now runs through whichever provider you configure — including a cli/subscription provider at $0 per call.
The output is injected into every Round 1 agent prompt via --scope-file, so each agent knows which sources to weight. This is the single largest credibility upgrade in the pipeline — a generic prompt produces generic sources.
Round 1: Multi-Model Parallel Research
Step 1.1: Pre-flight cost check
python3 dispatch.py --topic "..." --scope "..." --output-dir ./round1/ \
--scope-file ./round0/scope.json \
--estimate-only
The dispatcher prints a cost estimate per agent. Round 1 alone runs $5–40 depending on which agent types are enabled; full pipeline (rounds 2–5) typically adds 50–80% on top.
Step 1.2: Dispatch with budget gate and language list
python3 dispatch.py \
--topic "Your research topic here" \
--scope "Detailed scope: what to cover, subtopics, depth, time period..." \
--output-dir ./research/[topic-slug]/round1/ \
--scope-file ./research/[topic-slug]/round0/scope.json \
--languages en,fr,de,zh \
--max-cost-usd 50 \
--resume
| Flag | Purpose | |---|---| | --scope-file | Injects Round 0 domain priorities into each agent's prompt | | --languages | Tells agents to also search non-English primary sources | | --max-cost-usd | Hard cap; aborts if estimated cost exceeds it | | --resume | Skip agent types whose output file already exists (recovers from partial failure) | | --no-confirm | Skip the interactive cost prompt | | --estimate-only | Print estimate and exit | | --agents | Run a subset of agent types, e.g. --agents academic,real-time,contrarian (default: all) |
Step 1.3: Agent types and default provider pairings
| Agent type | Default provider | Strategy | Why this pairing | |---|---|---|---| | academic | Claude (claude-opus-4-20250514) | Academic deep dive — journals, NBER, SSRN, citation chains | Best at long-form analytical synthesis | | practitioner | ChatGPT (gpt-4.1) | Practitioner & explainer — white papers, industry reports | Strong structured analysis | | real-time | Perplexity (sonar-deep-research) | Real-time web — current news, recent data, live citations | Built-in deep web search; requires web_search capability | | grey-literature | Gemini (gemini-2.5-pro) | Grey literature & primary sources — governmental, IGO, treaty | Largest context, strong document analysis | | contrarian | Grok (grok-3-latest) | Contrarian & cross-disciplinary — dissent, alternative framings | Challenges consensus |
The default provider is used when the built-in env-var key is present. Override any pairing via [agents.] provider = "..." in TOML. Add entirely new agent types the same way.
> Real-time guard: The real-time agent type requires a provider with capabilities = ["web_search"] (e.g. perplexity). If no such provider is configured, a console warning is printed and the report file is prefixed with > [no live web search — knowledge-cutoff results] so a stale answer is never silently filed under a real-time heading.
Round 1 prompt rules — encoded in dispatch.py
Every Round 1 agent prompt enforces:
- No fabrication. "Mark UNVERIFIED rather than guess."
- Date stamping. Any year/statistic/"current" claim must carry
[as of: ]. - Confidence tagging. High-stakes empirical claims get
[confidence: high/medium/low — ]. - Source preference. Primary > institutional > peer-reviewed > news > blog > wiki.
- Multilingual. If
--languagesincludes non-English, cite original-language titles.
Step 1.4: Citation supplement with Claude Code subagent
After the dispatcher completes, dispatch one additional Claude Code subagent with WebSearch/WebFetch tools to fill gaps identified in the manifest. This agent can verify URLs, fetch specific documents, and search Google Scholar — capabilities the raw API calls lack.
Dispatch a Claude Code background agent that:
1. Reads all 4-5 round1 files
2. Uses WebSearch to verify 20-30 key citations from each report
3. Fetches any URLs that other models cited but couldn't verify
4. Writes a verification overlay to round1/citation-verification.md
Output Location
[project]/research/[topic-slug]/
├── round0/
│ ├── scope.md ← Domain classification + priorities
│ └── scope.json ← Machine-readable (used by dispatch.py)
├── round1/
│ ├── agent-academic.md
│ ├── agent-practitioner.md
│ ├── agent-real-time.md
│ ├── agent-grey-literature.md
│ ├── agent-contrarian.md
│ ├── citation-verification.md
│ ├── excerpts/ ← Pre-extracted section excerpts
│ └── manifest.json ← Includes `assignments` map (agent-type → provider)
├── round2/
│ └── adversarial-comparison.md
├── round3/
│ ├── section-plans/ ← 3 independent planner outputs
│ │ ├── planner-1.md
│ │ ├── planner-2.md
│ │ ├── planner-3.md
│ │ └── reconciled-plan.md
│ ├── section-01-[topic].md
│ ├── section-02-[topic].md
│ ├── ...
│ ├── section-bibliography.md
│ └── cross-section-audit.md
├── round4/
│ ├── citation-verification.md ← From scripts/verify_citations.py
│ ├── tier-report.md ← From scripts/classify_sources.py
│ ├── missing-lit.md ← From scripts/lit_search.py --compare-bib
│ ├── factcheck-*.md
│ ├── fix-log.md
│ └── [TOPIC] - Research Bible.md
└── round5/ ← optional iterative deepening
└── deepening-log.md
Graceful degradation
The dispatcher auto-detects which API keys are set and only runs those agent types. Missing providers are skipped with a notice — no errors, no failures. Even a single agent type produces useful output that feeds into Rounds 2-4. But more agent types = better cross-validation. Three or more is the sweet spot.
You can also run a subset of agent types: --agents academic,contrarian,real-time
Round 2: Adversarial Comparison
After all Round 1 agents complete, dispatch **1 adver
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: nraford7
- Source: nraford7/deep-research
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.