Skip to content

About

DeepResearch-Full

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

DeepResearch Lite

A lightweight, English-first multi-agent research assistant: give it a question, it drafts a research plan for your approval, searches the web, reflects on what is missing, and writes a cited report — streaming every step to the browser.

Built with LangGraph (agent orchestration) + FastAPI (API and SSE) + React 19 / Vite / Tailwind (UI).

Why "Lite"? This is a deliberately stripped-down edition of a larger enterprise DeepResearch system. Authentication, the PostgreSQL user store and the operational scaffolding were removed so the whole pipeline fits in one repository you can read in an afternoon. See docs/en/adr/006-lite-edition-scope.md for exactly what was kept and what was dropped, and why.


Table of contents


How it works

The pipeline is three composable stages, each an independently testable LangGraph subgraph:

Stage Nodes What happens
1. Plan (human-in-the-loop) generate_plan → evaluate_plan → confirm_plan / replan / awaiting_plan_confirmation The agent turns your question into a structured research plan and stops. Nothing is searched until you confirm (Confirm plan). Unconfirmed plans are routed back to replan.
2. Research (subgraph) generate_queries → web_search (fan-out, one per query) → critique → loop Queries are generated, searched in parallel via Send() fan-out, then a reflection step decides whether the evidence is sufficient. If not, it loops with follow-up queries until max_research_loops.
3. Write (subgraph) outline → draft ⇄ critic_review → cite_and_polish An outline is drafted, each section written, a critic scores the draft and can send it back for revision (bounded by max_revisions), then citations are resolved and the report is polished.

Every node transition and every streamed token is published to a resumable SSE stream, so the browser shows live progress and can reconnect without losing events.

Architecture

Main graph overview

Diagram What it shows
main_graph_overview.png All four execution lanes, the HITL pause and the shared state
research_subgraph.png generate_queries → parallel web_search → critique loop
writer_subgraph_with_review.png outline → draft ⇄ critic_review → cite_and_polish
human_in_the_loop.png Run 1 pauses; run 2 resumes the same thread as confirmed
basic_graph.png The straight-through chain with each node's role
multi_agent_graph.png The three agents, their prompts and the shared OverallState

Runtime sketch

Browser (React 19 + Vite)
   │  POST /api/research ─────────────► FastAPI custom app  (backend/src/agent/app.py)
   │  GET  /api/research/{id}/stream ◄── resumable SSE (events carry their Redis stream id)
   ▼
Redis Streams  ──►  background worker  ──►  LangGraph graph  (checkpointed in Redis)
 (task queue)         (single coroutine)      │
                                              ├─ LLM: any OpenAI-compatible endpoint
                                              ├─ Web search: Exa  (or DashScope MCP app)
                                              ├─ Cache: Redis (per-query search cache)
                                              └─ Knowledge base: Milvus (optional) + embeddings

Quick start

Prerequisites: Python 3.11+ (3.13 tested) · Node 20+ (24 tested) · a running Redis (task queue, search cache and LangGraph checkpoints).

1. Backend

python3.13 -m venv .venv
cd backend
../.venv/bin/python -m pip install -e ".[dev]"        # Windows: ..\.venv\Scripts\python.exe
cp .env.example .env                                  # then fill in your keys

Start Redis if you don't have one running:

docker run -d --name deepresearch-redis -p 6379:6379 redis:7-alpine

Then launch the backend from backend/:

# Linux / macOS
PYTHONUTF8=1 ../.venv/bin/langgraph dev --no-browser --no-reload --allow-blocking

# Windows (cmd)
set PYTHONUTF8=1
..\.venv\Scripts\langgraph.exe dev --no-browser --no-reload --allow-blocking

Windows note — PYTHONUTF8=1 is required. langgraph-api reads its bundled OpenAPI spec with the active code page; on systems using a legacy code page (e.g. cp932) startup dies with UnicodeDecodeError before the server binds. The repo-root wrappers run_backend.bat / run_backend.sh set it for you.

The backend serves http://127.0.0.1:2024 — the custom API plus LangGraph Studio at https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024.

2. Frontend

cd frontend
npm install
npm run dev            # http://localhost:5173/

/api, /threads, /runs and /assistants are proxied to http://127.0.0.1:2024 (override with BACKEND_URL=... npm run dev). On Windows you can double-click run_backend.bat and run_frontend.bat instead.

3. Ask something

Open http://localhost:5173/, enter a question, pick effort and model, then send. When the plan appears, review it and press Confirm plan to start the research run.

Configuration

All backend settings live in backend/.env (see .env.example for the annotated template).

Variable Required Purpose
APP_TOKEN yes API key for your LLM endpoint
LLM_BASE_URL yes Any OpenAI-compatible base URL (default: https://api.deepseek.com)
AVAILABLE_MODELS yes JSON array of models offered to the UI. Every model_id must exist on your endpoint — the first entry is the default, the middle one is used for reflection
EXA_API_KEY recommended Web search via Exa. When set, it takes precedence
MCP_APP_ID fallback DashScope MCP web-search application, used when no Exa key is configured
REDIS_URL yes Task queue, event streams, search cache and checkpoints
WEB_SEARCH_MAX_QPS no Client-side search throttle (default 12)
MILVUS_URI, EMBEDDING_* no Knowledge base. Without it the KB silently degrades and the pipeline still runs
KB_LIFECYCLE_MODE no off / inform / freshness (default) / lifecycle — freshness filtering and confidence decay
RERANKER_* no Optional cross-encoder reranking (disabled by default)
QUERY_GENERATOR_MODEL, REFLECTION_MODEL, ANSWER_MODEL no Pin a model per stage instead of deriving it from AVAILABLE_MODELS

Using the app

  1. Ask — type a research question and choose an effort level (low/medium/high map to different initial_search_query_count / max_research_loops).
  2. Review the plan — the plan is not a formality: research does not start until you press Confirm plan, and you can keep the conversation going to refine it.
  3. Watch it work — the activity timeline shows each node (Generating plan, Web research, Reflection and analysis, Generating outline, Writing draft, Polishing and adding citations, Finalizing answer) with streamed tokens.
  4. Read the report — the final answer arrives as Markdown with resolved source links.

Quality gates

Every gate below is enforced in .github/workflows/ci.yml:

cd backend
../.venv/bin/python -m ruff check .            # lint — currently clean
../.venv/bin/python -m pytest test -q          # 296 passed, 4 skipped
../.venv/bin/python ../scripts/check_no_cjk.py # English-only gate
cd ../frontend && npx tsc -b && npm run build  # typecheck + production build
  • Hermetic tests — the suite mocks LLM, search, Redis and Milvus, so it runs with no infrastructure (verified with Redis deliberately unreachable).
  • English-only gate — scripts/check_no_cjk.py walks every shipped text file and fails if any CJK character survives, with docs/zh-CN/ and README.zh-CN.md as the only bilingual exceptions.
  • Language contract — prompts are English and carry an explicit "always write your output in English" instruction, so reports stay English regardless of input language.

Design decisions

The reasoning behind the non-obvious choices is recorded as ADRs in docs/en/adr/:

ADR Decision
001 LangGraph + a pluggable tool stack instead of a bespoke agent loop
002 Pause for plan confirmation before spending search/LLM budget
003 Split the monolith into independently testable subgraphs
004 Classify failures (transient vs permanent) and retry only what can succeed
005 Redis Streams task queue with a resumable SSE contract
006 What this edition drops (auth, PostgreSQL) and why

Project layout

DeepResearchLite/
├── backend/
│   ├── src/agent/
│   │   ├── app.py                # FastAPI app: /api/models, /api/research, SSE stream
│   │   ├── graph.py              # main graph: plan phase + HITL routing
│   │   ├── sub_agents/           # research_agent (query→search→reflect), writer_agent
│   │   ├── base_agent.py         # Agent / JsonAgent / WebSearchAgent / ExaSearchAgent
│   │   ├── task_queue.py         # Redis Streams queue, worker, resumable event stream
│   │   ├── prompts.py            # all prompt templates (English)
│   │   ├── configuration.py      # runtime configuration + model selection
│   │   ├── search_cache.py       # per-query Redis cache
│   │   ├── reranker.py           # optional cross-encoder reranking
│   │   └── kb/                   # optional Milvus knowledge base (facts + lifecycle)
│   ├── eval/                     # optional LLM-as-judge benchmark harness
│   ├── test/                     # 300 tests
│   └── pyproject.toml            # deps + ruff/pytest config
├── frontend/src/                 # React UI: plan confirmation, timeline, streamed report
├── docs/
│   ├── diagrams/                 # English architecture diagrams (generated by scripts/)
│   ├── en/adr/                   # architecture decision records
│   └── zh-CN/                    # Chinese long-form docs (bilingual exception)
├── scripts/
│   ├── check_no_cjk.py           # English-only gate
│   └── render_graph_diagrams_en.ps1
├── run_backend.bat / .sh         # one-command startup
└── run_frontend.bat / .sh

Limitations and roadmap

Honest list — these are the things a reviewer should know before running it:

  • Single-user by design. No accounts, no per-user isolation; the API is meant to run on localhost. Do not expose it to the internet as-is.
  • Redis is required for the task queue, event streams, search cache and checkpoints.
  • The knowledge base is optional and off the happy path. Without Milvus the KB layer degrades silently; enabling it also requires an embedding endpoint. It has not been exercised end-to-end in this edition.
  • Latency is dominated by the model. A local run of the sample question produced a ~52,000-character report from 40 web sources in about 12 minutes with initial_search_query_count=1. The writer's critique loop revised the draft four times; lowering max_revisions or the effort level shortens runs substantially.
  • The dev server is not a deployment target. langgraph dev is an in-memory runtime for development. frontend/nginx.conf shows the production shape (static SPA + reverse proxy with SSE buffering disabled).
  • No demo GIF yet. The architecture diagrams under docs/diagrams/ are generated by scripts/render_graph_diagrams_en.ps1; a screen capture of a live run is still to be added.

License and provenance

License has been granted. This codebase was built as a hands-on project from a training course, adapted and re-implemented into an English-first lite edition; This project/re-implemention has been authorized.

Acknowledgements

  • LangGraph for orchestration and the dev server.
  • Exa for the web-search API used by default.
  • DashScope for the MCP web-search fallback, embeddings and reranking.

About

DeepResearch-Full

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages