You probably don't need an eval platform
What actually caught regressions while building an AI detection product: traces you can diff, plus a small golden set in CI.
I pick the model and the harness that get something in front of a user. I still start in Cursor, and I still reach for Claude Code when the job is heavy. Buying an eval platform so I can watch a scoreboard is not a toolbox.
Every few weeks someone asks which one they should buy. At this size, none of them. I say that as someone who builds an AI detection product. Scoring text for AI involvement is close to a worst-case eval problem. The thing you are measuring is fuzzy and the models underneath keep shifting. A regression does not throw an exception. It just quietly starts giving wrong answers with the same confident tone as before. If eval tooling were going to save anyone, it would save me. What actually saved me was embarrassingly small, and I want to describe it concretely, because I wasted real time believing it had to be bigger.
The trap looks like diligence
When your model-backed feature misbehaves, the industry’s default advice is to stand up an evaluation pipeline. Dataset management, scoring dashboards, experiment tracking, a vendor for each. I went partway down that road, and I can report what’s at the end of it for a small team: another system to maintain, sitting between you and the product, whose own configuration becomes a source of bugs.
These platforms are built for teams where ten people share one model pipeline and need to coordinate. On a team of one or three, the coordination problem they solve doesn’t exist yet, and the ceremony they add lands on the same person who was supposed to be shipping. It’s the same instinct I wrote about in the orchestration trap: when the core problem is hard, building scaffolding around it feels like progress and postpones the hard part indefinitely.
What a regression actually looks like
Here’s the moment that converted me to minimalism. A dependency bump changed how my pipeline chunked long documents. No test failed. The API returned 200s. Scores still looked score-shaped. But long submissions were now being judged mostly on their opening sections, and accuracy on exactly one category of input fell off a cliff.
I caught it days later than I should have, and what finally exposed it was diffing two stored traces of the same document, one from before the bump and one from after, and seeing that the second one processed a third as much text. That experience set my priorities permanently. Everything I now consider essential is whatever would have caught that bug on day zero.
The whole system, honestly
Three pieces. All of them live in the repo next to the code.
Traces you can diff. Every scoring run writes a structured record: model, version, input hash, intermediate outputs, final score, latency. Plain JSON lines. When something feels off, I pull the trace for the same input from last week and diff them. Ninety percent of “the model got worse” investigations end here, and about half of them turn out to be my code, the chunking, the prompt template, a truncation, and never the model at all.
A golden set of about twenty inputs. Real documents, chosen because each one nearly fooled the system in a different way. Human-written text that looks AI-ish, AI text that’s been hand-edited, mixed authorship, one document in the category that burned me above. Twenty is a deliberate number. I can read every failure by hand over a coffee, and I actually do, which is precisely what nobody does with a two-thousand-row eval suite. When a new failure mode shows up in production, one example of it earns a place in the set, and something redundant leaves.
A CI gate with documented tolerance. The golden set runs on every pull request. Scores can drift within a written-down band before the build fails, because model-backed systems wobble and a zero-tolerance gate just trains you to ignore red builds. The tolerances live in a comment right above the numbers, with a sentence explaining each one, so future me knows whether a violation is alarming or expected.
Total cost: a few files, no vendors, no dashboard. It has caught every regression that mattered since, including two more that arrived the same way as the first one, through innocent-looking dependency changes rather than through anything I did to prompts.
The uncomfortable part
The reason this works is that the golden set is small enough that a human still reads the failures. Once the output pile is bigger than what I will look at, I stop seeing why a score moved. A 0.91 to 0.89 shift is noise until I open the two documents that flipped.
So I keep traces from day one and a set of about twenty examples I actually understand. The CI gate uses tolerances I wrote down on purpose. The money I did not give an eval vendor goes to coffee while I read my own failures. When this stops being enough, it will be because coordinating people is the bottleneck, not catching regressions.