Skip to content

RAGWire

Production-grade RAG toolkit for document ingestion and retrieval with hybrid search support.

RAGWire handles the full RAG pipeline, from loading raw documents to storing and retrieving them from a vector database, so you can focus on building your application.


RAGWire High-Level Overview


Features

Ingestion

  • Document Loading: PDF, DOCX, XLSX, PPTX and more via MarkItDown
  • LLM Metadata Extraction: extracts company, doc type, and fiscal period automatically
  • Smart Text Splitting: markdown-aware and recursive chunking strategies
  • SHA256 Deduplication: at both file and chunk level, so nothing is ingested twice
  • Source Sync: reconcile against local folders and S3, including the deletions plain ingestion never notices

Retrieval and answers

  • Multiple Embedding Providers: Ollama, OpenAI, OpenRouter, HuggingFace, Google, FastEmbed
  • Qdrant Vector Store: dense, sparse, and hybrid search
  • Advanced Retrieval: similarity, MMR, and hybrid search with metadata filtering
  • Reranking: optional cross-encoder second stage, local and API-key-free by default
  • Grounded Answers: cited answers that refuse rather than guess, sync and async

Operating it

  • Evaluation: recall@k, MRR and config sweeps against your own golden set
  • MCP Server: expose a collection to Claude Desktop, Claude Code and Cursor
  • CLI: ragwire ingest, sync, eval and mcp serve

Architecture

RAGWire Architecture


Installation

pip install ragwire

# With Ollama support (local, no API key)
pip install "ragwire[ollama]"

# Optional capabilities
pip install "ragwire[rerank]"   # local cross-encoder reranking, no API key
pip install "ragwire[mcp]"      # MCP server for Claude Desktop / Code / Cursor
pip install "ragwire[s3]"       # S3 source connector for rag.sync()

# Everything
pip install "ragwire[all]"

None of the optional extras are needed for the core install, and evaluation needs no extra package at all.


Quick Start

from ragwire import RAGWire

rag = RAGWire("config.yaml")

# Ingest documents
stats = rag.ingest_documents(["data/Apple_10k_2025.pdf"])
print(f"Chunks created: {stats['chunks_created']}")

# Ask a question and get a cited answer
answer = rag.query("What is Apple's total revenue?")
print(answer.formatted())

# Or work with the chunks directly
results = rag.retrieve("What is Apple's total revenue?", top_k=5)
for doc in results:
    print(doc.metadata.get("company_name"), doc.page_content[:200])

Where To Go Next

If you want to Read
Get running from scratch Installation & Setup
Follow a worked example Quick Tutorial
Get answers rather than chunks Answer Questions
Improve result quality Reranking
Find out whether a change helped Measure Retrieval Quality
Use your documents from Claude or Cursor MCP Server
Keep the collection current automatically Sync Sources
Scope queries to the right documents Metadata & Filtering

Supported Providers

Provider Embeddings LLM Free
Ollama Yes Yes Yes (local)
OpenAI Yes Yes No
OpenRouter Yes Yes Free tier
Google Gemini Yes Yes Free tier
Groq No Yes Free tier
Anthropic No Yes No
HuggingFace Yes No Yes (local)
FastEmbed Yes No Yes (local)