nishanttyagi-agenteval 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. nishanttyagi_agenteval-0.1.0/LICENSE +21 -0
  2. nishanttyagi_agenteval-0.1.0/PKG-INFO +290 -0
  3. nishanttyagi_agenteval-0.1.0/README.md +263 -0
  4. nishanttyagi_agenteval-0.1.0/__init__.py +3 -0
  5. nishanttyagi_agenteval-0.1.0/__main__.py +6 -0
  6. nishanttyagi_agenteval-0.1.0/adapters/__init__.py +15 -0
  7. nishanttyagi_agenteval-0.1.0/adapters/agentic_data_analyst.py +155 -0
  8. nishanttyagi_agenteval-0.1.0/adapters/base.py +90 -0
  9. nishanttyagi_agenteval-0.1.0/adapters/contract_shield.py +14 -0
  10. nishanttyagi_agenteval-0.1.0/adapters/data_analyst.py +9 -0
  11. nishanttyagi_agenteval-0.1.0/adapters/scheme_saathi.py +14 -0
  12. nishanttyagi_agenteval-0.1.0/agents.yaml +77 -0
  13. nishanttyagi_agenteval-0.1.0/baselines/data_analyst.json +35 -0
  14. nishanttyagi_agenteval-0.1.0/cli.py +484 -0
  15. nishanttyagi_agenteval-0.1.0/core/__init__.py +1 -0
  16. nishanttyagi_agenteval-0.1.0/core/ci_matrix.py +49 -0
  17. nishanttyagi_agenteval-0.1.0/core/ci_preflight.py +28 -0
  18. nishanttyagi_agenteval-0.1.0/core/compare.py +263 -0
  19. nishanttyagi_agenteval-0.1.0/core/config.py +66 -0
  20. nishanttyagi_agenteval-0.1.0/core/flakiness.py +256 -0
  21. nishanttyagi_agenteval-0.1.0/core/generator.py +174 -0
  22. nishanttyagi_agenteval-0.1.0/core/judge.py +78 -0
  23. nishanttyagi_agenteval-0.1.0/core/metrics.py +574 -0
  24. nishanttyagi_agenteval-0.1.0/core/provenance.py +52 -0
  25. nishanttyagi_agenteval-0.1.0/core/registry.py +216 -0
  26. nishanttyagi_agenteval-0.1.0/core/runner.py +276 -0
  27. nishanttyagi_agenteval-0.1.0/core/schema.py +228 -0
  28. nishanttyagi_agenteval-0.1.0/core/store.py +223 -0
  29. nishanttyagi_agenteval-0.1.0/core/trajectory.py +134 -0
  30. nishanttyagi_agenteval-0.1.0/dashboard/__init__.py +1 -0
  31. nishanttyagi_agenteval-0.1.0/dashboard/app.py +907 -0
  32. nishanttyagi_agenteval-0.1.0/nishanttyagi_agenteval.egg-info/PKG-INFO +290 -0
  33. nishanttyagi_agenteval-0.1.0/nishanttyagi_agenteval.egg-info/SOURCES.txt +90 -0
  34. nishanttyagi_agenteval-0.1.0/nishanttyagi_agenteval.egg-info/dependency_links.txt +1 -0
  35. nishanttyagi_agenteval-0.1.0/nishanttyagi_agenteval.egg-info/entry_points.txt +2 -0
  36. nishanttyagi_agenteval-0.1.0/nishanttyagi_agenteval.egg-info/requires.txt +6 -0
  37. nishanttyagi_agenteval-0.1.0/nishanttyagi_agenteval.egg-info/top_level.txt +1 -0
  38. nishanttyagi_agenteval-0.1.0/pyproject.toml +64 -0
  39. nishanttyagi_agenteval-0.1.0/setup.cfg +4 -0
  40. nishanttyagi_agenteval-0.1.0/tests/golden/analyst_cases.yaml +234 -0
  41. nishanttyagi_agenteval-0.1.0/tests/test_adapter_contract.py +47 -0
  42. nishanttyagi_agenteval-0.1.0/tests/test_adapter_usage.py +32 -0
  43. nishanttyagi_agenteval-0.1.0/tests/test_agentic_data_analyst_trajectory.py +137 -0
  44. nishanttyagi_agenteval-0.1.0/tests/test_ci_matrix.py +15 -0
  45. nishanttyagi_agenteval-0.1.0/tests/test_ci_workflow.py +24 -0
  46. nishanttyagi_agenteval-0.1.0/tests/test_cli_agents.py +80 -0
  47. nishanttyagi_agenteval-0.1.0/tests/test_compare.py +158 -0
  48. nishanttyagi_agenteval-0.1.0/tests/test_config.py +38 -0
  49. nishanttyagi_agenteval-0.1.0/tests/test_dashboard_flakiness.py +88 -0
  50. nishanttyagi_agenteval-0.1.0/tests/test_dashboard_run_selection.py +114 -0
  51. nishanttyagi_agenteval-0.1.0/tests/test_dashboard_trajectory.py +80 -0
  52. nishanttyagi_agenteval-0.1.0/tests/test_flakiness.py +140 -0
  53. nishanttyagi_agenteval-0.1.0/tests/test_flakiness_store.py +188 -0
  54. nishanttyagi_agenteval-0.1.0/tests/test_generator.py +81 -0
  55. nishanttyagi_agenteval-0.1.0/tests/test_metrics_integrity.py +106 -0
  56. nishanttyagi_agenteval-0.1.0/tests/test_packaging.py +41 -0
  57. nishanttyagi_agenteval-0.1.0/tests/test_provenance.py +25 -0
  58. nishanttyagi_agenteval-0.1.0/tests/test_registry.py +126 -0
  59. nishanttyagi_agenteval-0.1.0/tests/test_repeat_cli.py +184 -0
  60. nishanttyagi_agenteval-0.1.0/tests/test_runner_trajectory.py +168 -0
  61. nishanttyagi_agenteval-0.1.0/tests/test_schema_trajectory.py +76 -0
  62. nishanttyagi_agenteval-0.1.0/tests/test_store_git_sha.py +42 -0
  63. nishanttyagi_agenteval-0.1.0/tests/test_trajectory.py +130 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nishant Tyagi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,290 @@
1
+ Metadata-Version: 2.4
2
+ Name: nishanttyagi-agenteval
3
+ Version: 0.1.0
4
+ Summary: CI-integrated evaluation harness for LLM agents
5
+ Author: Nishant Tyagi
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/nishanttyagi28/agenteval
8
+ Project-URL: Repository, https://github.com/nishanttyagi28/agenteval
9
+ Project-URL: Issues, https://github.com/nishanttyagi28/agenteval/issues
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Testing
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: PyYAML<7,>=6.0
22
+ Requires-Dist: pandas<4,>=2.2
23
+ Requires-Dist: streamlit<2,>=1.59
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest<9,>=8; extra == "dev"
26
+ Dynamic: license-file
27
+
28
+ # AgentEval
29
+
30
+ [![AgentEval regression gate](https://github.com/nishanttyagi28/agenteval/actions/workflows/eval.yml/badge.svg?branch=main)](https://github.com/nishanttyagi28/agenteval/actions/workflows/eval.yml)
31
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
32
+ [![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-blue.svg)](pyproject.toml)
33
+ [![Open in Streamlit](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://agenteval-6honbe24hradazngswxkrq.streamlit.app/)
34
+
35
+ **CI for AI agents — pytest and GitHub Actions style evaluation for LLM systems.**
36
+
37
+ AgentEval runs an agent against YAML golden suites, scores five reliability metrics, compares results with a versioned baseline, and turns regressions into a reviewable CI decision.
38
+
39
+ **[Open the live dashboard](https://agenteval-6honbe24hradazngswxkrq.streamlit.app/)**
40
+
41
+ ## Why AgentEval
42
+
43
+ LLM agents are probabilistic. A prompt, model, or tool change can improve one answer while silently reducing correctness elsewhere, increasing hallucinations, or raising latency and cost. Traditional unit tests remain useful for deterministic code, but they do not fully cover model outputs, tool routing, or quality drift across versions.
44
+
45
+ AgentEval adds the missing evaluation layer:
46
+
47
+ - YAML-defined golden test cases
48
+ - deterministic-first scoring with an LLM judge only for open-ended answers
49
+ - baseline comparison and configurable regression gates
50
+ - explicit agent, evaluator, missing-case, and skipped-case failures
51
+ - a Streamlit dashboard for summary, regression, and case-level inspection
52
+ - GitHub Actions automation with a six-case smoke suite and optional 21-case full suite
53
+ - reviewable adversarial variants that remain outside blocking CI until approved
54
+
55
+ ## Evaluation flow
56
+
57
+ ```mermaid
58
+ flowchart TD
59
+ Cases["YAML golden cases"] --> Runner["Agent runner"]
60
+ Runner --> Metrics["Five metrics"]
61
+ Metrics --> Gate["Baseline regression gate"]
62
+ Gate --> CI["GitHub Actions report"]
63
+ Gate --> Dashboard["Streamlit dashboard"]
64
+ ```
65
+
66
+ 1. Define the prompt, ground truth, required tools, and tolerance in YAML.
67
+ 2. Run each case through an adapter for the agent under test.
68
+ 3. Score the output and store a provenance-linked JSON run.
69
+ 4. Compare the current report with a versioned baseline.
70
+ 5. Fail CI when configured quality gates or case-integrity checks are violated.
71
+ 6. Inspect suite and case-level evidence in the dashboard.
72
+
73
+ ## Five metrics
74
+
75
+ | Metric | What it evaluates | Implementation |
76
+ |---|---|---|
77
+ | **Correctness** | Whether the answer matches the expected result | Exact, contains, numeric, numeric-table, or LLM-judge checks |
78
+ | **Hallucination rate** | Unsupported numeric or factual claims | Deterministic ground-truth comparison |
79
+ | **Tool-call accuracy** | Whether the required tools were invoked | Precision, recall, and suite-level F1 |
80
+ | **Latency** | Response-time distribution | p50 and p95 wall-clock latency |
81
+ | **Cost** | Estimated or provider-reported usage cost | Per-case and suite-level USD estimate |
82
+
83
+ Correctness uses the exact tolerance configured in YAML. Hallucination detection applies a separate minimum absolute tolerance of 0.01 for harmless numeric formatting noise; that floor cannot convert an incorrect answer into a correctness pass.
84
+
85
+ ## Failure taxonomy and gate integrity
86
+
87
+ AgentEval distinguishes output quality from execution and evaluation failures:
88
+
89
+ | Status | Meaning | Quality denominators | Default gate behaviour |
90
+ |---|---|---:|---|
91
+ | `failed` | The agent ran but failed an expectation | Included | Can fail metric gates |
92
+ | `agent_error` | Provider, ingestion, SQL, adapter, or execution failure | Excluded | Fails loudly |
93
+ | `evaluator_error` | The evaluator or LLM judge could not produce a valid decision | Excluded | Fails loudly |
94
+ | `skipped` | A case produced no scored result | Excluded | Fails loudly |
95
+ | `missing` | A baseline case is absent from the current run | Not applicable | Fails loudly |
96
+
97
+ Infrastructure failures are not counted as incorrect or hallucinated answers, so provider outages do not corrupt quality rates. They remain visible and fail the regression gate by default. Missing and skipped cases are also gated to prevent an incomplete run from appearing healthy.
98
+
99
+ ## Flakiness detection
100
+
101
+ LLM agents can produce different answers for the same prompt even when the code and inputs have not changed. AgentEval's opt-in repeat mode separates two different problems: an agent can be **consistently wrong** (the same failing verdict every time) or **flaky** (the verdict or comparable numeric value changes across observations). The report stores both consistency and pass rate so repeatability is never mistaken for correctness.
102
+
103
+ Run the normal suite once and repeat only explicitly selected cases:
104
+
105
+ ```bash
106
+ python -m agenteval run \
107
+ --agent agentic_data_analyst \
108
+ --repeat 5 \
109
+ --repeat-case total_customers \
110
+ --repeat-case avg_monthly_charges
111
+ ```
112
+
113
+ `--repeat 5` means five total observations for each selected case: the primary suite result plus four additional invocations. Requiring explicit `--repeat-case` values prevents an accidental N-times increase in API calls across the full suite. The default `--repeat 1` follows the existing single-pass path without creating flakiness evidence.
114
+
115
+ | Classification | Consistency score |
116
+ |---|---:|
117
+ | `stable` | `1.0` |
118
+ | `flaky` | `0.80` to `<1.0` |
119
+ | `unstable` | `<0.80` |
120
+
121
+ These labels are documented defaults rather than information-losing buckets: every artifact retains the raw consistency fraction, such as `4/5`, so thresholds can be adjusted later.
122
+
123
+ Scalar numeric cases use `largest_complete_link_cluster`. Values cluster when the difference between the cluster maximum and minimum remains within the case's existing `numeric_tolerance`; the largest same-verdict cluster wins, and the primary observation receives no special preference. Exact, contains, and LLM-judge cases use verdict consistency. Ambiguous scalar numeric answers and numeric-table cases also fall back to verdict-only consistency.
124
+
125
+ Flakiness is observability-only in this phase. It does not affect the regression gate or baseline comparison. Evidence is stored separately under `runs/<agent>/flakiness/<run_id>.json`, keeping repeated latency, cost, answers, and verdicts isolated from the primary run report.
126
+
127
+ ## Trajectory scoring
128
+
129
+ Trajectory scoring adds step-level evidence about how an agent reached its answer. A golden case can optionally declare the expected ordered events alongside its existing output expectations:
130
+
131
+ ```yaml
132
+ - id: total_customers
133
+ prompt: "How many customers are in the dataset?"
134
+ expects:
135
+ correctness_type: numeric
136
+ ground_truth: 7043
137
+ expected_trajectory: ["route:sql", "agent:sql"]
138
+ ```
139
+
140
+ AgentEval compares `expected_trajectory` with the adapter's actual `nodes_fired` sequence using a longest common subsequence (LCS). The matched subsequence produces precision (matched steps divided by actual steps), recall (matched steps divided by expected steps), and their F1 score, while preserving evidence about exact match, ordering, missing steps, and extra steps. Duplicate steps retain their multiplicity.
141
+
142
+ The field is optional and backward compatible: cases without it are scored and serialized exactly as before. Trajectory scoring is observability-only in v1 and does not affect correctness, existing metrics, baseline comparison, or CI gates.
143
+
144
+ ## Golden case example
145
+
146
+ ```yaml
147
+ - id: avg_tenure_months
148
+ prompt: "What is the average tenure in months?"
149
+ expects:
150
+ correctness_type: numeric
151
+ must_call_tools: [sql_agent]
152
+ must_not_hallucinate: true
153
+ ground_truth: 25.23
154
+ numeric_tolerance: 0.05
155
+ ```
156
+
157
+ The current analyst suite contains 21 hand-written cases grounded in the demonstration dataset.
158
+
159
+ ## Dashboard evidence
160
+
161
+ AgentEval is integrated with [Agentic Data Analyst](https://github.com/nishanttyagi28/agentic-data-analyst), a modular application that routes natural-language questions to SQL, ML, statistics, forecasting, reporting, and RAG components.
162
+
163
+ ### Historical run summary
164
+
165
+ ![AgentEval summary dashboard](assets/summary.png)
166
+
167
+ The screenshot records a specific historical run; it is evidence from that run, not a claim about the current deployment state.
168
+
169
+ ### Regression trade-off
170
+
171
+ ![AgentEval regression dashboard](assets/regression.png)
172
+
173
+ The comparison view exposes trade-offs instead of collapsing health into one number. In the recorded example, correctness improved from 85.7% to 95.2%, while p95 latency and estimated cost both increased.
174
+
175
+ ### Failure drill-down
176
+
177
+ ![AgentEval failure drill-down](assets/failure.png)
178
+
179
+ A numeric answer of approximately 25 months failed against a ground truth of 25.23 with a tolerance of 0.05. The ground truth was intentionally preserved rather than loosened to produce a green result.
180
+
181
+ ## Quickstart
182
+
183
+ Python 3.12 is used by the CI workflow.
184
+
185
+ ```bash
186
+ # Keep both repositories as siblings
187
+ git clone https://github.com/nishanttyagi28/agentic-data-analyst
188
+ git clone https://github.com/nishanttyagi28/agenteval
189
+
190
+ python -m pip install -r agenteval/requirements.txt
191
+ python -m pip install -r agentic-data-analyst/requirements.txt
192
+
193
+ export AGENTIC_ANALYST_PATH="$PWD/agentic-data-analyst"
194
+
195
+ # Run all golden cases
196
+ python -m agenteval run
197
+
198
+ # Compare a current report with the versioned baseline
199
+ python -m agenteval compare \
200
+ --baseline agenteval/baselines/data_analyst.json \
201
+ --current agenteval/runs/<run>.json
202
+
203
+ # Launch the dashboard
204
+ python -m streamlit run agenteval/dashboard/app.py
205
+ ```
206
+
207
+ The repositories must share the same parent directory so Python can resolve the `agenteval` package and the sibling agent dependency.
208
+
209
+ ## GitHub Actions
210
+
211
+ `.github/workflows/eval.yml` runs on pull requests and manual dispatch:
212
+
213
+ - deterministic unit tests and CLI validation run first
214
+ - an internal pull request or manual dispatch can run the live evaluation
215
+ - pull requests use six selected smoke cases
216
+ - manual dispatch with `full_suite=true` runs all 21 golden cases
217
+ - the current report is compared with the versioned baseline
218
+ - evidence is uploaded as a workflow artifact
219
+ - a generated Markdown report is created or updated on the pull request
220
+ - missing `GROQ_API_KEY` produces an explicit skipped-evaluation summary
221
+ - concurrency cancellation and job timeouts prevent stale or runaway runs
222
+
223
+ ## Adversarial robustness
224
+
225
+ Generate reviewable, expectation-preserving candidates:
226
+
227
+ ```bash
228
+ python -m agenteval generate \
229
+ --cases agenteval/tests/golden/analyst_cases.yaml \
230
+ --variants 3 \
231
+ --output agenteval/tests/adversarial/candidates.yaml
232
+ ```
233
+
234
+ Each candidate retains its parent case, ground truth, tool expectations, and mutation type. New variants start with `review_status: candidate` and are not added to the blocking golden gate until reviewed.
235
+
236
+ ## Project structure
237
+
238
+ ```text
239
+ agenteval/
240
+ ├── agents.yaml # Registered agents, adapters, suites, and gate defaults
241
+ ├── adapters/ # Agent interface and concrete adapter
242
+ ├── core/
243
+ │ ├── schema.py # Test-case and run-report models
244
+ │ ├── runner.py # Suite execution
245
+ │ ├── flakiness.py # Repeat consistency analysis and classification
246
+ │ ├── trajectory.py # Step-sequence evaluation and evidence
247
+ │ ├── metrics.py # Correctness, hallucination, tools, latency, cost
248
+ │ ├── judge.py # LLM judge for open-ended correctness
249
+ │ ├── compare.py # Baseline comparison and CI decision
250
+ │ ├── provenance.py # Reproducibility metadata
251
+ │ └── store.py # JSON run persistence
252
+ ├── dashboard/app.py # Streamlit dashboard
253
+ ├── tests/golden/ # Hand-written YAML suite
254
+ ├── baselines/ # Versioned baseline reports
255
+ ├── runs/ # Standard single-pass run artifacts
256
+ │ └── <agent>/
257
+ │ └── flakiness/ # Isolated repeated-run evidence by run_id
258
+ └── .github/workflows/ # CI regression workflow
259
+ ```
260
+
261
+ ## Testing
262
+
263
+ ```bash
264
+ python -m pip install -r requirements-dev.txt
265
+ python -m pytest -q
266
+ python -m agenteval --help
267
+ python -m agenteval compare --help
268
+ ```
269
+
270
+ Deterministic tests cover schema and metrics behaviour, error handling, baseline comparison, missing/skipped-case gates, adversarial generation, provenance, and CLI paths without requiring a live provider call.
271
+
272
+ ## Current limitations
273
+
274
+ - The included adapter and golden suite are demonstrated primarily with Agentic Data Analyst.
275
+ - Live evaluation requires the sibling agent repository, its runtime dependencies, and `GROQ_API_KEY`.
276
+ - LLM-judge correctness is reserved for open-ended cases and introduces provider dependence.
277
+ - Adversarial candidates require human review before entering blocking evaluation.
278
+ - Cost falls back to a character-based token estimate when provider usage is unavailable.
279
+ - Flakiness is not yet part of CI gating and has no cross-agent comparison view.
280
+ - Numeric-table flakiness currently compares verdicts only rather than extracting and clustering each table cell.
281
+ - The smoke suite's only scalar numeric case currently falls back to verdict consistency because its answer restates the same count; `largest_complete_link_cluster` is covered deterministically but has not yet been exercised by a live CI repeat run.
282
+ - Current trajectory depth is limited to the adapter's shallow `route → agent` sequence (typically two events); instrumenting deeper orchestrator events is a candidate for future enrichment.
283
+
284
+ ## License
285
+
286
+ AgentEval is available under the [MIT License](LICENSE).
287
+
288
+ ---
289
+
290
+ Built by [Nishant Tyagi](https://github.com/nishanttyagi28).
@@ -0,0 +1,263 @@
1
+ # AgentEval
2
+
3
+ [![AgentEval regression gate](https://github.com/nishanttyagi28/agenteval/actions/workflows/eval.yml/badge.svg?branch=main)](https://github.com/nishanttyagi28/agenteval/actions/workflows/eval.yml)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
5
+ [![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-blue.svg)](pyproject.toml)
6
+ [![Open in Streamlit](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://agenteval-6honbe24hradazngswxkrq.streamlit.app/)
7
+
8
+ **CI for AI agents — pytest and GitHub Actions style evaluation for LLM systems.**
9
+
10
+ AgentEval runs an agent against YAML golden suites, scores five reliability metrics, compares results with a versioned baseline, and turns regressions into a reviewable CI decision.
11
+
12
+ **[Open the live dashboard](https://agenteval-6honbe24hradazngswxkrq.streamlit.app/)**
13
+
14
+ ## Why AgentEval
15
+
16
+ LLM agents are probabilistic. A prompt, model, or tool change can improve one answer while silently reducing correctness elsewhere, increasing hallucinations, or raising latency and cost. Traditional unit tests remain useful for deterministic code, but they do not fully cover model outputs, tool routing, or quality drift across versions.
17
+
18
+ AgentEval adds the missing evaluation layer:
19
+
20
+ - YAML-defined golden test cases
21
+ - deterministic-first scoring with an LLM judge only for open-ended answers
22
+ - baseline comparison and configurable regression gates
23
+ - explicit agent, evaluator, missing-case, and skipped-case failures
24
+ - a Streamlit dashboard for summary, regression, and case-level inspection
25
+ - GitHub Actions automation with a six-case smoke suite and optional 21-case full suite
26
+ - reviewable adversarial variants that remain outside blocking CI until approved
27
+
28
+ ## Evaluation flow
29
+
30
+ ```mermaid
31
+ flowchart TD
32
+ Cases["YAML golden cases"] --> Runner["Agent runner"]
33
+ Runner --> Metrics["Five metrics"]
34
+ Metrics --> Gate["Baseline regression gate"]
35
+ Gate --> CI["GitHub Actions report"]
36
+ Gate --> Dashboard["Streamlit dashboard"]
37
+ ```
38
+
39
+ 1. Define the prompt, ground truth, required tools, and tolerance in YAML.
40
+ 2. Run each case through an adapter for the agent under test.
41
+ 3. Score the output and store a provenance-linked JSON run.
42
+ 4. Compare the current report with a versioned baseline.
43
+ 5. Fail CI when configured quality gates or case-integrity checks are violated.
44
+ 6. Inspect suite and case-level evidence in the dashboard.
45
+
46
+ ## Five metrics
47
+
48
+ | Metric | What it evaluates | Implementation |
49
+ |---|---|---|
50
+ | **Correctness** | Whether the answer matches the expected result | Exact, contains, numeric, numeric-table, or LLM-judge checks |
51
+ | **Hallucination rate** | Unsupported numeric or factual claims | Deterministic ground-truth comparison |
52
+ | **Tool-call accuracy** | Whether the required tools were invoked | Precision, recall, and suite-level F1 |
53
+ | **Latency** | Response-time distribution | p50 and p95 wall-clock latency |
54
+ | **Cost** | Estimated or provider-reported usage cost | Per-case and suite-level USD estimate |
55
+
56
+ Correctness uses the exact tolerance configured in YAML. Hallucination detection applies a separate minimum absolute tolerance of 0.01 for harmless numeric formatting noise; that floor cannot convert an incorrect answer into a correctness pass.
57
+
58
+ ## Failure taxonomy and gate integrity
59
+
60
+ AgentEval distinguishes output quality from execution and evaluation failures:
61
+
62
+ | Status | Meaning | Quality denominators | Default gate behaviour |
63
+ |---|---|---:|---|
64
+ | `failed` | The agent ran but failed an expectation | Included | Can fail metric gates |
65
+ | `agent_error` | Provider, ingestion, SQL, adapter, or execution failure | Excluded | Fails loudly |
66
+ | `evaluator_error` | The evaluator or LLM judge could not produce a valid decision | Excluded | Fails loudly |
67
+ | `skipped` | A case produced no scored result | Excluded | Fails loudly |
68
+ | `missing` | A baseline case is absent from the current run | Not applicable | Fails loudly |
69
+
70
+ Infrastructure failures are not counted as incorrect or hallucinated answers, so provider outages do not corrupt quality rates. They remain visible and fail the regression gate by default. Missing and skipped cases are also gated to prevent an incomplete run from appearing healthy.
71
+
72
+ ## Flakiness detection
73
+
74
+ LLM agents can produce different answers for the same prompt even when the code and inputs have not changed. AgentEval's opt-in repeat mode separates two different problems: an agent can be **consistently wrong** (the same failing verdict every time) or **flaky** (the verdict or comparable numeric value changes across observations). The report stores both consistency and pass rate so repeatability is never mistaken for correctness.
75
+
76
+ Run the normal suite once and repeat only explicitly selected cases:
77
+
78
+ ```bash
79
+ python -m agenteval run \
80
+ --agent agentic_data_analyst \
81
+ --repeat 5 \
82
+ --repeat-case total_customers \
83
+ --repeat-case avg_monthly_charges
84
+ ```
85
+
86
+ `--repeat 5` means five total observations for each selected case: the primary suite result plus four additional invocations. Requiring explicit `--repeat-case` values prevents an accidental N-times increase in API calls across the full suite. The default `--repeat 1` follows the existing single-pass path without creating flakiness evidence.
87
+
88
+ | Classification | Consistency score |
89
+ |---|---:|
90
+ | `stable` | `1.0` |
91
+ | `flaky` | `0.80` to `<1.0` |
92
+ | `unstable` | `<0.80` |
93
+
94
+ These labels are documented defaults rather than information-losing buckets: every artifact retains the raw consistency fraction, such as `4/5`, so thresholds can be adjusted later.
95
+
96
+ Scalar numeric cases use `largest_complete_link_cluster`. Values cluster when the difference between the cluster maximum and minimum remains within the case's existing `numeric_tolerance`; the largest same-verdict cluster wins, and the primary observation receives no special preference. Exact, contains, and LLM-judge cases use verdict consistency. Ambiguous scalar numeric answers and numeric-table cases also fall back to verdict-only consistency.
97
+
98
+ Flakiness is observability-only in this phase. It does not affect the regression gate or baseline comparison. Evidence is stored separately under `runs/<agent>/flakiness/<run_id>.json`, keeping repeated latency, cost, answers, and verdicts isolated from the primary run report.
99
+
100
+ ## Trajectory scoring
101
+
102
+ Trajectory scoring adds step-level evidence about how an agent reached its answer. A golden case can optionally declare the expected ordered events alongside its existing output expectations:
103
+
104
+ ```yaml
105
+ - id: total_customers
106
+ prompt: "How many customers are in the dataset?"
107
+ expects:
108
+ correctness_type: numeric
109
+ ground_truth: 7043
110
+ expected_trajectory: ["route:sql", "agent:sql"]
111
+ ```
112
+
113
+ AgentEval compares `expected_trajectory` with the adapter's actual `nodes_fired` sequence using a longest common subsequence (LCS). The matched subsequence produces precision (matched steps divided by actual steps), recall (matched steps divided by expected steps), and their F1 score, while preserving evidence about exact match, ordering, missing steps, and extra steps. Duplicate steps retain their multiplicity.
114
+
115
+ The field is optional and backward compatible: cases without it are scored and serialized exactly as before. Trajectory scoring is observability-only in v1 and does not affect correctness, existing metrics, baseline comparison, or CI gates.
116
+
117
+ ## Golden case example
118
+
119
+ ```yaml
120
+ - id: avg_tenure_months
121
+ prompt: "What is the average tenure in months?"
122
+ expects:
123
+ correctness_type: numeric
124
+ must_call_tools: [sql_agent]
125
+ must_not_hallucinate: true
126
+ ground_truth: 25.23
127
+ numeric_tolerance: 0.05
128
+ ```
129
+
130
+ The current analyst suite contains 21 hand-written cases grounded in the demonstration dataset.
131
+
132
+ ## Dashboard evidence
133
+
134
+ AgentEval is integrated with [Agentic Data Analyst](https://github.com/nishanttyagi28/agentic-data-analyst), a modular application that routes natural-language questions to SQL, ML, statistics, forecasting, reporting, and RAG components.
135
+
136
+ ### Historical run summary
137
+
138
+ ![AgentEval summary dashboard](assets/summary.png)
139
+
140
+ The screenshot records a specific historical run; it is evidence from that run, not a claim about the current deployment state.
141
+
142
+ ### Regression trade-off
143
+
144
+ ![AgentEval regression dashboard](assets/regression.png)
145
+
146
+ The comparison view exposes trade-offs instead of collapsing health into one number. In the recorded example, correctness improved from 85.7% to 95.2%, while p95 latency and estimated cost both increased.
147
+
148
+ ### Failure drill-down
149
+
150
+ ![AgentEval failure drill-down](assets/failure.png)
151
+
152
+ A numeric answer of approximately 25 months failed against a ground truth of 25.23 with a tolerance of 0.05. The ground truth was intentionally preserved rather than loosened to produce a green result.
153
+
154
+ ## Quickstart
155
+
156
+ Python 3.12 is used by the CI workflow.
157
+
158
+ ```bash
159
+ # Keep both repositories as siblings
160
+ git clone https://github.com/nishanttyagi28/agentic-data-analyst
161
+ git clone https://github.com/nishanttyagi28/agenteval
162
+
163
+ python -m pip install -r agenteval/requirements.txt
164
+ python -m pip install -r agentic-data-analyst/requirements.txt
165
+
166
+ export AGENTIC_ANALYST_PATH="$PWD/agentic-data-analyst"
167
+
168
+ # Run all golden cases
169
+ python -m agenteval run
170
+
171
+ # Compare a current report with the versioned baseline
172
+ python -m agenteval compare \
173
+ --baseline agenteval/baselines/data_analyst.json \
174
+ --current agenteval/runs/<run>.json
175
+
176
+ # Launch the dashboard
177
+ python -m streamlit run agenteval/dashboard/app.py
178
+ ```
179
+
180
+ The repositories must share the same parent directory so Python can resolve the `agenteval` package and the sibling agent dependency.
181
+
182
+ ## GitHub Actions
183
+
184
+ `.github/workflows/eval.yml` runs on pull requests and manual dispatch:
185
+
186
+ - deterministic unit tests and CLI validation run first
187
+ - an internal pull request or manual dispatch can run the live evaluation
188
+ - pull requests use six selected smoke cases
189
+ - manual dispatch with `full_suite=true` runs all 21 golden cases
190
+ - the current report is compared with the versioned baseline
191
+ - evidence is uploaded as a workflow artifact
192
+ - a generated Markdown report is created or updated on the pull request
193
+ - missing `GROQ_API_KEY` produces an explicit skipped-evaluation summary
194
+ - concurrency cancellation and job timeouts prevent stale or runaway runs
195
+
196
+ ## Adversarial robustness
197
+
198
+ Generate reviewable, expectation-preserving candidates:
199
+
200
+ ```bash
201
+ python -m agenteval generate \
202
+ --cases agenteval/tests/golden/analyst_cases.yaml \
203
+ --variants 3 \
204
+ --output agenteval/tests/adversarial/candidates.yaml
205
+ ```
206
+
207
+ Each candidate retains its parent case, ground truth, tool expectations, and mutation type. New variants start with `review_status: candidate` and are not added to the blocking golden gate until reviewed.
208
+
209
+ ## Project structure
210
+
211
+ ```text
212
+ agenteval/
213
+ ├── agents.yaml # Registered agents, adapters, suites, and gate defaults
214
+ ├── adapters/ # Agent interface and concrete adapter
215
+ ├── core/
216
+ │ ├── schema.py # Test-case and run-report models
217
+ │ ├── runner.py # Suite execution
218
+ │ ├── flakiness.py # Repeat consistency analysis and classification
219
+ │ ├── trajectory.py # Step-sequence evaluation and evidence
220
+ │ ├── metrics.py # Correctness, hallucination, tools, latency, cost
221
+ │ ├── judge.py # LLM judge for open-ended correctness
222
+ │ ├── compare.py # Baseline comparison and CI decision
223
+ │ ├── provenance.py # Reproducibility metadata
224
+ │ └── store.py # JSON run persistence
225
+ ├── dashboard/app.py # Streamlit dashboard
226
+ ├── tests/golden/ # Hand-written YAML suite
227
+ ├── baselines/ # Versioned baseline reports
228
+ ├── runs/ # Standard single-pass run artifacts
229
+ │ └── <agent>/
230
+ │ └── flakiness/ # Isolated repeated-run evidence by run_id
231
+ └── .github/workflows/ # CI regression workflow
232
+ ```
233
+
234
+ ## Testing
235
+
236
+ ```bash
237
+ python -m pip install -r requirements-dev.txt
238
+ python -m pytest -q
239
+ python -m agenteval --help
240
+ python -m agenteval compare --help
241
+ ```
242
+
243
+ Deterministic tests cover schema and metrics behaviour, error handling, baseline comparison, missing/skipped-case gates, adversarial generation, provenance, and CLI paths without requiring a live provider call.
244
+
245
+ ## Current limitations
246
+
247
+ - The included adapter and golden suite are demonstrated primarily with Agentic Data Analyst.
248
+ - Live evaluation requires the sibling agent repository, its runtime dependencies, and `GROQ_API_KEY`.
249
+ - LLM-judge correctness is reserved for open-ended cases and introduces provider dependence.
250
+ - Adversarial candidates require human review before entering blocking evaluation.
251
+ - Cost falls back to a character-based token estimate when provider usage is unavailable.
252
+ - Flakiness is not yet part of CI gating and has no cross-agent comparison view.
253
+ - Numeric-table flakiness currently compares verdicts only rather than extracting and clustering each table cell.
254
+ - The smoke suite's only scalar numeric case currently falls back to verdict consistency because its answer restates the same count; `largest_complete_link_cluster` is covered deterministically but has not yet been exercised by a live CI repeat run.
255
+ - Current trajectory depth is limited to the adapter's shallow `route → agent` sequence (typically two events); instrumenting deeper orchestrator events is a candidate for future enrichment.
256
+
257
+ ## License
258
+
259
+ AgentEval is available under the [MIT License](LICENSE).
260
+
261
+ ---
262
+
263
+ Built by [Nishant Tyagi](https://github.com/nishanttyagi28).
@@ -0,0 +1,3 @@
1
+ """AgentEval — CI-integrated evaluation harness for LLM agents."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,6 @@
1
+ """Allow `python -m agenteval` once cli is implemented."""
2
+
3
+ from agenteval.cli import main
4
+
5
+ if __name__ == "__main__":
6
+ main()
@@ -0,0 +1,15 @@
1
+ """Agent adapters for AgentEval."""
2
+
3
+ from agenteval.adapters.base import AgentAdapter, AgentResponse, AgentRun
4
+ from agenteval.adapters.agentic_data_analyst import (
5
+ AgenticDataAnalystAdapter,
6
+ DataAnalystAdapter,
7
+ )
8
+
9
+ __all__ = [
10
+ "AgentAdapter",
11
+ "AgentResponse",
12
+ "AgentRun",
13
+ "AgenticDataAnalystAdapter",
14
+ "DataAnalystAdapter",
15
+ ]