| name | neuron-evaluation-engineer |
| description | Create and run AI evaluations with datasets, assertions, and output drivers in Neuron AI. Use this skill whenever the user mentions evaluation, testing AI systems, creating evaluators, dataset-driven testing, assertion-based validation, or wants to measure AI system performance. Also trigger for tasks involving evaluator discovery, output configuration, result analysis, or building custom assertions. |
Neuron AI Evaluation Engineer
This skill helps you create and run evaluations for AI systems in Neuron AI. The evaluation system provides dataset-driven testing with flexible assertions, comprehensive result reporting, and extensible output drivers.
Core Concepts
The Evaluation System
Evaluations test AI systems using three main components:
- Evaluators - Test classes that define what to run and how to validate
- Datasets - Test data sources (arrays, JSON files)
- Assertions - Validation rules for checking outputs
Dataset Items → Evaluator::run() → Output → Evaluator::evaluate() → Assertions → Results
Evaluation Flow
For each dataset item:
setUp() - Initialize resources (once per evaluator)
run(datasetItem) - Execute your AI logic
evaluate(output, datasetItem) - Assert against expected results
- Repeat for next item
Note: Each evaluation starts with a fresh assertion executor - no manual reset needed.
Creating Custom Evaluators
Basic Evaluator
use NeuronAI\Evaluation\BaseEvaluator;
use NeuronAI\Evaluation\Contracts\DatasetInterface;
use NeuronAI\Evaluation\Assertions\StringContains;
use NeuronAI\Evaluation\Dataset\ArrayDataset;
use NeuronAI\Agent;
use NeuronAI\Agent\SystemPrompt;
class ContainsEvaluator extends BaseEvaluator
{
public function getDataset(): DatasetInterface
{
return new ArrayDataset([
[
'text' => 'I love this product!',
'content' => 'product',
],
[
'text' => 'This is terrible.',
'content' => 'positive',
],
]);
}
public function run(array $datasetItem): mixed
{
$response = MyAgent::make()->chat(
new UserMessage($datasetItem['text'])
)->getMessage();
return $response->getContent();
}
public function evaluate(mixed $output, array $datasetItem): void
{
$this->assert(
new StringContains($datasetItem['content']),
$output
);
}
}
JSON Dataset
For larger datasets, use JSON files:
use NeuronAI\Evaluation\Dataset\JsonDataset;
public function getDataset(): DatasetInterface
{
return new JsonDataset(__DIR__ . '/datasets/sentiment.json');
}
JSON format (sentiment.json):
[
{"text": "I love this!", "expected": "positive"},
{"text": "This is bad.", "expected": "negative"}
]
Built-in Assertions
String Assertions
StringContains
Check if the output contains a substring:
$this->assert(new StringContains('positive'), $output);
StringContainsAll
Check if the output contains all keywords:
$this->assert(new StringContainsAll(['hello', 'world']), $output);
StringContainsAny
Check if the output contains any of the keywords:
$this->assert(new StringContainsAny(['success', 'completed']), $output);
StringStartsWith
Check if the output starts with a prefix:
$this->assert(new StringStartsWith('Hello'), $output);
StringEndsWith
Check if the output ends with a suffix:
$this->assert(new StringEndsWith('!'), $output);
StringLengthBetween
Check if the string length is within range:
$this->assert(new StringLengthBetween(10, 100), $output);
StringDistance
Check string similarity using Levenshtein distance:
$this->assert(new StringDistance(
reference: 'expected text',
threshold: 0.5, // Minimum similarity score
maxDistance: 50 // Maximum allowed edits
), $output);
StringSimilarity
Check string similarity using embeddings:
use NeuronAI\Evaluation\Assertions\StringSimilarity;
use NeuronAI\RAG\Embeddings\OpenAI\OpenAIEmbeddings;
$this->assert(new StringSimilarity(
reference: 'The quick brown fox',
embeddingsProvider: new OpenAIEmbeddings(key: 'YOUR_KEY'),
threshold: 0.6
), $output);
Pattern Assertions
MatchesRegex
Match against regular expression:
$this->assert(new MatchesRegex('/^\d{3}-\d{2}-\d{4}$/'), $output);
Structure Assertions
IsValidJson
Check if the output is valid JSON:
$this->assert(new IsValidJson(), $output);
AI Judge Assertions
AgentJudge
Use an AI agent to evaluate outputs with custom criteria:
use NeuronAI\Evaluation\Assertions\AgentJudge;
use NeuronAI\Agent;
$judge = Agent::make()
->setInstructions('You are an expert evaluator for customer support responses.');
$this->assert(new AgentJudge(
judge: $judge,
criteria: 'Response should be helpful, polite, and address the customer\'s question directly',
threshold: 0.7
), $output);
$this->assert(new AgentJudge(
judge: $judge,
criteria: 'The response should convey the same meaning as the reference',
threshold: 0.8,
reference: $datasetItem['expected_answer']
), $output);
$this->assert(new AgentJudge(
judge: $judge,
criteria: 'Rate the factual accuracy of the response',
threshold: 0.7,
examples: [
[
'input' => 'What is 2+2?',
'output' => '2+2 equals 4',
'score' => 1.0,
'reasoning' => 'Mathematically correct and clear.',
],
]
), $output);
Pre-configured Judges
Built-in judges for common evaluation scenarios:
use NeuronAI\Evaluation\Assertions\Judges\{FaithfulnessJudge, CorrectnessJudge, RelevanceJudge, HelpfulnessJudge};
$this->assert(new FaithfulnessJudge(
judge: $judge,
context: $retrievedDocuments,
threshold: 0.7
), $output);
$this->assert(new CorrectnessJudge(
judge: $judge,
expected: $datasetItem['expected_answer'],
threshold: 0.7
), $output);
$this->assert(new RelevanceJudge(
judge: $judge,
question: $datasetItem['question'],
threshold: 0.7
), $output);
$this->assert(new HelpfulnessJudge(
judge: $judge,
threshold: 0.7
), $output);
Creating Custom Assertions
use NeuronAI\Evaluation\Assertions\AbstractAssertion;
use NeuronAI\Evaluation\AssertionResult;
class GreaterThanAssertion extends AbstractAssertion
{
public function __construct(
private readonly float $threshold
) {}
public function evaluate(mixed $actual): AssertionResult
{
if (!is_numeric($actual)) {
return AssertionResult::fail(
0.0,
'Expected numeric value, got ' . gettype($actual),
);
}
if ($actual > $this->threshold) {
return AssertionResult::pass(1.0);
}
return AssertionResult::fail(
0.0,
"Expected {$actual} to be greater than {$this->threshold}",
);
}
}
Use it:
$this->assert(new GreaterThanAssertion(0.8), $score);
Running Evaluations
CLI Command
vendor/bin/neuron evaluation /path/to/evaluators
vendor/bin/neuron evaluation --verbose /path/to/evaluators
vendor/bin/neuron evaluation --path=/path/to/evaluators
vendor/bin/neuron evaluation --help
Programmatic Execution
use NeuronAI\Evaluation\Runner\EvaluatorRunner;
$runner = new EvaluatorRunner();
$evaluator = new MyEvaluator();
$summary = $runner->run($evaluator);
echo "Passed: {$summary->getPassedCount()}\n";
echo "Failed: {$summary->getFailedCount()}\n";
echo "Success Rate: {$summary->getSuccessRate() * 100}%\n";
Output Configuration
Config File
Create evaluation.php in project root:
<?php
use NeuronAI\Evaluation\Output\ConsoleOutput;
use NeuronAI\Evaluation\Output\JsonOutput;
return [
'output' => [
ConsoleOutput::class,
JsonOutput::class => [
'path' => 'evaluation-results.json',
],
],
];
Default behavior: If no config exists, uses ConsoleOutput.
Built-in Output Drivers
ConsoleOutput
ConsoleOutput::class => ['verbose' => true]
verbose - Show detailed input/output for failures
JsonOutput
JsonOutput::class => ['path' => 'results.json']
JsonOutput::class
Creating Custom Output Drivers
use NeuronAI\Evaluation\Contracts\EvaluationOutputInterface;
use NeuronAI\Evaluation\Runner\EvaluatorSummary;
class DatabaseOutput implements EvaluationOutputInterface
{
public function __construct(
private readonly \PDO $pdo,
private readonly string $table = 'evaluations'
) {}
public function output(EvaluatorSummary $summary): void
{
$stmt = $this->pdo->prepare(
"INSERT INTO {$this->table}
(passed, failed, success_rate, total_time, created_at)
VALUES (?, ?, ?, ?, NOW())"
);
$stmt->execute([
$summary->getPassedCount(),
$summary->getFailedCount(),
$summary->getSuccessRate(),
$summary->getTotalExecutionTime(),
]);
}
}
Register in config:
DatabaseOutput::class => [
'pdo' => new \PDO('mysql:host=localhost;dbname=evaluations', 'user', 'pass'),
'table' => 'evaluations',
]
Project Setup
Configuring Autoloader
Add evaluators directory to composer.json:
{
"autoload-dev": {
"psr-4": {
"App\\Evaluators\\": "evaluators/"
}
}
}
Directory Structure
project/
├── evaluators/
│ ├── SentimentEvaluator.php
│ ├── SummarizationEvaluator.php
│ └── datasets/
│ ├── sentiment.json
│ └── summarization.json
├── evaluation.php
└── vendor/bin/neuron
Result Analysis
Accessing Results
$summary = $runner->run($evaluator);
$summary->getPassedCount();
$summary->getFailedCount();
$summary->getTotalCount();
$summary->getSuccessRate();
$summary->getTotalExecutionTime();
$summary->getAverageExecutionTime();
$summary->getTotalAssertions();
$summary->getTotalAssertionsPassed();
$summary->getTotalAssertionsFailed();
$summary->getAssertionSuccessRate();