Conteúdo da trilha
9 minNarração em inglês, legenda em portuguêsPodcast (RSS)
Capítulos
  1. 0:00Abertura
  2. 1:16A ideia
  3. 2:42Como funciona
  4. 3:17Um caso real
  5. 5:03Um desafio
  6. 5:48Quantos casos
  7. 6:26Dados sintéticos
  8. 7:09Armadilhas comuns
  9. 7:50Em produção
  10. 8:38Fechamento
Transcrição

Abertura

O Marcos montou o primeiro eval do classificador de tickets numa tarde. Ele pediu ao próprio modelo que gerasse cem tickets de exemplo, cada um com a fila certa.

O eval deu 96%. E em produção, o time de atendimento reclamava de tickets na fila errada todo santo dia.

Quando olhou tickets reais, ele entendeu. Os clientes escrevem com erro de digitação. Misturam dois assuntos. Colam print e respondem e-mail antigo. Os cem tickets gerados eram limpos, curtos e sempre sobre uma coisa só. O eval media um mundo que não existia.

E tinha um problema mais sutil. O mesmo modelo que escreveu os tickets também classificava. Ele escreveu do jeito que ele entendia, então acertava quase todos. O eval era um espelho.

Pior ainda. Quando um ticket real caía na fila errada, alguém corrigia o prompt, mas o caso nunca entrava no eval. Três meses depois, o mesmo erro voltava com outra mudança de prompt. Nesta aula, você vai aprender de onde vêm os casos de um eval confiável, e como mantê-los confiáveis com o tempo.

A ideia

A resposta é tratar o dataset como um ativo do produto. Com dono, versões e regras do que entra.

Origem real. Os casos vêm da produção, anonimizados. Casos sintéticos só entram para cobrir lacunas conhecidas, e ficam marcados como sintéticos.

Rótulos revisados. A resposta esperada vem de alguém que conhece o domínio. E casos difíceis ganham uma segunda revisão.

Cobertura por categoria. Toda categoria tem casos, inclusive as raras, e casos difíceis de propósito.

Crescimento por bug. Todo erro de produção vira um caso, antes de ser corrigido.

E separação. Uma parte do dataset é para desenvolvimento. Outra fica guardada, só para a decisão final, para você não sobreajustar.

Das cinco, o crescimento por bug é a que mais rende com o tempo. Um dataset que só recebe casos no dia em que foi criado envelhece junto com o produto. Um que recebe todo erro de produção vira a memória do time. Tudo o que quebrou uma vez fica vigiado para sempre.

E a ordem importa. Registre o caso, rode o eval e veja o caso falhar. Só então corrija. Se o caso não falha antes da correção, ele não reproduz o bug. E o teste não protege nada.

Como funciona

Aqui está o fluxo. Os casos novos vêm de dois lugares. Amostras do tráfego de produção, e bugs reportados.

Dados pessoais são removidos ou mascarados, antes de qualquer coisa.

Um especialista do domínio rotula a resposta esperada. Casos ambíguos ganham uma segunda revisão.

O dataset é versionado como código, com histórico de quem acrescentou o quê, e por quê.

Uma parte serve para iterar no prompt. A outra só é usada na decisão de deploy.

E o eval harness roda o sistema contra tudo isso.

Um caso real

Vamos seguir um bug até ele entrar no dataset. Numa segunda, o atendimento sinaliza um ticket. Paguei o boleto, mas o pedido 4521 continua pendente, e quero trocar o tamanho. Ele foi para a fila de pedidos. O financeiro só viu dois dias depois.

A pessoa de plantão acha o trace do ticket e manda para o dataset com um clique. Ele cai na fila de rotulagem, já mascarado.

Quem rotula aplica o guia. Dois assuntos, e o pagamento trava o pedido, então é financeiro. Como é um caso difícil, uma segunda pessoa confirma.

O caso entra, marcado como vindo de um bug, com o motivo. O eval roda no prompt atual, e o caso novo falha. Esperado financeiro, veio pedidos. Ótimo. Agora ele reproduz o bug.

Aí o prompt ganha a regra do assunto que trava, com um exemplo que não é esse ticket.

O eval roda de novo. O caso passa, e você confere se nada que passava agora falha. Só então o bug é fechado. E daqui a seis meses, quando alguém reescrever o prompt por outro motivo, aquele caso continua lá, e avisa se o erro voltar.

E esse guia de rotulagem é o que faz duas pessoas concordarem. É um documento curto que responde as dúvidas que vão aparecer. Dois assuntos? Use a fila do que trava o cliente. Só um print? Rotule pelo conteúdo dele. Na dúvida? Liste as duas e mande para segunda revisão. Todo empate novo achado na revisão vira regra no guia. E o guia é versionado junto com o dataset, porque rótulos e regras andam juntos.

Um desafio

Uma pergunta para você. A fila jurídica é 2% dos tickets. A sua amostra aleatória de duzentos casos trouxe quatro deles, e o eval mostra 75% nessa fila. O que você conclui?

Que com quatro casos o número quase não diz nada. Um erro vale vinte e cinco pontos. Um único ticket estranho explica os 75%. Puxe mais casos dessa fila.

E não ignore porque 2% quase não mexe na média. Pesar pouco na média não quer dizer custar pouco. Um ticket jurídico na fila errada pode virar processo. Categorias raras e caras merecem cobertura própria.

Quantos casos

Por isso a amostra é estratificada. Você puxa de propósito mais casos das categorias raras, até cada uma ter algumas dezenas. Numa categoria com vinte casos, cada erro mexe cinco pontos no placar. Numa com quatro, vinte e cinco.

O efeito colateral é que a média simples deixa de refletir a produção. Então mostre cada categoria separada. E calcule o placar geral ponderado pela frequência real de cada categoria.

E antes de comemorar dois pontos de ganho, veja quais casos mudaram. Em cem casos, dois pontos são dois tickets.

Dados sintéticos

Então, dado sintético é proibido? Não. Digamos que o time quer dobrar o eval esta semana, e alguém sugere pedir ao modelo de produção trezentos tickets novos, já rotulados. Volume não compensa origem. Casos gerados pelo modelo que você está avaliando tendem a ser fáceis para ele. O eval acaba medindo a si mesmo.

Mas uma proibição total vai longe demais. Sem casos sintéticos, uma categoria rara pode ficar sem nenhum. Use para preencher lacunas conhecidas. Pegue casos reais difíceis e gere variações, com erro de digitação, dois assuntos, outro idioma. Marque como sintético e revise os rótulos.

Armadilhas comuns

Agora, as armadilhas. Quem escreveu o prompt rotula sozinho. A tendência é rotular do jeito que o prompt já responde. Chame alguém do atendimento ou do financeiro.

Apagar o caso que sempre falha. Se um caso falha em todas as versões, revise o rótulo. Se o rótulo está certo, esse caso é exatamente o que o dataset precisa.

Espiar a parte guardada. Olhar ela a cada iteração, e ficar com a versão que foi melhor nela, transforma ela em dado de desenvolvimento.

E copiar casos do eval para o prompt como exemplos. O eval passa de memória, e o placar sobe sem a produção melhorar.

Em produção

Em produção, facilite. Um botão ou um comando que manda um trace direto para a fila de rotulagem.

Um painel com o tamanho do dataset por categoria, e a data do caso mais recente de cada uma.

Um alerta quando uma categoria nova aparece em produção sem casos no dataset.

E uma fila de rotulagem com dono e prazo. Fila sem dono vira cemitério de traces.

E lembre que o dataset guarda dado real. Mascarar só CPF e e-mail não basta. Tickets trazem nome, endereço, telefone, número de cartão e, às vezes, dado de saúde. Rode uma detecção mais completa, revise uma amostra na mão a cada lote, e restrinja quem tem acesso.

Fechamento

Então, a ideia para levar. Um eval é tão honesto quanto os casos dele. Tire da produção, e rotule com gente que conhece o domínio. Cubra as categorias raras de propósito, guarde uma fatia que você nunca espia, e transforme todo bug num caso antes de corrigir. Esse arquivo vira a memória do seu time.

Na próxima aula, a gente coloca esses evals para trabalhar num smell que quase todo time tem, e quase ninguém percebe até o fechamento do mês: texto passado entre duas máquinas. Free-text handoff. Até lá.

PadrãoOperação e qualidade

Dataset de Ouro

Golden Dataset

Dataset de Ouro (Golden Dataset) é um padrão de projeto de IA para apps com LLM e agentes, do grupo Operação e qualidade. Manter um conjunto curado de entradas e respostas esperadas, crescendo com bugs reais.

Elemento
65/70
Nível
Intermediário
Leitura
9 min
Atualizado
Nesta página 17
  1. 01Intenção
  2. 02Problema
  3. 03Solução
  4. 04Estrutura
  5. 05Pseudocódigo
  6. 06Cenários reais
  7. 07Aplicabilidade
  8. 08Quando não usar
  9. 09Como implementar
  10. 10Variações
  11. 11Custo, latência e falhas
  12. 12Como avaliar
  13. 13Em produção
  14. 14Segurança
  15. 15Prós e contras
  16. 16Código
  17. 17Teste seu entendimento
  18. ··Perguntas rápidas

Intenção

Manter um conjunto curado de entradas com a resposta esperada, que cresce a cada bug real e serve de referência para toda mudança. Serve para qualquer sistema com IA que precisa de um eval confiável ao longo do tempo.

Em uma frase
O gabarito oficial de uma prova, revisado a cada vez que alguém acha uma questão mal corrigida.

Problema

Marcos montou o primeiro eval do classificador de tickets em uma tarde: pediu ao próprio modelo para gerar 100 tickets de exemplo com a fila certa. O eval dava 96%. Em produção, o time de suporte reclamava de tickets na fila errada todos os dias.

Quando ele olhou os tickets reais, entendeu. Clientes escrevem com erros, misturam dois assuntos, colam prints, respondem a um email antigo. Os 100 tickets gerados eram limpos, curtos e sempre sobre uma coisa só. O eval media um mundo que não existia.

Tinha um segundo problema, mais sutil. O mesmo modelo que gerou os tickets também os classificava. Ele escrevia casos do jeito que ele próprio entendia, então acertava quase todos. O eval era um espelho.

Pior: quando um ticket real caía na fila errada, alguém corrigia o prompt, mas o caso nunca entrava no eval. Três meses depois, o mesmo erro voltou com outra mudança de prompt, e ninguém percebeu até o suporte reclamar de novo.

A pergunta que este padrão responde: de onde vêm os casos de um eval que represente de verdade a produção, e como ele continua representando com o tempo?

Solução

Trate o dataset como um ativo do produto, com dono, versão e regras de entrada:

  • Origem real. Os casos vêm de produção, anonimizados. Dados sintéticos só entram para cobrir lacunas conhecidas e ficam marcados.
  • Rótulo revisado. A resposta esperada é anotada por quem entende do domínio, e casos difíceis passam por uma segunda pessoa.
  • Cobertura por categoria. O dataset tem casos de todas as categorias, inclusive as raras, e casos difíceis de propósito.
  • Crescimento por bug. Todo erro de produção vira um caso antes de ser corrigido.
  • Separação. Uma parte do dataset é usada para desenvolver; outra fica guardada para a decisão final, para não sobreajustar.

Das cinco regras, o crescimento por bug é a que mais rende com o tempo. Um dataset que só recebe casos no dia em que foi criado envelhece junto com o produto. Um que recebe cada erro de produção vira a memória do time: tudo que já quebrou uma vez fica vigiado para sempre.

A ordem “caso antes da correção” também importa. Você grava o caso, roda o eval e vê o caso falhar. Só então corrige. Se o caso não falha antes da correção, ele não reproduz o bug, e o teste não protege nada.

Checagem +20 XP de primeiraSeu time quer dobrar o tamanho do eval esta semana. Alguém sugere pedir ao modelo de produção para gerar 300 tickets novos, já com a fila certa. O que você faz?

Estrutura

flowchart LR
  P[("1. Produção: traces e feedback")]:::store --> S["2. Amostrar e anonimizar"]:::tool
  B(["1. Bug reportado"]):::io --> S
  S --> L((("3. Rotular e revisar"))):::human
  L --> D[("4. Dataset versionado")]:::store
  D --> DEV["5a. Parte de desenvolvimento"]:::tool
  D --> HO["5b. Parte reservada"]:::tool
  DEV --> E(["6. Eval"]):::llm
  HO --> E
  1. Casos novos vêm de amostras de produção e de bugs reportados.
  2. Os dados pessoais são removidos ou mascarados antes de qualquer coisa.
  3. Uma pessoa do domínio anota a resposta esperada; casos ambíguos têm segunda revisão.
  4. O dataset é versionado como código, com histórico de quem adicionou o quê e por quê.
  5. Uma parte serve para iterar no prompt; a outra só é usada na decisão de deploy.
  6. A Bancada de Evals roda o sistema contra o dataset.

Pseudocódigo

schema GoldenCase {
    id: string, input: any, expected: any, category: string,
    source: "production" | "bug" | "synthetic", difficulty: "easy" | "hard",
    split: "dev" | "holdout", added_by: string, reason: string
}

function add_from_bug(report):
    raw = traces.find(report.trace_id)
    case = GoldenCase(input=redact_pii(raw.input), source="bug", difficulty="hard",
                      split=assign_split(), reason=report.summary)
    case.expected = human.label(case)                     # 3
    if disagreement(case): case.expected = human.review(case)
    dataset.append(case)                                  # 4
    dataset.commit("bug " + report.id)

function sample_production(n):
    for raw in traces.sample(n, stratify_by="category"):  # 1 e 2
        queue_for_labeling(redact_pii(raw.input))

function coverage_report():
    return dataset.count(by=["category", "difficulty", "source"])

Cenários reais

  • Extração de NF-e e contratos. Cada layout de nota que falhou vira caso, com o valor certo de cada campo. O dataset é organizado por emitente e por tipo de documento, porque um emitente novo costuma trazer um layout novo.
  • Perguntas em linguagem natural para SQL. Perguntas reais de analistas com a consulta correta e o resultado esperado num banco de teste fixo. O eval compara o resultado, não o texto da consulta, porque duas consultas diferentes podem estar certas.
  • Triagem automática de tickets. Tickets reais com a fila correta, estratificados para que filas raras tenham casos suficientes. É o caso do Marcos, e o exemplo trabalhado abaixo.

Aplicabilidade

  • Você vai rodar evals mais de uma vez.
  • O sistema tem categorias com frequências muito diferentes.
  • Bugs de produção acontecem e são corrigidos no prompt.
  • Mais de uma pessoa precisa confiar no resultado do eval.
  • Você vai trocar de modelo um dia e quer saber o que muda antes de trocar.

Quando não usar

  • Protótipo sem usuários reais. Comece com 20 casos escritos à mão e troque pelos reais assim que eles existirem.
  • Tarefas sem resposta esperada (texto criativo). Use critérios escritos e uma rubrica avaliada por pessoas ou por um modelo juiz; o dataset vira um conjunto de entradas sem gabarito.
  • Exemplos para o prompt. O dataset de eval não deve ser a mesma coisa que os exemplos do Seletor de Exemplos; se for, o eval mede decoreba.

Como implementar

  1. Puxe 100 a 200 entradas de produção, estratificadas por categoria.
  2. Remova dados pessoais com uma rotina automática e revise uma amostra.
  3. Rotule com quem entende do domínio, com instruções escritas de rotulagem.
  4. Marque dificuldade e origem em cada caso.
  5. Separe 20% a 30% como reserva, por sorteio dentro de cada categoria.
  6. Versione em arquivos de texto (JSONL) no repositório ou num armazenamento com histórico.
  7. Crie a regra: nenhum bug é fechado sem virar caso.
  8. Revise o dataset a cada trimestre: rótulos errados, categorias novas, casos que não fazem mais sentido.

A instrução de rotulagem

Dois rotuladores só concordam se a regra estiver escrita. A instrução é um documento curto que responde às dúvidas que vão aparecer. Um trecho do guia da triagem:

Fila de um ticket com dois assuntos:
  use a fila do assunto que impede o cliente de usar o produto.
  "paguei e o pedido segue pendente, e quero trocar o tamanho"
  -> billing (o pagamento não confirmado bloqueia o pedido)

Ticket só com print, sem texto:
  rotule pelo conteúdo do print; se ilegível, marque "unclear" e não use no eval.

Na dúvida entre duas filas:
  marque as duas em "alternatives" e mande para segunda revisão.

Cada vez que uma revisão encontra um empate novo, a regra entra no guia. O guia é versionado junto com o dataset, porque rótulo e regra andam juntos.

Quantos casos bastam

A conta é simples e assusta. Numa categoria com 20 casos, cada erro move a taxa em 5 pontos. Numa com 4 casos, em 25.

Suponha que a fila “jurídico” seja 2% dos tickets. Uma amostra aleatória de 200 casos traz uns 4 dela. Um erro e a fila aparece com 75%; nenhum erro e ela aparece com 100%. Nenhum dos dois números diz muito.

Por isso a amostra é estratificada: você puxa de propósito mais casos das filas raras, até cada uma ter algumas dezenas. O efeito colateral é que a média simples do dataset deixa de refletir a produção. Resolva assim:

  • Reporte a taxa de cada categoria separadamente.
  • Calcule a taxa global ponderada pela frequência real de cada categoria em produção.
  • Antes de comemorar uma melhora de dois ou três pontos, olhe quais casos mudaram. Em 100 casos, dois pontos são dois tickets.
Checagem +20 XP de primeiraA fila 'jurídico' é 2% dos tickets. Sua amostra aleatória de 200 casos trouxe 4 dela, e o eval mostra 75% de acerto nessa fila. O que você conclui?

Exemplo trabalhado: do bug ao caso

Uma segunda-feira, o suporte avisa: um cliente escreveu “oi, paguei o boleto mas o pedido 4521 continua como pendente e quero trocar o tamanho”. O ticket foi para a fila de pedidos. O financeiro só viu dois dias depois.

  1. Achar o trace. A pessoa de plantão clica em “mandar para o dataset” no trace do ticket. A entrada vai para a fila de rotulagem já mascarada.
  2. Rotular. A rotuladora aplica o guia: dois assuntos, o pagamento bloqueia o pedido, então billing. Como é caso difícil, uma segunda pessoa confirma.
  3. Gravar e ver falhar. O caso entra como tk-0912, com source: "bug" e o motivo. O eval roda com o prompt atual:
golden/tickets v41  (212 casos: 158 dev, 54 reserva)   exemplo ilustrativo
prompt triage@v17
  dev      91,1%   reserva  88,9%
  FALHA tk-0912  esperado=billing  obtido=orders  motivo: dois assuntos
  1. Corrigir. O prompt ganha a regra do assunto que bloqueia, com um exemplo que não é o tk-0912.
  2. Ver passar e comparar. O eval roda de novo. O tk-0912 passa, e você confere se algum caso que passava começou a falhar. Só então o bug é fechado.

O passo 5 é o que protege o futuro. Daqui a seis meses, quando alguém reescrever o prompt para outra coisa, o tk-0912 continua lá e avisa se o erro voltar.

Armadilhas comuns

  • O autor do prompt rotula sozinho. Ele tende a rotular do jeito que o prompt já responde. Chame alguém do suporte ou do financeiro.
  • Apagar o caso que sempre falha. Se um caso falha em todas as versões, revise o rótulo. Se o rótulo estiver certo, o caso é exatamente o que o dataset precisa.
  • Espiar a reserva. Olhar a reserva a cada iteração e escolher a versão que foi melhor nela transforma a reserva em parte de desenvolvimento.
  • Copiar casos para o prompt. O caso vira exemplo few-shot, o eval acerta por memória e a nota sobe sem a produção melhorar.

Variações

  • Dataset sintético dirigido. Um modelo gera variações de casos reais difíceis (com erro de digitação, dois assuntos, outro idioma). Útil para cobrir lacunas, sempre marcado como sintético.
  • Dataset vivo a partir de feedback. Respostas com polegar para baixo entram numa fila de rotulagem.
  • Dataset por versão de política. Quando a regra de negócio muda, os rótulos mudam junto; mantenha a versão da política em cada caso.

Custo, latência e falhas

Aspecto O que acontece Como aparece
Custo Tempo de pessoas do domínio para rotular horas de rotulagem por mês
Execução O tamanho do dataset define custo e tempo de cada eval custo do job de eval
Falha: rótulo errado O eval reprova a resposta certa casos que falham em todas as versões
Falha: dataset enviesado Só casos fáceis ou só de uma categoria taxa alta no eval e reclamações em produção
Falha: vazamento Casos do eval viram exemplos do prompt acurácia no eval muito acima da produção
Falha: reserva gasta A reserva foi usada para escolher entre versões reserva e dev sempre com a mesma nota
Falha: dados pessoais Dado real não mascarado no repositório achado em revisão de segurança

Como avaliar

  • Concordância entre rotuladores num subconjunto: se duas pessoas discordam muito, a tarefa ou a instrução está mal definida. A medida mais comum é o kappa de Cohen, que desconta a concordância que aconteceria por acaso.
  • Correlação com produção: a taxa no eval acompanha as reclamações e correções em produção? Se o eval sobe e as reclamações não caem, o dataset não representa a produção.
  • Cobertura: casos por categoria e por dificuldade, e fração de bugs do trimestre que viraram caso.
{ "id": "tk-0912", "input": "oi, paguei o boleto mas o pedido 4521 continua como pendente e quero trocar o tamanho", "expected": "billing", "category": "billing", "source": "bug", "difficulty": "hard", "split": "holdout", "reason": "dois assuntos; roteado para pedidos em 2026-08" }

Em produção

  • Botão ou comando para mandar um trace de produção direto para a fila de rotulagem.
  • Painel com o tamanho do dataset por categoria e a data do último caso de cada uma.
  • Alerta quando uma categoria nova aparece na produção sem casos no dataset.
  • Fila de rotulagem com dono e prazo. Uma fila sem dono vira um cemitério de traces.

Segurança

O dataset contém dados reais. Mascare dados pessoais antes de gravar, restrinja o acesso e registre a base legal do uso, em linha com a LGPD.

Mascarar só CPF e email não basta. Tickets trazem nome, endereço, telefone, número de cartão e, às vezes, dados de saúde. Rode uma detecção mais completa e revise uma amostra à mão a cada lote.

Prós e contras

Prós Contras
O eval mede o mundo real Rotular custa tempo de especialistas
Bugs corrigidos não voltam Exige disciplina para crescer
Base comum para todas as decisões Rótulos envelhecem quando a regra muda
Reserva evita sobreajuste Dados reais exigem cuidado com privacidade

Código

As duas abas implementam a entrada de um caso a partir de um bug e o relatório de cobertura.

Python. Use quando o dataset vive num JSONL versionado no repositório.

import hashlib
import json
import re
from collections import Counter
from pathlib import Path

DATASET = Path("evals/golden/tickets.jsonl")
CPF = re.compile(r"\b\d{3}\.?\d{3}\.?\d{3}-?\d{2}\b")
EMAIL = re.compile(r"[\w.+-]+@[\w-]+\.[\w.]+")


def redact(text: str) -> str:  # 2. mascarar antes de gravar
    return EMAIL.sub("<email>", CPF.sub("<cpf>", text))


def assign_split(case_id: str, holdout_share: float = 0.25) -> str:
    bucket = int(hashlib.sha256(case_id.encode()).hexdigest(), 16) % 100
    return "holdout" if bucket < holdout_share * 100 else "dev"  # estável por id


def add_from_bug(bug_id: str, text: str, expected: str, category: str, reason: str, author: str) -> dict:
    case_id = f"bug-{bug_id}"
    case = {
        "id": case_id, "input": redact(text), "expected": expected, "category": category,
        "source": "bug", "difficulty": "hard", "split": assign_split(case_id),
        "added_by": author, "reason": reason,
    }
    with DATASET.open("a", encoding="utf-8") as f:  # 4. versionado com git
        f.write(json.dumps(case, ensure_ascii=False) + "\n")
    return case


def coverage() -> Counter:
    with DATASET.open(encoding="utf-8") as f:
        cases = [json.loads(line) for line in f if line.strip()]
    return Counter((c["category"], c["difficulty"], c["split"]) for c in cases)

O que você ganhou: casos com origem, motivo e divisão estável, revisáveis em pull request. O que você perdeu: o mascaramento por regex pega só formatos conhecidos; use uma rotina de detecção mais completa antes de produção.

TypeScript. Use quando a fila de rotulagem roda num serviço Node.

import { createHash } from "node:crypto";
import { appendFileSync, readFileSync } from "node:fs";

const DATASET = "evals/golden/tickets.jsonl";

type GoldenCase = {
  id: string; input: string; expected: string; category: string;
  source: "production" | "bug" | "synthetic"; difficulty: "easy" | "hard";
  split: "dev" | "holdout"; added_by: string; reason: string;
};

const redact = (t: string) =>
  t.replace(/[\w.+-]+@[\w-]+\.[\w.]+/g, "<email>").replace(/\b\d{3}\.?\d{3}\.?\d{3}-?\d{2}\b/g, "<cpf>");

const split = (id: string): GoldenCase["split"] =>
  parseInt(createHash("sha256").update(id).digest("hex").slice(0, 8), 16) % 100 < 25 ? "holdout" : "dev";

export function addFromBug(bug: { id: string; text: string; expected: string; category: string; reason: string; author: string }) {
  const id = `bug-${bug.id}`;
  const c: GoldenCase = {
    id, input: redact(bug.text), expected: bug.expected, category: bug.category,
    source: "bug", difficulty: "hard", split: split(id), added_by: bug.author, reason: bug.reason,
  };
  appendFileSync(DATASET, JSON.stringify(c) + "\n");
  return c;
}

export function coverage(): Record<string, number> {
  const cases: GoldenCase[] = readFileSync(DATASET, "utf8").split("\n").filter((l) => l.trim()).map((l) => JSON.parse(l));
  return cases.reduce<Record<string, number>>((acc, c) => {
    const key = `${c.category}/${c.difficulty}/${c.split}`;
    acc[key] = (acc[key] ?? 0) + 1;
    return acc;
  }, {});
}

O que você ganhou: o mesmo formato de caso que a bancada lê, com divisão estável. O que você perdeu: o mesmo que em Python; o mascaramento é só um começo.

Teste seu entendimento

Checagem +20 XP de primeiraDepois de 15 rodadas ajustando o prompt, você olhou o resultado da parte reservada em cada rodada e ficou com a versão que foi melhor nela. Qual é o problema?

Checagem +20 XP de primeiraUm cliente reclama que o ticket dele caiu na fila errada. Qual sequência protege o produto contra o mesmo erro no futuro?

Checagem +20 XP de primeiraUm caso do dataset falha em todas as versões do prompt há quatro meses, inclusive com o modelo maior. Qual é o primeiro passo?

Checagem +20 XP de primeiraDuas pessoas do suporte rotularam os mesmos 50 tickets e discordaram em 15. O que isso indica primeiro?

Perguntas rápidas

O que é Dataset de Ouro?

Dataset de Ouro (Golden Dataset) é um padrão de projeto de IA para apps com LLM e agentes, do grupo Operação e qualidade. Manter um conjunto curado de entradas e respostas esperadas, crescendo com bugs reais.

Quais smells o padrão Dataset de Ouro ajuda a curar?

Acúmulo de Exemplos, Exemplos Chumbados, Prompt Sem Eval, Prompt Preso ao Modelo e Eval no Olhômetro.

Onde Dataset de Ouro aparece na prática?

Nos cenários reais Extração de NF-e e contratos, Perguntas em linguagem natural para SQL e Triagem automática de tickets.

Para ir além

Relações

Aparece nas trilhas 1
Buscar