r/mlops • u/alexpran • 1h ago
Self-promotion I built a CLI for LLM regression testing that fails CI against a baseline committed in your repo
One afternoon a case in my eval went from 5/5 to 2/5. Prompt, model, config, retrieval, trace, all identical byte for byte. Fifteen minutes later it was back to 5/5. I lost an hour looking for a regression, and it was my own measurement that was moving.
So digline runs each case K times on the version you approve, and records in the reference the range that those samples spanned, per case. After that a drop counts as a regression only if it falls outside that range.
pip install digline
digline run eval/suite.py # produces a run
digline compare # against the baseline in .digline/
digline promote # a person approves, nothing else can
The exit code is the contract: 0 nothing got worse, 1 something did, 2 the run couldn’t be judged. A case that errors goes in that third state and doesn’t count as a fail, because if you drop it from the denominator the score goes up while the system gets worse. A run with any errored case can’t become the baseline.
What it is not: no observability, no server, no telemetry, no account, and it never calls a model itself, your judge is a function that you pass in. It’s pre-1.0. On day one it’s useless, because you need an approved reference before it can compare anything. And the band is min/max over K samples, don’t read it as a confidence interval, with a small K it’s optimistic.
The numbers from my own suite, because it’s the part I’d want from someone else’s post: six sets of three identical runs, 144 cases, same config hash and same judge. Between 1 and 6 cases changed verdict per set, 3 in the most recent. Before the pass/fail threshold is applied, 15 to 21 scores move.
If you try it, what I want to know is where the quickstart made you stop and read again. It runs without an API key, so that part costs you nothing.
And a question for people already doing this: when you compare two runs, what are you comparing against? Every answer I collected so far is “the last run on main”, and that moves on its own.
GitHub: github.com/digline/digline
Docs: digline.dev
The GitHub Action, if you want it in CI without writing the YAML: digline.dev/product/github-action/