Skip to content
artinamrPublic

About

Self-hosted recursive deep research agent in one Python file — Ollama/OpenAI-compatible LLMs, DuckDuckGo/SearXNG search, live SSE UI, cited Markdown + PDF reports.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

🔬 DeepResearch Agent

A recursive, self-hosted deep research agent in a single Python file. It plans searches, reads the web, audits its own evidence, and streams a fully-cited Markdown report to your browser — powered entirely by your models on your hardware.

License: MIT Python Docker Local-First API Fees PRs Welcome


💥 Why this exists

In 2025 the big labs started selling "deep research" as a premium feature — $200/month for the privilege of having your questions, your sources, and your thinking habits logged on someone else's server.

That's a rental. This is ownership.

🔬 DeepResearch Agent OpenAI Deep Research Perplexity Pro
Monthly cost $0 (your hardware) $200 (ChatGPT Pro) $20
Query privacy Topic & report never leave your network* Full platform telemetry Full platform telemetry
Model freedom Any GGUF via Ollama — llama3.1, qwen2.5, mistral, your fine-tune Fixed frontier models only Fixed models only
Rate limits None. Research at 3 AM if you want. Usage caps apply Usage caps apply
Citations Verbatim inline [Title](URL) from real scraped pages Yes, opaque pipeline Mixed quality
Customization The entire agent is one readable Python file Closed Closed
Works during outages ✅ Your stack, your rules ❌ ❌

* Honest disclosure: search queries are sent to DuckDuckGo or your SearXNG instance — that's how web search works for everyone, including the paid tools. Page fetching happens directly from your machine. Everything else — planning, reading, auditing, writing — touches your LLM on your hardware.

The pitch: a standard 8B model running on an 8 GB laptop can now do what used to require an enterprise subscription.


🏗️ Architecture

flowchart LR
    A["🧑‍💻 User Query"] --> B["🧠 Query Planner<br/>(LLM → 3-5 sub-queries)"]
    B --> C["🔎 Search Engine<br/>DDG / SearXNG · parallel"]
    C --> D["🕸 Async Scraper<br/>httpx + BeautifulSoup4"]
    D --> E["⚖️ Evidence Auditor<br/>sufficient? else refine"]
    E -- "gaps found · depth ≤ 2" --> B
    E -- "evidence solid" --> F["✍️ Ollama Summarizer<br/>streaming synthesis"]
    F --> G["📄 Streamed Report<br/>live SSE markdown + citations"]
    G --> H["⬇ Export .md / .pdf"]
Loading

One pass looks like this:

  1. 🧠 Plan — your local LLM decomposes the topic into 3–5 diverse, high-signal search queries.
  2. 🔎 Search — queries fan out in parallel through DuckDuckGo (or your SearXNG instance).
  3. 🕸 Read — top 3 results per query are fetched concurrently with httpx, stripped of boilerplate by BeautifulSoup4, and distilled into targeted excerpts using rarity-weighted term matching.
  4. ⚖️ Audit — the LLM judges whether the evidence is sufficient. Not convinced? It writes 2 sharper follow-up queries targeting the exact gaps and the loop recurses (depth ≤ 2).
  5. ✍️ Synthesize — a structured report (Executive Summary → Key Findings → Analysis → Gaps → Conclusion → References) streams token-by-token over Server-Sent Events, with every claim cited [Title](URL) verbatim from scraped sources.
  6. ⬇ Export — one-click .md download, or .pdf via a PDF writer built from raw bytes — no wkhtmltopdf, no headless Chrome, no extra dependencies.

Everything above streams live into the UI's agent trace: you watch it think, search, read, and change its mind in real time.


🚀 60-Second Quickstart

Option A — Docker (recommended)

Prereq: Ollama running somewhere reachable (ollama pull llama3.1).

git clone https://github.com/artinamr/DeepLocal.git
cd DeepLocal
docker compose up -d

Open http://localhost:8000 — first boot installs deps inside the container (~30 s), then it's permanent. Reports persist to ./reports on your host.

Option B — Raw Python

# 1. get it
git clone https://github.com/artinamr/DeepLocal.git
cd DeepLocal
python -m venv .venv && source .venv/bin/activate    # optional but polite

# 2. install 5 packages — that's the whole dependency tree
pip install fastapi uvicorn httpx beautifulsoup4 duckduckgo-search

# 3. point it at your brain
ollama pull llama3.1

# 4. launch
python app.py

Open http://127.0.0.1:8000, type a question like "How will solid-state batteries reshape EV economics by 2030?", hit Launch, and watch the recursion happen.

Already running LM Studio / vLLM / LiteLLM / any OpenAI-compatible server?
export OPENAI_BASE_URL=http://localhost:1234/v1   # LM Studio example
export OPENAI_MODEL=qwen2.5-14b-instruct
python app.py

No key needed for local servers — just leave OPENAI_API_KEY unset and it won't be sent.


🖥 System Requirements

Deliberately modest. If it can run a chat model, it can run this agent.

Setup Total RAM Suggested Model Experience
Minimum 8 GB llama3.1:8b (Q4_K_M ≈ 4.9 GB) Fully working; CPU inference is slower but coherent
Comfortable 16 GB llama3.1:8b Q8, qwen2.5:14b Q4 Fast planning + crisp citations
Luxury 32 GB+ / 12 GB VRAM GPU qwen2.5:32b, llama3.1:70b split Analyst-grade prose

The agent itself: ~150 MB of Python process memory. No database, no Redis, no browser binaries, no message queue. The web UI is embedded in the single file and served straight from FastAPI.

Component Requirement
OS Linux, macOS, Windows (WSL2)
Python 3.11+ (raw install only)
Docker Any recent engine (compose route only)
LLM backend Ollama or anything speaking OpenAI's /chat/completions
Outbound net HTTPS to search engine + pages you ask it to read

⚙️ Configuration

Every knob is an environment variable with a sane default. Zero config = working out of the box with Ollama.

Variable Default What it does
LLM_PROVIDER auto (ollama, falls back per below) Force ollama or openai
OLLAMA_BASE_URL http://localhost:11434 Ollama endpoint
OLLAMA_MODEL llama3.1 Any Ollama model tag
OLLAMA_NUM_CTX 8192 Context window handed to Ollama — raise for long reports
OPENAI_BASE_URL https://api.openai.com/v1 Point at LM Studio / vLLM / LiteLLM / Groq…
OPENAI_API_KEY (unset) Setting this (or base URL) switches provider to openai
OPENAI_MODEL gpt-4o-mini Model name for the compatible endpoint
SEARXNG_URL (unset) e.g. http://localhost:8888 — used before DDG, great for meta-search self-hosters
REPORTS_DIR (unset) When set, every finished report is archived here as .md
HOST / PORT 127.0.0.1 / 8000 Bind address

📁 Report Archival

Mount a directory and set REPORTS_DIR (the bundled docker-compose.yml does this automatically):

reports/
├── 20250112-093014-solid-state-batteries-ev-economics-a1b2c3d4.md
├── 20250112-104438-compare-vector-databases-rag-e5f6a7b8.md
└── ...

Every mission also stays downloadable in-browser until restart via /api/report/{id}.md and /api/report/{id}.pdf.


🌐 Behind a Reverse Proxy?

SSE needs buffering disabled:

location / {
    proxy_pass http://127.0.0.1:8000;
    proxy_buffering off;          # critical for live streaming
    proxy_cache off;
    proxy_set_header Connection '';
    proxy_http_version 1.1;
}

The app already sends X-Accel-Buffering: no, which Caddy Traefik and friends respect out of the box.


🗺 Roadmap

  • Multi-model crews (planner ≠ writer)
  • Per-mission model picker in the UI
  • SearXNG JSON instances bundled as a second compose service
  • EPUB export
  • Optional auth layer for exposed instances

🤝 Contributing

The whole project is one file on purpose — readable top-to-bottom in one sitting. PRs that keep it that way are merged fast.

📜 License

MIT — do whatever you want, build companies on it, just keep the notice.


If a $200/mo subscription was your only option for deep research, it wasn't — star this repo and run your own. ⭐

Built with FastAPI · AsyncIO · httpx · BeautifulSoup4 · duckduckgo-search · and whatever GGUF you love

About

Self-hosted recursive deep research agent in one Python file — Ollama/OpenAI-compatible LLMs, DuckDuckGo/SearXNG search, live SSE UI, cited Markdown + PDF reports.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages