Skip to content

Repository files navigation

Lumina — AI Research Agent

An autonomous AI agent that researches any topic end-to-end.
Give it a question. It searches the web, reads the sources, synthesizes the findings,
and returns a structured report — all without human intervention.

FastAPI smolagents MongoDB Docker Python

API Docs · Quick Start · Architecture


What is Lumina?

Lumina is a production-grade agentic AI system that autonomously conducts research on any topic. Unlike a simple chatbot that answers from training data, Lumina's agent actively:

  1. Searches the web using DuckDuckGo — no API key required
  2. Reads and scrapes the most relevant pages
  3. Synthesizes everything into a structured JSON report
  4. Stores every session in MongoDB for instant retrieval

This is not a wrapper around a chat API. It is a real agentic loop — the LLM decides which tools to call, how many times, and in what order, based on what it finds at each step.


Why this matters

Traditional chatbot Lumina agent
Answers from static training data Actively searches the live web
Single LLM call Multi-step autonomous reasoning loop
No memory Full session history in MongoDB
No sources Cited sources with relevance explanations
Script Production API with Swagger docs, caching, streaming

This architecture is directly applicable to real-world products:

  • Enterprise knowledge bases — swap web search for internal document search
  • Competitive intelligence tools — research competitors automatically
  • Academic assistants — summarize papers and surface follow-up questions
  • News aggregators — monitor topics and synthesize daily briefs
  • Customer support — agent researches answers before responding

Features

  • Agentic loopsmolagents CodeAgent autonomously decides when and how to use tools
  • Live web search — DuckDuckGo search tool, no API key needed
  • Page scrapinghttpx + BeautifulSoup4 extracts clean text from any URL
  • Structured output — every report has summary, key points, cited sources, follow-up questions
  • Streaming — live progress bar via server-sent events while the agent works
  • Caching — repeated queries return instantly without hitting the LLM again
  • Full history — every session saved to MongoDB, searchable and retrievable
  • REST API — FastAPI with auto-generated Swagger UI at /docs
  • Dockerized — one command to run the full stack locally or in production
  • Polished UI — Inter + Cal Sans fonts, dark theme, sidebar history, export to Markdown

Architecture

┌─────────────────────────────────────────────────────┐
│                    Lumina Frontend                  │
│         (Vanilla JS · Inter font · Dark UI)         │
└───────────────────────┬─────────────────────────────┘
                        │ HTTP / SSE
┌───────────────────────▼─────────────────────────────┐
│                   FastAPI Backend                    │
│     Pydantic validation · Middleware · Swagger       │
│                                                     │
│  ┌─────────────┐   ┌──────────┐   ┌─────────────┐  │
│  │  /research  │   │ /history │   │   /health   │  │
│  │  /stream    │   │ /search  │   │ /cache/stats│  │
│  └──────┬──────┘   └────┬─────┘   └─────────────┘  │
│         │               │                           │
│  ┌──────▼──────┐  ┌─────▼──────┐                   │
│  │ Cache layer │  │  MongoDB   │                   │
│  │ (in-memory) │  │  (motor)   │                   │
│  └──────┬──────┘  └────────────┘                   │
│         │                                           │
│  ┌──────▼──────────────────────────────────┐        │
│  │           smolagents CodeAgent           │        │
│  │                                         │        │
│  │  ┌──────────────┐  ┌────────────────┐   │        │
│  │  │ WebSearchTool│  │ ScrapePageTool │   │        │
│  │  │  DuckDuckGo  │  │  httpx + BS4   │   │        │
│  │  └──────────────┘  └────────────────┘   │        │
│  └──────────────────┬──────────────────────┘        │
└─────────────────────┼───────────────────────────────┘
                      │ Inference API
┌─────────────────────▼───────────────────────────────┐
│          HuggingFace Inference API                   │
│       Llama 4 Scout 17B · Free tier                  │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│                  Docker Compose                      │
│   research_api (port 8000) + research_mongo (27017)  │
│   mongo_data volume · healthcheck · auto-restart     │
└─────────────────────────────────────────────────────┘

Tech Stack

Layer Technology Why
Agent framework smolagents HuggingFace's lightweight agent library — tool use + reasoning loop
LLM Llama 4 Scout 17B Free via HF Inference API, strong instruction following
Web search ddgs (DuckDuckGo) Free, no API key, reliable
Page scraping httpx + BeautifulSoup4 Fast async HTTP + clean text extraction
API FastAPI Auto Swagger docs, Pydantic validation, async, streaming
Database MongoDB + motor Async NoSQL — perfect for JSON research documents
Caching In-memory with TTL Instant repeat queries, configurable expiry
Streaming Server-Sent Events Live progress updates without WebSockets
Containerization Docker + Docker Compose One-command full-stack deployment
Frontend Vanilla JS + Inter font Zero dependencies, fast, polished

Quick Start

Prerequisites

  • Docker Desktop installed and running
  • A free HuggingFace account and token

1. Clone the repo

git clone https://github.com/NadaBhm/lumina-research-agent.git
cd lumina-research-agent

2. Set up environment

cp .env.example .env

Edit .env:

HF_TOKEN=hf_yourTokenHere

MONGO_USER=admin
MONGO_PASSWORD=yourPasswordHere
MONGO_DB=research_agent

CACHE_TTL_SECONDS=3600
API_VERSION=1.0.0

Get your free HuggingFace token at huggingface.co/settings/tokens. Select "Make calls to Inference Providers".

3. Run

docker-compose up --build

That's it. Visit:

URL What
http://localhost:8000 Lumina frontend
http://localhost:8000/docs Swagger API docs
http://localhost:8000/health Health check
http://localhost:8000/history All saved research

API Reference

POST /research

Run the agent on a topic.

curl -X POST http://localhost:8000/research \
  -H "Content-Type: application/json" \
  -d '{"topic": "What is retrieval augmented generation?", "depth": "standard"}'

Request body:

{
  "topic": "What is retrieval augmented generation?",
  "depth": "quick"
}
Field Type Values Default
topic string 3–300 chars required
depth enum quick standard deep standard

Response:

{
  "id": "664f2a3b1c9d4e5f6a7b8c9d",
  "topic": "What is retrieval augmented generation?",
  "depth": "quick",
  "summary": "Retrieval Augmented Generation (RAG) is...",
  "key_points": [
    "RAG combines retrieval systems with generative models",
    "It reduces hallucinations by grounding answers in real documents"
  ],
  "sources": [
    {
      "title": "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks",
      "url": "https://arxiv.org/abs/2005.11401",
      "relevance": "The original RAG paper by Lewis et al."
    }
  ],
  "follow_up_questions": [
    "How does RAG compare to fine-tuning?",
    "What vector databases work best with RAG?"
  ],
  "cached": false
}

POST /research/stream

Same as above but streams progress via server-sent events.

const res = await fetch('/research/stream', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ topic: 'What is RAG?', depth: 'quick' })
});

const reader = res.body.getReader();
// Events:
// { type: 'progress', step, total, message }
// { type: 'cache_hit', message }
// { type: 'done', result }
// { type: 'error', message }

GET /history

curl http://localhost:8000/history?limit=20

GET /history/{id}

curl http://localhost:8000/history/664f2a3b1c9d4e5f6a7b8c9d

DELETE /history/{id}

curl -X DELETE http://localhost:8000/history/664f2a3b1c9d4e5f6a7b8c9d

GET /history/search/{query}

curl http://localhost:8000/history/search/vector%20database

GET /cache/stats

curl http://localhost:8000/cache/stats

DELETE /cache

curl -X DELETE http://localhost:8000/cache

Depth Levels

Level Agent steps Typical time Best for
quick 3 ~20s Fast overviews, known topics
standard 8 ~45s Balanced research
deep 15 ~90s Thorough investigation

Embed in Your Own Project

In a website

<script>
async function research(topic) {
  const res = await fetch('http://localhost:8000/research', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ topic, depth: 'quick' })
  });
  return res.json();
}

const report = await research('What is the James Webb telescope?');
console.log(report.summary);
</script>

Python client

import httpx

def research(topic: str, depth: str = "standard") -> dict:
    res = httpx.post(
        "http://localhost:8000/research",
        json={"topic": topic, "depth": depth},
        timeout=120
    )
    return res.json()

report = research("What are large language models?")
print(report["summary"])
for point in report["key_points"]:
    print(f"- {point}")

Automate a research pipeline

topics = [
    "What is RAG?",
    "What are vector databases?",
    "How does fine-tuning work?",
]

for topic in topics:
    report = research(topic, depth="quick")
    print(f"\n## {topic}")
    print(report["summary"])

Project Structure

lumina-research-agent/
├── agent/
│   ├── __init__.py
│   ├── tools.py          # WebSearchTool + ScrapePageTool
│   └── agent.py          # CodeAgent setup + run_research()
├── static/
│   └── index.html        # Full frontend (no framework)
├── main.py               # FastAPI app, all endpoints
├── schemas.py            # Pydantic request/response models
├── database.py           # MongoDB async CRUD (motor)
├── cache.py              # In-memory cache with TTL
├── config.py             # Centralised settings from .env
├── Dockerfile
├── docker-compose.yml
├── .dockerignore
├── .env.example
└── requirements.txt

Extending Lumina

The agent is designed to be extended. Adding a new tool takes ~10 lines:

from smolagents import Tool

class WikipediaTool(Tool):
    name = "wikipedia_search"
    description = "Search Wikipedia for reliable encyclopedic information."
    inputs = {"query": {"type": "string", "description": "Topic to search"}}
    output_type = "string"

    def forward(self, query: str) -> str:
        import httpx
        r = httpx.get(
            f"https://en.wikipedia.org/api/rest_v1/page/summary/{query.replace(' ', '_')}"
        )
        return r.json().get("extract", "Not found.")

Then register it in agent.py:

tools=[WebSearchTool(), ScrapePageTool(), WikipediaTool()]

Environment Variables

Variable Required Default Description
HF_TOKEN Yes HuggingFace API token
MONGO_USER Yes MongoDB username
MONGO_PASSWORD Yes MongoDB password
MONGO_DB No research_agent Database name
CACHE_TTL_SECONDS No 3600 Cache expiry in seconds
API_VERSION No 1.0.0 Shown in /health response

Certificates

This project was built to apply skills from:

  • Develop Generative AI Applications: Get Started — Coursera
  • Hugging Face Agents Course — HuggingFace

License

MIT — free to use, modify, and deploy.


Built by NadaBhm · smolagents · FastAPI · MongoDB · Docker

About

Agentic AI research assistant built with smolagents, FastAPI, MongoDB & Docker. Give it a topic, it searches the web, reads sources, and returns a structured report.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages