This is a compact Python refactor of dzhng/deep-research.
It keeps the original idea small and readable:
- Generate targeted search queries.
- Search and scrape pages with Firecrawl.
- Extract dense learnings and follow-up questions.
- Recurse with lower breadth/depth.
- Write a final Markdown report or short answer.
deep_research/
cli.py Command-line entry point.
core.py Compatibility API for direct Python imports.
agents/ Manager + Specialist research pipeline.
memory/ SQLite/FTS/vector memory, compression, and CLI helpers.
review/ Red-Blue adversarial review and JSON fallback parsing.
search.py Firecrawl search adapter.
llm.py DeepSeek/OpenAI-compatible chat client.
The orchestration lives in agents/manager.py. Specialist agents stay small:
query planning, web search, evidence extraction, gap analysis, report writing,
and lightweight critique each have their own module.
Memory code is split by responsibility: store.py handles persistence
operations, schema.py owns SQLite setup, fts.py owns search query escaping,
embeddings.py owns the local vector index, and compressor.py prepares compact
context for long research runs.
python -m venv .venv
source .venv/bin/activate
pip install -e .
cp .env.example .envFill in .env:
DEEPSEEK_API_KEY=...
SEARCH_PROVIDER=duckduckgoOptional settings:
DEEPSEEK_MODEL=deepseek-v4-flash
DEEPSEEK_BASE_URL=https://api.deepseek.com
SEARCH_PROVIDER=duckduckgo # duckduckgo or firecrawl
SEARCH_CONCURRENCY=2
SEARCH_RESULTS_PER_QUERY=8
DUCKDUCKGO_BASE_URL=https://html.duckduckgo.com/html/
FIRECRAWL_BASE_URL=https://api.firecrawl.dev
FIRECRAWL_API_VERSION=v2
FIRECRAWL_API_KEY=... # only required when SEARCH_PROVIDER=firecrawl
CONTEXT_SIZE=128000
MAX_RESEARCH_BREADTH=8
MAX_RESEARCH_DEPTH=4
DEFAULT_RESEARCH_MODE=reportInteractive:
deep-researchNon-interactive:
deep-research "Compare LangGraph and CrewAI for production research agents" \
--breadth 4 \
--depth 2 \
--mode report \
--output report.mdFor a concise answer:
deep-research "Which model won the latest Deep Research Bench?" --mode answerRun the FastAPI web app:
deep-research-web --host 0.0.0.0 --port 8000Then open http://127.0.0.1:8000/. The ChatGPT-style frontend creates
research jobs with POST /api/research/jobs and reconnects to
GET /api/research/jobs/{job_id}/stream, while the backend runs the same
Manager + Specialist research pipeline used by the CLI.
- DeepSeek is the default LLM provider. The default model is
deepseek-v4-flash. - Use
DEEPSEEK_MODEL=deepseek-v4-proif you want the stronger model. OPENAI_API_KEYcan also be provided asOPENAI_KEYfor compatibility with the TypeScript project.CUSTOM_MODELis also honored; it takes precedence overOPENAI_MODEL.- Firecrawl v2 is the default. Set
FIRECRAWL_API_VERSION=v1if you use an older Firecrawl server.
The project includes a lightweight benchmark for research-agent quality. The built-in ResearchBench currently has 35 cases across 11 domains, plus a 12-case Hotpot-style suite for multi-hop evidence-chain research. It tracks report grounding, citation coverage, evidence volume, source diversity, failure recovery, Red-Blue review score, and optional LLM-as-Judge scores.
List built-in cases:
python3 -m deep_research.bench.cli list
python3 -m deep_research.bench.cli list --suite hotpotRun a small smoke benchmark:
python3 -m deep_research.bench.cli run --limit 2 --breadth 2 --depth 1Run the full built-in benchmark:
python3 -m deep_research.bench.cli run --breadth 2 --depth 1Run the Hotpot-style multi-hop suite:
python3 -m deep_research.bench.cli run --suite hotpot --breadth 2 --depth 1Run every built-in case:
python3 -m deep_research.bench.cli run --suite all --breadth 2 --depth 1Enable five-dimensional LLM-as-Judge scoring:
python3 -m deep_research.bench.cli run --limit 2 --breadth 2 --depth 1 --judgeOutputs are written to bench/reports/:
eval_results.jsonl
eval_report.md
drb_*.md
Summarize or compare experiments:
python3 -m deep_research.bench.cli summarize bench/reports/eval_results.jsonl
python3 -m deep_research.bench.cli compare baseline.jsonl candidate.jsonlPreset experiments:
python3 -m deep_research.bench.cli experiment smoke
python3 -m deep_research.bench.cli experiment full
python3 -m deep_research.bench.cli experiment hotpot
python3 -m deep_research.bench.cli experiment memory_ab
python3 -m deep_research.bench.cli experiment regression
python3 -m deep_research.bench.cli experiment stressmemory_ab runs two variants by default, memory_on and memory_off, then
prints the delta and Cohen's d. For a single variant:
python3 -m deep_research.bench.cli experiment memory_ab --memory-mode off