This file provides instructions for AI agents working with the AgentEval codebase.
AgentEval is the comprehensive .NET evaluation toolkit for AI agents, built first for Microsoft Agent Framework (MAF). What RAGAS and DeepEval do for Python, AgentEval does for .NET:
- Tool usage validation with fluent assertions
- RAG quality metrics (faithfulness, relevance, groundedness)
- stochastic evaluation and statistical model comparison
- Behavioral policies (NeverCallTool, MustConfirmBefore)
- Trace record/replay for deterministic CI testing
dotnet build # Build all projects
dotnet test # Run all tests (×3 TFMs)
dotnet run --project samples/AgentEval.Samplessrc/AgentEval/- Umbrella packaging project (NuGet: AgentEval)src/AgentEval.Abstractions/- Public contracts: interfaces, modelssrc/AgentEval.Core/- Implementations: metrics, assertions, comparison, tracingsrc/AgentEval.DataLoaders/- Data loaders, exporters, output formattingsrc/AgentEval.MAF/- Microsoft Agent Framework integrationsrc/AgentEval.Memory/- Memory evaluation (retention, temporal, cross-session, benchmarks)src/AgentEval.RedTeam/- Security scanning, attack types, compliancetests/AgentEval.Tests/- Unit tests (mirrors src structure)tests/AgentEval.Memory.Tests/- Memory module unit testssamples/AgentEval.Samples/- 41 runnable samplesdocs/- Documentation
IMetric→IRAGMetric,IAgenticMetricIEvaluableAgent→IStreamableAgentIEvaluationHarness→MAFEvaluationHarness
llm_*= LLM-evaluated (API cost)code_*= Code-computed (free)embed_*= Embedding-based
result.ToolUsage!.Should() // Tool assertions
result.Performance!.Should() // Performance assertions
result.ActualOutput!.Should() // Response assertions- C# preview features enabled (LangVersion=preview)
- Nullable enabled throughout
- File-scoped namespaces preferred
requiredproperties for models- XML docs on public APIs
MethodName_StateUnderTest_ExpectedBehavior
Must include: Expected, Actual, Suggestions, Because parameter
This codebase follows SOLID, DRY, KISS, CLEAN principles strictly. See docs/adr/006-service-based-architecture-di.md for details.
- Interface-First: All core services have interfaces (IStochasticRunner, IModelComparer, etc.)
- DI/IOC: Use
services.AddAgentEval()for registration; inject interfaces, not implementations - No Over-Engineering: Don't add interfaces for builders, config objects, or test-time tools
- Single Responsibility: Each service has one focused purpose
// Register all services (umbrella convenience):
services.AddAgentEvalAll();
// Or register selectively:
services.AddAgentEval(); // Core services
services.AddAgentEvalDataLoaders(); // DataLoaders + Exporters
services.AddAgentEvalMemory(); // Memory evaluation
services.AddAgentEvalRedTeam(); // Red Team security testing
// Inject interfaces
public class MyService(IStochasticRunner runner, IModelComparer comparer) { }- Create in appropriate sub-project:
src/AgentEval.Core/Metrics/RAG/for RAG metricssrc/AgentEval.Core/Metrics/Agentic/for agentic metrics
- Implement
IRAGMetricorIAgenticMetric - Use appropriate prefix (
llm_/code_/embed_) - Add tests using
FakeChatClientintests/AgentEval.Tests/Metrics/
- Add to
ToolUsageAssertions,PerformanceAssertions, orResponseAssertions - Use
[StackTraceHidden]attribute - Call
AgentEvalScope.FailWith()with structured exception
- Create
SampleXX_Name.csin samples project - Register in
Program.csmenu - Follow header template with time estimate
- Provide mock fallback for offline testing
Use FakeChatClient for unit tests:
var fakeClient = new FakeChatClient("""{"score": 95}""");
var metric = new FaithfulnessMetric(fakeClient);Use Trace Replay for integration tests:
var trace = await TraceSerializer.LoadFromFileAsync("saved-trace.json");
var replayer = new TraceReplayingAgent(trace);
var response = await replayer.InvokeAsync("prompt");When making multiple small changes (docs, formatting, etc.), use [skip ci] to avoid triggering full CI pipeline:
git commit -m "docs: Fix typo in README [skip ci]"
git commit -m "style: Format code [skip ci]"When to use [skip ci]:
- Documentation-only changes
- Comment/typo fixes
- Formatting changes
- Intermediate commits during a multi-commit refactor
When NOT to use [skip ci]:
- Any code changes (even small ones)
- Final commit of a feature/fix
- Changes to tests, samples, or configuration
Use conventional commits:
feat:New featurefix:Bug fixdocs:Documentation onlystyle:Formatting, no code changerefactor:Code restructuringtest:Adding/updating testschore:Maintenance tasks
For samples/integration tests:
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/
AZURE_OPENAI_API_KEY=your-api-key
AZURE_OPENAI_DEPLOYMENT=gpt-4o
This repository uses Microsoft Agent Framework. The maf-doctor MCP server (also called "MAF Doctor") is installed and exposes tools for diagnosing, fixing, and migrating MAF code.
Before answering MAF questions or proposing changes:
-
Always call
MafDoctorfirst on the repo path to get the current health grade (A-F) and the top issues. Don't speculate about MAF quality without this baseline. -
For any
[Obsolete]warning,CS0618/CS0246diagnostic, or build failure mentioning a MAF type — callMafRunCs0618Hunt(full project scan) orMafApiSafety(single symbol) BEFORE suggesting a fix. The maf-doctor registry has curated fix recipes that supersede your training data — MAF ships breaking changes every minor version, so training data is likely outdated. -
To fix issues —
MafAutoFixAll --dry-runthen apply handles the mechanical rules deterministically (offer this first; the rewrites are tested). To fix everything, run themaf-remediateprompt (or just ask "fix all the issues maf-doctor found"): it grades → plans → autofixes → then works each semantic finding. Every finding carries aconfidence(certain/high/heuristic); aheuristicfinding may be a false positive — confirm it withMafExplainFindingbefore editing. Get the plan viaMafDoctor(format: "plan")(human) or--plan --json(structured manifest); per-rule fix + false-positive guidance lives in themaf-remediation-playbookskill. -
When designing a new MAF agent or workflow — call
MafNewAgent/MafNewExecutorfor scaffolds, orMafSimulateWorkflowfor topology preview. Don't reconstruct patterns from memory. -
For deep architectural / security / migration questions — run the
maf-review(best-practice audit),maf-audit(pre-migration scan + plan),maf-migrate(execute a migration-plan.md), ormaf-debug(diagnose a symptom) MCP prompts —initwires these up automatically, no extra setup needed. If.github/agents/was also copied in from the maf-doctor source repo (GitHub Copilot only — see the toolkit's init-reference.md), the equivalent@maf-best-practice-reviewer,@maf-auditor,@maf-migration, or@maf-incident-responderpersonas work the same way. -
To migrate FROM Semantic Kernel TO MAF (a cross-framework port, NOT a MAF version bump) — call
MafDetectSourceFramework(CLI:maf-doctor migrate-scan) to inventory SK usage and scope it, then run themaf-migrate-fromprompt (or the@maf-cross-migrationagent, if.github/agents/was also copied in). It scaffolds a new MAF project beside the original and ports it construct-by-construct, non-destructively. The mapping lives atmaf://migrate-from?source=semantic-kernel.
maf-doctor tools are MAF-version-aware via applies_to_codebases markers
in the registry — they know which fix applies to which MAF version. Defer to
the tools.