@mastra/core
Version:
142 lines (104 loc) • 5.23 kB
Markdown
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
# Gates and verdicts
Gates and verdicts add severity semantics to `runEvals`. Gates are scorers that must score 1.0 — hard requirements that block a run. Thresholds are minimum acceptable scores on tracked metrics. The verdict summarizes the outcome as `passed`, `scored`, or `failed`.
## When to use gates and verdicts
- Enforce hard requirements in CI (e.g., "agent must call the right tool")
- Track quality metrics with minimum thresholds (e.g., "faithfulness above 0.7")
- Get a single verdict signal (`passed`, `scored`, or `failed`) from an eval run without writing custom assertion logic
- Separate "must pass" gates from "nice to have" tracked metrics
## Quickstart
```typescript
import { runEvals } from '@mastra/core/evals'
import { checks } from '@mastra/evals/checks'
import { weatherAgent } from '../agents'
import { faithfulnessScorer } from '../scorers'
const result = await runEvals({
data: [{ input: 'What is the weather in Brooklyn?' }],
target: weatherAgent,
// Gates: must all score 1.0 or the run fails
gates: [checks.calledTool('get_weather'), checks.noToolErrors()],
// Scorers: tracked with optional thresholds
scorers: [
{ scorer: faithfulnessScorer, threshold: 0.7 },
checks.includes('Brooklyn'), // no threshold = tracked only
],
})
console.log(result.verdict) // 'passed' | 'scored' | 'failed'
```
## How verdicts work
The verdict is computed from gates and thresholds after all data items are processed:
- `failed`: At least one gate averaged below 1.0 across data items
- `scored`: All gates passed, but at least one threshold scorer missed its threshold
- `passed`: All gates scored 1.0 and all thresholds were met
When no gates or threshold-bearing scorers are provided, the verdict field is omitted and `runEvals` behaves exactly as before.
## Gates
Gates are scorers passed via the `gates` field. They run before regular scorers on each data item. A gate must average a score of 1.0 across all data items to pass.
```typescript
import { runEvals } from '@mastra/core/evals'
import { checks } from '@mastra/evals/checks'
const result = await runEvals({
data: [{ input: 'What is the weather?' }],
target: weatherAgent,
gates: [checks.calledTool('get_weather')],
scorers: [qualityScorer],
})
// result.gateResults: [{ id: 'check-called-tool', passed: true, score: 1 }]
```
Any scorer works as a gate. Quick Checks are a natural fit because they return binary 1/0 scores.
> **Note:** Visit [runEvals() reference](https://mastra.ai/reference/evals/run-evals) for the full parameter and return type documentation.
## Thresholds
Wrap a scorer in `{ scorer, threshold }` to set pass/fail bounds. The threshold is compared against the scorer's average score across all data items.
A `threshold` can be:
- **A number** — implies minimum (score at or above passes): `{ scorer, threshold: 0.7 }`
- **An object with `min` and/or `max`** — for range-based checks: `{ scorer, threshold: { max: 0.3 } }`
Use `max` for scorers where a high score is bad (e.g., hallucination, toxicity). Use `{ min, max }` when the score should fall within a specific band.
```typescript
import { runEvals } from '@mastra/core/evals'
const result = await runEvals({
data: [{ input: 'Explain quantum computing' }],
target: myAgent,
scorers: [
{ scorer: faithfulnessScorer, threshold: 0.7 }, // min threshold (number shorthand)
{ scorer: hallucinationScorer, threshold: { max: 0.3 } }, // max threshold — high score = bad
{ scorer: verbosityScorer, threshold: { min: 0.3, max: 0.8 } }, // range threshold
toneScorer, // bare scorer, no threshold — tracked only
],
})
// result.thresholdResults:
// [
// { id: 'faithfulness', passed: true, averageScore: 0.85, threshold: 0.7 },
// { id: 'hallucination', passed: true, averageScore: 0.1, threshold: { max: 0.3 } },
// { id: 'verbosity', passed: false, averageScore: 0.9, threshold: { min: 0.3, max: 0.8 } },
// ]
```
A bare scorer (no threshold) still appears in `result.scores` but does not affect the verdict.
## Using verdicts in CI
The verdict gives a single signal for CI pipelines:
```typescript
import { runEvals } from '@mastra/core/evals'
import { checks } from '@mastra/evals/checks'
const result = await runEvals({
data: testDataset,
target: myAgent,
gates: [checks.calledTool('search'), checks.noToolErrors()],
scorers: [{ scorer: faithfulnessScorer, threshold: 0.7 }],
})
if (result.verdict === 'failed') {
console.error(
'Gate failures:',
result.gateResults?.filter(g => !g.passed),
)
process.exit(1)
}
if (result.verdict === 'scored') {
console.warn(
'Threshold misses:',
result.thresholdResults?.filter(t => !t.passed),
)
}
```
## Related
- [Quick Checks](https://mastra.ai/docs/evals/quick-checks): Zero-LLM micro-scorers that work well as gates
- [runEvals() reference](https://mastra.ai/reference/evals/run-evals): Full API documentation
- [Built-in scorers](https://mastra.ai/docs/evals/built-in-scorers): LLM-based and code-based scorers
- [Running evals in CI](https://mastra.ai/docs/evals/running-in-ci): CI integration patterns