Skip to main content

Regress

Your agent's production failures become its regression suite. Automatically.

Python 3.11+ License: Apache 2.0 CI Status: pre-alpha

Regress is an open-source failure-to-eval compiler. Every LLM observability vendor captures traces and scores them — then leaves the hard part to you, by hand, forever: turning a cluster of bad outputs into a committed regression test that blocks the next bad deploy. Regress automates exactly that loop:

production trace → clustered failure → tracked issue → auto-generated eval → CI regression gate

Self-hostable, adoptable in under 5 minutes, SQLite by default, no account and no API key for Regress itself.


Does it actually work?

Yes — here's the whole loop run end to end against a real LlamaIndex RAG over SQuAD, with numbers straight out of the run:

Stage Result
Ingest (one line: instrument()) 100 questions → 200 traces, zero app changes
Score vs. gold answers 21 real failures found (79% answer accuracy)
Cluster 21 failures → 2 auto-titled issues
EvalGen 8 committed regression cases
Calibrate judge-vs-human Cohen's κ = 0.435
Gate caught a degraded RAG (79% → 47%) at p < 0.00001, ignored a 4-pt noise drop

Total API cost for the entire study: under $0.05. It even found (and fixed) a real bug in Regress itself. Full write-up → docs/case-study.md.


Quickstart

pip install git+https://github.com/arshadvani3/Regress.git
# once published to PyPI: pip install regress-ai

regress demo        # load a sample scenario — see the whole loop, zero setup
regress up          # then open http://localhost:8990

regress demo seeds a small sample (failing traces already scored and clustered into Issues, including a regressed one) so the dashboard is populated the moment you install — nothing to instrument first. regress demo --reset clears it. To point Regress at your app instead, change one line:

from regress import instrument
instrument()        # patches OpenAI/Anthropic SDKs, emits OTel spans to localhost

Then use your app, open http://localhost:8990, watch traces stream in, and run the loop below. No Postgres, no account, no YAML until you want it.


How it works

                        ┌────────────────────────────────────────────────┐
                        │                 regress up (FastAPI)           │
                        │                                                │
 your app ──OTLP──▶     │  /v1/traces  ──▶  Ingest ──▶ Store (SQLite/PG) │
 (instrument() or       │                              + embeddings      │
  any OTel exporter)    │                                                │
                        │  Scorer  ── deterministic checks + judge ──▶   │
                        │            span/trace scores                   │
                        │                                                │
                        │  Clusterer ── embed failed traces ──▶ Issues   │
                        │               (HDBSCAN, LLM-written titles,    │
                        │                active → resolved → regressed)  │
                        │                                                │
                        │  EvalGen ── issue ──▶ evals/<issue>.yaml       │
                        │                                                │
                        │  Calibrator ── human labels ──▶ judge kappa    │
                        │                                                │
                        │  Dashboard (React+TS+Tailwind, served static)  │
                        └────────────────────────────────────────────────┘

 CI: regress run evals/ --against <live app> ──▶ pass/fail + significance test
     shipped as a reusable GitHub Action (.github/actions/gate)

Six stages, one command each:

Stage Command What it does
Ingest instrument() / any OTLP exporter Record LLM calls as traces
Score regress score Deterministic checks + LLM-judge
Cluster regress cluster Group failures into tracked Issues
EvalGen regress evalgen Issue → YAML + pytest regression test
Gate regress run --gate Fail CI on a significant regression
Calibrate regress calibrate Measure how much to trust the judge

Full walkthrough with the reasoning behind each stage (plus an interactive visual version).


Usage

A tour of the loop. Full flag-by-flag reference: docs/usage.md.

Ingest — one line in your app, or point any OTel exporter at regress up:

from regress import instrument
instrument()   # every openai/anthropic call now exports a trace

Score — deterministic checks + an optional LLM-judge, configured in an optional regress.yaml (regress init scaffolds one with a menu of ready-to-use rubrics):

regress init                       # writes a starter regress.yaml
regress score --config regress.yaml

Cluster scored-bad traces into Issues (needs the cluster extra). A new failure landing in a resolved issue flips it to regressed — a fix that didn't hold:

pip install 'regress-ai[cluster]'
regress cluster

Generate evals — each issue becomes a sanitized, human-editable YAML eval plus a pytest module (pytest evals/ works with no server):

regress evalgen

Or run score → cluster → evalgen in one shot: regress analyze.

Gate CI — replay recorded traces, or hit your live app and block the deploy on a statistically significant drop (a two-proportion test, not a raw diff):

regress run evals/ --against http://localhost:8000/predict --gate

Calibrate the judge — hand-label a sample and get Cohen's κ, because the judge drives everything above:

regress calibrate --label 20 --labeler you@example.com
regress calibrate --report

Why not just Langfuse / Braintrust / <observability vendor>?

Those tools are excellent at the first half of the loop — capturing traces and scoring them. What they leave to you, manually, every time, is the second half: turning a cluster of bad traces into a committed regression test that blocks a bad deploy. Regress's only job is that second half, done automatically, and it speaks OpenTelemetry GenAI conventions so it plugs into whatever you're already exporting from. It's not replacing your observability stack — it's making one specific workflow (failure → eval → gate) something you never do by hand again.

Design principles

  • Zero-config default path. SQLite + local embeddings (bge-small-en-v1.5) out of the box. Postgres + pgvector is opt-in via REGRESS_DB_URL for scale.
  • Standards over SDK lock-in. Ingestion speaks OpenTelemetry GenAI conventions over OTLP/HTTP. instrument() is a convenience, not a requirement.
  • Everything is also a file. Generated evals are plain YAML + Python in your repo, runnable with regress run or plain pytest — no server in CI.
  • One process, one port for local dev; the judge works against any OpenAI-compatible endpoint, including a fully-local Ollama.

Non-goals (v0)

No hosted/multi-tenant SaaS, no auth beyond a single optional bearer token, no prompt-management/playground features, no fine-tuning loops, no non-GenAI OTel traffic, no Kubernetes manifests. The scope is intentional.

Status & what's next

Pre-alpha. The full loop — ingest → score → cluster → evalgen → gate → calibrate, plus the dashboard — works end to end, proven against a real LlamaIndex RAG (see the case study). It's a self-hosted single-node tool today; public APIs may still shift.

Streaming-completion capture already landed (instrument() traces token-streamed responses without forcing non-streaming), and a shared deployment can now require a bearer token (REGRESS_AUTH_TOKEN) and redact PII before it's stored (REGRESS_SANITIZE_INGEST) — see docs/usage.md. Where it goes next:

  • Postgres + pgvector for teams past the single-node SQLite default — the storage layer is already abstracted behind REGRESS_DB_URL.
  • Async, cached judge calls so a large score run isn't a sequential wait and identical output+rubric pairs aren't re-judged.
  • More judge backends beyond OpenAI-compatible — the judge is a thin provider-agnostic client, so Anthropic/Bedrock/local slot in cleanly.

Contributing

git clone https://github.com/arshadvani3/Regress.git && cd Regress
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest && ruff check . && mypy src

The dashboard (dashboard/, Vite + React + TypeScript + Tailwind) is a separate npm project that builds into src/regress/dashboard_dist/, which regress up serves as static files:

cd dashboard && npm install
npm run dev      # Vite dev server on :5173, proxies /api to :8990
npm run build    # writes the bundle regress up serves

License

Apache-2.0. See LICENSE.

Download files

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

Source Distribution

regress_ai-0.1.0.tar.gz (134.3 kB view details)

Uploaded Source

Built Distribution

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

regress_ai-0.1.0-py3-none-any.whl (77.9 kB view details)

Uploaded Python 3

File details

Details for the file regress_ai-0.1.0.tar.gz.

File metadata

  • Download URL: regress_ai-0.1.0.tar.gz
  • Upload date:
  • Size: 134.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for regress_ai-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d5b3ec985c14d91930fea45341e5e5c3cfaf9d51ceec90883e33169701eb5861
MD5 faf9c640cc57a19f4071f2aeb4135519
BLAKE2b-256 d5dbea2f90a42f9ecaaf760d4f5080307a0c2b972e63a4beb81607537774e66e

See more details on using hashes here.

Provenance

The following attestation bundles were made for regress_ai-0.1.0.tar.gz:

Publisher: release.yml on arshadvani3/Regress

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file regress_ai-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: regress_ai-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 77.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for regress_ai-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0faeb9ced0e9d233e702b6f524101e49be46249d34fffcf93a77457114bd9b36
MD5 eb87d58e519698aca03f1b25dcdb603a
BLAKE2b-256 a33478013b7b21761b4e2c83f15cd7bcc3c72d099a315b04a45372ba227771ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for regress_ai-0.1.0-py3-none-any.whl:

Publisher: release.yml on arshadvani3/Regress

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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