Best for
- User asks for "deep research", "research report", "comprehensive analysis"
- User wants a written report on a topic (not just a quick answer)
- Question requires multi-source synthesis with citations
moonlight-lupin/agent-skills/research/deep-research/SKILL.md
Autonomous multi-step deep research engine implementing an iterative Think → Search → Extract → Synthesize → Stop loop. The LLM drives every decision: what to search, what's relevant, what's missing, and when to stop. Produces a cited, magazine-quality report with inline citations, category- specific formatting, and research stats. Trigger when the user asks for "deep research", "research report on", "comprehensive analysis of", "look into X in depth", "write a report on X", or any question need
Decision brief
An autonomous, multi-step research engine that performs exhaustive information gathering and synthesis. Unlike a single websearch, this skill implements an iterative loop where the agent plans, searches, extracts, synthesizes, and decides when to stop — producing a cited report…
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/moonlight-lupin/agent-skills --skill "research/deep-research"Inspect the Agent Skill "deep-research" from https://github.com/moonlight-lupin/agent-skills/blob/78aee69209dc94cb90d5bed4fa8e2f3bfbb993ee/research/deep-research/SKILL.md at commit 78aee69209dc94cb90d5bed4fa8e2f3bfbb993ee. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
Before planning, assess whether the question is specific enough to research productively. This step prevents wasting rounds on a question that's too vague.
Before searching, break the question into a research plan. Output:
Inject the current date before any search. This is mandatory — LLMs default to training-cutoff years, producing stale queries.
Each round follows: Query → Search → Extract → Synthesize → Check Stop
Produce the final report. Minimum 800 words (scale with topic complexity).
Permission review
The documentation includes network, browsing, or remote request actions.
*Track URLs already fetched** — do not re-fetch the same URL across rounds. Maintain a mental list of analyzed URLs.The documentation asks the agent to create, modify, or delete local files.
Save each source as a numbered file in `sources/` with verbatim extractsEvidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 96/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 16 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
An autonomous, multi-step research engine that performs exhaustive information
gathering and synthesis. Unlike a single web_search, this skill implements an
iterative loop where the agent plans, searches, extracts, synthesizes, and
decides when to stop — producing a cited report with structured evidence,
source quality tiers, and explicit gaps/contradictions sections.
Inspired by PewDiePie's Odysseus project, Alibaba/Tongyi's IterResearch
approach, and the sn-deep-research evidence-structuring architecture
(OpenSenseNova/SenseNova-Skills, MIT). The full 9-role sn pipeline was
evaluated and intentionally NOT adopted — only the evidence.json layer and
refute-polarity requirement were ported, based on empirical side-by-side
testing (July 2026). See references/structured-evidence-format.md.
v1.2.0 changes (July 2026): overview-first report structure (comparison table right after executive summary), language anchoring (BCP 47), structured evidence step (3e), refute polarity requirement, source quality classification, explicit contradictions + gaps sections. Architecture diagram corrected.
v1.3.0 changes (July 2026): source quality ranking and weighting — primary (3×) > secondary (2×) > tertiary (1×). Conflict resolution by quality tier. Quality distribution check (healthy/acceptable/weak) before writing. Tertiary source overreliance pitfall. Source table now shows quality distribution summary. Prompted by user noting too many tertiary sources in the self-hosting vs API report.
v1.5.0 changes (July 2026): adaptive depth (complexity-based round caps),
optional clarification phase (Step 0), token budget awareness, numbered
citations, progressive empty-search refinement, explicit synthesis prompt
structure. Concepts adapted from DocsGPT's ResearchAgent (arc53/DocsGPT, MIT).
See references/docsgpt-concepts.md for the concept mapping.
entity-research (has sanctions screening, structured lenses)news-monitoring (has cron, dedup, multi-language)notebooklm-mode (has vault + RAG)web_search directlyweb_search + web_extractUser question
→ Step 0: Clarification (optional — assess if question is too vague)
→ Step 1: Plan (sub-questions, key topics, success criteria, category, language, complexity)
→ Step 2: Date grounding + language anchor
→ Step 3: Iterative loop (max rounds = complexity cap: simple=2, moderate=3, complex=5)
├─ 3a: Generate gap-driven queries (incl. refute queries from round 2+, empty-search refinement)
├─ 3b: Search (web_search) + fetch (web_extract)
├─ 3c: Quality filter + extraction + source quality classification + numbered citations
├─ 3d: Synthesize into cumulative research state (with token budget check)
├─ 3e: Structured evidence (optional: evidence.json for 5+ sources)
└─ 3f: Stopping check (LLM evaluates coverage + token budget)
→ Step 4: Final report (overview-first structure, see template)
→ Step 5: Stats summary
Report output order (overview-first): Executive Summary → comparison/overview table → detailed analysis per sub-question → contradictions → gaps → conclusion → source table. Readers get the answer and the at-a-glance comparison before the detailed reasoning.
Before planning, assess whether the question is specific enough to research productively. This step prevents wasting rounds on a question that's too vague.
When to clarify:
When NOT to clarify:
How: Present 1-3 short questions to the user that would narrow the scope. Keep it brief — this is a scope check, not an interview:
"Before I start researching, I'd like to clarify:
- [narrowing question 1]
- [narrowing question 2]
Please provide these details and I'll begin."
If the question is already specific, skip this step entirely and proceed to Step 1.
Before searching, break the question into a research plan. Output:
## Research Plan
Question: [user's question]
Date: [current date]
Language: [BCP 47 tag — e.g. en, zh-Hans, ja. Detect from query; user's explicit language preference overrides. Use consistently throughout the report.]
Sub-questions:
1. [specific sub-question 1]
2. [specific sub-question 2]
3. [specific sub-question 3]
4. [up to 6 total]
Key topics:
- [topic 1]
- [topic 2]
Success criteria:
- [what would comprehensive coverage look like?]
- [minimum: each sub-question has ≥1 source]
Report category: [factual | comparison | product | how-to | fact-check | explainer]
Complexity: [simple | moderate | complex]
Complexity assessment and adaptive depth: Classify the question's complexity to determine the maximum number of research rounds. This prevents over-searching simple questions and under-searching complex ones.
| Complexity | Max rounds | When to use |
|---|---|---|
| simple | 2 | Single-factual question, narrow scope, 1-2 sub-questions. Example: "What is the latest version of Python?" |
| moderate | 3 | Multi-faceted question, 3-4 sub-questions, comparison or how-to. Example: "Compare Qdrant vs pgvector for RAG" |
| complex | 5 | Broad scope, 5-6 sub-questions, requires deep synthesis across domains. Example: "Comprehensive analysis of the self-hosting vs managed API tradeoff for AI infrastructure" |
The complexity cap is a maximum, not a target. The stopping check (Step 3f) still governs early termination. A simple question that finds comprehensive answers in 1 round should stop at 1 — the cap of 2 means it can go to 2 if needed, not that it must.
Language anchoring: Detect the output language from the query and normalize to a BCP 47 tag (e.g. en, zh-Hans, zh-Hant, ja). Use it consistently throughout — executive summary, analysis, contradictions, gaps, conclusion. Source titles, URLs, proper nouns, and code may stay in their original language; search queries may use any language that helps evidence gathering. If the user explicitly switches language mid-research, update the anchor and use the new language for all subsequent output.
Report category detection:
Inject the current date before any search. This is mandatory — LLMs default to training-cutoff years, producing stale queries.
Today's date is {current date as "DD Month YYYY"}. When a search query needs a year or refers to "latest"/"current"/"this year", use {current year} or relative wording — never a year inferred from training data.
Each round follows: Query → Search → Extract → Synthesize → Check Stop
Run max N rounds where N = complexity cap from Step 1 (simple=2, moderate=3, complex=5). Most topics converge in 2-3 rounds. The cap is a ceiling, not a target.
Generate 2-4 search queries per round. Round 1 targets the sub-questions from the plan. Round 2+ targets gaps identified in the previous synthesis.
Before generating queries, review:
Generate queries that target the gaps, not repeat what's already found.
Refute polarity requirement: Round 2+ must include at least one query targeting counter-evidence, opposing viewpoints, or criticisms of the leading hypothesis. If no counter-evidence is found after searching, note it explicitly in the synthesis — refute count = 0 usually means you didn't search well, not that no counter-evidence exists. This prevents confirmation-biased research.
Progressive empty-search refinement: When a search returns no useful results, escalate the refinement strategy across consecutive empty results:
web_search(query="...", limit=10)
Run one web_search per query. From the results, pick 3-5 URLs per round to fetch in full:
web_extract(urls=["url1", "url2", "url3"])
Track URLs already fetched — do not re-fetch the same URL across rounds. Maintain a mental list of analyzed URLs.
Before extracting content, discard low-quality results:
For each quality source, extract goal-relevant facts:
[1], [2], etc. on first encounter — reuse the same number for subsequent facts from the same source. This produces cleaner inline citations than full URLs (especially on mobile/messaging platforms) and matches academic/magazine citation style. Deduplicate by URL: the same URL seen twice gets the same number.primary (official docs, model cards, SEC filings, original papers), secondary (tech journalism, analyst reports, reviews), tertiary (Wikipedia, aggregators, forum posts). This tier appears in the final source table and signals evidence strength to the reader.Tag every material fact with the basis on which you're asserting it. A material fact is any substantive claim a reader would act on or challenge: a statistic, date, named entity or relationship, causal claim, or direct quote. This is deep-research's adaptation of pere-toolkit's canonical evidence discipline — the same four labels, applied to facts rather than financial figures.
| Label | A fact is [LABEL] when it is… |
|---|---|
[VERIFIED] | corroborated across ≥2 independent, cited, dated sources |
[SOURCED] | stated by one named / cited source, not independently corroborated |
[REASONED] | your own analytical judgement or inference — not stated by any source |
[ESTIMATED] | a calculation or stated assumption (e.g. a figure you derived from source data) |
Rules:
[VERIFIED] / [SOURCED]. Present [REASONED] / [ESTIMATED] claims as indicative ("likely", "suggests", "on these figures") — never as hard fact.[Official], [Expert], [Consensus] → these are [SOURCED], or [VERIFIED] only if independently corroborated).~50% [SOURCED], not 50.0%.[REASONED] guess dressed as fact.Relationship to source-quality tiers: the primary/secondary/tertiary tier (above) classifies the source; the [VERIFIED]/[SOURCED]/[REASONED]/[ESTIMATED] label classifies the fact. They are orthogonal: a fact from a single primary source is [SOURCED] (strong source, but uncorroborated); the same fact from two independent primary sources becomes [VERIFIED]. Use both: tier in the source table, label inline on each claim.
After extracting from all sources in the round, integrate findings into the cumulative research state:
Token budget awareness: Track approximate context consumption across rounds. If the cumulative research state + extracted content is approaching the model's context window or a self-imposed budget (suggested: ~50K tokens for moderate, ~100K for complex), prioritize synthesis and stopping over gathering more sources. When the budget is tight, summarize earlier rounds' findings more aggressively rather than carrying full extracts forward.
Rough estimation heuristic: You can't count tokens precisely, but you can estimate: each web_extract returning ~5K characters contributes ~1.5K tokens; the research state after N rounds with 3-5 sources per round is roughly N × 8-12K tokens. If you're on round 3+ of a complex topic and the last web_extract returned >10K characters, you're likely past 50K — summarize aggressively and head toward synthesis. When in doubt, treat any round-3+ complex research as budget-tight.
## Research State (after Round N)
[evolving synthesis of all findings so far]
### Sub-question 1: [question]
Status: [answered / partially answered / unanswered]
Findings: [synthesized facts, each with a numbered inline citation [N] matching the source table, and an evidence-basis tag, e.g. "adoption grew 40% in 2025 [1] [VERIFIED]"]
### Sub-question 2: [question]
Status: [...]
Findings: [...]
### Gaps identified:
- [what's still missing for round N+1 to target]
Synthesis rules:
[N] assigned in §3c, matching the source table[VERIFIED] / [SOURCED] / [REASONED] / [ESTIMATED] (see §3c). A fact becomes [VERIFIED] only once ≥2 independent sources corroborate it; a single source is [SOURCED]. Corroboration during dedup is what promotes [SOURCED] → [VERIFIED].Before writing the final report, structure the extracted evidence into a lightweight evidence.json intermediate. This separates evidence gathering from report writing and makes fabrication detectable. See references/structured-evidence-format.md for the schema, source quality ranking/weighting rules, and worked example.
When to use: reports with 5+ sources, comparison/fact-check categories, or when the user may want to verify claims. Skip for quick 2-3 source reports.
Benefits validated in side-by-side testing (July 2026):
Source quality ranking and weighting (see references/structured-evidence-format.md for full rules):
Quality distribution check before writing the report:
Conflict resolution by quality: When sources disagree, primary > secondary > tertiary. 2 independent secondary sources ≈ 1 primary. Tertiary cannot override secondary/primary — it becomes refute counter-evidence or writing_context instead.
After synthesis (and optional evidence structuring), evaluate whether the report is comprehensive enough:
Given the research plan's success criteria:
- Are all key sub-questions addressed with at least one source?
- Are there significant gaps or unanswered aspects?
- Is the evidence sufficient and corroborated?
- Am I approaching the token budget? (tight context = prioritize synthesis)
Reply YES (stop) or NO (continue) + one-sentence reason.
Stop if:
Continue if:
Produce the final report. Minimum 800 words (scale with topic complexity).
Output order is overview-first: the reader gets the answer and the at-a-glance comparison before the detailed reasoning. Do not bury the comparison table after the per-topic analysis.
Carry each material fact's evidence-basis tag inline (§3c), lead on [VERIFIED] / [SOURCED], keep [REASONED] / [ESTIMATED] claims framed as indicative, and paste the Evidence key legend below the Sources table so the tags decode.
Synthesis prompt structure: When writing the final report, explicitly consult: (1) the original question, (2) the research plan (sub-questions, success criteria), (3) the cumulative research state from all rounds, (4) the evidence.json if produced, and (5) the numbered source list. Do not rely on the cumulative state alone if it has been compressed across many rounds — go back to the per-round findings to verify key claims. This prevents detail loss when the research state was aggressively summarized due to token budget pressure.
# [Report Title]
> **Research date:** [date] · **Rounds:** [N] · **Sources:** [N] · **Category:** [type]
## Executive Summary
[2-3 paragraph overview of key findings — the answer up front. If using structured evidence, note claim count and refute count here so the reader knows the evidence base.]
## [Comparison Table | Overview | Key Findings at a Glance]
[For comparison reports: a markdown table comparing options/entities across criteria. For factual/explainer reports: a numbered list of key findings with claim references. This section gives the reader the complete picture in one screen — the detailed analysis below is the supporting reasoning, not the main event. If using structured evidence, cite claim IDs like [c1], [c3] in table cells or list items.]
## [## Section per sub-question]
[Detailed analysis with inline citations — this is the supporting reasoning for the overview above. Each section traces back to the overview claims.]
### [### Subsections as needed]
[...]
## Contradictions
[If sources disagree, present both sides with attribution. Do not silently arbitrate. If no contradictions found, state "No direct contradictions between sources." This section is REQUIRED — its absence is a quality signal that counter-evidence wasn't searched.]
## Gaps
[What couldn't be determined from available sources. Each gap should note: what's unknown, why it matters, and whether it could be resolved with more research. If using structured evidence, reference the writing_context items. If no gaps, state "No significant gaps identified."]
## Conclusion
[Synthesis of findings, implications, remaining uncertainties — ties back to the executive summary and overview. The conclusion confirms or qualifies the overview, it doesn't introduce new analysis.]
---
## Sources
**Quality distribution:** [N] primary · [N] secondary · [N] tertiary — [healthy/acceptable/weak]
| # | Title | URL | Quality | Accessed |
|---|-------|-----|---------|----------|
| 1 | [title] | [url] | primary/secondary/tertiary | [date] |
**Citation format:** Inline citations use `[N]` matching the source table above. On first mention of a source, include `[N]` — subsequent mentions may use `[N]` alone. For claims from the same source, cite the number once per paragraph unless the source is paginated.
**Evidence key** — `[VERIFIED]` corroborated across ≥2 independent, cited, dated sources · `[SOURCED]` from one named source, not independently corroborated · `[REASONED]` analytical judgement / inference · `[ESTIMATED]` calculation or stated assumption.
| Category | Overview section format |
|---|---|
| comparison | Markdown table comparing options across criteria, with a verdict row or column. The detailed sections below provide the reasoning per option. |
| product | Ranked list with pros/cons, price range, and a "top pick" callout. Detailed sections cover each product. |
| how-to | Numbered overview of the steps. Detailed sections cover prerequisites, execution, and troubleshooting per step. |
| fact-check | Evidence for/against the claim in a two-column table, with a preliminary verdict. Detailed sections assess source credibility and reasoning. |
| explainer | Numbered key findings or a "progressive depth" overview (simple → deep). Detailed sections go deeper per concept. Glossary if technical. |
| factual | Numbered key findings with claim references. Detailed sections provide the supporting evidence per finding. |
If LLM synthesis fails (timeout, error, garbled output), compile raw findings into a basic report:
After the report, output a compact stats block:
---
📊 Research stats: [duration] · [N] rounds · [N] queries · [N] URLs fetched · [N] sources cited
When the research report covers a real estate or investment question and the
user subsequently provides specific deal parameters (price, area, location),
build a quantitative pro-forma using execute_code. The pattern:
Critical: Always model the as-is use case as a baseline. If the alternative-use NOI exceeds the converted-use NOI, the conversion destroys value at that acquisition price — say so clearly.
See references/real-estate-investment-analysis.md for the full template,
Japan-specific data sources, renovation cost benchmarks, and cap rate ranges.
See references/structured-evidence-format.md for the evidence.json schema,
claim rules, writing-context vs claims distinction, and the side-by-side test
results that validated the structured-evidence approach (July 2026).
For larger research tasks (10+ sources) or when the user may want to follow up with grounded Q&A:
notebooklm-mode at <project_folder>/research-<topic>/sources/ with verbatim extractsingest_source.py to write + index atomicallyThis is optional — the skill works fully without a vault for one-off reports.
For genuinely parallel research across distinct sub-topics (e.g. researching 3 unrelated companies):
delegate_task(
goal="Research [sub-topic] as part of a deep-research project. Run web searches, extract content, and return findings with source URLs and titles.",
context="You are a research subagent. Topic: [sub-topic]. Sub-questions: [list]. Use web_search and web_extract. Return structured findings with citations.",
toolsets=["web"]
)
Rules:
web_extract fails on a URL, note it and move on — don't retry endlesslyweb_search returns no results, apply the progressive empty-search refinement protocol (§3a) — first try broader keywords, then a fundamentally different angle, then move on[N] matching the source table, or (Source: URL, "Title") for claims from sources not in the numbered table.[VERIFIED]/[SOURCED]/[REASONED]/[ESTIMATED] tag is half-graded. Tag it, and include the Evidence key so the tags decode.[Official], [Confirmed], or [Consensus] breaks the discipline; map it to one of the four.[VERIFIED], and don't restate precision the source didn't give. When torn between two labels, pick the weaker one.[REASONED] guess dressed as a sourced fact.Odysseus — PewDiePie's self-hosted AI workspace — includes a "Deep Research" feature with multi-step web research and source reading, conceptually similar to this skill's Think → Search → Extract → Synthesize → Stop loop. This skill is a pure-prompt workflow (no UI, no server) designed to run inside any agent's tool loop.
DocsGPT (arc53, MIT) — Private AI platform with a ResearchAgent (application/agents/research_agent.py) that implements a Plan → Research → Synthesize pipeline with adaptive depth (complexity caps), clarification phase, token budget tracking, citation deduplication, and progressive empty-search refinement. v1.5.0 of this skill adapted these concepts from DocsGPT's ResearchAgent; see references/docsgpt-concepts.md for the mapping.
evals/routing-fixtures.json holds lightweight contract fixtures — sample
request → expected routing (including when a request should go to
entity-research / notebooklm-mode / news-monitoring instead), required
output fields, and forbidden output patterns. They are specs, not run against a
live model; the repo-root tests/test_routing_fixtures.py validates they stay well-formed and
route to real skills.
Frequently asked questions
An autonomous, multi-step research engine that performs exhaustive information gathering and synthesis. Unlike a single websearch, this skill implements an iterative loop where the agent plans, searches, extracts, synthesizes, and decides when to stop — producing a cited report…
The source record exposes this install command: npx skills add https://github.com/moonlight-lupin/agent-skills --skill "research/deep-research". Inspect the command and pinned source before running it.
Static rules flagged network, write-files in the source; the page lists the matching lines and excerpts.
Alternatives
brucesongs/kali-claw
Multi-source intelligence gathering through systematic web research — producing thorough, cited reports from diverse sources.
lovstudio/skills
Use when the user needs multi-source research with citation tracking, evidence persistence, and structured report generation. Triggers on "deep research", "comprehensive analysis", "research report", "compare X vs Y", "analyze trends", or "state of the art". Not for simple lookups, debugging, or questions answerable with 1-2 searches.
MichelKerkmeester/opencode--skilled-agent-loops-with-spec-kit-memory
Autonomous deep-research loop: iterative investigation, externalized state, convergence detection, fresh context per pass.
samber/cc-skills
Deep research skill — broad parallel web searches, multi-source validation, confidence tracking, cited Markdown report. Supports 11 research types: market (TAM/SAM, segments, pricing, trends), domain (industry structure, ecosystem, regulatory landscape), technical (architecture, tools, benchmarks), competitive (competitor teardown, positioning, win/loss), product (feature analysis, reviews, roadmap signals), academic (literature survey, citation networks, key authors), person/org (due diligence