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.
- layaeval-0.1.4/PKG-INFO +506 -0
- layaeval-0.1.4/README.md +480 -0
- {layaeval-0.1.2 → layaeval-0.1.4}/pyproject.toml +2 -2
- {layaeval-0.1.2 → layaeval-0.1.4}/pyproject.toml.orig +2 -2
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/__init__.py +5 -0
- layaeval-0.1.4/src/layaeval/_version.py +1 -0
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/cli.py +15 -2
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/evaluator.py +31 -7
- layaeval-0.1.4/src/layaeval/hardware.py +146 -0
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/mcp/client.py +39 -14
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/metrics/_base.py +9 -0
- layaeval-0.1.4/src/layaeval/progress.py +248 -0
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/report.py +5 -0
- layaeval-0.1.2/PKG-INFO +0 -386
- layaeval-0.1.2/README.md +0 -360
- layaeval-0.1.2/src/layaeval/_version.py +0 -1
- {layaeval-0.1.2 → layaeval-0.1.4}/LICENSE +0 -0
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/dataset.py +0 -0
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/mcp/__init__.py +0 -0
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/metrics/__init__.py +0 -0
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/metrics/agent.py +0 -0
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/metrics/rag.py +0 -0
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/metrics/registry.py +0 -0
- {layaeval-0.1.2 → layaeval-0.1.4}/src/layaeval/py.typed +0 -0
layaeval-0.1.4/PKG-INFO
ADDED
|
@@ -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 • Sub-50ms latency • Zero external LLM judge costs • 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> •
|
|
48
|
+
<a href="#key-highlights">Highlights</a> •
|
|
49
|
+
<a href="#why-layaeval">Why LayaEval</a> •
|
|
50
|
+
<a href="#installation">Installation</a> •
|
|
51
|
+
<a href="#quickstart">Quickstart</a> •
|
|
52
|
+
<a href="#interactive-notebooks">Notebooks</a> •
|
|
53
|
+
<a href="#how-it-works">Architecture</a> •
|
|
54
|
+
<a href="#supported-metrics-catalog">Metric Catalog (42)</a> •
|
|
55
|
+
<a href="#cli-usage">CLI Reference</a> •
|
|
56
|
+
<a href="#acknowledgements--special-thanks">Acknowledgements</a> •
|
|
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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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` • `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.
|