Open Deep Research is an agentic AI-powered research tool that operates on local PDF and Markdown document corpora (not the open internet). Given a research question, it orchestrates AI agents to exhaustively evaluate, synthesize, and verify information, producing a Markdown report with inline citations.
Built on the OpenAI Agents SDK, compatible with OpenAI, Ollama, vLLM, or any OpenAI-compatible API endpoint.
Session memories and user preferences are stored in memory/ at the project root. See @MEMORY.md for the index.
- Python >= 3.12
- uv package manager
uv venv --python=3.12
source .venv/bin/activate
uv pip install -r requirements.txtCopy .env.example to .env and configure:
OPENAI_API_KEY- API key for the model serverOPENAI_BASE_URL- Base URL (default: OpenAI, or set to local server)ODR_MODEL- Model name (default:gpt-oss-120b)
python example.pyEdit the question variable in example.py (~line 51) to change the research question. Set corpus_dir (~line 36) to point at your document directory.
The system uses a programmatic pipeline (not LLM-driven handoffs) for reliability with local models. Four stages:
- Manager Agent (
research/manager.py) -- Decomposes the question into sub-questions viasubmit_plantool - Exhaustive Scanner (
research/exhaustive_scanner.py) -- Evaluates every corpus chunk against all sub-questions using batch LLM calls. Optional BM25 prefilter for faster debugging. - Synthesis Pipeline (
research/synthesis_agent.py+research/pipeline.py):- 3a. Synthesis Manager plans report outline, assigns citation IDs to sections
- 3b. Section Writer writes each section with its assigned evidence
- 3c. Assembly concatenates sections + references
- Evaluation Probes (
probes/) -- LM-judge evaluators run after each section, scoring quality. Results stored onSectionResult.probe_results.
All agents share a ResearchContext (research/context.py) with immutable ResearchInfrastructure and mutable ResearchState.
Detailed references: @docs/pipeline.md (pipeline flow, modules, tools, persistence), @docs/models.md (data models, context), @docs/probes.md (probe registry, design patterns, planned probes).
- Tracing is disabled (
set_tracing_disabled(True)) inexample.py - No telemetry sent to external services
- Only communicates with configured
OPENAI_BASE_URLendpoint
- Use async/await throughout (all agents and tools are async)
- All data models use Pydantic BaseModel with type hints
- Configuration via environment variables with
ODR_prefix - Use
uvfor dependency management, not pip directly - Deterministic chunk IDs derived from
doc_idandchunk_index src/is added tosys.pathinexample.py-- no pip install needed for imports