I’ve been building AI apps with coding agents for a while.
Lately, I’ve been experimenting with evals too.
The app in this example mostly worked. That was the problem.
The bug
I built a small support-triage app for a fictional shipment-tracking company.
A customer sends a support ticket, and the app decides what it is about, how urgent it is, and whether a human needs to respond.
A real outage should be escalated.
But this ticket was different:
“URGENT need key rotation now”
The customer was asking how to rotate their own API key before a security review.
The app classified it as a security incident and escalated it to a human.
That was wrong. The policy said normal key rotation was a self-service how-to request.
Nothing crashed. The app returned valid JSON. The fields all contained allowed values.
The behavior was still wrong.
Why clicking around wasn’t enough
I could test a few tickets manually and convince myself the app worked.
But after changing the prompt, what would I actually know?
Would the outage case still escalate?
Would normal how-to questions stay in the normal queue?
Would another API-key question behave differently?
I didn’t want to change the prompt and simply hope for the best.
I wanted a set of cases I could run again.
Adding DeepEval with Cursor
I installed the DeepEval agent skill:
npx skills add confident-ai/deepeval --skill "deepeval"
Then I asked Cursor to add evals to the app:
This app sometimes treats normal support questions like emergencies and sends
them to a human.
Add DeepEval so I can test this using the tickets and policy already in the repo.
I am new to evals, so use the simplest setup DeepEval already provides, explain
what you create, and ask me anything you need.
Run the app as it is first and show me what fails. Do not fix it yet.
Cursor already had the app, tickets, and policy, so it went straight to creating the baseline.
Goldens are the checklist
The first useful artifact was a JSON dataset.
Each golden contained:
the customer message
the expected category
the expected priority
whether a human should be involved
For example:
{
"input": "URGENT need key rotation now",
"expected": {
"category": "how-to",
"priority": "P3",
"needs_human": false
}
}
The app does not learn from these examples.
The dataset is a checklist. It tells me which behaviors need to keep working before I ship a prompt update.
That was the part that made evals click for me.
The metrics
Cursor used built-in DeepEval metrics to check two different things.
The first compared the app’s routing fields with the expected values in the golden:
- category
- priority
- human escalation The second checked whether the decision followed the escalation rules in the policy.
So I could ask two separate questions:
- Did the app return the expected decision?
- Does that decision make sense under the policy?
The baseline failure
The first run caught the key-rotation case.
The app returned:
category: security
priority: P1
needs_human: true
The expected result was:
category: how-to
priority: P3
needs_human: false
The output was valid. The behavior was not.
The policy check also gave Cursor a reason explaining why the decision did not fit the support rules.
That was already more useful than changing the prompt, clicking the same ticket again, and hoping I hadn’t broken something else.
Fixing the prompt
The failure pointed back to an over-broad instruction in the triage prompt.
It was treating anything involving API keys as a security incident.
That was too aggressive.
The fix was to reserve escalation for actual compromise, suspicious access, or an outage.
Then Cursor reran the same test cases.
The key-rotation case passed.
The real outage case still escalated.
That second part matters. Fixing one case is not enough. I also want to know that I didn’t break a case that was already working.
The loop
This is the workflow I’ve been using:
Build the app
Create test cases
Run the app
Read the failure
Fix the prompt
Run the same cases again
Without evals, I would change the prompt and hope I didn’t create three new bugs.
With evals, every prompt change has a checklist behind it.
I recorded the full workflow here:
Watch the video: https://x.com/juampitech/status/2084330588593385637?s=20
DeepEval is open source and runs locally. You don’t need a Confident AI account for this workflow. LLM-as-a-judge metrics require a model API key.
DeepEval Vibe Coder quickstart:
Top comments (0)