Case study
Mendrift
An autonomous MLOps incident response agent. It investigates why a production model is failing, proposes a fix, and executes only after cryptographically enforced human approval.
First load can take around 40 seconds while the free tier server wakes up.
- LangGraph
- MCP
- Claude
- MLflow
- Evidently
- FastAPI
- React
0%
task success on live-model scenarios
0
logic-distinct incidents in the eval harness
0.0K
input tokens per incident, about 630 out
0
ungated writes, enforced by a hard assertion
The problem
Production ML models fail silently. Data drifts, an upstream schema changes, or a bad model version ships, and the model keeps running, quietly making worse decisions until a business metric drops days later.
When someone finally notices, an on-call engineer opens several dashboards, correlates the alert against recent deploys, and decides under pressure whether to roll back. Mendrift automates that tedious investigation while keeping a human in control of the one decision that can't be undone.
What it does
01
Classify
Decides whether the alert is real drift, a quality regression, or just noise.
02
Gather evidence
Calls tools on its own: computes drift, reads the model registry, diffs the last two deployments.
03
Diagnose
Works out the root cause and cites the actual numbers behind the conclusion.
04
Propose
Recommends a remediation. Usually a rollback, sometimes just monitor, sometimes open an incident.
05
Halt for approval
Stops before any destructive action and waits for a human decision.
06
Execute and verify
On approval, performs the rollback and confirms the model actually recovered.
The core idea
Safety enforced in code, not prompts
The hard problem with AI agents isn't making them act. It's guaranteeing they can't act unsafely. Mendrift's answer: the approval gate lives in the tool layer, not the prompt. The execute_rollback tool verifies a single-use, action-scoped HMAC token that only the human approval flow can mint, and the minting function is never exposed to the agent. A prompt-injected, confused, or adversarial agent has no path to a write.
I proved this adversarially. I told the model to roll back claiming full authorization: it proposed the action but refused to fabricate a token. Then I handed it a forged token: the gate rejected it with a constant-time comparison.
Two demos: crafted and real
The live app toggles between two worlds running the same agent, one crafted and one real.
Synthetic scenario
A crafted incident with a clean, teachable rollback story.
Real US credit data
The Give Me Some Credit benchmark, real US consumer credit records, with a controlled model regression injected so the incident has ground truth. Real distributions, real drift computation, and a known correct action. Injecting a known regression into real data is standard practice for validating a drift detection system.
On the real-data run the agent independently found that recall on defaulters had collapsed from 0.62 to 0.18, that predictions diverged 79.6% from the prior version, and that borrower age had genuinely drifted. It concluded the failure was model-induced rather than population drift, and recommended a rollback.
How it's built
Agent orchestration
LangGraph, with checkpointing and a human-in-the-loop interrupt
LLM layer
LangChain + Claude. Haiku for classify and verify, Sonnet for diagnosis
Tools
Model Context Protocol (MCP) server
Drift computation
Evidently, real Wasserstein and JS distances
Model registry
MLflow: versions, aliases, and real rollback
Web app
React (Vite) frontend, FastAPI backend, deployed on Render
Published
PyPI and the official MCP Registry
Crash proof
The graph checkpoints every step to SQLite. The process can die mid-incident, and a new process resumes the same incident by ID after a human approves.
Cost aware by design
Model routing lives in a code table, not prompts, so cost per path is measurable: about 3.9K input and 630 output tokens per incident.
Evaluated, not just built
Nineteen logic-distinct incident scenarios span the full decision space: rollback, retrain, monitor, investigate, graceful degradation, noise, and human-declined. Each replays against the real agent graph with a hard assertion that no destructive action ever executes without a valid token. The result is roughly 95% task success on live models.
The eval suite surfaced real bugs during development. A JSON parser was masking a correct decision. A classifier got baited by an alert's reassuring wording. A diagnoser proposed rollback on correlation alone. Each was fixed at the right layer, whether parser, fixture, or prompt, instead of being papered over.
What I took away
- Enforcing safety in the tool layer, where the model can't reach it, beats enforcing it by instruction.
- Real data is messier than crafted data. A clean demo often requires injecting a known problem so you have ground truth to validate against.
- The valuable engineering judgment is knowing when the agent should do nothing, and just monitor, rather than act.