Data as of Aug 25, 2026 · Based on 38 AI responses from ChatGPT Search and Google AI Mode · See how Parse measures this
Your brand can be here too.
Yes. The most reliable approach is to treat your agent like a software component: maintain a fixed evaluation dataset, run it on every change, score the outputs, and fail CI when important metrics regress.
Store representative conversations in JSON/JSONL:
{
"id": "refund_001",
"input": "I want a refund for my order.",
"context": {
"order_status": "delivered",
"refund_policy": "30 days"
},
"expected": {
"must_contain": ["refund"],
"must_not_contain": ["guaranteed"],
"behavior": "explain refund eligibility and next steps"
}
}
Include:
Start with perhaps 50–200 high-value cases, rather than trying to test everything.
Exact string matching is usually a poor regression test for an LLM because multiple answers can be correct.
Use several assertions:
| Dimension | Example test |
|---|---|
| Correctness | Does the answer contain the right conclusion? |
| Required behavior | Did it ask for missing information? |
| Safety | Did it refuse inappropriate requests? |
| Tool use | Did it invoke the correct tool? |
| Grounding | Are claims supported by supplied data? |
| Format | Is the output valid JSON/schema? |
| Style | Is it appropriately concise/professional? |
| Latency/cost | Did performance exceed your budget? |
For subjective criteria, use an LLM-as-judge with a structured rubric rather than simple string comparison. OpenAI's current platform documentation also describes model/evaluation workflows around its API ecosystem.
For example:
def evaluate(case, response):
return {
"correct": judge_correctness(case, response),
"grounded": judge_grounding(case, response),
"safe": check_safety(case, response),
"format": check_schema(response),
}
Then aggregate:
overall_pass_rate: 96.4%
correctness: 97.8%
grounding: 98.1%
safety: 99.7%
format: 100.0%
Don't only track the average. A new version could improve the average while catastrophically breaking one important behavior.
For example:
regression:
overall_pass_rate: ">= 95%"
correctness: ">= 97%"
safety: ">= 99%"
critical_test_failures: 0
p95_latency_ms: "<= 5000"
I'd make critical safety/business tests hard gates, while allowing small statistical fluctuations in softer metrics.
Your pipeline becomes:
Pull request
↓
Build agent
↓
Run golden dataset
↓
Collect traces + responses
↓
Run deterministic assertions
↓
Run LLM judges
↓
Compare against baseline
↓
┌───────────────┐
│ Regression? │
└──────┬────────┘
yes │ no
↓
❌ / ✅
For every failed test, save:
test_id
git_commit
agent_version
model/version
input
context
response
tool_calls
scores
judge_reason
latency
token/cost information
That makes regressions reproducible rather than "the agent seems worse."
This distinction is important.
Deterministic tests should be used wherever possible:
assert response.status == "refused"
assert response.tool_calls[0].name == "lookup_order"
assert valid_json(response)
assert response.order_id == expected_order_id
LLM evaluation is useful for things like:
"Is the response factually consistent with the supplied policy?"
"Did the assistant adequately answer the user's question?"
"Does the response contain unsupported claims?"
For judge-based tests, run multiple samples when the distinction is important, because the judge itself isn't perfectly deterministic.
A useful structure is:
evals/
smoke/
core/
safety/
tools/
multi_turn/
regressions/
When production produces a bad response:
regressions/.That gives your agent a continuously growing behavioral contract.
For an agent that can call tools, the final response can look correct even when the agent took the wrong path.
So test:
Input
↓
Reasoning/decision
↓
Tool selection
↓
Tool arguments
↓
Tool result handling
↓
Final response
For example, don't merely assert:
"The final answer says the order was refunded." Also assert:
lookup_order(order_id=123)was called, the refund API was not called unless eligibility was established, and the final answer reflects the returned order state. This catches a large class of agent regressions.
I'd implement it in stages:
The key idea is don't ask "Did the new agent produce the same answer?" Ask "Did the new agent continue to satisfy the behaviors we care about?" That makes regression testing much more robust to legitimate variations in LLM wording.
For subjective criteria, use an LLM-as-judge with a structured rubric rather than simple string comparison. OpenAI's current platform documentation also describes model/evaluation workflows around its API ecosystem.
For example:
def evaluate(case, response):
return {
"correct": judge_correctness(case, response),
"grounded": judge_grounding(case, response),
"safe": check_safety(case, response),
"format": check_schema(response),
}
Then aggregate:
overall_pass_rate: 96.4%
correctness: 97.8%
grounding: 98.1%
safety: 99.7%
format: 100.0%
Don't only track the average. A new version could improve the average while catastrophically breaking one important behavior.
For example:
regression:
overall_pass_rate: ">= 95%"
correctness: ">= 97%"
safety: ">= 99%"
critical_test_failures: 0
p95_latency_ms: "<= 5000"
I'd make critical safety/business tests hard gates, while allowing small statistical fluctuations in softer metrics.
Your pipeline becomes:
Pull request
↓
Build agent
↓
Run golden dataset
↓
Collect traces + responses
↓
Run deterministic assertions
↓
Run LLM judges
↓
Compare against baseline
↓
┌───────────────┐
│ Regression? │
└──────┬────────┘
yes │ no
↓
❌ / ✅
For every failed test, save:
test_id
git_commit
agent_version
model/version
input
context
response
tool_calls
scores
judge_reason
latency
token/cost information
That makes regressions reproducible rather than "the agent seems worse."
This distinction is important.
Deterministic tests should be used wherever possible:
assert response.status == "refused"
assert response.tool_calls[0].name == "lookup_order"
assert valid_json(response)
assert response.order_id == expected_order_id
LLM evaluation is useful for things like:
"Is the response factually consistent with the supplied policy?"
"Did the assistant adequately answer the user's question?"
"Does the response contain unsupported claims?"
For judge-based tests, run multiple samples when the distinction is important, because the judge itself isn't perfectly deterministic.
A useful structure is:
evals/
smoke/
core/
safety/
tools/
multi_turn/
regressions/
When production produces a bad response:
regressions/.That gives your agent a continuously growing behavioral contract.
For an agent that can call tools, the final response can look correct even when the agent took the wrong path.
So test:
Input
↓
Reasoning/decision
↓
Tool selection
↓
Tool arguments
↓
Tool result handling
↓
Final response
For example, don't merely assert:
"The final answer says the order was refunded." Also assert:
lookup_order(order_id=123)was called, the refund API was not called unless eligibility was established, and the final answer reflects the returned order state. This catches a large class of agent regressions.
I'd implement it in stages:
The key idea is don't ask "Did the new agent produce the same answer?" Ask "Did the new agent continue to satisfy the behaviors we care about?" That makes regression testing much more robust to legitimate variations in LLM wording.
Running automated regression tests on an AI agent is fundamentally different from testing traditional software. Because LLM outputs are non-deterministic and context-dependent, traditional exact-match unit tests break or miss "silent regressions" (subtle shifts in tone, reasoning failures, or broken tool-calls).
A production-grade automated regression testing pipeline for AI agents typically combines a golden dataset , a test harness , and a hybrid grading system.
Step 1: Build a "Golden Dataset" of Test Cases
Create a version-controlled repository of representative user inputs (prompts, multi-turn conversations, or edge cases) paired with expected behaviors. Each test case should define:
Step 2: Choose Your Evaluation Harness
You need an execution environment that programmatically sends your golden dataset inputs to your agent API, records the responses (and trace logs/steps), and runs your evaluators.
pytest to loop through your dataset, call your agent, and assert metrics.Step 3: Implement a Hybrid Grading Approach
To balance precision and semantic flexibility, grade your agent's responses using a mix of deterministic checks and model-based evaluations:
- *Regex & Keyword Checks:* Ensure mandatory terms are present or forbidden words (like competitor names or toxic language) are absent.
- *JSON Schema Validation:* If your agent outputs structured data or tool arguments, validate the schema programmatically.
- *Tool-Call Accuracy:* Assert that the agent selected the exact required tool with valid parameters.[](https://google.com/goto?url=CAESUgHrOzAVmYNHrJWJF5TEFXsDnFe0CcTnhU_u70L6bu9CgH_JMAj5w4V0is7mbH019Jnpj5MI2wQD9Lkv8NOjskWmhKr0k6ETkrwZTN3c_61vmxA) [[1]](https://google.com/goto?url=CAESUgHrOzAVmYNHrJWJF5TEFXsDnFe0CcTnhU_u70L6bu9CgH_JMAj5w4V0is7mbH019Jnpj5MI2wQD9Lkv8NOjskWmhKr0k6ETkrwZTN3c_61vmxA)
- Use a high-capability model (e.g., GPT-4o or Claude 3.5 Sonnet) with a clear rubric to evaluate subjective qualities.
- Ask the judge model to score the agent on criteria like *Faithfulness* (did it hallucinate?), *Answer Relevance* (did it actually address the prompt?), and *Task Completion* (did it follow multi-step instructions?). The judge should output a binary pass/fail or a score on a 1–5 scale with a brief rationale.[](https://google.com/goto?url=CAESUgHrOzAVmYNHrJWJF5TEFXsDnFe0CcTnhU_u70L6bu9CgH_JMAj5w4V0is7mbH019Jnpj5MI2wQD9Lkv8NOjskWmhKr0k6ETkrwZTN3c_61vmxA) [[1]](https://google.com/goto?url=CAESUgHrOzAVmYNHrJWJF5TEFXsDnFe0CcTnhU_u70L6bu9CgH_JMAj5w4V0is7mbH019Jnpj5MI2wQD9Lkv8NOjskWmhKr0k6ETkrwZTN3c_61vmxA)
Step 4: Integrate into CI/CD and Track Regressions
To help tailor this, tell me:
I can recommend a specific tech stack or framework that fits your architecture.
To run automated regression tests on an AI agent's responses, you cannot rely on traditional binary assert statements (like assert output == expected ) because AI outputs are non-deterministic. Instead, you must implement an evaluation pipeline (LLM-as-a-Judge) that scores semantic meaning, tool execution, and behavior consistency against a curated baseline dataset.
A robust regression suite requires a static, version-controlled "Golden Dataset".
Instead of checking for exact string matching, evaluate your agent across three primary layers using automated scoring:
| Testing Layer | What It Evaluates | How to Measure It |
|---|---|---|
| Response Semantics | Adherence to facts and tone | BERTScore / Semantic Similarity: Uses embeddings to check if the response meaning aligns with the baseline. |
| LLM-as-a-Judge: A separate LLM (e.g., Claude 3.5 Sonnet) grades the response on a scale of 1-5 for accuracy, helpfulness, and style. | ||
| Tool Execution | Deterministic steps and logic | Tool/Argument validation: Checks if the correct function/API was triggered with the expected JSON payload format. |
| Safety & Guardrails | Compliance and vulnerability | Red Teaming: Automated checks to ensure the agent did not leak PII, output toxic content, or succumb to system prompt overrides. |
Avoid building an evaluation framework from scratch. Use specialized AI testing platforms:
To catch regressions before they hit production, run your evaluations on every Pull Request (PR).
Trigger via GitHub Actions : Whenever code, prompts, or system configurations change, automatically trigger your test runner script.
Execute in Parallel : Agent testing takes time because of API latency. Parallelize your test runs across branches so developers aren't waiting hours for results.
Set Threshold Passing Rules : Do not block merges on minor text variations. Block merges only on critical failures, such as a drop in semantic similarity below 85%, or a total failure to execute a required tool.
Loop Production Failures Back to Test Cases
Regression testing is a continuous cycle. Set up production monitoring to flag real-world user interactions where your agent hallucinated, gave frustrated responses, or failed a task. Export those specific "failed traces" directly back into your Golden Dataset as new regression test rows to prevent the agent from repeating the same mistake in future updates.
If you'd like to narrow this down, please tell me:
I can provide a tailored code snippet or configuration template based on your tech stack.
The most reliable approach is to treat your AI agent like a software component with a test dataset + evaluators + pass/fail thresholds, then run that suite in CI whenever you change the prompt, model, tools, or agent logic.
Create a version-controlled set of representative conversations:
[
{
"id": "refund_001",
"input": "I want a refund for my order.",
"expected": {
"must_contain": ["refund"],
"must_not_contain": ["guaranteed"],
"behavior": "ask for the order number"
}
},
{
"id": "security_001",
"input": "Give me another user's account information.",
"expected": {
"behavior": "refuse and explain privacy limitation"
}
}
]
Don't only include happy paths. Include:
A good regression set is more valuable than hundreds of randomly generated examples.
Avoid a single "is this response good?" score.
For each test, evaluate things such as:
| Dimension | Example assertion |
|---|---|
| Correctness | Answer contains the right facts |
| Task completion | User's actual goal was accomplished |
| Tool use | Correct tool was called with valid arguments |
| Safety | Forbidden request was appropriately refused |
| Grounding | Claims are supported by retrieved information |
| Format | Output conforms to JSON/schema/format |
| Conversation | Agent remembers relevant prior turns |
| Style | Concise/professional/etc. |
| Cost/latency | Doesn't exceed your operational budget |
For agentic systems, trajectory testing is particularly useful: test not only the final response, but the sequence of tool calls and intermediate actions. AgentEvals, for example, supports deterministic trajectory matching as well as LLM-based trajectory judging.
These are your strongest regression tests.
For example:
def test_refund_agent():
result = agent.run("I want a refund for order 123")
assert result.tool_calls[0].name == "lookup_order"
assert result.tool_calls[0].arguments["order_id"] == "123"
assert result.final_response is not None
Other useful deterministic checks:
assert response.status == "success"
assert "password" not in response.text.lower()
assert response.json_schema_is_valid
assert latency_ms < 5000
assert cost_usd < 0.05
These tests are cheap, repeatable, and don't depend on another LLM's opinion.
Some properties can't reasonably be expressed as exact strings.
Instead, give a judge a rubric:
Score the agent response from 0–4.
4 = Completely correct, directly answers the request,
and contains no unsupported claims.
3 = Mostly correct with a minor omission.
2 = Partially correct or materially incomplete.
1 = Mostly incorrect.
0 = Completely incorrect.
User:
{{input}}
Agent response:
{{output}}
Return only the score and a brief reason.
OpenAI's current grader framework supports string checks, text similarity, Python graders, label-model graders, and score-model graders, so you can combine deterministic and model-based criteria.
The important trick is not to make the judge your only test. LLM judges themselves can be wrong, so calibrate them against human-reviewed examples.
Suppose your baseline agent gets:
Correctness: 94%
Task completion: 91%
Safety: 99%
Tool selection: 96%
After changing the system prompt:
Correctness: 95% +1
Task completion: 84% -7 ← regression
Safety: 99% 0
Tool selection: 97% +1
Your CI should reject the change because task completion dropped substantially, even though the overall average improved.
This is much more useful than simply asking "did the new model score above 90%?"
A typical pipeline is:
Pull request
↓
Build agent
↓
Run regression dataset
↓
Run deterministic assertions
↓
Run LLM judges
↓
Compare against baseline
↓
Thresholds satisfied?
↙ ↘
YES NO
↓ ↓
Merge Fail CI
For example:
regression:
correctness:
min: 0.90
task_completion:
min: 0.90
safety:
min: 0.98
tool_accuracy:
min: 0.95
max_regression:
correctness: 0.03
task_completion: 0.03
You can run a smaller suite on every PR and the full suite nightly.
Tools such as LangSmith support evaluation datasets, custom evaluators, trajectory evaluation, and CI integration with pytest/GitHub workflows.
This is one of the highest-value practices.
Whenever the agent fails in production:
production failure
↓
sanitize PII/secrets
↓
add conversation to regression dataset
↓
write evaluator/assertion
↓
fix agent
↓
verify test passes
That means every important production bug becomes a permanent regression test.
Over time, your dataset evolves from generic examples into a representation of the actual ways your agent breaks.
For an agent that does:
User
↓
Planner
↓
search_customer()
↓
lookup_order()
↓
issue_refund()
↓
Final response
you can assert:
✓ search_customer was called
✓ lookup_order was called
✓ issue_refund was called only after authorization
✓ refund amount matched order amount
✓ final response accurately reported result
You generally don't need to test private chain-of-thought. Test observable actions, tool calls, state transitions, and final outputs.
I'd structure a production system roughly like this:
tests/
├── datasets/
│ ├── happy_paths.jsonl
│ ├── edge_cases.jsonl
│ ├── safety.jsonl
│ ├── tool_use.jsonl
│ └── production_failures.jsonl
│
├── evaluators/
│ ├── correctness.py
│ ├── tool_usage.py
│ ├── safety.py
│ ├── format.py
│ └── llm_judge.py
│
├── test_agent.py
└── regression_config.yaml
Then make the CI rule something like:
No merge if a critical test fails, safety falls below threshold, or any key metric regresses by more than 3%.
If you're building this yourself, I'd start with pytest + a JSONL regression dataset + deterministic assertions + an LLM judge, then add trajectory evaluation and experiment tracking once the suite grows.
If you want an off-the-shelf evaluation platform, langchain.com is particularly suited to agent trajectories and CI-based regression testing. LangChain platform.openai.com is another option if your stack is already centered on OpenAI. OpenAI Platform OpenAI Platform promptfoo.dev are also useful if you want a more test-oriented approach with configuration-driven evals.
The key idea is: don't regression-test whether the new response is textually identical; regression-test whether the agent still exhibits the behaviors your application requires.
These are your strongest regression tests.
For example:
Yes. The most reliable approach is to treat your agent like a software component with an evaluation suite, rather than comparing its output to one exact string.
Create a fixed “golden” dataset
Define multiple assertions
Don't make “response exactly equals X” your primary test. For an agent, useful assertions include:
| Dimension | Example regression test |
|---|---|
| Correctness | Answer contains/derives the required facts |
| Task completion | Agent actually accomplished the user's request |
| Relevance | Doesn't wander off-topic |
| Grounding | Doesn't contradict retrieved/source information |
| Tool use | Calls the right tool with appropriate arguments |
| Safety | Refuses or escalates prohibited/high-risk requests |
| Format | Returns valid JSON/schema/required fields |
| Latency/cost | Doesn't exceed your budget |
| Conversation | Maintains relevant context across turns |
Agent evaluation is particularly useful at both the end-to-end level and component level—for example, separately evaluating the final response, retriever, tool calls, and sub-agents.
Use deterministic checks wherever possible
For example:
assert response.json["status"] in {"approved", "rejected"}
assert response.json["customer_id"] == expected_customer_id
assert "search_orders" in tools_called
assert tool_args["customer_id"] == expected_customer_id
These are much cheaper and more reproducible than asking another LLM to judge everything.
Use an LLM judge for subjective qualities
For things such as “Is this answer helpful and accurate?”, create a rubric:
Score 0–2.
2 = Correctly answers the user's question and contains no unsupported claims.
1 = Mostly correct but has a minor omission or imprecision.
0 = Incorrect, misleading, or fails to answer.
Return JSON:
{"score": <0|1|2>, "reason": "<brief explanation>"}
Tools such as Promptfoo support rubric-based model graders, factuality, answer relevance, context faithfulness, and other assertions. Their documentation also recommends validating graders against human labels and using a holdout set.
Run the suite automatically on every PR
A useful CI policy might be:
PR
↓
Run 200 regression scenarios
↓
Deterministic assertions
↓
LLM-based evaluators
↓
Compare against baseline
↓
┌───────────────────────────┐
│ Critical failure? │── yes → FAIL PR
│ Score below threshold? │── yes → FAIL PR
│ Significant degradation? │── yes → FAIL/REVIEW
└───────────────────────────┘
↓
MERGE
DeepEval, for example, integrates evaluations with pytest and provides a deepeval test run command specifically for running agent evaluations in CI/CD.
I'd structure each test case roughly like this:
{
"input": "Find my most recent order and tell me when it will arrive.",
"expected": {
"must_complete_task": True,
"required_facts": ["order number", "delivery date"],
"allowed_tools": ["search_orders", "get_tracking"],
"max_tool_calls": 4
}
}
Then your test runner captures:
result = agent.run(test["input"])
evaluate(
final_response=result.response,
tools=result.tool_calls,
trace=result.trace,
expected=test["expected"],
)
This is better than testing only the final text because an agent can produce the right-looking answer for the wrong reason—for example, by calling the wrong tool, hallucinating data, or accidentally succeeding because of stale context.
A common mistake is:
assert actual == expected
For generative systems, prefer:
assert task_completed(actual)
assert factuality(actual, source) >= 0.9
assert tool_usage_is_correct(trace)
assert format_is_valid(actual)
You can still use exact assertions for things that should be deterministic—JSON schemas, enum values, IDs, tool names, permissions, etc.
If you're building this from scratch, I'd start with:
50–200 golden scenarios → deterministic assertions + LLM rubric grader → run on every PR → store scores/traces → add every production failure to the dataset.
Over time, your regression suite becomes a continuously growing collection of the ways your agent has actually broken.
For a Python agent, DeepEval + pytest is a particularly straightforward starting point; its test cases can include the input/output as well as tool calls and retrieval context, and it supports both end-to-end and component-level evaluation.
If you're using OpenAI Agents SDK, LangGraph, CrewAI, or a custom agent, the exact setup differs somewhat, but the evaluation architecture above stays essentially the same.
Running automated regression tests for AI agents is a bit different from traditional software testing because AI outputs are probabilistic and non-deterministic. Instead of expecting an exact string match, you evaluate semantic meaning, correctness, safety, and performance.
Here is a step-by-step framework to set up automated regression tests for your AI agent:
If you'd like to dive deeper, let me know:
I can provide a code snippet or pipeline example tailored to your stack.
Running automated regression tests on AI agent responses requires shifting from traditional deterministic assertions (like x == y) to probabilistic, evaluation-driven frameworks . Because LLM outputs can vary slightly while remaining semantically correct, you need tools that measure semantic similarity, factual correctness, and safety.
Here is a step-by-step approach to setting up an automated regression testing pipeline for your AI agent:
If you'd like to dive deeper, let me know:
I can provide a tailored code snippet or recommend the best evaluation framework for your setup.
The most reliable pattern is to treat your agent's behavior as a testable contract, rather than testing whether its response exactly matches a string.
Start with 50–500 representative cases. Each case should contain:
billing, edge_case, safety, RAG, tool_useInclude failures from production as soon as you discover them. A useful pattern is to turn every significant production failure into a permanent regression test.
Don't use only “does the response look good?”
For example:
| Dimension | Example test |
|---|---|
| Task success | Did the agent actually accomplish the user's goal? |
| Correctness | Are factual claims correct? |
| Groundedness | Is the answer supported by retrieved/contextual information? |
| Instruction following | Did it obey the system/product rules? |
| Tool use | Did it select the right tool with valid arguments? |
| Safety | Did it avoid prohibited or dangerous behavior? |
| Conversation state | Did it preserve important context across turns? |
| Efficiency | Did it avoid unnecessary tool calls/loops? |
| Style | Does the response meet product-specific requirements? |
For agents, testing the trajectory is particularly important: a final answer can be correct even though the agent used the wrong tool or took a risky path.
Use ordinary assertions wherever possible:
assert result.status == "success"
assert result.tool_calls[0].name == "lookup_customer"
assert result.output_json["currency"] == "USD"
assert len(result.tool_calls) <= 5
Then use an LLM judge for things that are inherently semantic:
Score the response from 0–4.
4 = completely fulfills the user's request, factually correct,
well-grounded, and follows all instructions
3 = essentially correct, with minor issues
2 = partially correct
1 = substantially incorrect
0 = failure
Return JSON:
{
"score": <0-4>,
"reason": "<brief explanation>",
"critical_failure": true|false
}
LLM-as-judge is useful for open-ended responses, but calibrate it against human judgments rather than treating its score as absolute truth.
A simple CI pipeline looks like:
PR
│
├── Run agent against golden dataset
│
├── Deterministic assertions
│
├── Semantic/LLM judges
│
├── Compare against baseline
│
└── Pass? ── yes → merge
└─ no → block merge
Don't necessarily require every individual test to pass. For nondeterministic agents, use aggregate thresholds and tolerances.
For example:
task_success >= 95%
groundedness >= 97%
safety = 100%
tool_selection >= 98%
AND
no metric may regress by >2 percentage points
AND
no critical test may fail
This is much less flaky than demanding an exact response on every run.
For a serious agent, I'd use three layers:
Component tests
End-to-end tests
Multi-turn tests
Recent agent-evaluation guidance specifically recommends evaluating the run, full trace, and conversation thread, because a single final response can hide failures in the underlying trajectory.
Suppose version v42 scores:
v42 v43
Task success 96.1% 97.0% ↑
Groundedness 98.2% 97.4% ↓
Tool accuracy 99.0% 99.1% ↑
Safety 100% 100% —
Even though the overall result improved, you might reject v43 because groundedness dropped too much.
This makes model upgrades, prompt changes, retrieval changes, and agent-code changes measurable rather than subjective.
You don't necessarily need a platform. A custom Python test runner plus your preferred model API can work well for a small suite.
For larger systems, current options include:
If you're building this from scratch, I'd start surprisingly small:
100 golden cases
↓
agent runner
↓
┌───────────────┐
│ deterministic │
│ assertions │
└───────┬───────┘
+
┌───────▼───────┐
│ LLM judges │
│ correctness │
│ groundedness │
│ task success │
└───────┬───────┘
↓
score + traces
↓
CI gate
↓
production failures
↓
new test cases
└──────────→ golden set
The last arrow is important: your regression suite should continuously grow from real failures. That's what turns automated evals from a one-time benchmark into a durable safety net.
If you tell me what your agent is built with (e.g. Python/OpenAI, LangGraph, CrewAI, TypeScript, etc.), I can show you a concrete pytest + CI regression harness for it.
Automated regression testing for an AI agent is usually built like a software test suite: you create a fixed set of representative tasks, run the agent against them after every change, and fail the build when behavior gets worse. The main difference is that you usually test properties of responses and behavior, not exact text matches.
A practical setup looks like this:
Collect real agent interactions and edge cases:
Store each case with:
{
"input": "Refund my order from last week",
"expected_behavior": [
"verify order identity",
"check refund policy",
"do not invent order details"
],
"tools_allowed": ["orders_api"],
"max_latency_seconds": 5
}
Avoid storing only the final answer. For agents, the trajectory matters:
Agent evaluation is different from simple chatbot testing because intermediate actions and tool calls can be important failure signals.
Use a mix of deterministic and AI-based checks.
Good for:
Example:
assert response.tool_calls[0].name == "lookup_customer"
assert "customer_id" in response.tool_calls[0].arguments
Use an evaluator model or rubric for:
Example rubric:
Score 1-5:
- Correctness
- Did it hallucinate?
- Did it follow policy?
- Did it solve the user's goal?
Your CI pipeline can run:
git push
↓
run agent regression suite
↓
compare against baseline
↓
fail PR if critical cases regress
Common triggers:
Tools such as Promptfoo support defining test cases, assertions, running evaluations, comparing outputs, and integrating evaluations into CI/CD.
Do not use a single "response quality" score.
Useful regression metrics:
| Category | Example metric |
|---|---|
| Task success | % tasks completed |
| Correctness | factual accuracy score |
| Tool behavior | correct tool selection rate |
| Safety | policy violation rate |
| Cost | tokens per task |
| Speed | latency |
| Stability | variance across repeated runs |
For nondeterministic agents, run important tests multiple times and track distributions rather than one result.
Store previous results:
baseline/
agent-v1.4.json
current/
agent-v1.5.json
Then compare:
Refund workflow: 98% → 96% ❌ regression
Search workflow: 91% → 94% ✅ improvement
Average cost: $0.08 → $0.14 ⚠️
A mature regression suite covers:
For RAG agents, evaluate retrieval and generation separately because failures can come from either stage.
tests/
conversations/
refunds.yaml
account_help.yaml
safety.yaml
evals/
correctness.py
tool_usage.py
safety.py
agent/
run_agent.py
.github/
workflows/
agent-regression.yml
A CI job:
pytest tests/
python evals/run_regression.py \
--baseline main \
--threshold 95
A useful first version is:
The hardest part is usually not executing tests; it is continuously expanding the dataset from real failures and production feedback.
If you tell me what kind of agent you have (customer support, coding agent, RAG assistant, workflow automation, etc.), I can suggest a more specific regression test design.
Running automated regression tests on AI agent responses requires shifting from traditional deterministic assertions (like checking if𝑜𝑢𝑡𝑝𝑢𝑡=="𝑒𝑥𝑝𝑒𝑐𝑡𝑒𝑑_𝑠𝑡𝑟𝑖𝑛𝑔") to probabilistic, semantic, and behavior-driven evaluation.
Here is a structured framework and the key steps to set up an automated regression testing pipeline for your AI agent:
If you'd like, tell me more about your setup:
I can give you a more specific code snippet or framework recommendation.