layaeval 0.1.2__tar.gz → 0.1.4__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.
@@ -0,0 +1,506 @@
1
+ Metadata-Version: 2.4
2
+ Name: layaeval
3
+ Version: 0.1.4
4
+ Summary: Agent and RAG evaluation metrics powered by the Laya MCP server
5
+ Keywords: evaluation,rag,agent,llm-as-judge,laya,mcp,groundedness,faithfulness,metrics,ai-evaluation,hallucination,tool-accuracy,policy-compliance
6
+ Author: Vinay Chaudhari
7
+ Author-email: Vinay Chaudhari <vinaychaudhari1996@gmail.com>
8
+ License-Expression: Apache-2.0
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Classifier: Topic :: Software Development :: Quality Assurance
18
+ Requires-Dist: numpy>=1.24
19
+ Requires-Dist: laya[mcp]>=0.3.28 ; extra == 'laya'
20
+ Requires-Python: >=3.11
21
+ Project-URL: Homepage, https://github.com/VinayChaudhari1996/LayaEval
22
+ Project-URL: Repository, https://github.com/VinayChaudhari1996/LayaEval
23
+ Project-URL: Documentation, https://github.com/VinayChaudhari1996/LayaEval#readme
24
+ Provides-Extra: laya
25
+ Description-Content-Type: text/markdown
26
+
27
+ <p align="center">
28
+ <img alt="LayaEval Logo" src="https://raw.githubusercontent.com/VinayChaudhari1996/LayaEval/main/assets/logo.svg" width="130" height="130">
29
+ </p>
30
+
31
+ <h1 align="center">LayaEval</h1>
32
+
33
+ <p align="center">
34
+ <strong>Ultra-Fast Neural Evaluation Framework for Agent and RAG Systems</strong><br>
35
+ <em>42 production-ready metrics &bull; Sub-50ms latency &bull; Zero external LLM judge costs &bull; Calibrated confidence</em>
36
+ </p>
37
+
38
+ <p align="center">
39
+ <a href="https://pypi.org/project/layaeval/"><img src="https://img.shields.io/pypi/v/layaeval.svg?style=flat-square&color=8A6AFF" alt="PyPI version"></a>
40
+ <a href="https://pypi.org/project/layaeval/"><img src="https://img.shields.io/pypi/pyversions/layaeval.svg?style=flat-square&color=3776AB" alt="Python Versions"></a>
41
+ <a href="https://github.com/VinayChaudhari1996/LayaEval/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg?style=flat-square" alt="License"></a>
42
+ <a href="https://github.com/NandhaKishorM/laya"><img src="https://img.shields.io/badge/powered%20by-Laya%20MCP-8A6AFF?style=flat-square" alt="Powered by Laya MCP"></a>
43
+ <a href="https://github.com/astral-sh/uv"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json&style=flat-square" alt="uv"></a>
44
+ </p>
45
+
46
+ <p align="center">
47
+ <a href="#table-of-contents">Documentation Index</a> &bull;
48
+ <a href="#key-highlights">Highlights</a> &bull;
49
+ <a href="#why-layaeval">Why LayaEval</a> &bull;
50
+ <a href="#installation">Installation</a> &bull;
51
+ <a href="#quickstart">Quickstart</a> &bull;
52
+ <a href="#interactive-notebooks">Notebooks</a> &bull;
53
+ <a href="#how-it-works">Architecture</a> &bull;
54
+ <a href="#supported-metrics-catalog">Metric Catalog (42)</a> &bull;
55
+ <a href="#cli-usage">CLI Reference</a> &bull;
56
+ <a href="#acknowledgements--special-thanks">Acknowledgements</a> &bull;
57
+ <a href="#license">License</a>
58
+ </p>
59
+
60
+ ---
61
+
62
+ ## Table of Contents
63
+
64
+ - [⚡ Key Highlights](#key-highlights)
65
+ - [💡 Why LayaEval?](#why-layaeval)
66
+ - [📦 Installation](#installation)
67
+ - [Standard pip / uv](#installation)
68
+ - [Google Colab & Jupyter Setup](#installation)
69
+ - [🚀 Quickstart & Real Code Examples](#quickstart)
70
+ - [1. Instant Multi-Metric RAG Evaluation](#1-instant-multi-metric-rag-evaluation)
71
+ - [2. Autonomous Agent Execution & Trace Evaluation](#2-autonomous-agent-execution--trace-evaluation)
72
+ - [3. Direct Callable Metric Objects](#3-direct-callable-metric-objects)
73
+ - [4. Managed Evaluator Context Session](#4-managed-evaluator-context)
74
+ - [5. Dataset Benchmark Evaluation & Reports](#5-dataset-evaluation--reporting)
75
+ - [6. Infrastructure Detection & Progress Tracking](#6-infrastructure-detection--progress-tracking)
76
+ - [📓 Interactive Notebooks](#interactive-notebooks)
77
+ - [🏗️ How It Works & Architecture](#how-it-works)
78
+ - [📊 Supported Metrics Catalog (42 Metrics)](#supported-metrics-catalog)
79
+ - [1. RAG Metrics Catalog (20 Metrics)](#1-rag-metrics-catalog-20-metrics)
80
+ - [2. Agent Metrics Catalog (22 Metrics)](#2-agent-metrics-catalog-22-metrics)
81
+ - [💻 CLI Usage Reference](#cli-usage)
82
+ - [🛠️ Development & Testing](#development--testing)
83
+ - [🤝 Acknowledgements & Special Thanks](#acknowledgements--special-thanks)
84
+ - [📄 License](#license)
85
+
86
+ **LayaEval** is an ultra-fast, developer-first Python evaluation SDK for **Agentic workflows and RAG pipelines**, powered by the **Laya MCP Server**.
87
+
88
+ LayaEval brings **42 production-grade evaluation metrics** (20 RAG metrics + 22 Agent metrics) directly into your CI/CD and production verification loops—executed as calibrated, non-autoregressive neural decisions with **zero external LLM API cost** and **sub-50ms latency**.
89
+
90
+ ---
91
+
92
+ ## Key Highlights
93
+
94
+ - ⚡ **Sub-50ms Latency**: Non-autoregressive neural verification replaces slow, multi-second LLM-as-a-judge roundtrips.
95
+ - 💰 **Zero External Token Cost**: No OpenAI or Anthropic API bills for running quality guardrails and regression suites.
96
+ - 🎯 **42 Production-Ready Metrics**: Comprehensive coverage spanning retrieval quality, groundedness, hallucination risk, multi-step agent traces, tool accuracy, policy compliance, and prompt injections.
97
+ - 🚀 **Single Forward Pass Batching**: Evaluates multiple metrics for an interaction in a unified forward pass for optimal throughput.
98
+ - 📊 **Calibrated Confidence**: Outputs statistical probabilities ($P(\text{true})$), standard confidence intervals, and configurable pass/fail thresholds.
99
+ - 🔌 **Native MCP Integration**: Direct connection via stdio JSON-RPC or embedded runtime to the Laya MCP ecosystem.
100
+ - 🪶 **Ultra Lightweight**: Zero heavy dependencies required at install time (`numpy` only).
101
+
102
+ ---
103
+
104
+ ## Why LayaEval?
105
+
106
+ | Feature | Traditional LLM-as-a-Judge | LayaEval |
107
+ | :--- | :--- | :--- |
108
+ | **Latency per Metric** | 1,500ms – 5,000ms | **< 50ms** |
109
+ | **API Cost** | ~$0.01 – $0.05 per eval call | **$0.00 (Zero external API fees)** |
110
+ | **Determinism & Calibration** | Brittle prompt parsing & hallucinations | **Calibrated neural probabilities & confidence** |
111
+ | **Multi-Metric Evaluation** | Sequential calls or bloated judge prompts | **Single forward-pass batching** |
112
+ | **CI/CD Regression Suitability** | Slow, flaky, expensive | **Fast, offline-capable, cost-free** |
113
+ | **Dependencies** | Bulky orchestration frameworks | **Ultra-lightweight (`numpy` only)** |
114
+
115
+ ---
116
+
117
+ ## Installation
118
+
119
+ Install via [`uv`](https://github.com/astral-sh/uv) (recommended) or `pip`:
120
+
121
+ ```bash
122
+ # Core package (ultra-lightweight, connects to existing laya-mcp-server)
123
+ uv add layaeval
124
+
125
+ # Or with full local Laya runtime included:
126
+ uv add "layaeval[laya]"
127
+ ```
128
+
129
+ Using standard `pip`:
130
+
131
+ ```bash
132
+ pip install layaeval
133
+ # Or with local Laya runtime & MCP server:
134
+ pip install "layaeval[laya]"
135
+ ```
136
+
137
+ > **Google Colab / Jupyter Notebooks**:
138
+ > ```bash
139
+ > !pip install "layaeval[laya]"
140
+ > ```
141
+
142
+ ---
143
+
144
+ ## Quickstart
145
+
146
+ ### 1. Instant Multi-Metric RAG Evaluation
147
+
148
+ Evaluate multiple metrics in a single neural forward pass with zero boilerplate:
149
+
150
+ ```python
151
+ import layaeval
152
+
153
+ results = layaeval.evaluate(
154
+ ["groundedness", "hallucination", "response_relevance"],
155
+ query="What is the capital and population of France?",
156
+ retrieved_context="Paris is the capital and most populous city of France, with 2.1M residents.",
157
+ response="Paris is the capital of France, home to about 2.1 million people.",
158
+ )
159
+
160
+ for r in results:
161
+ print(
162
+ f"[{r.metric_name:<20}] Passed: {r.passed:<5} | Value: {r.value:.2f} | Confidence: {r.confidence:.2f}"
163
+ )
164
+ ```
165
+
166
+ **Output:**
167
+ ```text
168
+ [groundedness ] Passed: True | Value: 3.80 | Confidence: 0.94
169
+ [hallucination ] Passed: True | Value: 0.06 | Confidence: 0.95
170
+ [response_relevance ] Passed: True | Value: 3.80 | Confidence: 0.94
171
+ ```
172
+
173
+ ---
174
+
175
+ ### 2. Autonomous Agent Execution & Trace Evaluation
176
+
177
+ Audit multi-step tool calls, goal achievement, and task completion using metric classes or identifiers:
178
+
179
+ ```python
180
+ import layaeval
181
+ from layaeval import TaskCompletion, ToolCallAccuracy
182
+
183
+ task = "Find user #104 and check subscription status."
184
+ trace = "Step 1: db.query(user_id=104) -> Plan: Pro\nStep 2: stripe.check(sub_id=sub_104) -> Active"
185
+ result = "User #104 has an active Pro subscription."
186
+
187
+ res = layaeval.evaluate(
188
+ TaskCompletion(threshold=0.75),
189
+ task=task,
190
+ agent_trace=trace,
191
+ final_result=result,
192
+ )
193
+
194
+ print(f"Task Completed: {res.passed} (P(true) = {res.noul:.2f}, confidence = {res.confidence:.2f})")
195
+ ```
196
+
197
+ **Output:**
198
+ ```text
199
+ Task Completed: True (P(true) = 0.94, confidence = 0.95)
200
+ ```
201
+
202
+ ---
203
+
204
+ ### 3. Direct Callable Metric Objects
205
+
206
+ Metric objects can be instantiated with custom thresholds and called directly like standard functions:
207
+
208
+ ```python
209
+ from layaeval import Groundedness
210
+
211
+ groundedness = Groundedness(threshold=3.0)
212
+
213
+ res = groundedness(
214
+ retrieved_context="Paris is the capital of France.",
215
+ response="Paris is the capital.",
216
+ )
217
+
218
+ print(f"Passed: {res.passed} (Score: {res.score}/4.0 | Confidence: {res.confidence:.2f})")
219
+ ```
220
+
221
+ **Output:**
222
+ ```text
223
+ Passed: True (Score: 3.80/4.0 | Confidence: 0.94)
224
+ ```
225
+
226
+ ---
227
+
228
+ ### 4. Managed Evaluator Context
229
+
230
+ For dedicated server processes, custom models, or high-throughput batch sessions:
231
+
232
+ ```python
233
+ from layaeval import Evaluator, Groundedness, HallucinationRisk
234
+
235
+ with Evaluator(model="auto") as ev:
236
+ results = ev.evaluate(
237
+ [Groundedness(threshold=3.0), HallucinationRisk(threshold=0.2)],
238
+ retrieved_context="Revenue grew by 24% year-over-year.",
239
+ response="The company posted 24% YoY revenue growth.",
240
+ )
241
+ for r in results:
242
+ print(f"{r.metric_name}: {r.passed} (Score/Risk: {r.value:.2f})")
243
+ ```
244
+
245
+ **Output:**
246
+ ```text
247
+ groundedness: True (Score/Risk: 3.80)
248
+ hallucination: True (Score/Risk: 0.06)
249
+ ```
250
+
251
+ ---
252
+
253
+ ### 5. Dataset Evaluation & Reporting
254
+
255
+ Run evaluations against entire benchmark datasets and generate structured summary reports:
256
+
257
+ ```python
258
+ from layaeval import EvalDataset, evaluate
259
+
260
+ dataset = EvalDataset.from_jsonl("eval_benchmark.jsonl")
261
+
262
+ report = evaluate(
263
+ dataset,
264
+ metrics=["groundedness", "hallucination", "response_relevance"],
265
+ name="v1.2-rag-baseline",
266
+ )
267
+
268
+ print(report.summary())
269
+ print(f"Pass Rate: {report.pass_rate * 100:.1f}%")
270
+ print(f"Total Evaluations: {report.total_evaluations}")
271
+ report.save("eval_report.json")
272
+ ```
273
+
274
+ **Output:**
275
+ ```text
276
+ ======================================================================
277
+ LayaEval Evaluation Report (Total: 9, Pass Rate: 100.0%)
278
+ ======================================================================
279
+ Metric Type Count Pass Rate Mean Value
280
+ ----------------------------------------------------------------------
281
+ groundedness score 3 100.0% 3.80/4.0
282
+ hallucination noul 3 100.0% 6.00%
283
+ response_relevance score 3 100.0% 3.80/4.0
284
+ ======================================================================
285
+ Pass Rate: 100.0%
286
+ Total Evaluations: 9
287
+ ```
288
+
289
+ ---
290
+
291
+ ### 6. Infrastructure Detection & Progress Tracking
292
+
293
+ LayaEval automatically detects your compute infrastructure (NVIDIA CUDA GPUs, Apple Silicon Metal/MPS, or multi-core CPUs) and displays real-time progress bars as well as internal process visibility (including HuggingFace model weight downloads and MCP server initialization):
294
+
295
+ ```python
296
+ import layaeval
297
+
298
+ # 1. Check your compute accelerator
299
+ hw = layaeval.detect_hardware()
300
+ print(hw.description)
301
+
302
+ # 2. Evaluate dataset with real-time progress bar (enabled by default)
303
+ report = layaeval.evaluate(dataset, metrics=["groundedness", "hallucination"], progress=True)
304
+ ```
305
+
306
+ **Output:**
307
+ ```text
308
+ ⚡ [LayaEval] Hardware: GPU: NVIDIA A100-SXM4-40GB (CUDA, 40.0 GB VRAM, Device 0)
309
+ 🚀 [LayaEval] Initializing Laya MCP Server (model: auto)...
310
+ [LayaEval] Evaluating (v1.2-rag-baseline): [████████████████████████] 100% (50/50 examples)
311
+ ```
312
+
313
+ *(Note: To silence progress output in CI/CD, set `progress=False` or export `LAYAEVAL_PROGRESS=0`)*
314
+
315
+ ---
316
+
317
+ ## Interactive Notebooks
318
+
319
+ Hands-on Jupyter notebooks with end-to-end code, real-world examples, and step-by-step walkthroughs are available in the [`examples/notebook/`](https://github.com/VinayChaudhari1996/LayaEval/tree/main/examples/notebook) folder:
320
+
321
+ | Evaluation Domain | Notebook File Path | Workflows & Metrics Covered | Run Command |
322
+ | :--- | :--- | :--- | :--- |
323
+ | 🔍 **RAG Evaluation** | [`examples/notebook/rag_metrics_evaluation.ipynb`](https://github.com/VinayChaudhari1996/LayaEval/blob/main/examples/notebook/rag_metrics_evaluation.ipynb) | End-to-end evaluation of retrieval relevance, document relevance, context sufficiency & coverage, groundedness, hallucination detection, citation correctness, and contradiction detection. | `uv run --with jupyter jupyter notebook examples/notebook/rag_metrics_evaluation.ipynb` |
324
+ | 🤖 **Autonomous Agents** | [`examples/notebook/agent_metrics_evaluation.ipynb`](https://github.com/VinayChaudhari1996/LayaEval/blob/main/examples/notebook/agent_metrics_evaluation.ipynb) | Multi-step agent trace auditing, task completion, tool call & parameter validation, workflow navigation efficiency, agent groundedness, policy compliance, and prompt injection detection. | `uv run --with jupyter jupyter notebook examples/notebook/agent_metrics_evaluation.ipynb` |
325
+
326
+ To launch the notebooks with all dependencies:
327
+
328
+ ```bash
329
+ # Launch Jupyter Lab directly via uv
330
+ uv run --with jupyter jupyter lab examples/notebook/
331
+ ```
332
+
333
+ ---
334
+
335
+ ## How It Works
336
+
337
+ <p align="center">
338
+ <img alt="LayaEval Architecture" src="https://raw.githubusercontent.com/VinayChaudhari1996/LayaEval/main/assets/architecture.svg" width="100%">
339
+ </p>
340
+
341
+ <details>
342
+ <summary><b>View Mermaid Source</b></summary>
343
+
344
+ ```mermaid
345
+ flowchart LR
346
+ subgraph Client["Your Application / Pipeline"]
347
+ A["RAG Context & Response"] --> C["LayaEval SDK"]
348
+ B["Agent Execution Trace"] --> C
349
+ end
350
+
351
+ subgraph Batcher["LayaEval Orchestrator"]
352
+ C --> D["Pack Questions & States"]
353
+ D --> E["Single JSON-RPC / MCP Request"]
354
+ end
355
+
356
+ subgraph MCP["Laya MCP Server"]
357
+ E --> F["Non-Autoregressive Neural Model"]
358
+ F --> G["Multi-Question Forward Pass"]
359
+ end
360
+
361
+ G --> H["Calibrated Verdicts\nScore (0-4) • P(true) • Confidence"]
362
+ H --> C
363
+ ```
364
+
365
+ </details>
366
+
367
+ 1. **State Aggregation**: You supply standard state keys (`query`, `retrieved_context`, `response`, `agent_trace`, etc.).
368
+ 2. **Batch Construction**: LayaEval compiles the requested metrics into typed neural decision prompts.
369
+ 3. **Sub-50ms Inference**: The Laya MCP Server runs a non-autoregressive forward pass, returning calibrated probabilities rather than generating arbitrary text tokens.
370
+ 4. **Normalized Results**: Every output is mapped to a typed `EvalResult` with normalized scores, confidence intervals, and pass/fail statuses against your specified thresholds.
371
+
372
+ ---
373
+
374
+ ## Supported Metrics Catalog
375
+
376
+ LayaEval uses three calibrated output types:
377
+ - **Score (0.0 – 4.0)**: Graded rubric (0: poor, 1: weak, 2: partial, 3: mostly good, 4: perfect). Default pass threshold is **$\ge 3.0$**.
378
+ - **Probability $P(\text{true})$ (0.0 – 1.0)**: Calibrated likelihood for positive qualities. Default pass threshold is **$\ge 0.50$** (or **$\ge 0.70$**).
379
+ - **Risk Probability $P(\text{true}) \le \text{threshold}$**: Calibrated likelihood of negative events (hallucination, contradiction, security injection). Safe pass threshold is **$\le 0.20$ or $\le 0.30$**.
380
+
381
+ ---
382
+
383
+ ### 1. RAG Metrics Catalog (20 Metrics)
384
+
385
+ > 📓 **Interactive Notebook**: Open [`examples/notebook/rag_metrics_evaluation.ipynb`](https://github.com/VinayChaudhari1996/LayaEval/blob/main/examples/notebook/rag_metrics_evaluation.ipynb) for runnable code examples of each RAG metric.
386
+
387
+ | # | Metric & ID | Definition | Output Type & Default Threshold | Required State Fields |
388
+ | :-: | :--- | :--- | :--- | :--- |
389
+ | **1** | **`RetrievalRelevance`**<br>`RAG-001` &bull; `retrieval_relevance` | Measures how relevant the retrieved context chunks are to the user's question. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `query`, `retrieved_context` |
390
+ | **2** | **`DocumentRelevance`**<br>`RAG-002` &bull; `document_relevance` | Evaluates whether a single specific document chunk contains pertinent information. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `query`, `document` |
391
+ | **3** | **`ContextSufficiency`**<br>`RAG-003` &bull; `context_sufficient` | Checks if the retrieved context has all needed facts to answer without guessing. | $P(\text{true})$ (0–1)<br>Default Pass: **$\ge 0.50$** | `query`, `retrieved_context` |
392
+ | **4** | **`ContextCoverage`**<br>`RAG-004` &bull; `context_coverage` | Quantifies what fraction of the required information is present in the context. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `query`, `retrieved_context` |
393
+ | **5** | **`RetrievalCompleteness`**<br>`RAG-005` &bull; `retrieval_completeness` | Evaluates whether retrieved evidence is complete or missing major pieces. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `query`, `retrieved_context` |
394
+ | **6** | **`Groundedness`**<br>`RAG-006` &bull; `groundedness` | Measures how well the response statements are supported by facts in the context. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `retrieved_context`, `response` |
395
+ | **7** | **`StrictGroundedness`**<br>`RAG-007` &bull; `strictly_grounded` | Strict binary verification that every material claim in the response is proven. | $P(\text{true})$ (0–1)<br>Default Pass: **$\ge 0.50$** | `retrieved_context`, `response` |
396
+ | **8** | **`HallucinationRisk`**<br>`RAG-008` &bull; `hallucination` | Detects whether the response fabricates facts unsupported by the retrieved context. | Risk $P \le \text{threshold}$<br>Safe Pass: **$\le 0.30$** | `retrieved_context`, `response` |
397
+ | **9** | **`ResponseRelevance`**<br>`RAG-009` &bull; `response_relevance` | Evaluates how directly and appropriately the response answers the user's query. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `query`, `response` |
398
+ | **10** | **`ResponseCompleteness`**<br>`RAG-010` &bull; `response_completeness` | Checks whether the response answers all sub-questions and key parts of the query. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `query`, `response` |
399
+ | **11** | **`FactualCorrectness`**<br>`RAG-011` &bull; `factual_correctness` | Compares the generated response against a reference ground-truth answer. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `query`, `response`, `ground_truth` |
400
+ | **12** | **`Answerability`**<br>`RAG-012` &bull; `answerable` | Checks if the question can realistically be answered given the retrieved context. | $P(\text{true})$ (0–1)<br>Default Pass: **$\ge 0.50$** | `query`, `retrieved_context` |
401
+ | **13** | **`AbstentionCorrectness`**<br>`RAG-013` &bull; `abstention_correct` | Verifies if the model appropriately refused to answer when context was missing. | $P(\text{true})$ (0–1)<br>Default Pass: **$\ge 0.50$** | `query`, `retrieved_context`, `response` |
402
+ | **14** | **`ContextUtilization`**<br>`RAG-014` &bull; `context_utilization` | Checks how effectively the response incorporated available facts from context. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `retrieved_context`, `response` |
403
+ | **15** | **`CitationCorrectness`**<br>`RAG-015` &bull; `citation_correctness` | Verifies whether inline citations accurately support the claim they are attached to. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `query`, `response`, `citations`, `cited_source_text` |
404
+ | **16** | **`CitationCompleteness`**<br>`RAG-016` &bull; `citation_completeness` | Measures whether all important factual claims include appropriate citations. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `response`, `citations` |
405
+ | **17** | **`CitationRelevance`**<br>`RAG-017` &bull; `citation_relevance` | Evaluates if the cited source document is directly relevant to the specific claim. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `claim`, `citation`, `source_text` |
406
+ | **18** | **`ClaimSupport`**<br>`RAG-018` &bull; `claim_supported` | Tests whether a single isolated claim is directly corroborated by given evidence. | $P(\text{true})$ (0–1)<br>Default Pass: **$\ge 0.50$** | `claim`, `evidence` |
407
+ | **19** | **`ContradictionDetection`**<br>`RAG-019` &bull; `contradiction` | Detects if the response directly contradicts or refutes facts stated in the context. | Risk $P \le \text{threshold}$<br>Safe Pass: **$\le 0.20$** | `context`, `response` |
408
+ | **20** | **`ContextConflictDetection`**<br>`RAG-020` &bull; `context_conflict` | Flags when two or more retrieved source documents provide conflicting information. | Risk $P \le \text{threshold}$<br>Safe Pass: **$\le 0.30$** | `query`, `retrieved_context` |
409
+
410
+ ---
411
+
412
+ ### 2. Agent Metrics Catalog (22 Metrics)
413
+
414
+ > 📓 **Interactive Notebook**: Open [`examples/notebook/agent_metrics_evaluation.ipynb`](https://github.com/VinayChaudhari1996/LayaEval/blob/main/examples/notebook/agent_metrics_evaluation.ipynb) for runnable code examples of each Agent metric.
415
+
416
+ | # | Metric & ID | Definition | Output Type & Default Threshold | Required State Fields |
417
+ | :-: | :--- | :--- | :--- | :--- |
418
+ | **1** | **`IntentResolution`**<br>`AG-001` &bull; `intent` | Classifies the user's primary intent (information, action, troubleshooting, etc.). | Choice (Category)<br>Confidence **$\ge 0.70$** | `query` |
419
+ | **2** | **`TaskCompletion`**<br>`AG-002` &bull; `task_completed` | Verifies whether the agent fully finished the task and produced the expected result. | $P(\text{true})$ (0–1)<br>Default Pass: **$\ge 0.50$** | `task`, `agent_trace`, `final_result` |
420
+ | **3** | **`TaskAdherence`**<br>`AG-003` &bull; `task_adherence` | Measures how strictly the agent adhered to instructions, constraints, and guidelines. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `instructions`, `query`, `agent_trace`, `response` |
421
+ | **4** | **`GoalAchievement`**<br>`AG-004` &bull; `goal_achieved` | Checks whether the agent's actions achieved the true underlying objective. | $P(\text{true})$ (0–1)<br>Default Pass: **$\ge 0.50$** | `goal`, `agent_trace`, `final_result` |
422
+ | **5** | **`ToolSelection`**<br>`AG-005` &bull; `tool_selection` | Identifies which tool is the optimal choice for the current step in the workflow. | Choice (Category)<br>Confidence **$\ge 0.70$** | `task`, `available_tools`, `selected_tool` |
423
+ | **6** | **`ToolSelectionCorrectness`**<br>`AG-006` &bull; `tool_selection_correct` | Verifies whether the tool chosen by the agent was appropriate for the task step. | $P(\text{true})$ (0–1)<br>Default Pass: **$\ge 0.50$** | `task`, `tool_definition`, `selected_tool` |
424
+ | **7** | **`ToolCallAccuracy`**<br>`AG-007` &bull; `tool_call_accuracy` | Evaluates whether the generated tool call was structured and executed correctly. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `task`, `tool_definition`, `tool_call` |
425
+ | **8** | **`ToolInputAccuracy`**<br>`AG-008` &bull; `tool_input_accuracy` | Checks whether tool input arguments are correct, schema-compliant, and accurate. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `task`, `tool_schema`, `tool_input` |
426
+ | **9** | **`ToolOutputUtilization`**<br>`AG-009` &bull; `tool_output_utilization` | Measures how well the agent leveraged tool return values in next steps or answers. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `task`, `tool_output`, `subsequent_actions`, `final_response` |
427
+ | **10** | **`ToolNecessity`**<br>`AG-010` &bull; `tool_needed` | Evaluates whether invoking this tool was truly necessary or could be avoided. | $P(\text{true})$ (0–1)<br>Default Pass: **$\ge 0.50$** | `task`, `available_context`, `tool_call` |
428
+ | **11** | **`ToolRedundancy`**<br>`AG-011` &bull; `tool_call_redundant` | Flags whether the agent repeated a call for data it already had in prior turns. | Risk $P \le \text{threshold}$<br>Safe Pass: **$\le 0.30$** | `task`, `prior_tool_calls`, `current_tool_call` |
429
+ | **12** | **`ToolSequenceCorrectness`**<br>`AG-012` &bull; `tool_sequence` | Evaluates whether the multi-step ordering of tool calls was logical and optimal. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `task`, `executed_sequence`, `expected_sequence` |
430
+ | **13** | **`NavigationEfficiency`**<br>`AG-013` &bull; `navigation_efficiency` | Evaluates how directly the agent reached the solution without useless steps or loops. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `task`, `agent_trace`, `expected_workflow` |
431
+ | **14** | **`AgentGroundedness`**<br>`AG-014` &bull; `agent_groundedness` | Measures if the agent's final answer is supported by observed tool outputs. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `tool_outputs`, `context`, `response` |
432
+ | **15** | **`AgentHallucinationRisk`**<br>`AG-015` &bull; `agent_hallucination` | Detects if the agent fabricated action outcomes not present in execution evidence. | Risk $P \le \text{threshold}$<br>Safe Pass: **$\le 0.30$** | `tool_outputs`, `context`, `response` |
433
+ | **16** | **`AgentResponseRelevance`**<br>`AG-016` &bull; `agent_response_relevance` | Evaluates how directly the agent's final message responds to the user's prompt. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `query`, `response` |
434
+ | **17** | **`AgentAnswerCompleteness`**<br>`AG-017` &bull; `agent_answer_completeness` | Checks whether the agent's final response covers all parts of the assigned task. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `task`, `response` |
435
+ | **18** | **`AgentCorrectness`**<br>`AG-018` &bull; `agent_correct` | Compares the agent's final outcome against expected ground-truth answers. | Score (0–4)<br>Default Pass: **$\ge 3.0$** | `task`, `final_result`, `ground_truth` |
436
+ | **19** | **`AgentAbstention`**<br>`AG-019` &bull; `should_abstain` | Verifies whether the agent properly abstains from unauthorized or impossible actions. | $P(\text{true})$ (0–1)<br>Default Pass: **$\ge 0.50$** | `task`, `context`, `response`, `available_tools` |
437
+ | **20** | **`PolicyCompliance`**<br>`AG-020` &bull; `policy_compliant` | Checks whether the agent's actions and responses adhered to policies & guardrails. | $P(\text{true})$ (0–1)<br>Default Pass: **$\ge 0.50$** | `policy`, `task`, `agent_trace`, `response` |
438
+ | **21** | **`PromptInjectionDetection`**<br>`AG-021` &bull; `prompt_injection` | Detects direct user jailbreak attempts or instruction overrides in user prompts. | Risk $P \le \text{threshold}$<br>Safe Pass: **$\le 0.20$** | `user_input`, `system_instructions` |
439
+ | **22** | **`IndirectPromptInjectionDetection`**<br>`AG-022` &bull; `indirect_prompt_injection` | Detects hidden adversarial commands inside retrieved third-party text or tool data. | Risk $P \le \text{threshold}$<br>Safe Pass: **$\le 0.20$** | `retrieved_or_tool_content`, `system_instructions` |
440
+
441
+ ---
442
+
443
+ ## CLI Usage
444
+
445
+ LayaEval includes a command-line interface for benchmarking, dataset runs, and regression testing:
446
+
447
+ ```bash
448
+ # 1. List all 42 available metrics with descriptions
449
+ layaeval list-metrics
450
+ ```
451
+
452
+ **Output:**
453
+ ```text
454
+ Available LayaEval Metrics:
455
+
456
+ ID Name Type
457
+ ----------------------------------------------------
458
+ RAG-001 retrieval_relevance score
459
+ RAG-002 document_relevance score
460
+ RAG-003 context_sufficient noul
461
+ ...
462
+ AG-001 intent choice
463
+ AG-002 task_completed noul
464
+ ...
465
+ ```
466
+
467
+ ```bash
468
+ # 2. Evaluate a JSONL dataset with real-time progress bar
469
+ layaeval run dataset.jsonl --metrics groundedness hallucination task_completed --output report.json
470
+
471
+ # 3. Compare candidate run against a baseline to check for regressions
472
+ layaeval compare baseline_report.json candidate_report.json
473
+ ```
474
+
475
+ ---
476
+
477
+ ## Development & Testing
478
+
479
+ Run unit tests and lint checks using `uv`:
480
+
481
+ ```bash
482
+ # Install dev dependencies
483
+ uv sync --all-extras
484
+
485
+ # Run test suite
486
+ uv run pytest
487
+
488
+ # Check code formatting and linting
489
+ uv run ruff check .
490
+ ```
491
+
492
+ ---
493
+
494
+ ## Acknowledgements & Special Thanks
495
+
496
+ Special thanks and gratitude to the **[Laya](https://github.com/NandhaKishorM/laya)** open-source contributors and community. LayaEval is powered by the foundational non-autoregressive neural architectures, latency breakthroughs, and high-performance Model Context Protocol (MCP) server engineered by the Laya project.
497
+
498
+ - **Laya GitHub Repository**: [github.com/NandhaKishorM/laya](https://github.com/NandhaKishorM/laya)
499
+ - **Laya MCP Ecosystem & Docs**: [github.com/NandhaKishorM/laya/blob/main/docs](https://github.com/NandhaKishorM/laya/blob/main/docs)
500
+
501
+
502
+ ---
503
+
504
+ ## License
505
+
506
+ This project is licensed under the Apache License 2.0. See the [LICENSE](https://github.com/VinayChaudhari1996/LayaEval/blob/main/LICENSE) file for details.