Every aspect, nothing missed.
A trace-first agent evaluation framework. Decorate your agent once — Rubra captures every tool call, LLM call, token, and cost automatically, then scores it across 36 metrics, including 11 tool-orchestration metrics not commonly found elsewhere.
import rubra # one decorator — that's the entire integration @rubra.agent(task="Answer questions using web search") def my_agent(question: str) -> str: context = search_web(question) return call_llm(context, question) my_agent("What is the capital of France?") report = rubra.evaluate(rubra.get_last_trace()) print(f"Rubra Score: {report.rubra_score:.3f}") # Rubra Score: 0.923
Python contextvars.ContextVar propagates the active trace — async-safe and thread-safe by construction, no globals, no locks. Every @rubra.agent call gets its own isolated trace, so concurrent agents never cross-contaminate.
Zero-config by default — SQLite auto-inits at .rubra/rubra.db. Four core dependencies, no LLM required unless you opt into goal metrics.
Deterministic, zero LLM cost.
Precision/recall/F1 on tool selection, call-order scoring, redundant-call detection.
Prompt injection, scope creep, PII propagation.
Answer relevance, coherence, format, groundedness.
Reference-free, via rubra[judge]. Any litellm model, including free local Ollama.
Weighted roll-ups computed automatically.
Self-host a backend for your traces: browse them, run evaluations, and generate HTML reports from a browser — no notebook required.
| Metric | Score | Result |
|---|---|---|
| task_completion_rate | 1.000 | PASS |
| tool_call_success_rate | 1.000 | PASS |
| latency_score | 0.000 | FAIL |
| cost_efficiency | 1.000 | PASS |
Or pip install rubra-server. Either way, the dashboard polls /api/v1/traces every 30s — traces produced anywhere pointed at the same database show up automatically.
| Method | Path |
|---|---|
| GET | /api/v1/traces |
| POST | /api/v1/eval |
| GET | /api/v1/report/{trace_id} |
| DEL | /api/v1/traces/{trace_id} |
A production-shaped chart: ClusterIP service, persistent volume for SQLite, liveness/readiness probes against /api/v1/health, and an optional Ingress.
# from the OCI registry — no chart repo needed helm install rubra oci://ghcr.io/pm1715/charts/rubra \ --version 0.1.0 # with a real judge-model API key + Postgres: helm upgrade rubra oci://ghcr.io/pm1715/charts/rubra \ --set secrets.apiKeySecretName=rubra-api-key \ --set env.RUBRA_DATABASE_URL="postgresql://..."
Also ships scripts/test-in-kind.sh — builds the real Dockerfile, loads it into a throwaway kind cluster, and does a genuine end-to-end deploy test with no cloud cluster or registry required.
| Feature | Rubra | TruLens | RAGAS | DeepEval |
|---|---|---|---|---|
| 1-line agent instrumentation | Yes | No | No | No |
| Tool orchestration metrics (11 unique) | Yes | No | No | Partial |
| OpenAI + Anthropic auto-trace | Yes | Manual | Manual | Manual |
| Reference-free goal evaluation | Yes | No | Partial | Partial |
| LangGraph + LangChain integration | Yes | Yes | No | Partial |
| Safety metrics (injection, PII, scope) | Yes | No | No | Yes |
| Self-hosted REST API + Dashboard | Yes | Yes | No | Yes |
| Zero config (SQLite default) | Yes | No | No | Partial |
Where Rubra is most confidently different is the 11 tool-orchestration metrics — precision/recall/F1 on tool selection, call-order scoring, redundant-call detection — which the others don't expose as first-class metrics today. Most of the rest of the table is closer to different design choices than better or worse: TruLens and DeepEval in particular have mature ecosystems and production track records Rubra doesn't have yet.