A CLI application for answering questions about research papers using RAG (Retrieval-Augmented Generation) with Ollama as the LLM backend.
┌───────────────────────────────────────────────────────────────┐
│ RAG Q&A CLI │
│ ┌───────┐ ┌─────────┐ ┌────────┐ ┌──────────────────────┐ │
│ │ index │ │ ask │ │ chat │ │ test │ │
│ └───┬───┘ └────┬────┘ └───┬────┘ └──────────┬───────────┘ │
└──────┼──────────┼───────────┼───────────────────┼─────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌───────────────────────────────────────────────────────────────┐
│ RAG Chain │
│ ┌─────────────────┐ ┌────────────┐ ┌───────────────────┐ │
│ │ Query Classifier│─▶│ Retriever │─▶│ LLM Generator │ │
│ └─────────────────┘ └─────┬──────┘ └───────────────────┘ │
└─────────────────────────────┼─────────────────────────────────┘
│
┌──────────────────────┼──────────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌───────────────┐ ┌───────────────┐
│ PDF Loader │ │ Vector Store │ │ Ollama API │
│ (PyMuPDF) │ │ (ChromaDB) │ │ (LLM + Embed) │
└─────────────┘ └───┬───────────┘ └───────────────┘
│
Retriever Pipeline:
Semantic + BM25
│
Title Boost
│
RRF Fusion
│
Cross-Encoder
Re-ranking
│
Score Filter → top-k
cross-encoder/ms-marco-MiniLM-L-6-v2 for improved precisionollama serve
ollama pull qwen2.5:7b
ollama pull nomic-embed-text
# Clone and enter directory
cd ragqa
# Install Poetry (if not already installed)
pipx install poetry
# Install dependencies (creates .venv automatically)
poetry install
# Copy environment template
cp .env.example .env
# Download research papers from arXiv
poetry run python scripts/download_papers.py --file papers.txt
# Build the index (first time)
poetry run ragqa index
# Force rebuild
poetry run ragqa index --force
# Single question
poetry run ragqa ask "What is ToolMem?"
# JSON output
poetry run ragqa ask --json "What is ToolMem?"
# No streaming
poetry run ragqa ask --no-stream "What is ToolMem?"
poetry run ragqa chat
poetry run ragqa list-docs
# Golden file tests
poetry run ragqa test
# JSON output for CI
poetry run ragqa test --json
poetry run ragqa config
Environment variables (in .env):
| Variable | Default | Description |
|---|---|---|
OLLAMA_BASE_URL | http://localhost:11434 | Ollama API endpoint |
OLLAMA_MODEL | qwen2.5:7b | LLM model for generation |
OLLAMA_EMBED_MODEL | nomic-embed-text | Embedding model |
PAPERS_DIR | ./research_papers | PDF papers directory |
LOG_LEVEL | INFO | Logging level |
DEBUG | false | Enable debug mode |
RERANKER_ENABLED | false | Enable cross-encoder re-ranking (downloads model on first use) |
RERANKER_MODEL | cross-encoder/ms-marco-MiniLM-L-6-v2 | Cross-encoder model name |
all_docs: Overview of all paperssingle_doc: Summary of specific paperspecific: Factual/how-to questionsragqa/
├── src/ragqa/
│ ├── __init__.py # Logging configuration
│ ├── config.py # Settings (pydantic-settings)
│ ├── exceptions.py # Custom exceptions
│ ├── protocols.py # Protocol interfaces for DI
│ ├── core/
│ │ ├── models.py # Data models (Chunk, Document)
│ │ ├── pdf_loader.py # PDF parsing
│ │ └── rag_chain.py # RAG orchestration (sync + async)
│ ├── retrieval/
│ │ ├── embeddings.py # Ollama embeddings (sync + async)
│ │ ├── vectorstore.py # ChromaDB wrapper
│ │ ├── bm25_index.py # BM25 keyword search
│ │ ├── retriever.py # Hybrid search + RRF
│ │ ├── reranker.py # Cross-encoder re-ranking
│ │ └── query_classifier.py
│ ├── llm/
│ │ ├── client.py # Ollama client (sync + async)
│ │ └── prompts.py # Prompt templates
│ └── cli/
│ ├── app.py # Typer commands
│ ├── display.py # Rich output
│ └── banner.py # ASCII banner
└── tests/
├── conftest.py # Shared fixtures
├── golden/ # Golden test cases
├── core/ # Core module tests
├── retrieval/ # Retrieval tests
└── llm/ # LLM client tests
# Run tests
poetry run pytest
# Type checking
poetry run mypy src/
# Linting
poetry run ruff check src/ tests/
# Format
poetry run ruff format src/ tests/
MIT
25 commits
11 commits
Python
100.0%
A CLI application for answering questions about research papers using RAG (Retrieval-Augmented Generation) with Ollama as the LLM backend.
┌───────────────────────────────────────────────────────────────┐
│ RAG Q&A CLI │
│ ┌───────┐ ┌─────────┐ ┌────────┐ ┌──────────────────────┐ │
│ │ index │ │ ask │ │ chat │ │ test │ │
│ └───┬───┘ └────┬────┘ └───┬────┘ └──────────┬───────────┘ │
└──────┼──────────┼───────────┼───────────────────┼─────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌───────────────────────────────────────────────────────────────┐
│ RAG Chain │
│ ┌─────────────────┐ ┌────────────┐ ┌───────────────────┐ │
│ │ Query Classifier│─▶│ Retriever │─▶│ LLM Generator │ │
│ └─────────────────┘ └─────┬──────┘ └───────────────────┘ │
└─────────────────────────────┼─────────────────────────────────┘
│
┌──────────────────────┼──────────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌───────────────┐ ┌───────────────┐
│ PDF Loader │ │ Vector Store │ │ Ollama API │
│ (PyMuPDF) │ │ (ChromaDB) │ │ (LLM + Embed) │
└─────────────┘ └───┬───────────┘ └───────────────┘
│
Retriever Pipeline:
Semantic + BM25
│
Title Boost
│
RRF Fusion
│
Cross-Encoder
Re-ranking
│
Score Filter → top-k
cross-encoder/ms-marco-MiniLM-L-6-v2 for improved precisionollama serve
ollama pull qwen2.5:7b
ollama pull nomic-embed-text
# Clone and enter directory
cd ragqa
# Install Poetry (if not already installed)
pipx install poetry
# Install dependencies (creates .venv automatically)
poetry install
# Copy environment template
cp .env.example .env
# Download research papers from arXiv
poetry run python scripts/download_papers.py --file papers.txt
# Build the index (first time)
poetry run ragqa index
# Force rebuild
poetry run ragqa index --force
# Single question
poetry run ragqa ask "What is ToolMem?"
# JSON output
poetry run ragqa ask --json "What is ToolMem?"
# No streaming
poetry run ragqa ask --no-stream "What is ToolMem?"
poetry run ragqa chat
poetry run ragqa list-docs
# Golden file tests
poetry run ragqa test
# JSON output for CI
poetry run ragqa test --json
poetry run ragqa config
Environment variables (in .env):
| Variable | Default | Description |
|---|---|---|
OLLAMA_BASE_URL | http://localhost:11434 | Ollama API endpoint |
OLLAMA_MODEL | qwen2.5:7b | LLM model for generation |
OLLAMA_EMBED_MODEL | nomic-embed-text | Embedding model |
PAPERS_DIR | ./research_papers | PDF papers directory |
LOG_LEVEL | INFO | Logging level |
DEBUG | false | Enable debug mode |
RERANKER_ENABLED | false | Enable cross-encoder re-ranking (downloads model on first use) |
RERANKER_MODEL | cross-encoder/ms-marco-MiniLM-L-6-v2 | Cross-encoder model name |
all_docs: Overview of all paperssingle_doc: Summary of specific paperspecific: Factual/how-to questionsragqa/
├── src/ragqa/
│ ├── __init__.py # Logging configuration
│ ├── config.py # Settings (pydantic-settings)
│ ├── exceptions.py # Custom exceptions
│ ├── protocols.py # Protocol interfaces for DI
│ ├── core/
│ │ ├── models.py # Data models (Chunk, Document)
│ │ ├── pdf_loader.py # PDF parsing
│ │ └── rag_chain.py # RAG orchestration (sync + async)
│ ├── retrieval/
│ │ ├── embeddings.py # Ollama embeddings (sync + async)
│ │ ├── vectorstore.py # ChromaDB wrapper
│ │ ├── bm25_index.py # BM25 keyword search
│ │ ├── retriever.py # Hybrid search + RRF
│ │ ├── reranker.py # Cross-encoder re-ranking
│ │ └── query_classifier.py
│ ├── llm/
│ │ ├── client.py # Ollama client (sync + async)
│ │ └── prompts.py # Prompt templates
│ └── cli/
│ ├── app.py # Typer commands
│ ├── display.py # Rich output
│ └── banner.py # ASCII banner
└── tests/
├── conftest.py # Shared fixtures
├── golden/ # Golden test cases
├── core/ # Core module tests
├── retrieval/ # Retrieval tests
└── llm/ # LLM client tests
# Run tests
poetry run pytest
# Type checking
poetry run mypy src/
# Linting
poetry run ruff check src/ tests/
# Format
poetry run ruff format src/ tests/
MIT
25 commits
11 commits
Python
100.0%