Skip to main content

⚡ RagArena

Evaluate & benchmark every RAG strategy × LLM × embedding model — with one unified API

18 strategies · 100+ models · 20+ providers · 10 metrics · Next.js playground · Docker/PyPI/GitHub

PyPI Python 3.9+ License: MIT Tests

📐 Architecture & full feature reference · 🐳 Docker guide · 📝 Changelog

One unified API across every RAG strategy, LLM and embedding model:

from ragarena import evaluate

evaluate(questions=[...], documents=[...],
         strategy="hybrid",                      # any of 18 strategies
         model="openai/gpt-4o-mini",             # swap with claude/gemini/llama/...
         embedding_model="voyage/voyage-3",      # swap with openai/cohere/jina/...
         metrics="quality").print_summary()

Why RagArena?

Choosing a RAG stack is guesswork today. "Is hybrid retrieval actually better than naive for my data? Is GPT-4o worth 17× the price of GPT-4o-mini for answer faithfulness? Do Voyage-3 embeddings beat OpenAI's on my legal corpus?"

RagArena turns those guesses into a leaderboard.

Ragas DeepEval TruLens RagArena
Score your existing pipeline
Run the pipelines themselves (18 strategies)
Swap LLM/embedding providers per run (provider/model syntax) partial partial partial ✅ 100+ models
Built-in cost + latency accounting per strategy partial
Head-to-head leaderboard w/ shared index
Zero-config web dashboard

Install

pip install ragarena                 # core
pip install "ragarena[all]"          # + all provider SDKs
export OPENAI_API_KEY=sk-...        # only the providers you use

60-second quickstart

from ragarena import evaluate

docs = [
    {"text": "Retrieval-Augmented Generation (RAG) grounds LLM answers in your documents."},
    {"text": "Hybrid retrieval combines dense vector search with BM25 keyword search."},
    {"text": "Cross-encoder rerankers like bge-reranker significantly improve precision."},
]

report = evaluate(
    questions=["What is RAG?", "How does hybrid retrieval work?"],
    documents=docs,
    reference_answers=["RAG grounds LLMs in docs", "It fuses dense + BM25 search"],
    strategy="hybrid",                          # naive|hybrid|multi_query|hyde|rerank|
                                                # rag_fusion|compression|crag|self_rag|
                                                # decomposition|step_back|agentic|flare
    model="openai/gpt-4o-mini",
    embedding_model="openai/text-embedding-3-small",
    metrics="quality",                          # quick|quality|full|production
)

report.print_summary()
report.save("report.json")
╭─ RagArena · hybrid · openai/gpt-4o-mini
├─ embedding : openai/text-embedding-3-small
├─ samples   : 2   wall time 6.4s
├──────────────────────────────────────────────────────────
│     faithfulness : 0.92      answer relevance : 0.95
│ context precision : 0.83      context recall : 0.88
│       hit rate : 1.0                   mrr : 0.75
│   avg latency : 3.1s           total cost : $0.00214
╰──────────────────────────────────────────────────────────

🏆 Find the best strategy/model in one call

from ragarena import compare

result = compare(
    questions=my_questions,
    documents=my_docs,
    reference_answers=ground_truth,
    configs=[
        {"strategy": "naive",       "model": "openai/gpt-4o-mini"},
        {"strategy": "hybrid",      "model": "openai/gpt-4o-mini"},
        {"strategy": "hyde",        "model": "openai/gpt-4o-mini"},
        {"strategy": "agentic",     "model": "groq/openai/gpt-oss-120b"},
        {"strategy": "hybrid",      "model": "anthropic/claude-3-haiku-20240307"},
    ],
)
result.print_leaderboard(sort_by="faithfulness")
print("WINNER:", result.best("faithfulness"))

The document index is embedded once and shared across all configs — comparisons are fast and cheap.

🎯 "Which strategy is best for MY data?"

Don't want to hand-pick configs? recommend_strategy() runs every strategy (or a chosen subset) against your corpus and questions, then ranks them by a quality/cost/latency-weighted composite score:

from ragarena import recommend_strategy

rec = recommend_strategy(
    questions=my_questions,
    documents=my_docs,
    reference_answers=ground_truth,
    model="groq/openai/gpt-oss-20b",
    embedding_model="google/gemini-embedding-001",
    quality_weight=0.7, cost_weight=0.15, latency_weight=0.15,   # tune for your priorities
)
rec.print_summary()
print(rec.best, rec.reasoning)

Also available as ragarena recommend --documents ... --questions ... (CLI) and POST /api/recommend (used by the Recommend tab in the playground UI).

📄 Bring your own data — any format, any database

from ragarena import parse_file, parse_dir, from_sql

docs = parse_file("report.pdf")                 # pdf, docx, pptx, html, csv, json,
docs += parse_file("notes.docx")                 # xlsx, md, txt, images, .sql, .sqlite
docs += parse_dir("./knowledge_base/", recursive=True)   # walk a whole directory, mixed formats

docs += from_sql("postgresql://user:pass@host/db",       # any SQLAlchemy-supported DB
                  "SELECT id, title, body FROM articles")

pip install "ragarena[ingest,sql]" for the optional parser/DB-driver dependencies.

🖥 Web dashboard

RagArena serve            # → http://localhost:4000
  • Overview — run history & framework stats
  • New Evaluation — pick strategy/models from dropdowns, paste corpus, score instantly
  • Compare — build config matrices, get leaderboards + Chart.js visualizations
  • Runs — drill into every sample: answer, chunks, metric reasoning
  • Catalog — browse all 100+ models with pricing/context windows

🔀 Every popular provider, one syntax

Models are addressed as provider/name:

from ragarena import completion

completion(model="openai/gpt-4o-mini", ...)          # OpenAI
completion(model="anthropic/claude-3-5-sonnet-20240620", ...)
completion(model="google/gemini-1.5-flash", ...)
completion(model="deepseek/deepseek-chat", ...)      # 97% cheaper than gpt-4o
completion(model="groq/openai/gpt-oss-20b", ...)   # sub-second inference
completion(model="ollama/llama3.1", ...)             # local & free
completion(model="bedrock/meta.llama3-1-405b-instruct-v1:0", ...)
📋 Full provider support matrix (click to expand)

LLM Providersprovider/ prefix:

Provider Example models Notes
openai/ gpt-4o, gpt-4o-mini, o1-preview flagship quality
anthropic/ claude-3-5-sonnet, opus, haiku best coding/agentic
google/, vertex/ gemini-1.5-pro (2M ctx), flash huge context
azure/ any OpenAI model on Azure enterprise compliance
bedrock/ claude/llama/titan on AWS VPC deployments
cohere/ command-r-plus native RAG features
mistral/ large, nemo, codestral EU-hosted options
xai/ grok-beta real-time knowledge
deepseek/ deepseek-chat, coder extreme $/quality
groq/ gpt-oss-120b @300tok/s fastest hosted
together/, fireworks/, deepinfra/ llama, qwen, mixtral open-model hosts
perplexity/ sonar-online search-grounded
openrouter/ 100+ gateway models one key, all models
nvidia_nim/, anyscale/, ai21/, databricks/
ollama/, vllm/, lmstudio/ local llama/qwen/gemma/phi free, private

Embedding Providers: openai/text-embedding-3-* · cohere/embed-* · voyage/voyage-3(-large|-code|-law|-finance) · jina/jina-embeddings-v3 · mistral/mistral-embed · google/text-embedding-004 · bedrock/amazon.titan-embed-text-v2 · huggingface/BAAI/bge-m3 (+MiniLM, E5, GTE) · ollama/nomic-embed-text

Rerankers: cohere/rerank-v3.5 · voyage/rerank-2 · huggingface/BAAI/bge-reranker-v2-m3

Vector stores: FAISS (built-in) · Chroma · Pinecone · Qdrant · Weaviate · Milvus · LanceDB · pgvector · Elasticsearch · Redis · OpenSearch · MongoDB

Browse everything from the CLI:

RagArena models list                       # all 100+
RagArena models list --modality embedding  # embeddings only
RagArena models providers                  # provider summary
RagArena strategies                        # the 18 strategies

🧪 The 18 built-in strategies

Strategy What it does Best for
naive dense top-k → generate baseline / simple corpora
hybrid dense + BM25 weighted fusion (α-tunable) keyword-heavy domains
multi_query LLM rewrites N queries, merges results vague questions
rag_fusion multi-query + Reciprocal Rank Fusion robustness over multi_query
hyde retrieve using an imagined answer's embedding vocabulary mismatch
rerank wide recall → cross-encoder refine precision-critical
compression LLM strips irrelevant spans pre-generation long noisy chunks
crag grades retrieval; rewrites query if weak production guardrails
self_rag model decides if retrieval is needed mixed easy/hard traffic
decomposition splits complex Q → sub-Qs → synthesis multi-hop questions
step_back abstract principle question first conceptual/domain Qs
agentic iterative search→reflect→search loop hard research tasks
flare flags uncertain draft claims → re-retrieves hallucination-prone domains
graph_local entity-precise retrieval over a knowledge graph "who/what" factual lookups
graph_global macro-theme retrieval across entity communities "how/why" analytical Qs
graph_hybrid combines local entities + global themes general-purpose graph RAG
graph_mix local + global fused in one synthesis pass best-of-both retrieval
multimodal retrieves typed chunks (text/table/image/equation) mixed-content documents

🕸️ Graph RAG (dual-level retrieval)

graph_* strategies layer a lightweight knowledge graph over your index — entities are extracted per chunk, chunks that share entities form communities, and queries are answered at two levels:

  • local (graph_local) — match the query's entities to graph nodes and pull the connected chunks. Best for precise "who/what" factual lookups.
  • global (graph_global) — summarise each community, rank communities by relevance to the query, then synthesise a cross-document answer. Best for "how/why" analysis.
  • hybrid / mix (graph_hybrid, graph_mix) — combine both levels.

The graph is built lazily and cached on a shared index, so compare() only builds it once. Entity extraction falls back to a deterministic keyword extractor if the LLM is unavailable.

from ragarena import compare

result = compare(
    questions=["Who builds Pinecone?", "How do retrieval systems relate?"],
    documents=my_docs,
    configs=[
        {"strategy": "graph_local",  "model": "openai/gpt-4o-mini"},
        {"strategy": "graph_global", "model": "openai/gpt-4o-mini"},
        {"strategy": "graph_hybrid", "model": "anthropic/claude-3-haiku-20240307"},
    ],
)

Build a graph index directly for inspection:

from ragarena import VectorIndex, GraphIndex

vi = VectorIndex(embedding_model="openai/text-embedding-3-small")
vi.add_documents(my_docs)
g = GraphIndex(vi).build("openai/gpt-4o-mini")   # cache on the index
local  = g.local_search("What is Pinecone?", k=5, llm_model="openai/gpt-4o-mini")
chunks, theme = g.global_search("How do vector DBs compare?", k=5, llm_model="openai/gpt-4o-mini")

🖼️ Multimodal RAG

Tables, images and equations are kept intact (not sentence-split) and tagged with a doc_type so retrieval and generation can treat them differently:

from ragarena import MultimodalDocument, evaluate

docs = [
    MultimodalDocument(content="| model | params |", doc_type="table"),
    MultimodalDocument(content="E = mc^2",           doc_type="equation"),
    {"text": "RAG grounds LLMs in retrieved context.", "metadata": {"doc_type": "text"}},
]
evaluate(questions=["..."], documents=docs, strategy="multimodal",
         model="openai/gpt-4o-mini")

📐 Metrics

Presets: quick · quality · full · production — or cherry-pick:

metrics=["context_precision", "context_recall", "hit_rate", "mrr",   # retrieval
         "faithfulness", "answer_relevance", "answer_correctness",   # generation (LLM-judge)
         "latency_s", "cost_usd", "total_tokens"]                    # operational

Any model can be the judge: judge_model="anthropic/claude-3-haiku-20240307".

📦 Use inside your existing pipeline

Already have a RAG system? Score it directly:

from ragarena import VectorIndex
from ragarena.engine import EvalSample, MetricContext
from ragarena.metrics import resolve_metrics

# ...run YOUR pipeline to get answer + chunks...
sample = EvalSample(question=q, reference_answer=gt,
                    generated_answer=your_answer,
                    retrieved_chunks=[{"text": c} for c in your_chunks],
                    context="...", usage={...}, latency_s=..., intermediate={})
for m in resolve_metrics("full"):
    print(m.name, m.compute(sample, MetricContext(judge_model="openai/gpt-4o-mini")).score)

HTTP API

curl -X POST localhost:4000/api/evaluate -H 'Content-Type: application/json' -d '{
  "questions": ["What is RAG?"],
  "documents": [{"text": "RAG grounds LLM answers in documents."}],
  "strategy": "hybrid",
  "model": "openai/gpt-4o-mini",
  "embedding_model": "voyage/voyage-3"
}'

Also available: POST /api/compare · GET /api/catalog · GET /api/runs/{id} · GET /health

Roadmap

  • Async batch runner + checkpoint/resume
  • Statistical significance tests (paired bootstrap) between configs
  • Chroma/Pinecone/Qdrant backends for VectorIndex
  • Graph RAG incremental updates + community-aware re-indexing
  • Cloud/blob storage ingestion (S3, Azure Blob, GCS) alongside local parse_dir()
  • Prompt-optimization loop (DSPy-style)
  • Team features: API keys, budgets, RBAC
  • CI mode: ragarena ci --threshold faithfulness>=0.8 (fails PRs on regressions)

Contributing

PRs welcome! pip install -e ".[dev]" && pytest. Please read CONTRIBUTING.md.

License

MIT © RagArena contributors

Built for developers tired of guessing. Star ⭐ if it saved you a benchmark week.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ragarena-0.2.2.tar.gz (299.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ragarena-0.2.2-py3-none-any.whl (340.0 kB view details)

Uploaded Python 3

File details

Details for the file ragarena-0.2.2.tar.gz.

File metadata

  • Download URL: ragarena-0.2.2.tar.gz
  • Upload date:
  • Size: 299.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.11

File hashes

Hashes for ragarena-0.2.2.tar.gz
Algorithm Hash digest
SHA256 0ced70eab1aea52dc72ed85e1c09a094d4e8b47903fca238b4a02dbe67bf9c22
MD5 db1211ed99f48eedf9dd68f7de012b69
BLAKE2b-256 884a252e81ec99ea1dd01f0967425e1ed7bc1132adaaefe3c48b578cfb8e9327

See more details on using hashes here.

File details

Details for the file ragarena-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: ragarena-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 340.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.11

File hashes

Hashes for ragarena-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d8538d3fbac417a116eaf0b027c483c89ace1aafaa214dbedcde6c277e986be0
MD5 14e94138d6f7d78feb84f32eedf456ab
BLAKE2b-256 038810b1bb7559cdd33fb3f6d7531b229c23aec6decd201f4b828a1ffac565ac

See more details on using hashes here.

Release history Release notifications | RSS feed

0.2.4

2 files

0.2.3

2 files

This release

0.2.2 This release

2 files

0.2.1

2 files

0.2.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page