layaeval 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.
layaeval-0.1.0/LICENSE ADDED
@@ -0,0 +1,17 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright 2026 Convai Innovations / Vinay Chaudhari
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
@@ -0,0 +1,395 @@
1
+ Metadata-Version: 2.4
2
+ Name: layaeval
3
+ Version: 0.1.0
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>=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
+ <picture>
29
+ <img alt="LayaEval Logo" src="assets/logo.svg" width="130" height="130">
30
+ </picture>
31
+ </p>
32
+
33
+ <h1 align="center">LayaEval</h1>
34
+
35
+ <p align="center">
36
+ <strong>Ultra-Fast Neural Evaluation Framework for Agent and RAG Systems</strong><br>
37
+ <em>42 production-ready metrics &bull; Sub-50ms latency &bull; Zero external LLM judge costs &bull; Calibrated confidence</em>
38
+ </p>
39
+
40
+ <p align="center">
41
+ <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>
42
+ <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>
43
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg?style=flat-square" alt="License"></a>
44
+ <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>
45
+ <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>
46
+ </p>
47
+
48
+ <p align="center">
49
+ <a href="#key-highlights">Highlights</a> &bull;
50
+ <a href="#why-layaeval">Why LayaEval</a> &bull;
51
+ <a href="#installation">Installation</a> &bull;
52
+ <a href="#quickstart">Quickstart</a> &bull;
53
+ <a href="#interactive-notebooks">Notebooks</a> &bull;
54
+ <a href="#how-it-works">How It Works</a> &bull;
55
+ <a href="#supported-metrics-catalog">Metric Catalog</a> &bull;
56
+ <a href="#cli-usage">CLI Reference</a> &bull;
57
+ <a href="#acknowledgements--special-thanks">Acknowledgements</a> &bull;
58
+ <a href="#citation">Citation</a> &bull;
59
+ <a href="#license">License</a>
60
+ </p>
61
+
62
+ ---
63
+
64
+ **LayaEval** is an ultra-fast, developer-first Python evaluation SDK for **Agentic workflows and RAG pipelines**, powered by the **Laya MCP Server**.
65
+
66
+ 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**.
67
+
68
+ ---
69
+
70
+ ## Key Highlights
71
+
72
+ - ⚑ **Sub-50ms Latency**: Non-autoregressive neural verification replaces slow, multi-second LLM-as-a-judge roundtrips.
73
+ - πŸ’° **Zero External Token Cost**: No OpenAI or Anthropic API bills for running quality guardrails and regression suites.
74
+ - 🎯 **42 Production-Ready Metrics**: Comprehensive coverage spanning retrieval quality, groundedness, hallucination risk, multi-step agent traces, tool accuracy, policy compliance, and prompt injections.
75
+ - πŸš€ **Single Forward Pass Batching**: Evaluates multiple metrics for an interaction in a unified forward pass for optimal throughput.
76
+ - πŸ“Š **Calibrated Confidence**: Outputs statistical probabilities ($P(\text{true})$), standard confidence intervals, and configurable pass/fail thresholds.
77
+ - πŸ”Œ **Native MCP Integration**: Direct connection via stdio JSON-RPC or embedded runtime to the Laya MCP ecosystem.
78
+ - πŸͺΆ **Ultra Lightweight**: Zero heavy dependencies required at install time (`numpy` only).
79
+
80
+ ---
81
+
82
+ ## Why LayaEval?
83
+
84
+ | Feature | Traditional LLM-as-a-Judge | LayaEval |
85
+ | :--- | :--- | :--- |
86
+ | **Latency per Metric** | 1,500ms – 5,000ms | **< 50ms** |
87
+ | **API Cost** | ~$0.01 – $0.05 per eval call | **$0.00 (Zero external API fees)** |
88
+ | **Determinism & Calibration** | Brittle prompt parsing & hallucinations | **Calibrated neural probabilities & confidence** |
89
+ | **Multi-Metric Evaluation** | Sequential calls or bloated judge prompts | **Single forward-pass batching** |
90
+ | **CI/CD Regression Suitability** | Slow, flaky, expensive | **Fast, offline-capable, cost-free** |
91
+ | **Dependencies** | Bulky orchestration frameworks | **Ultra-lightweight (`numpy` only)** |
92
+
93
+ ---
94
+
95
+ ## Installation
96
+
97
+ Install via [`uv`](https://github.com/astral-sh/uv) (recommended) or `pip`:
98
+
99
+ ```bash
100
+ # Core package (ultra-lightweight, connects to existing laya-mcp-server)
101
+ uv add layaeval
102
+
103
+ # Or with full local Laya runtime included:
104
+ uv add "layaeval[laya]"
105
+ ```
106
+
107
+ Using standard `pip`:
108
+
109
+ ```bash
110
+ pip install layaeval
111
+ # Or with local Laya runtime:
112
+ pip install "layaeval[laya]"
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Quickstart
118
+
119
+ ### 1. Instant Multi-Metric RAG Evaluation
120
+
121
+ Evaluate multiple metrics in a single neural forward pass with zero boilerplate:
122
+
123
+ ```python
124
+ import layaeval
125
+
126
+ results = layaeval.evaluate(
127
+ ["groundedness", "hallucination", "response_relevance"],
128
+ query="What is the capital and population of France?",
129
+ retrieved_context="Paris is the capital and most populous city of France, with 2.1M residents.",
130
+ response="Paris is the capital of France, home to about 2.1 million people.",
131
+ )
132
+
133
+ for r in results:
134
+ print(
135
+ f"[{r.metric_name:<20}] Passed: {r.passed:<5} | Score: {r.score or r.noul:.2f} | Confidence: {r.confidence:.2f}"
136
+ )
137
+ ```
138
+
139
+ ### 2. Autonomous Agent Execution & Trace Evaluation
140
+
141
+ Audit multi-step tool calls, goal achievement, and task completion using metric classes or identifiers:
142
+
143
+ ```python
144
+ import layaeval
145
+ from layaeval import TaskCompletion, ToolCallAccuracy
146
+
147
+ task = "Find user #104 and check subscription status."
148
+ trace = "Step 1: db.query(user_id=104) -> Plan: Pro\nStep 2: stripe.check(sub_id=sub_104) -> Active"
149
+ result = "User #104 has an active Pro subscription."
150
+
151
+ res = layaeval.evaluate(
152
+ TaskCompletion(threshold=0.75),
153
+ task=task,
154
+ agent_trace=trace,
155
+ final_result=result,
156
+ )
157
+
158
+ print(f"Task Completed: {res.passed} (P(true) = {res.noul:.2f}, confidence = {res.confidence:.2f})")
159
+ ```
160
+
161
+ ### 3. Direct Callable Metric Objects
162
+
163
+ Metric objects can be instantiated with custom thresholds and called directly like standard functions:
164
+
165
+ ```python
166
+ from layaeval import Groundedness
167
+
168
+ groundedness = Groundedness(threshold=3.0)
169
+
170
+ res = groundedness(
171
+ retrieved_context="Paris is the capital of France.",
172
+ response="Paris is the capital.",
173
+ )
174
+
175
+ print(f"Passed: {res.passed} (Score: {res.score}/4.0 | Reason: {res.reasoning})")
176
+ ```
177
+
178
+ ### 4. Managed Evaluator Context
179
+
180
+ For dedicated server processes, custom models, or high-throughput batch sessions:
181
+
182
+ ```python
183
+ from layaeval import Evaluator, Groundedness, HallucinationRisk
184
+
185
+ with Evaluator(model="auto") as ev:
186
+ results = ev.evaluate(
187
+ [Groundedness(threshold=3.0), HallucinationRisk(threshold=0.2)],
188
+ retrieved_context="Revenue grew by 24% year-over-year.",
189
+ response="The company posted 24% YoY revenue growth.",
190
+ )
191
+ for r in results:
192
+ print(f"{r.metric_name}: {r.passed} (Score/Risk: {r.score or r.noul})")
193
+ ```
194
+
195
+ ### 5. Dataset Evaluation & Reporting
196
+
197
+ Run evaluations against entire benchmark datasets and generate structured summary reports:
198
+
199
+ ```python
200
+ from layaeval import EvalDataset, evaluate
201
+
202
+ dataset = EvalDataset.from_jsonl("eval_benchmark.jsonl")
203
+
204
+ report = evaluate(
205
+ dataset,
206
+ metrics=["groundedness", "hallucination", "response_relevance"],
207
+ name="v1.2-rag-baseline",
208
+ )
209
+
210
+ print(f"Pass Rate: {report.pass_rate * 100:.1f}%")
211
+ print(f"Total Evaluations: {report.total_evaluations}")
212
+ report.save("eval_report.json")
213
+ ```
214
+
215
+ ---
216
+
217
+ ## Interactive Notebooks
218
+
219
+ Hands-on Jupyter notebooks with end-to-end code, real-world examples, and step-by-step walkthroughs are available in the [`examples/notebook/`](examples/notebook/) folder:
220
+
221
+ | Evaluation Domain | Notebook File Path | Workflows & Metrics Covered | Run Command |
222
+ | :--- | :--- | :--- | :--- |
223
+ | πŸ” **RAG Evaluation** | [`examples/notebook/rag_metrics_evaluation.ipynb`](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` |
224
+ | πŸ€– **Autonomous Agents** | [`examples/notebook/agent_metrics_evaluation.ipynb`](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` |
225
+
226
+ To launch the notebooks with all dependencies:
227
+
228
+ ```bash
229
+ # Launch Jupyter Lab directly via uv
230
+ uv run --with jupyter jupyter lab examples/notebook/
231
+ ```
232
+
233
+ ---
234
+
235
+ ## How It Works
236
+
237
+ ```mermaid
238
+ flowchart LR
239
+ subgraph Client["Your Application / Pipeline"]
240
+ A["RAG Context & Response"] --> C["LayaEval SDK"]
241
+ B["Agent Execution Trace"] --> C
242
+ end
243
+
244
+ subgraph Batcher["LayaEval Orchestrator"]
245
+ C --> D["Pack Questions & States"]
246
+ D --> E["Single JSON-RPC / MCP Request"]
247
+ end
248
+
249
+ subgraph MCP["Laya MCP Server"]
250
+ E --> F["Non-Autoregressive Neural Model"]
251
+ F --> G["Multi-Question Forward Pass"]
252
+ end
253
+
254
+ G --> H["Calibrated Verdicts\nScore (0-4) β€’ P(true) β€’ Confidence"]
255
+ H --> C
256
+ ```
257
+
258
+ 1. **State Aggregation**: You supply standard state keys (`query`, `retrieved_context`, `response`, `agent_trace`, etc.).
259
+ 2. **Batch Construction**: LayaEval compiles the requested metrics into typed neural decision prompts.
260
+ 3. **Sub-50ms Inference**: The Laya MCP Server runs a non-autoregressive forward pass, returning calibrated probabilities rather than generating arbitrary text tokens.
261
+ 4. **Normalized Results**: Every output is mapped to a typed `EvalResult` with normalized scores, confidence intervals, and pass/fail statuses against your specified thresholds.
262
+
263
+ ---
264
+
265
+ ## Supported Metrics Catalog
266
+
267
+ LayaEval uses three calibrated output types:
268
+ - **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$**.
269
+ - **Probability $P(\text{true})$ (0.0 – 1.0)**: Calibrated likelihood for positive qualities. Default pass threshold is **$\ge 0.50$** (or **$\ge 0.70$**).
270
+ - **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$**.
271
+
272
+ ---
273
+
274
+ ### 1. RAG Metrics Guide (20 Metrics)
275
+
276
+ > πŸ““ **Interactive Notebook**: Open [`examples/notebook/rag_metrics_evaluation.ipynb`](examples/notebook/rag_metrics_evaluation.ipynb) for runnable code examples of each RAG metric.
277
+
278
+ | Metric & ID | Definition | Type / Scale | Good Score (Pass) | Bad Score (Fail) | Required Inputs |
279
+ | :--- | :--- | :--- | :--- | :--- | :--- |
280
+ | **`RetrievalRelevance`**<br>`RAG-001` &bull; `retrieval_relevance` | Measures how relevant the retrieved context chunks are to the user's question. | Score (0–4) | **$\ge 3.0$**<br>Context directly addresses question | **$< 2.0$**<br>Context is noisy or off-topic | `query`, `retrieved_context` |
281
+ | **`DocumentRelevance`**<br>`RAG-002` &bull; `document_relevance` | Evaluates whether a single specific document chunk contains pertinent information. | Score (0–4) | **$\ge 3.0$**<br>Document is strongly relevant | **$< 2.0$**<br>Document contains useless data | `query`, `document` |
282
+ | **`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) | **$P \ge 0.50$**<br>Sufficient facts to answer | **$P < 0.50$**<br>Critical information missing | `query`, `retrieved_context` |
283
+ | **`ContextCoverage`**<br>`RAG-004` &bull; `context_coverage` | Quantifies what fraction of the required information is present in the context. | Score (0–4) | **$\ge 3.0$**<br>Covers almost all required details | **$< 2.0$**<br>Major knowledge gaps | `query`, `retrieved_context` |
284
+ | **`RetrievalCompleteness`**<br>`RAG-005` &bull; `retrieval_completeness` | Evaluates whether retrieved evidence is complete or missing major pieces. | Score (0–4) | **$\ge 3.0$**<br>Complete evidence package | **$< 2.0$**<br>Fragmented / incomplete evidence | `query`, `retrieved_context` |
285
+ | **`Groundedness`**<br>`RAG-006` &bull; `groundedness` | Measures how well the response statements are supported by facts in the context. | Score (0–4) | **$\ge 3.0$**<br>Claims solidly backed by context | **$< 2.0$**<br>Unverified claims made | `retrieved_context`, `response` |
286
+ | **`StrictGroundedness`**<br>`RAG-007` &bull; `strictly_grounded` | Strict binary verification that every material claim in the response is proven. | $P(\text{true})$ (0–1) | **$P \ge 0.50$**<br>100% of claims verified | **$P < 0.50$**<br>Contains unverified claim(s) | `retrieved_context`, `response` |
287
+ | **`HallucinationRisk`**<br>`RAG-008` &bull; `hallucination` | Detects whether the response fabricates facts unsupported by the retrieved context. | Risk $P \le \text{max}$ | **$P \le 0.30$**<br>Zero/minimal hallucination risk | **$P > 0.30$**<br>Fabricated facts detected | `retrieved_context`, `response` |
288
+ | **`ResponseRelevance`**<br>`RAG-009` &bull; `response_relevance` | Evaluates how directly and appropriately the response answers the user's query. | Score (0–4) | **$\ge 3.0$**<br>Directly answers user question | **$< 2.0$**<br>Rambling, evasive, or off-topic | `query`, `response` |
289
+ | **`ResponseCompleteness`**<br>`RAG-010` &bull; `response_completeness` | Checks whether the response answers all sub-questions and key parts of the query. | Score (0–4) | **$\ge 3.0$**<br>All questions addressed | **$< 2.0$**<br>Key questions left unanswered | `query`, `response` |
290
+ | **`FactualCorrectness`**<br>`RAG-011` &bull; `factual_correctness` | Compares the generated response against a reference ground-truth answer. | Score (0–4) | **$\ge 3.0$**<br>Accurately matches ground truth | **$< 2.0$**<br>Factually conflicts with ground truth | `query`, `response`, `ground_truth` |
291
+ | **`Answerability`**<br>`RAG-012` &bull; `answerable` | Checks if the question can realistically be answered given the retrieved context. | $P(\text{true})$ (0–1) | **$P \ge 0.50$**<br>Question is answerable | **$P < 0.50$**<br>Context cannot answer question | `query`, `retrieved_context` |
292
+ | **`AbstentionCorrectness`**<br>`RAG-013` &bull; `abstention_correct` | Verifies if the model appropriately refused to answer when context was missing. | $P(\text{true})$ (0–1) | **$P \ge 0.50$**<br>Correct decision to answer/abstain | **$P < 0.50$**<br>Answered blindly without facts | `query`, `retrieved_context`, `response` |
293
+ | **`ContextUtilization`**<br>`RAG-014` &bull; `context_utilization` | Checks how effectively the response incorporated available facts from context. | Score (0–4) | **$\ge 3.0$**<br>Appropriately uses provided facts | **$< 2.0$**<br>Ignores relevant facts in context | `retrieved_context`, `response` |
294
+ | **`CitationCorrectness`**<br>`RAG-015` &bull; `citation_correctness` | Verifies whether inline citations accurately support the claim they are attached to. | Score (0–4) | **$\ge 3.0$**<br>Citations accurately back claim | **$< 2.0$**<br>Citations point to wrong text | `query`, `response`, `citations`, `cited_source_text` |
295
+ | **`CitationCompleteness`**<br>`RAG-016` &bull; `citation_completeness` | Measures whether all important factual claims include appropriate citations. | Score (0–4) | **$\ge 3.0$**<br>All major claims properly cited | **$< 2.0$**<br>Claims made without citations | `response`, `citations` |
296
+ | **`CitationRelevance`**<br>`RAG-017` &bull; `citation_relevance` | Evaluates if the cited source document is directly relevant to the specific claim. | Score (0–4) | **$\ge 3.0$**<br>Source is pertinent to claim | **$< 2.0$**<br>Cited source is irrelevant | `claim`, `citation`, `source_text` |
297
+ | **`ClaimSupport`**<br>`RAG-018` &bull; `claim_supported` | Tests whether a single isolated claim is directly corroborated by given evidence. | $P(\text{true})$ (0–1) | **$P \ge 0.50$**<br>Claim is directly supported | **$P < 0.50$**<br>Evidence does not back claim | `claim`, `evidence` |
298
+ | **`ContradictionDetection`**<br>`RAG-019` &bull; `contradiction` | Detects if the response directly contradicts or refutes facts stated in the context. | Risk $P \le \text{max}$ | **$P \le 0.20$**<br>No contradictions found | **$P > 0.20$**<br>Contradicts retrieved context | `context`, `response` |
299
+ | **`ContextConflictDetection`**<br>`RAG-020` &bull; `context_conflict` | Flags when two or more retrieved source documents provide conflicting information. | Risk $P \le \text{max}$ | **$P \le 0.30$**<br>Sources are in agreement | **$P > 0.30$**<br>Sources present conflicting facts | `query`, `retrieved_context` |
300
+
301
+ ---
302
+
303
+ ### 2. Agent Metrics Guide (22 Metrics)
304
+
305
+ > πŸ““ **Interactive Notebook**: Open [`examples/notebook/agent_metrics_evaluation.ipynb`](examples/notebook/agent_metrics_evaluation.ipynb) for runnable code examples of each Agent metric.
306
+
307
+ | Metric & ID | Definition | Type / Scale | Good Score (Pass) | Bad Score (Fail) | Required Inputs |
308
+ | :--- | :--- | :--- | :--- | :--- | :--- |
309
+ | **`IntentResolution`**<br>`AG-001` &bull; `intent` | Classifies the user's primary intent (information, action, troubleshooting, etc.). | Choice (Category) | **Confidence $\ge 0.70$**<br>Correct intent identified | **Low confidence**<br>Misclassified or ambiguous intent | `query` |
310
+ | **`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) | **$P \ge 0.50$**<br>Task completed successfully | **$P < 0.50$**<br>Task aborted or left incomplete | `task`, `agent_trace`, `final_result` |
311
+ | **`TaskAdherence`**<br>`AG-003` &bull; `task_adherence` | Measures how strictly the agent adhered to instructions, constraints, and guidelines. | Score (0–4) | **$\ge 3.0$**<br>Followed instructions fully | **$< 2.0$**<br>Ignored or broke constraints | `instructions`, `query`, `agent_trace`, `response` |
312
+ | **`GoalAchievement`**<br>`AG-004` &bull; `goal_achieved` | Checks whether the agent's actions achieved the true underlying objective. | $P(\text{true})$ (0–1) | **$P \ge 0.50$**<br>End goal accomplished | **$P < 0.50$**<br>Underlying goal not achieved | `goal`, `agent_trace`, `final_result` |
313
+ | **`ToolSelection`**<br>`AG-005` &bull; `tool_selection` | Identifies which tool is the optimal choice for the current step in the workflow. | Choice (Category) | **Confidence $\ge 0.70$**<br>Optimal tool selected | **Low confidence**<br>Wrong tool selected | `task`, `available_tools`, `selected_tool` |
314
+ | **`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) | **$P \ge 0.50$**<br>Correct tool selected | **$P < 0.50$**<br>Inappropriate tool chosen | `task`, `tool_definition`, `selected_tool` |
315
+ | **`ToolCallAccuracy`**<br>`AG-007` &bull; `tool_call_accuracy` | Evaluates whether the generated tool call was structured and executed correctly. | Score (0–4) | **$\ge 3.0$**<br>Accurate, valid tool invocation | **$< 2.0$**<br>Malformed or invalid tool call | `task`, `tool_definition`, `tool_call` |
316
+ | **`ToolInputAccuracy`**<br>`AG-008` &bull; `tool_input_accuracy` | Checks whether tool input arguments are correct, schema-compliant, and accurate. | Score (0–4) | **$\ge 3.0$**<br>Valid and correct arguments | **$< 2.0$**<br>Invalid, missing, or fake params | `task`, `tool_schema`, `tool_input` |
317
+ | **`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) | **$\ge 3.0$**<br>Correctly used tool output | **$< 2.0$**<br>Ignored or misinterpreted output | `task`, `tool_output`, `subsequent_actions`, `final_response` |
318
+ | **`ToolNecessity`**<br>`AG-010` &bull; `tool_needed` | Evaluates whether invoking this tool was truly necessary or could be avoided. | $P(\text{true})$ (0–1) | **$P \ge 0.50$**<br>Tool was genuinely necessary | **$P < 0.50$**<br>Unnecessary or extraneous call | `task`, `available_context`, `tool_call` |
319
+ | **`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{max}$ | **$P \le 0.30$**<br>Non-redundant, clean execution | **$P > 0.30$**<br>Wasted, redundant tool call | `task`, `prior_tool_calls`, `current_tool_call` |
320
+ | **`ToolSequenceCorrectness`**<br>`AG-012` &bull; `tool_sequence` | Evaluates whether the multi-step ordering of tool calls was logical and optimal. | Score (0–4) | **$\ge 3.0$**<br>Optimal, logical sequence | **$< 2.0$**<br>Disordered or illogical steps | `task`, `executed_sequence`, `expected_sequence` |
321
+ | **`NavigationEfficiency`**<br>`AG-013` &bull; `navigation_efficiency` | Evaluates how directly the agent reached the solution without useless steps or loops. | Score (0–4) | **$\ge 3.0$**<br>Direct path with few extra steps | **$< 2.0$**<br>Inefficient path with retry loops | `task`, `agent_trace`, `expected_workflow` |
322
+ | **`AgentGroundedness`**<br>`AG-014` &bull; `agent_groundedness` | Measures if the agent's final answer is supported by observed tool outputs. | Score (0–4) | **$\ge 3.0$**<br>Backed by tool observations | **$< 2.0$**<br>Claims unsupported by tool data | `tool_outputs`, `context`, `response` |
323
+ | **`AgentHallucinationRisk`**<br>`AG-015` &bull; `agent_hallucination` | Detects if the agent fabricated action outcomes not present in execution evidence. | Risk $P \le \text{max}$ | **$P \le 0.30$**<br>No fabricated results | **$P > 0.30$**<br>Fictitious action results claimed | `tool_outputs`, `context`, `response` |
324
+ | **`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) | **$\ge 3.0$**<br>Directly answers user request | **$< 2.0$**<br>Off-topic or misses the request | `query`, `response` |
325
+ | **`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) | **$\ge 3.0$**<br>Thorough, complete resolution | **$< 2.0$**<br>Incomplete, leaves items pending | `task`, `response` |
326
+ | **`AgentCorrectness`**<br>`AG-018` &bull; `agent_correct` | Compares the agent's final outcome against expected ground-truth answers. | Score (0–4) | **$\ge 3.0$**<br>Matches ground-truth outcome | **$< 2.0$**<br>Incorrect or conflicting outcome | `task`, `final_result`, `ground_truth` |
327
+ | **`AgentAbstention`**<br>`AG-019` &bull; `should_abstain` | Verifies whether the agent properly abstains from unauthorized or impossible actions. | $P(\text{true})$ (0–1) | **$P \ge 0.50$**<br>Safely refuses out-of-scope tasks | **$P < 0.50$**<br>Recklessly executes unsafe action | `task`, `context`, `response`, `available_tools` |
328
+ | **`PolicyCompliance`**<br>`AG-020` &bull; `policy_compliant` | Checks whether the agent's actions and responses adhered to policies & guardrails. | $P(\text{true})$ (0–1) | **$P \ge 0.50$**<br>Fully compliant with policy | **$P < 0.50$**<br>Policy violation detected | `policy`, `task`, `agent_trace`, `response` |
329
+ | **`PromptInjectionDetection`**<br>`AG-021` &bull; `prompt_injection` | Detects direct user jailbreak attempts or instruction overrides in user prompts. | Risk $P \le \text{max}$ | **$P \le 0.20$**<br>Safe, benign prompt | **$P > 0.20$**<br>Direct injection attack detected | `user_input`, `system_instructions` |
330
+ | **`IndirectPromptInjectionDetection`**<br>`AG-022` &bull; `indirect_prompt_injection` | Detects hidden adversarial commands inside retrieved third-party text or tool data. | Risk $P \le \text{max}$ | **$P \le 0.20$**<br>Safe third-party content | **$P > 0.20$**<br>Indirect injection payload found | `retrieved_or_tool_content`, `system_instructions` |
331
+
332
+ ---
333
+
334
+ ## CLI Usage
335
+
336
+ LayaEval includes a command-line interface for testing, batch benchmarking, and regression comparison:
337
+
338
+ ```bash
339
+ # List all 42 available metrics with descriptions
340
+ layaeval list-metrics
341
+
342
+ # Evaluate a JSONL dataset with selected metrics
343
+ layaeval run dataset.jsonl --metrics groundedness hallucination task_completed --output report.json
344
+
345
+ # Compare candidate run against a baseline to check for regressions
346
+ layaeval compare baseline_report.json candidate_report.json
347
+ ```
348
+
349
+ ---
350
+
351
+ ## Development & Testing
352
+
353
+ Run unit tests and lint checks using `uv`:
354
+
355
+ ```bash
356
+ # Install dev dependencies
357
+ uv sync --all-extras
358
+
359
+ # Run test suite
360
+ uv run pytest
361
+
362
+ # Check code formatting and linting
363
+ uv run ruff check .
364
+ ```
365
+
366
+ ---
367
+
368
+ ## Acknowledgements & Special Thanks
369
+
370
+ 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.
371
+
372
+ - **Laya GitHub Repository**: [github.com/NandhaKishorM/laya](https://github.com/NandhaKishorM/laya)
373
+ - **Laya MCP Ecosystem & Docs**: [github.com/NandhaKishorM/laya/blob/main/docs](https://github.com/NandhaKishorM/laya/blob/main/docs)
374
+
375
+ ---
376
+
377
+ ## Citation
378
+
379
+ If you use LayaEval or its metric suite in your research, pipelines, or benchmarks, please cite:
380
+
381
+ ```bibtex
382
+ @software{layaeval2026,
383
+ author = {Chaudhari, Vinay and Laya Open Source Contributors},
384
+ title = {LayaEval: Ultra-Fast Neural Evaluation Framework for Agent and RAG Systems},
385
+ year = {2026},
386
+ url = {https://github.com/VinayChaudhari1996/LayaEval},
387
+ publisher = {GitHub}
388
+ }
389
+ ```
390
+
391
+ ---
392
+
393
+ ## License
394
+
395
+ This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details.