# Quick Checks Quick Checks are zero-LLM, composable micro-scorers for common assertions. They plug into the existing `scorers: [...]` array anywhere scorers are used — in `runEvals`, live scoring, experiments, and Studio. Internally they are standard `createScorer()` instances, so they have the same observability, storage, and pipeline integration as any other scorer. ## Usage example ```typescript import { checks } from '@mastra/evals/checks' import { runEvals } from '@mastra/core/evals' import { myAgent } from '../agents' const result = await runEvals({ data: [{ input: 'What is the weather in Brooklyn?' }], target: myAgent, scorers: [ checks.includes('sunny'), checks.calledTool('get_weather'), checks.toolOrder(['get_weather', 'summarize']), checks.noToolErrors(), ], }) console.log(result.scores) ``` ## Text checks ### `checks.includes(expected, options?)` Scores 1 if the agent's output text contains the expected substring, 0 otherwise. ```typescript checks.includes('sunny') checks.includes('Sunny', { ignoreCase: false }) ``` **expected** (`string`): Substring to search for in the output. **options.ignoreCase** (`boolean`): Case-insensitive matching. (Default: `true`) Returns: `1` if found, `0` otherwise. ### `checks.excludes(unwanted, options?)` Scores 1 if the agent's output text does NOT contain the substring, 0 otherwise. ```typescript checks.excludes('error') checks.excludes('Error', { ignoreCase: false }) ``` **unwanted** (`string`): Substring that must not appear in the output. **options.ignoreCase** (`boolean`): Case-insensitive matching. (Default: `true`) Returns: `1` if absent, `0` otherwise. ### `checks.equals(expected, options?)` Scores 1 if the output text exactly equals the expected string after optional normalization. ```typescript checks.equals('Hello, world!') checks.equals('Hello', { ignoreCase: false }) ``` **expected** (`string`): Exact string the output must match. **options.ignoreCase** (`boolean`): Case-insensitive matching. (Default: `true`) Returns: `1` if equal, `0` otherwise. ### `checks.matches(pattern, options?)` Scores 1 if the output matches the given regular expression. ```typescript checks.matches(/\d+°[FC]/) checks.matches(/^hello$/, { exact: true }) ``` **pattern** (`RegExp`): Regular expression to test against the output. **options.exact** (`boolean`): Anchor the pattern to match the entire output (adds ^ and $). (Default: `false`) Returns: `1` if matched, `0` otherwise. ### `checks.similarity(expected, options?)` Returns the string similarity score (0-1) between the output and an expected string using the Dice coefficient. When a `threshold` is set, returns binary 1/0 instead. ```typescript checks.similarity('Sunny, 72°F') checks.similarity('Sunny, 72°F', { threshold: 0.7 }) ``` **expected** (`string`): Reference string to compare against. **options.threshold** (`number`): Minimum similarity score (0-1) to return 1. When omitted, returns the raw similarity score. **options.ignoreCase** (`boolean`): Case-insensitive comparison. (Default: `true`) Returns: Raw similarity score (0-1), or binary `1`/`0` when `threshold` is set. ## Tool call checks ### `checks.calledTool(toolName, options?)` Scores 1 if the agent called the specified tool at least the required number of times. ```typescript checks.calledTool('get_weather') checks.calledTool('search', { times: 2 }) ``` **toolName** (`string`): Name of the tool to look for. **options.times** (`number`): Minimum number of times the tool must be called. (Default: `1`) Returns: `1` if called at least `times` times, `0` otherwise. ### `checks.didNotCall(toolName)` Scores 1 if the agent did NOT call the specified tool. ```typescript checks.didNotCall('delete_user') ``` **toolName** (`string`): Name of the tool that must not appear. Returns: `1` if the tool was not called, `0` otherwise. ### `checks.toolOrder(expectedOrder)` Scores 1 if the tools were called in the specified order. Uses relaxed matching — other tool calls between the expected tools are allowed. ```typescript checks.toolOrder(['search', 'summarize', 'respond']) ``` **expectedOrder** (`string[]`): Tool names in the expected calling sequence. Must appear as a subsequence of the actual tool calls. Returns: `1` if the expected order is satisfied, `0` otherwise. ### `checks.maxToolCalls(max)` Scores 1 if the agent used no more than `max` tool calls. ```typescript checks.maxToolCalls(5) ``` **max** (`number`): Maximum number of tool calls allowed. Returns: `1` if within the limit, `0` otherwise. ### `checks.usedNoTools()` Scores 1 if the agent made no tool calls at all. ```typescript checks.usedNoTools() ``` Returns: `1` if no tools were called, `0` otherwise. ### `checks.noToolErrors()` Scores 1 if none of the tool invocations resulted in an error state. Detects both error results (`result.error` present) and incomplete tool calls (`state === 'call'`). ```typescript checks.noToolErrors() ``` Returns: `1` if all tool calls succeeded, `0` otherwise. ## Combining checks with other scorers Checks compose with LLM-based and code-based scorers in the same `scorers` array: ```typescript import { checks } from '@mastra/evals/checks' import { createAnswerRelevancyScorer } from '@mastra/evals/scorers/prebuilt' import { runEvals } from '@mastra/core/evals' import { myAgent } from '../agents' const result = await runEvals({ data: [{ input: 'What is the weather in Brooklyn?' }], target: myAgent, scorers: [ // Zero-LLM checks checks.includes('Brooklyn'), checks.calledTool('get_weather'), checks.noToolErrors(), // LLM-based scorer createAnswerRelevancyScorer({ model: 'openai/gpt-5-mini' }), ], }) ``` ## Related - [Quick Checks overview](https://mastra.ai/docs/evals/quick-checks) - [Built-in Scorers](https://mastra.ai/docs/evals/built-in-scorers) - [`createScorer()` reference](https://mastra.ai/reference/evals/create-scorer) - [`runEvals()` reference](https://mastra.ai/reference/evals/run-evals) - [Custom Scorers](https://mastra.ai/docs/evals/custom-scorers)