Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
"
Evaluate this output against criteria:
{string.Join("
", criteria)}
Output:
{output}
Rate each criteria. Return ONLY a JSON object where keys are the criteria and values are objects with a 'status' ("
" or "
") and 'feedback' string.
"
""
var
await
new
var
"{}"
string
null
try
string
catch
// Fallback to empty if json parsing fails
new
string
if
null
0
"PASS"
return
var
"FAIL"
new
string
string
if
0
// If nothing explicitly failed but parsing succeeded, break out to avoid unguided infinite loops
break
var
var
$"Improve the original output to address these failures: {failedJson}\nOriginal Output: {output}"
var
await
string
return
private
class
CritiqueResult
JsonPropertyName("status")
public
string
get
set
string
JsonPropertyName("feedback")
public
string
get
set
string
Key insight: Use structured JSON output for reliable parsing of critique results. In .NET, you can also use
IChatClient directly with structured output models to avoid manual deserialization checking.
Pattern 2: Evaluator-Optimizer
Separate generation and evaluation into distinct components for clearer responsibilities.
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.AI;
namespaceDotNetAgentHarness.Evals.Engine;
publicclassEvaluatorOptimizer(IChatClient chatClient, double scoreThreshold = 0.8)
{
publicasync Task<string> GenerateAsync(string task, CancellationToken cancellationToken = default)
{
var response = await chatClient.GetResponseAsync($"Complete: {task}", cancellationToken: cancellationToken);
return response.Text ?? string.Empty;
}
publicasync Task<EvaluationResult> EvaluateAsync(string output, string task, CancellationToken cancellationToken = default)
{
var prompt = $$"""
Evaluate output for task: {{task}}
Output:
{{output}}
Return JSON in this format: { "overall_score": 0.0, "dimensions": { "accuracy": 0.0, "clarity": 0.0 } }
""";
var response = await chatClient.GetResponseAsync(
prompt,
new ChatOptions { ResponseFormat = ChatResponseFormat.Json },
cancellationToken);
var jsonText = response.Text ?? "{}";
try
{
return JsonSerializer.Deserialize<EvaluationResult>(jsonText) ?? new EvaluationResult();
}
catch (JsonException)
{
returnnew EvaluationResult();
}
}
publicasync Task<string> OptimizeAsync(string output, EvaluationResult feedback, CancellationToken cancellationToken = default)
{
var feedbackJson = JsonSerializer.Serialize(feedback);
var prompt = $"Improve based on feedback: {feedbackJson}\nOutput: {output}";
var response = await chatClient.GetResponseAsync(prompt, cancellationToken: cancellationToken);
return response.Text ?? string.Empty;
}
publicasync Task<string> RunAsync(string task, int maxIterations = 3, CancellationToken cancellationToken = default)
{
var output = await GenerateAsync(task, cancellationToken);
for (int i = 0; i < maxIterations; i++)
{
var evaluation = await EvaluateAsync(output, task, cancellationToken);
if (evaluation.OverallScore >= scoreThreshold)
{
break;
}
output = await OptimizeAsync(output, evaluation, cancellationToken);
}
return output;
}
}
publicclassEvaluationResult
{
[JsonPropertyName("overall_score")]
publicdouble OverallScore { get; set; }
[JsonPropertyName("dimensions")]
public Dictionary<string, double> Dimensions { get; set; } = new();
}
Pattern 3: Code-Specific Reflection
Test-driven refinement loop for code generation.
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.AI;
namespaceDotNetAgentHarness.Evals.Engine;
publicclassCodeReflector(IChatClient chatClient)
{
publicasync Task<string> ReflectAndFixAsync(string spec, int maxIterations = 3, CancellationToken cancellationToken = default)
{
var codeResponse = await chatClient.GetResponseAsync($"Write C# code for: {spec}", cancellationToken: cancellationToken);
var code = codeResponse.Text ?? string.Empty;
var testsResponse = await chatClient.GetResponseAsync($"Generate xUnit tests for: {spec}\nCode: {code}", cancellationToken: cancellationToken);
var tests = testsResponse.Text ?? string.Empty;
for (int i = 0; i < maxIterations; i++)
{
var result = await RunTestsAsync(code, tests, cancellationToken);
if (result.Success)
{
return code;
}
var fixResponse = await chatClient.GetResponseAsync($"Fix error: {result.Error}\nCode: {code}", cancellationToken: cancellationToken);
code = fixResponse.Text ?? string.Empty;
}
return code;
}
// Stub for actual test executionprivate Task<TestResult> RunTestsAsync(string code, string tests, CancellationToken cancellationToken = default)
{
// In a real implementation, you would compile and run the tests dynamicallyreturn Task.FromResult(new TestResult { Success = false, Error = "Mock test failure" });
}
privateclassTestResult
{
publicbool Success { get; set; }
publicstring Error { get; set; } = string.Empty;
}
}
Evaluation Strategies
Outcome-Based
Evaluate whether output achieves the expected result.
publicasync Task<string> LlmJudgeAsync(string outputA, string outputB, string criteria, CancellationToken cancellationToken = default)
{
var response = await chatClient.GetResponseAsync(
$"Compare outputs A and B for {criteria}. Which is better and why?\n\nOutput A:\n{outputA}\n\nOutput B:\n{outputB}",
cancellationToken: cancellationToken
);
return response.Text ?? string.Empty;
}
Rubric-Based
Score outputs against weighted dimensions.
publicclassRubricDimension
{
publicdouble Weight { get; set; }
}
publicasync Task<double> EvaluateWithRubricAsync(string output, Dictionary<string, RubricDimension> rubric, CancellationToken cancellationToken = default)
{
var dimensions = string.Join(", ", rubric.Keys);
var prompt = $"Rate 1-5 for each dimension: {dimensions}\nOutput: {output}\n\nReturn ONLY a JSON dictionary where keys are dimensions and values are numbers.";
var response = await chatClient.GetResponseAsync(
prompt,
new ChatOptions { ResponseFormat = ChatResponseFormat.Json },
cancellationToken);
var jsonText = response.Text ?? "{}";
Dictionary<string, double> scores;
try
{
scores = JsonSerializer.Deserialize<Dictionary<string, double>>(jsonText) ?? new Dictionary<string, double>();
}
catch (JsonException)
{
scores = new Dictionary<string, double>();
}
double totalScore = 0;
foreach (var dimension in rubric.Keys)
{
if (scores.TryGetValue(dimension, outvar score))
{
totalScore += score * rubric[dimension].Weight;
}
}
return totalScore / 5.0; // Normalize
}