setup-maf-evals: report generation, three evaluator tiers, MSTest project shape - #2
Closed
leslierichardson95 wants to merge 18 commits into
Closed
setup-maf-evals: report generation, three evaluator tiers, MSTest project shape#2leslierichardson95 wants to merge 18 commits into
leslierichardson95 wants to merge 18 commits into
Conversation
…detection) Rewrites SKILL.md and references to specify the v2 overhaul: - Replaces hand-rolled markdown runner with a Microsoft.Extensions.AI.Evaluation.Reporting + `aieval` HTML report pipeline (GA 10.7.0). - Switches the scaffolded project from a console runner to an MSTest `<App>.Evals.Tests` project matching the canonical Learn-docs pattern. - Categorizes evaluators into three independent tiers (NLP / Quality / Safety) with separate env knobs (EVAL_USE_REAL_AGENT, EVAL_USE_REAL_JUDGE, EVAL_USE_FOUNDRY_SAFETY). - Adds IChatClient auto-detection so generated AgentChatClientFactory wires to the app's existing chat client registration. - Adds opt-in Safety tier (ContentHarmEvaluator via Azure AI Foundry) and opt-in GitHub Actions workflow. - New eval.yaml has 8 scenarios covering scaffold, update-mode preservation, IChatClient detection, reporting wiring, schema v2, CI workflow, safety opt-in. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Skill Coverage Report
Uncovered:
|
Three gaps surfaced when scaffolding ELI5Agent.Evals.Tests against an Aspire 13.2 + Foundry app: 1. **Detection table missing the Aspire Inference pattern.** `builder.AddAzureChatCompletionsClient(\"chat\").AddChatClient(\"chat\")` is the standard Aspire 13.2 way of wiring an IChatClient against a Foundry chat deployment, and was not in the v2 detection table. Added to ichatclient-detection.md with a note that the argument is the connection-string name. 2. **Connection-string setup not surfaced for standalone runs.** When the app uses Aspire orchestration, `ConnectionStrings:<alias>` is populated by the AppHost — but `dotnet test` runs outside the host and gets a silent missing-config NRE on first real-agent run. Added a `Connection-string setup for standalone test runs` section to ichatclient-detection.md that surfaces both user-secrets and env-var setup paths and points to `azd env get-values`. 3. **WordCountEvaluator implementation not pinned.** The catalog called the evaluator out as `always scaffolded (custom)` but never gave a verbatim template. Added the Learn-doc canonical implementation to evaluators-catalog.md so every scaffold gets the same (correct) IEvaluator skeleton. Validated end-to-end against ELI5Agent: scaffolded ELI5Agent.Evals.Tests, `dotnet test` exits 0 in stub tier with 4 scenarios x 4 metrics (Words/BLEU/GLEU/F1) producing a 670 KB report.html. Real-judge tier deferred (no Azure creds set up locally for ELI5Agent — itself the trigger for finding 2). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…gnostic 1. New references/metrics-glossary.md authored as the source of truth for metric definitions/scales/thresholds across NLP, Quality, and Safety tiers. Includes the canonical Reporting/MetricsGlossary.cs template that the skill emits into <App>.Evals.Tests/Reporting/. 2. Factory template in references/ichatclient-detection.md now wraps DI resolution in try/catch and throws a friendly InvalidOperationException naming the connection-string key + the exact 'dotnet user-secrets set' command + the env-var alternative + 'azd env get-values' pointer. Replaces the silent NRE that ELI5Agent dogfooding hit when EVAL_USE_REAL_AGENT=1 with no creds set up. 3. Two new eval.yaml scenarios bind the new behavior: - scaffold-emits-metrics-glossary: asserts MetricsGlossary.cs exists, references metrics-glossary.md, has [AssemblyCleanup] - factory-emits-friendly-secrets-diagnostic: asserts AgentChatClientFactory mentions 'dotnet user-secrets' + 'ConnectionStrings' 4. Captured two MSTest constraints that turned up while implementing the glossary writer: - quality-modes.md ReportingConfig: ExecutionName must be cached at class load, NOT re-evaluated per call (otherwise AievalReport and MetricsGlossary land in different timestamped folders 5 s apart) - metrics-glossary.md template now declares MetricsGlossary as a plain static class; MSTest forbids more than one [AssemblyCleanup] per assembly (UTA014). Glossary write is chained from AievalReport's single AssemblyCleanup, wrapped in try/catch so a glossary-write failure doesn't mask the report. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Spec was creeping toward the validator's 'comprehensive' threshold (3,574 BPE tokens / 14,238 chars / 265 lines). Pulled prose-heavy sections into references and kept SKILL.md focused on decision-relevant content. - Step 3 (Scaffold): replaced 27-line file tree with a one-sentence summary + link to project-template.md. Kept the post-write powershell as a fenced code block so the agent has concrete commands. - Steps 4-9 (telemetry/quality/compare/safety/panel/CI): collapsed bulleted prose into 3-4 line stubs that retain the decision facts (default ON/OFF, opt-in semantics, env knob) and link the corresponding reference. - Step 11 (Surface in chat): added the metrics-glossary.md path to the 'Paths' bullet and to the trailing 'see also' line. - ## Common pitfalls: extracted to references/common-pitfalls.md (also adds two new entries from this work: the multi-AssemblyCleanup MSTest constraint and the AgentChatClientFactory friendly-NRE pattern). SKILL.md keeps a one-line link. - ## References: trimmed each bullet to one short line; consolidated the three external links onto a single line. Net effect: SKILL.md 14,238 -> 10,449 chars, 265 -> 189 lines, 3,574 -> 2,672 BPE tokens (-25%). Validator still passes; eval.yaml scenarios are unaffected (assertions are file-based, not prose-based). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Overhauls the
setup-maf-evalsskill so it produces the canonical Microsoft.Extensions.AI.Evaluation HTML report (per the Learn doc tutorial) instead of a hand-rolled markdown approximation.Dogfooding the v1 skill on a real MAF + Aspire + Foundry app revealed it never wired
Microsoft.Extensions.AI.Evaluation.Reporting— users got a markdown table where the docs promised a rich HTML report. Hence this rewrite.What changes
<App>.Evals.Tests(matches Learn doc +dotnet/ai-samplescanonical pattern;dotnet test+ Test Explorer + CI integration are native).DiskBasedReportingConfiguration+ScenarioRun.EvaluateAsync+[AssemblyCleanup]invokes theaievaldotnet tool (pinned viadotnet-tools.json).BLEUEvaluator/GLEUEvaluator/F1Evaluator/WordCountEvaluator): always on, no API key.RelevanceEvaluatoretc.): on whenEVAL_USE_REAL_JUDGE=1.ContentHarmEvaluatorbundle + others): opt-in viaEVAL_USE_FOUNDRY_SAFETY=1.Agent vs judge are also independently switchable (
EVAL_USE_REAL_AGENT).AddAzureOpenAIChatClient/AddOllamaChatClient/AddAIInference/ explicitservices.AddSingleton<IChatClient>and generatesWire/AgentChatClientFactory.csautomatically. Three cases handled (single hit, multiple hits, none).schema_version,reference_response(for BLEU/GLEU/F1/Equivalence/Completeness),context(for Groundedness),expected_tool_calls(for ToolCallAccuracy). Migration is additive.ContentHarmEvaluatorover 4 separate evaluators: 1 Foundry call vs 4 for the same metric bundle (Hate/SelfHarm/Violence/Sexual)..github/workflows/evals.ymlruns evals on PRs, tier-detects from repo secrets, uploadsreport.htmlas a build artifact.Assert.Inconclusivewhen Foundry creds missing — never fails the build for missing opt-in capability.Files
Updated:
SKILL.md(full rewrite — 11 numbered workflow steps),references/project-template.md,references/quality-modes.md,references/telemetry-capture.md,references/compare-mode.md,tests/dotnet-ai/setup-maf-evals/eval.yaml(8 new scenarios).New:
references/ichatclient-detection.md,references/evaluators-catalog.md,references/safety-mode.md,references/ci-workflow.md,references/dotnet-tools-manifest.md.Validation
eng/skill-validator/srcdotnet run -- check --plugin plugins/dotnet-ai-> ✅ all checks pass (9 skills, 1 agent, 1 plugin).eval.yamlcovers 8 scenarios binding the spec:scaffold-evals-tests-project-fresh,scaffold-with-safety-tier,scaffold-with-ci-workflow,ichatclient-detection-azure-openai,ichatclient-detection-missing-emits-stub,skip-when-no-app-host,update-mode-preserves-user-data,tier-banner-surfaces-in-chat-output.Pre-merge checklist
interview-coach-v2clone end-to-end.report.htmlwith ≥4 metric columns (Words/BLEU/GLEU/F1).EVAL_USE_REAL_JUDGE=1tier adds ≥3 Quality metrics (Relevance/Coherence/Fluency).dotnet testexits 0 in stub tier with no Azure creds.eval.yamlfixtures still pass (no regression).Background
This is the second skill PR in the
dev-integrationseries — see alsoskills/setup-maf-evals(v1, already merged intodev-integration). The v1 commit history is preserved; v2 sits on top.Upstream
dotnet/skillsPR deferred until validation finishes.