Nexttag.Ai.Evals
0.1.0
dotnet add package Nexttag.Ai.Evals --version 0.1.0
NuGet\Install-Package Nexttag.Ai.Evals -Version 0.1.0
<PackageReference Include="Nexttag.Ai.Evals" Version="0.1.0" />
<PackageVersion Include="Nexttag.Ai.Evals" Version="0.1.0" />
<PackageReference Include="Nexttag.Ai.Evals" />
paket add Nexttag.Ai.Evals --version 0.1.0
#r "nuget: Nexttag.Ai.Evals, 0.1.0"
#:package Nexttag.Ai.Evals@0.1.0
#addin nuget:?package=Nexttag.Ai.Evals&version=0.1.0
#tool nuget:?package=Nexttag.Ai.Evals&version=0.1.0
Nexttag.Ai.Evals
Avalia a qualidade das saídas de LLMs/agentes (estilo LangSmith evals): datasets, evaluators determinísticos e LLM-as-judge, com relatório agregado. É a medição de qualidade que o tracing (Langfuse) não cobre.
O que é e quando usar
Tracing (Langfuse) responde "o que aconteceu nesta chamada?" — tokens, custo, latência, prompt/resposta. Evals responde uma pergunta diferente: "o quão BOA é a saída?" — de forma sistemática, sobre muitos casos, com um número comparável.
Use quando precisar:
- medir a qualidade de um agente/grafo/prompt sobre um conjunto de casos representativos;
- evitar regressão: provar que a versão nova de um prompt não piorou antes de subir (gate de CI);
- comparar alternativas (modelo A vs B, prompt V1 vs V2) com o mesmo critério.
A ideia central, igual ao LangSmith/ragas: você tem um dataset de casos, roda seu alvo sobre eles, e um conjunto de evaluators dá uma nota de 0 a 1 para cada saída. O relatório agrega tudo.
Conceitos
| Peça | O que é |
|---|---|
EvalCase |
Um caso de teste: Input (o que entra no alvo), Expected? (gabarito opcional) e Metadata?. |
EvalDataset |
Coleção de casos. Crie em memória (FromCases) ou carregue de um arquivo .jsonl (FromJsonl). |
EvalTarget |
O que está sendo avaliado: uma função caso → texto. Pode ser seu agente, um grafo, um prompt ou um endpoint. |
IEvaluator |
Um critério que pontua a saída de 0 a 1. Há os determinísticos (Evaluators.*) e o LlmJudgeEvaluator. |
EvalRunner |
Orquestra: roda o alvo sobre cada caso, aplica os evaluators e monta o relatório (com concorrência). |
EvalReport |
Resultado agregado: score médio, taxa de aprovação, score por evaluator e a lista de falhas. |
Como funciona (o fluxo)
dataset (casos) ──► EvalRunner ──► para cada caso:
output = alvo(caso)
para cada evaluator: EvalResult { score 0..1, passed, reason }
──► EvalReport agregado
Modelo de pontuação:
- Cada
EvalResulttraz umScorede 0 a 1 e umPassed(aprovado segundo o limiar daquele evaluator). - Um caso (
EvalCaseResult) temScore= média dos evaluators ePassed= todos aprovaram. - O relatório (
EvalReport) trazMeanScore(média geral),PassRate(fração aprovada),MeanScoreByEvaluator(para comparar critérios) eFailures(casos reprovados, com a saída produzida).
Evaluators determinísticos (ExactMatch/Contains/Regex) dão 0 ou 1. O LLM-judge dá uma nota contínua (ex.: 0.8) pedindo a um modelo que pontue segundo um critério em linguagem natural — útil quando não há um gabarito exato (resumos, respostas abertas, tom).
Instalar
dotnet add package Nexttag.Ai.Evals
Requer .NET 10. Depende de Microsoft.Extensions.AI (para o LLM-judge). Sem dependência do Agent Framework.
Registrar (Program.cs)
Sem registro de DI — instancie EvalRunner direto. Para o LLM-judge, passe um IChatClient (o mesmo que você já usa, ex.: apontando para o gateway litellm).
Configurar
Sem configuração obrigatória. O LLM-judge usa o IChatClient que você fornecer.
Usar
1. Monte um dataset
using Nexttag.Ai.Evals;
// Em memória
var dataset = EvalDataset.FromCases(
new EvalCase("c1", input: "Capital da França?", expected: "Paris"),
new EvalCase("c2", input: "Capital do Brasil?", expected: "Brasília"));
// Ou de um arquivo JSONL (uma linha por caso: {"id"?,"input","expected"?,"metadata"?})
var deArquivo = EvalDataset.FromJsonl("casos.jsonl");
2. Escolha evaluators
// Determinísticos (sem LLM) — dão 0 ou 1
Evaluators.ExactMatch(); // saída == expected (ignora caixa/espaços)
Evaluators.Contains(); // saída contém o expected
Evaluators.Regex(@"\d{5}-?\d{3}"); // saída casa com o padrão
Evaluators.Custom("tamanho", (caso, saida) =>
new EvalResult("tamanho", saida.Length <= 280 ? 1 : 0, saida.Length <= 280, null));
// LLM-as-judge: pontua 0..1 segundo um critério em linguagem natural
var juiz = new LlmJudgeEvaluator(chatClient,
criterio: "A resposta responde à pergunta de forma correta e completa?",
limiarAprovacao: 0.7);
3. Rode sobre um alvo e leia o relatório
// O alvo é qualquer função caso → saída (seu agente, grafo, prompt, endpoint...)
EvalTarget alvo = async (caso, ct) => await meuAgente.ResponderAsync(caso.Input, ct);
var report = await new EvalRunner().RunAsync(
dataset, alvo,
evaluators: [Evaluators.Contains(), juiz]); // o caso passa se TODOS aprovarem
Console.WriteLine($"Score médio: {report.MeanScore:P0} | Aprovação: {report.PassRate:P0}");
foreach (var falha in report.Failures)
Console.WriteLine($" ✗ {falha.Case.Id}: {falha.Output}");
Receitas
Regressão de prompt (compare duas versões):
var antigo = await runner.RunAsync(dataset, AlvoComPromptV1, evals);
var novo = await runner.RunAsync(dataset, AlvoComPromptV2, evals);
if (novo.MeanScore < antigo.MeanScore)
throw new Exception($"Regressão: {novo.MeanScore:P0} < {antigo.MeanScore:P0}");
Avaliar um grafo do Nexttag.Ai.Graph:
EvalTarget alvo = async (caso, ct) =>
{
var final = await grafo.RunAsync(new RagState { Pergunta = caso.Input }, ct);
return final.Resposta ?? "";
};
var report = await new EvalRunner().RunAsync(dataset, alvo, [juiz]);
Logar cada caso (ex.: progresso ou score no Langfuse):
var opts = new EvalRunOptions(
MaxConcurrency: 8,
OnCaseEvaluated: cr => Console.WriteLine($"{cr.Case.Id}: {cr.Score:P0}"));
await runner.RunAsync(dataset, alvo, evals, opts);
Notas
EvalCaseResult.Passed= todos os evaluators aprovaram;Score= média dos scores (0..1).- O LLM-judge instrui o modelo a devolver só
{"score":0..1,"reason":"..."}; se vier sem JSON válido, o caso recebe score 0 com o motivo (não quebra a execução). UsaTemperature 0por padrão. MaxConcurrencycontrola o paralelismo dos casos (padrão 4) — cuidado com rate limit do provedor.- Para rastrear tokens/custo do juiz, use um
IChatClientapontando para o gateway litellm (cai no Langfuse automaticamente). - A ordem do relatório segue a ordem do dataset.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.AI (>= 10.6.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 760 | 6/17/2026 |
0.1.0: primeira versao. Avaliacao de saidas de LLM/agentes (estilo LangSmith evals): datasets (memoria + JSONL), evaluators deterministicos (ExactMatch, Contains, Regex, Custom) e LLM-as-judge (qualquer IChatClient), e um runner com relatorio agregado (score medio, taxa de aprovacao, por-caso e por-evaluator).