Skill-Validator Evaluation Framework Architecture: Inside the .NET Pipeline
The skill-validator evaluation framework architecture implements a modular command-line pipeline that discovers AI skills, executes three-arm LLM evaluations, and produces statistical quality reports via a self-contained .NET application.
The dotnet/skills repository hosts a sophisticated evaluation system designed to validate AI agents and skills through automated testing. This self-contained .NET console application orchestrates complex workflows including baseline comparisons, isolated testing, and plugin integration. Understanding the skill-validator evaluation framework architecture reveals how the system handles filesystem discovery, parallel LLM execution, statistical analysis, and multi-format reporting.
Architecture Layers
The framework organizes code into distinct logical layers under eng/skill-validator/src/, each with specific responsibilities and clear separation of concerns.
CLI Entry Point and Command Layer
Located in Program.cs, this layer initializes the System.CommandLine infrastructure to create a RootCommand with evaluate and check subcommands. The Evaluate/EvaluateCommand.cs and Check/CheckCommand.cs files parse command-line arguments and translate them into a ValidatorConfig object that drives the entire pipeline.
Discovery Layer
The Shared/SkillDiscovery.cs, Shared/PluginDiscovery.cs, and Shared/AgentDiscovery.cs files handle filesystem traversal to locate plugin.json, skill.yml, and *.agent.md files. This layer produces SkillInfo, AgentInfo, and plugin-root path objects consumed by the evaluation engine.
Evaluation Engine
The core orchestration lives in EvaluateCommand.Run, EvaluateTarget, EvaluateSkill, and EvaluateAgent. This engine implements the three-arm evaluation strategy (baseline, isolated, plugin) using AgentRunner for LLM execution, ConcurrencyLimiter for parallelism control, and RetryHelper for resilience. The Shared/Statistics.cs and Shared/Models.cs files define the data structures for metrics collection.
Judging and Comparison
Quality assessment occurs in Evaluate/Judge.cs, which calls the LLM judge model to generate rubric scores. The Comparator.cs handles pairwise comparisons when --judge-mode=pairwise is specified, while OverfittingJudge.cs detects judgment overfitting to evaluation prompts. These components produce ScenarioComparison objects that feed into the final SkillVerdict.
Baseline Caching
The BaselineStore.cs implements a caching mechanism for the baseline arm (no-skill/no-agent execution). This allows repeated runs to reuse baseline data via --baseline-from and --baseline-out parameters, significantly reducing evaluation time and API costs.
Reporting Layer
The Reporter.cs class formats results across multiple output formats including console, JSON, JUnit XML, and Markdown. It provides GenerateMarkdownSummary for human-readable reports and handles per-scenario markdown generation.
Data Flow Through the Pipeline
Execution begins at Program.cs with command parsing, flows through the discovery layer to build in-memory models, then enters the evaluation engine. The ValidatorConfig acts as the central configuration object passed through each stage. AgentRunner executes LLM calls while Judge and Comparator analyze outputs and compute improvement scores against the baseline. Finally, Reporter formats the list of SkillVerdict objects into the requested output formats.
Practical Usage Examples
Running a Full Evaluation
Invoke the evaluation pipeline from the command line using the evaluate subcommand:
skill-validator evaluate \
--tests-dir tests \
--results-dir .skill-validator-results \
--reporter console json markdown \
--model claude-opus-4.6 \
--runs 5 \
path/to/skill-or-plugin
This command triggers the full pipeline defined in EvaluateCommand.Run, including discovery, three-arm evaluation, judging, and multi-format reporting.
Reusing Cached Baselines
Avoid recomputing baseline runs by using the caching mechanism:
# First run – writes baseline data
skill-validator evaluate \
--baseline-out baseline.json \
--tests-dir tests \
...
# Later run – reads baseline instead of recomputing
skill-validator evaluate \
--baseline-from baseline.json \
--tests-dir tests \
...
The BaselineStore.cs handles persistence and retrieval of baseline runs via the BaselineOut and BaselineFrom configuration options.
Programmatic Integration
Integrate the evaluator directly into .NET applications using the EvaluateCommand.Run method:
using SkillValidator.Evaluate;
// Build a config the same way the CLI does
var config = new ValidatorConfig
{
TestsDir = "tests",
ResultsDir = ".skill-validator-results",
Model = "claude-opus-4.6",
Runs = 3,
// …set any other options you need
};
// Run the evaluation and get the verdict objects back
var exitCode = await EvaluateCommand.Run(config);
This pattern allows the skill-validator evaluation framework architecture to be embedded in larger test suites or CI/CD pipelines.
Generating Markdown Reports
Extract human-readable summaries from evaluation results:
var verdicts = /* result from EvaluateCommand.Run */;
var markdown = Reporter.GenerateMarkdownSummary(verdicts, "claude-opus-4.6", "claude-opus-4.6");
Console.WriteLine(markdown);
The Reporter.GenerateMarkdownSummary method in Reporter.cs creates formatted markdown summaries suitable for documentation or pull request comments.
Summary
- The skill-validator evaluation framework architecture follows a modular pipeline design with clear separation between CLI handling, discovery, evaluation, judging, and reporting concerns.
- All source code resides under
eng/skill-validator/src/withProgram.csserving as the entry point andEvaluateCommand.Runas the main execution coordinator. - The framework implements a three-arm evaluation strategy (baseline, isolated, plugin) using
AgentRunnerandConcurrencyLimiterfor parallel LLM execution. - Baseline caching via
BaselineStore.csenables efficient reuse of baseline runs across evaluation sessions. - Output formats include console, JSON, JUnit XML, and Markdown through the
Reporter.csclass.
Frequently Asked Questions
How does the skill-validator handle parallel execution?
The framework uses ConcurrencyLimiter in the Shared/ directory to manage parallel LLM calls during evaluation. This component prevents API rate limiting while maximizing throughput across multiple test scenarios.
What is the purpose of the three-arm evaluation strategy?
The three-arm strategy implemented in EvaluateSkill.cs and EvaluateAgent.cs compares baseline performance (no skill), isolated skill execution, and plugin-mode execution. This isolates the true impact of the skill being evaluated from confounding variables and environment noise.
Can I run evaluations without recomputing baselines every time?
Yes. The BaselineStore.cs implements caching through --baseline-out and --baseline-from parameters. Store baseline results to a JSON file and reuse them across subsequent evaluation runs to save time and API costs.
How does the judging system prevent overfitting?
The OverfittingJudge.cs specifically analyzes LLM judgment patterns to detect when the judge model is overfitting to evaluation prompts rather than assessing actual skill quality. This works alongside the standard Judge.cs and Comparator.cs components to ensure valid statistical comparisons.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →