Apostila completa de LLMOps & Avaliação de Sistemas de IA
Um protótipo de LLM sobe numa tarde. O que separa isso de um produto é conseguir responder, com números, se ele está bom, se piorou depois do último ajuste, quanto custa cada resposta e o que fazer quando a qualidade cai às 3h. Esta apostila cobre avaliação (offline e online, LLM-as-judge, RAG e agentes), observabilidade com tracing, o ciclo de melhoria contínua e os guardrails de qualidade — sempre com o olho no que empresas realmente pedem em vagas.
O que é LLMOps e por que não é só "MLOps com prompt"
Objetivo: entender o ciclo de vida de um sistema baseado em LLM, o que ele herda do MLOps e o que é genuinamente novo — e por que avaliação é o centro de tudo.
1.1 A promessa fácil e a dívida escondida
Construir um app de LLM começou trivial: uma chamada de API, um prompt, uma resposta convincente numa demo. O problema aparece depois: você mudou uma frase do prompt e não sabe se melhorou ou piorou; um usuário reclamou de uma resposta que você não consegue reproduzir; o custo mensal triplicou sem explicação; trocou de modelo e três casos que funcionavam quebraram silenciosamente.
LLMOps é o conjunto de práticas e ferramentas para operar sistemas de LLM com o mesmo rigor de qualquer software crítico: versionar o que importa, medir a qualidade de forma repetível, observar o comportamento em produção, iterar com base em evidência e controlar custo e latência.
Em software tradicional, o teste é binário: passou ou não passou. Em sistemas de LLM, a saída é texto aberto sem gabarito único e o modelo é não determinístico. Por isso, a disciplina que sustenta LLMOps é a avaliação — transformar "parece bom" em uma métrica que você pode acompanhar ao longo do tempo. Sem eval, você está fazendo deploy no escuro.
1.2 O ciclo de vida de um sistema de LLM
┌────────────┐ ┌──────────────┐ ┌─────────────┐ ┌────────────┐ ┌──────────────┐
│ 1. Definir │──▶│ 2. Construir │──▶│ 3. Avaliar │──▶│ 4. Publicar│──▶│ 5. Observar │
│ a tarefa e │ │ prompt/RAG/ │ │ offline vs │ │ (canary, │ │ traces, │
│ o "bom" │ │ agente/tools │ │ dataset de │ │ shadow, │ │ feedback, │
│ (rubrica) │ │ │ │ referência │ │ A/B) │ │ evals online │
└────────────┘ └──────────────┘ └─────────────┘ └────────────┘ └──────┬───────┘
▲ │
└────────────── 6. Melhorar: error analysis → novos casos ──────────────┘
de eval → ajuste de prompt/RAG/modelo
Note que a avaliação aparece duas vezes: offline (antes de publicar, contra um dataset controlado) e online (em produção, sobre tráfego real). E que o ciclo se fecha: os problemas achados em produção viram novos casos de teste. Isso é o "data flywheel" do LLMOps.
1.3 LLMOps × MLOps
| Dimensão | MLOps clássico | LLMOps |
|---|---|---|
| Artefato principal | Modelo treinado (pesos) | Prompt + config + pipeline (RAG, tools); o modelo em si costuma ser de terceiros |
| Métrica de qualidade | Acurácia, F1, AUC — bem definidas, com ground truth | Qualidade de texto aberto — sem rótulo único; precisa de juízes (humano ou LLM) e rubricas |
| Ciclo de mudança | Re-treino (horas a dias) | Editar prompt (segundos) — muda rápido demais para não ter regressão automatizada |
| Custo dominante | Treino (uma vez, caro) | Inferência (contínua, por token, escala com uso) |
| Não determinismo | Baixo na inferência | Alto: temperatura, versão do modelo, contexto variável |
| Novas superfícies | Data/feature drift | + regressão silenciosa de modelo do provedor, prompt injection, alucinação, custo/latência |
LLMOps herda do MLOps o versionamento, CI/CD, monitoramento, gestão de dados e a cultura de experimentação. O que muda é o objeto (prompt/pipeline em vez de pesos), a natureza da métrica (subjetiva, sem gabarito) e a velocidade da iteração.
"LLMOps Engineer", "AI Evals", "Applied AI Engineer" com foco em produção — categoria de vaga que explodiu em 2024–2026 conforme as empresas passaram do piloto para o produto. O gargalo do mercado não é quem sabe chamar a API; é quem sabe provar que o sistema está bom e mantê-lo assim. Perfis vêm de MLOps, de engenharia de dados/backend e de data science aplicada. Portfólio com um sistema de eval de verdade vale mais que qualquer certificado.
✏️ Exercício 1 — O que você mediria?
Uma empresa tem um bot que responde dúvidas sobre a política de reembolso a partir de uma base de documentos. Liste quatro perguntas que um sistema de LLMOps precisa conseguir responder e que uma demo não responde.
Gabarito (exemplos): (1) Em que % das perguntas a resposta é factualmente fiel aos documentos (não alucina)? (2) A última edição do prompt melhorou ou piorou isso, medido sobre os mesmos 200 casos? (3) Qual a latência p95 e o custo médio por resposta, e como evoluíram na última semana? (4) Quando um usuário dá "joinha para baixo", esse caso entra automaticamente no conjunto de regressão? (5) Se o provedor atualizar o modelo, o alarme dispara?
Anatomia de um sistema de LLM em produção
Objetivo: conhecer os componentes que ficam entre a requisição do usuário e a resposta — cada um é algo a versionar, medir e observar.
2.1 O caminho de uma requisição
usuário
│
▼
[ App / API ] ── autentica, monta a requisição
│
▼
[ Gateway de LLM ] ── roteamento de modelo, rate limit, quota, cache, fallback, redaction, custo
│
▼
[ Camada de prompt ] ── template versionado + variáveis + few-shot + system prompt
│
├─▶ [ Recuperação / RAG ] ── embedding, busca vetorial, rerank, montagem de contexto
├─▶ [ Ferramentas / agente ] ── loop planejar-agir-observar, chamadas de função
│
▼
[ Provedor de modelo ] ── API hospedada ou modelo self-hosted (vLLM, TGI)
│
▼
[ Pós-processamento ] ── parse/validação de schema, guardrails de saída, citações
│
▼
[ Observabilidade ] ── trace completo: spans, tokens, custo, latência, feedback
│
▼
resposta
2.2 O que cada peça exige de LLMOps
| Componente | Versionar | Medir |
|---|---|---|
| Prompt / template | Cada versão com id, diff e autor (prompt registry) | Qualidade da saída por versão, num dataset fixo |
| Modelo | Nome + versão exata + parâmetros (temp, top_p, max_tokens) | Qualidade, custo, latência; alarme em mudança do provedor |
| RAG | Modelo de embedding, chunking, top_k, reranker, fonte e data do índice | Métricas de recuperação e de geração ancorada (Módulo 5) |
| Ferramentas / agente | Definições de tools, política de loop, limites | Taxa de conclusão da tarefa, acurácia de chamada de ferramenta, nº de passos |
| Guardrails | Regras e classificadores, versão | Falsos positivos/negativos, impacto na experiência |
| Gateway | Regras de roteamento, cache, fallback | Hit rate de cache, economia, latência adicionada |
2.3 O gateway de LLM a peça que quase todo time acaba adotando
Um proxy único entre a aplicação e os provedores (LiteLLM, Portkey, Kong AI Gateway, Cloudflare AI Gateway, ou um interno). Centraliza o que você não quer espalhado pelo código: chaves e rotação, roteamento e fallback entre modelos, rate limiting e quota por time/feature, cache semântico, contabilização de custo por chamada, redaction de PII, e o ponto natural para instrumentar tracing. Adotar cedo evita ter que reformar tudo depois.
Pergunta comum: "Desenhe a arquitetura de um app de LLM em produção e diga o que você instrumenta em cada ponto." Saber citar o papel do gateway, do prompt registry e do trace de ponta a ponta — e o que cada um permite medir — mostra que você já operou, não só prototipou.
✏️ Exercício 2 — Aponte o que falta versionar
Um time guarda os prompts em strings dentro do código (versionadas por git) e usa model="o-mais-recente" na chamada. O que há de errado e o que muda?
Gabarito: (1) "o-mais-recente" é um alias móvel: o modelo por trás pode mudar sem aviso e regredir a qualidade sem nenhum commit seu. Fixe a versão exata e trate atualização como mudança avaliada. (2) Prompt em git é aceitável, mas sem um registro que ligue versão do prompt → resultado de eval → deploy, você não consegue responder "essa mudança melhorou?". Um prompt registry (ou ao menos um mapeamento versão↔score) resolve. (3) Faltam registrados os parâmetros de inferência (temperatura etc.), que afetam a saída tanto quanto o prompt.
Avaliação I — medir sem gabarito
Objetivo: entender por que as métricas clássicas de NLP falham em tarefas generativas, que tipos de eval existem, e como montar um dataset de avaliação que presta.
3.1 Por que "acurácia" não serve
Se a tarefa é classificar (sentimento, categoria, sim/não), você tem rótulo e usa acurácia, F1, matriz de confusão — trate como ML clássico. O problema é a maioria das tarefas de LLM: resumir, responder, redigir, extrair, conversar. Aí não existe uma resposta certa única: dez respostas diferentes podem ser todas boas.
| Métrica | Como funciona | Por que falha em geração |
|---|---|---|
| Exact match | String idêntica à referência | Penaliza qualquer paráfrase correta |
| BLEU / ROUGE | Sobreposição de n-gramas com a referência | Mede semelhança de palavras, não de sentido; alto ROUGE com resposta ruim é comum |
| BERTScore | Similaridade de embeddings com a referência | Melhor, mas ainda exige referência e ignora fidelidade factual |
| Perplexidade | Quão "provável" o texto é para o modelo | Não mede utilidade nem correção para a tarefa |
Rodar ROUGE contra uma resposta "de ouro" e reportar 0,42 como se fosse acurácia. Esse número não diz se o sistema está pronto. Métricas baseadas em sobreposição só fazem sentido em tarefas muito fechadas (tradução, sumarização extrativa com referência forte) — e mesmo aí, como sinal secundário.
3.2 A taxonomia de avaliação
- Por objeto: avaliar o modelo (benchmarks tipo MMLU, GPQA — úteis para escolher, inúteis para o seu caso) vs avaliar o seu sistema na sua tarefa (o que importa).
- Com referência × sem referência: reference-based compara com uma resposta esperada; reference-free julga a resposta sozinha, por critérios (é fiel ao contexto? responde à pergunta? tem o tom certo?). A maioria da avaliação prática de produto é reference-free com rubrica.
- Quem julga: humano (padrão-ouro, caro, lento), heurística/código (barato, só para o verificável), ou LLM-as-a-judge (escalável, o cavalo de batalha — Módulo 4).
- Determinístico × baseado em modelo: assert de código (o JSON tem os campos? o número está no intervalo? cita a fonte?) vs julgamento semântico.
- Offline × online: contra dataset fixo antes do deploy vs sobre tráfego real depois.
3.3 O dataset de avaliação (o ativo mais valioso do time)
Sua capacidade de melhorar o sistema é limitada pela qualidade do seu conjunto de avaliação. Um bom dataset:
- Reflete o tráfego real: construído a partir de logs de produção, não inventado na mesa. Comece com 50–100 casos reais bem escolhidos — vale mais que 10 mil sintéticos.
- Cobre a distribuição e as bordas: casos fáceis, casos difíceis, casos adversariais, casos onde a resposta certa é "não sei", categorias raras mas críticas.
- Tem o critério explícito por caso: não só a entrada, mas o que torna a saída boa (uma rubrica, uma checklist, uma resposta de referência, ou "deve conter X e não pode afirmar Y").
- É versionado e cresce: todo bug de produção vira um caso novo. É um dataset vivo, com dono.
- É estratificado: você reporta o score por segmento (tipo de pergunta, idioma, cliente), não só a média — a média esconde a regressão numa fatia importante.
# Um caso de eval: entrada + contexto + critérios (não uma "resposta certa" única) { "id": "refund-042", "input": "comprei ontem, posso devolver? já usei uma vez", "retrieved_context": ["Política: devolução em até 7 dias se o produto não foi usado..."], "rubric": { "faithful": "a resposta reflete a política recuperada, sem inventar prazo ou condição", "addresses_used_item": "reconhece que 'já usei' pode desqualificar a devolução", "tone": "cordial, direto, sem jargão jurídico", "must_not": "prometer reembolso garantido" }, "segment": "politica-devolucao" }
Perguntas: "Por que BLEU/ROUGE não bastam para avaliar um sistema generativo?", "Como você construiria um dataset de avaliação do zero?" (a partir de logs reais, 50–100 casos, com rubrica por caso, versionado, estratificado por segmento), "Diferença entre avaliar o modelo e avaliar o sistema". A resposta que impressiona enfatiza que o dataset vem de dados reais e é um ativo com dono, não um arquivo estático.
✏️ Exercício 3 — Critique a métrica
Um time avalia seu assistente de e-mail assim: gera 500 e-mails, calcula ROUGE-L contra e-mails "ideais" escritos por eles, reporta média 0,38 e diz "está bom, subimos de 0,31". Aponte três problemas e proponha uma abordagem melhor.
Gabarito: (1) ROUGE mede sobreposição de palavras, não qualidade do e-mail — um e-mail excelente com outra redação pontua baixo. (2) Os "ideais" são um único jeito de escrever; a tarefa admite muitos. (3) A média esconde os segmentos (e-mail de cobrança vs de agradecimento podem ter regredido em direções opostas). Melhor: dataset de ~150 casos reais com rubrica por caso (tom, completude, ação clara, sem erro factual), julgados por LLM-as-judge calibrado contra ~30 julgamentos humanos, reportado por segmento, com intervalo de confiança.
Avaliação II — LLM como juiz
Objetivo: usar um LLM para avaliar saídas em escala de forma confiável — os formatos, os vieses conhecidos, e como calibrar o juiz contra julgamento humano.
4.1 Por que LLM-as-a-judge
Avaliação humana é o padrão-ouro, mas não escala: caro, lento, inconsistente entre avaliadores. Um LLM forte, com uma boa rubrica, concorda com humanos numa taxa alta o suficiente para servir como proxy escalável — você roda milhares de avaliações por centavos, em minutos, a cada mudança de prompt. É a técnica que tornou a avaliação contínua viável.
4.2 Os três formatos
| Formato | O juiz recebe | Devolve | Quando usar |
|---|---|---|---|
| Pointwise (direct scoring) | Uma saída + rubrica | Nota (ex.: 1–5) ou pass/fail por critério | Acompanhar uma métrica ao longo do tempo; gates de CI |
| Pairwise | Duas saídas (A e B) para a mesma entrada | Qual é melhor (ou empate) | Comparar versão nova vs atual; mais confiável que nota absoluta |
| Reference-based | Saída + resposta de referência | Concorda/contradiz/incompleta | Quando existe gabarito (extração, QA fechado) |
# Juiz pointwise com rubrica e saída estruturada — a base de uma métrica repetível JUDGE_PROMPT = """Você avalia a resposta de um assistente de suporte. Pergunta do usuário: {input} Contexto recuperado: {context} Resposta do assistente: {output} Avalie CADA critério como PASS ou FAIL, com uma frase de justificativa: - faithful: toda afirmação factual é sustentada pelo contexto acima - relevant: responde de fato à pergunta feita - safe: não promete nada fora da política; não expõe dado sensível Responda em JSON: {{"faithful": {{"verdict": "...", "reason": "..."}}, ...}}""" # dica: temperature=0, peça justificativa ANTES do veredito (raciocínio melhora a nota), # e rode o juiz 2–3x para casos limítrofes (self-consistency)
4.3 Os vieses do juiz (e como mitigar) avançado
| Viés | O que é | Mitigação |
|---|---|---|
| Posição | Em pairwise, tende a preferir a primeira (ou a segunda) opção | Rodar nas duas ordens e média; contar empate quando discordam |
| Verbosidade | Prefere respostas mais longas mesmo quando não são melhores | Critério explícito de concisão; controlar tamanho; penalizar enrolação |
| Autopreferência | Favorece texto do mesmo modelo/família que o juiz | Usar juiz de família diferente da do sistema avaliado |
| Bajulação / formatação | Impressiona-se com tom confiante, markdown bonito, "como assistente prestativo…" | Rubrica focada em substância; exemplos calibrados de bom e ruim |
| Leniência | Dá PASS na dúvida | Critérios binários e específicos; exigir citação da evidência |
| Escala comprimida | Só usa 3, 4 e 5 numa escala 1–5 | Preferir binário por critério, ou pairwise, a notas de 1–5 |
4.4 Calibrar o juiz — o passo que quase todo mundo pula
Um juiz LLM só vale se você mediu a concordância dele com humanos. O processo:
- Faça 30–50 humanos avaliarem os mesmos casos (idealmente 2 avaliadores por caso, para ter a concordância humano-humano como teto).
- Rode o juiz nos mesmos casos.
- Meça a concordância (acurácia vs consenso humano; Cohen's kappa para descontar acerto ao acaso; em pairwise, taxa de concordância).
- Se baixa, itere na rubrica e no prompt do juiz — adicione exemplos, torne critérios mais específicos — e re-meça.
- Documente o kappa alcançado. Um juiz com kappa ~0,6–0,8 num critério bem definido é utilizável; abaixo disso, o número engana.
Não confie num juiz que você não calibrou. E mantenha um "conjunto de verdade" humano pequeno e fixo: sempre que mudar o prompt do juiz ou o modelo dele, re-rode a calibração — o juiz também sofre regressão.
4.5 G-Eval e rubricas estruturadas
G-Eval é um método popular: o juiz recebe o critério, gera os passos de avaliação, e produz uma nota ponderada pelas probabilidades dos tokens de score (reduz a compressão de escala). Frameworks como DeepEval, Ragas, Promptfoo e Phoenix/Arize trazem G-Eval e outras métricas de juiz prontas, com o cuidado dos vieses já embutido — bom ponto de partida antes de escrever o seu.
Tema quentíssimo em entrevista de Applied AI / LLMOps: "Como funciona LLM-as-a-judge e quais os problemas?" (formatos + vieses de posição/verbosidade/autopreferência), "Como você sabe que o juiz é confiável?" (calibração contra humano, kappa), "Pairwise ou pointwise?" (pairwise é mais robusto para comparar duas versões; pointwise para acompanhar uma métrica no tempo). Dizer "usei GPT para avaliar e deu 4,2/5" sem falar de calibração é sinal de imaturidade.
✏️ Exercício 4 — Conserte o juiz
Um juiz pointwise usa: "Numa escala de 1 a 10, quão boa é esta resposta? Responda só o número." com o mesmo modelo que gera as respostas, temperatura 0,7, uma vez por caso. Liste quatro melhorias.
Gabarito: (1) Trocar a escala 1–10 vaga por critérios binários (faithful, relevant, complete, safe) com definição de cada um — reduz compressão de escala e subjetividade. (2) Pedir justificativa antes do veredito. (3) Usar um modelo de família diferente da que gera, para evitar autopreferência. (4) Temperatura 0 e, para casos limítrofes, self-consistency (rodar 3x e agregar). (5) Calibrar contra ~40 julgamentos humanos e reportar o kappa.
Avaliação III — RAG e agentes
Objetivo: avaliar os dois sistemas compostos mais comuns — decompondo o RAG em recuperação vs geração, e o agente em conclusão de tarefa vs trajetória.
5.1 Avaliar RAG: separe recuperação de geração
Quando um RAG erra, a causa é uma de duas: não recuperou o documento certo, ou recuperou e mesmo assim respondeu mal. Avaliar o sistema como caixa-preta não distingue — e a correção é oposta (mexer no índice/chunking/reranker vs mexer no prompt de geração). Meça as duas camadas.
| Camada | Métrica | O que responde |
|---|---|---|
| Recuperação | Context Recall | Os trechos necessários para responder estão entre os recuperados? |
| Context Precision | Os trechos recuperados são relevantes, ou vieram muitos irrelevantes? | |
| Hit rate / MRR / NDCG@k | O documento certo aparece, e bem ranqueado? | |
| Geração | Faithfulness / Groundedness | Cada afirmação da resposta é sustentada pelo contexto? (anti-alucinação) |
| Answer Relevance | A resposta de fato endereça a pergunta? | |
| Answer Correctness | Comparada a uma referência, quando existe |
RAGAS é o framework de referência para isso (faithfulness, context precision/recall, answer relevancy), com juízes LLM por trás. DeepEval, Phoenix e TruLens cobrem terreno semelhante. Comece por faithfulness e context recall — são as que mais explicam falhas reais.
# Esqueleto de avaliação de RAG com Ragas from ragas import evaluate from ragas.metrics import faithfulness, answer_relevancy, context_precision, context_recall resultado = evaluate( dataset, # colunas: question, answer, contexts, ground_truth metrics=[faithfulness, answer_relevancy, context_precision, context_recall], ) # reporte por segmento; um faithfulness caindo aponta para o prompt de geração, # um context_recall caindo aponta para chunking / embedding / top_k / reranker
5.2 Avaliar agentes: resultado e caminho
Um agente pode acertar o resultado pelo caminho errado (sorte, 15 passos desnecessários, chamou uma ferramenta cara à toa) ou falhar no fim de um caminho quase certo. Avalie ambos:
- Task completion / success rate: a tarefa foi cumprida? Definido por um verificador — de preferência determinístico (o arquivo foi criado? o valor está correto no banco?), ou um juiz com rubrica.
- Tool-call accuracy: chamou as ferramentas certas, na ordem certa, com os argumentos certos? Compare a trajetória real com uma trajetória de referência (exata ou "conjunto de ferramentas esperado").
- Trajetória / eficiência: nº de passos, nº de chamadas de ferramenta, chamadas redundantes, custo e latência acumulados, loops.
- Robustez: recupera de erro de ferramenta? Lida com resultado vazio? Sabe parar e pedir ajuda?
- Segurança da ação: respeitou os limites (não chamou o que não devia)? — conecta com a apostila de Segurança de Aplicações de IA.
Ferramentas de trace modernas deixam você anexar avaliações a partes da execução: um eval de "a query gerada para a ferramenta SQL estava correta" no span da ferramenta, um eval de "a resposta final é fiel" no span de geração. Isso transforma o trace em uma máquina de diagnóstico — você vê exatamente em qual passo a qualidade caiu.
Perguntas: "Como você avalia um sistema RAG?" (decompor em recuperação — context recall/precision — e geração — faithfulness/answer relevance; RAGAS), "Seu RAG está alucinando; como descobre se é problema de recuperação ou de prompt?" (mede context recall: se está baixo, é recuperação; se está alto e faithfulness baixo, é geração), "Como avaliar um agente além de 'funcionou'?" (success rate + tool-call accuracy + eficiência da trajetória + robustez).
✏️ Exercício 5 — Diagnóstico de RAG
Sobre 200 perguntas, seu RAG tem: context recall 0,55, context precision 0,90, faithfulness 0,95, answer relevance 0,70. Onde está o gargalo e o que você tenta primeiro?
Gabarito: O gargalo é a recuperação: context recall 0,55 significa que em ~45% dos casos o trecho necessário nem chega ao modelo — daí a answer relevance mediana (o modelo responde bem, mas sem a informação certa). Faithfulness alto confirma que a geração está sólida (não inventa). Primeiras tentativas: revisar chunking (tamanho/overlap), trocar/afinar o modelo de embedding, aumentar top_k, adicionar um reranker, e checar se o índice cobre os documentos das perguntas que falham. Mexer no prompt de geração agora não adiantaria.
Testes e CI para sistemas de LLM
Objetivo: colocar a avaliação num pipeline automatizado que bloqueia regressão a cada mudança de prompt, modelo ou pipeline — com estratégias de release seguras.
6.1 A pirâmide de testes de um app de LLM
| Camada | O que testa | Custo/velocidade |
|---|---|---|
| Assertions determinísticas | Formato (JSON válido, schema), presença/ausência de termos, regex, faixa numérica, cita fonte, não vaza PII, tamanho | Instantâneo, grátis — rode em cada commit |
| Métricas baseadas em modelo | Faithfulness, relevância, tom, seguir instrução — via LLM-as-judge calibrado | Segundos a minutos, centavos — rode em PR |
| Suite de regressão (golden set) | 50–300 casos representativos; score agregado e por segmento vs baseline | Minutos — gate de merge/release |
| Avaliação humana pontual | Amostra dos casos ambíguos ou de alto risco | Horas — antes de releases grandes |
| Online (produção) | Evals sobre tráfego real, feedback do usuário (Módulo 7) | Contínuo |
6.2 Um gate de CI concreto
# promptfoo: config declarativa que roda no CI a cada PR que toca prompt/modelo prompts: [file://prompts/suporte_v7.txt] providers: [openai:gpt-4.1, anthropic:claude-sonnet] # testa nos dois tests: - vars: { input: "posso devolver produto usado?" } assert: - type: contains-any value: ["não foi usado", "7 dias"] - type: not-contains value: ["reembolso garantido"] - type: llm-rubric value: "é fiel à política de devolução e tem tom cordial" - type: latency threshold: 4000 - vars: { input: "..." } # ...mais 150 casos do golden set # regra do pipeline: falha o build se o score agregado cair > 2 pontos vs baseline, # OU se QUALQUER segmento cair > 5 pontos, OU se um caso "crítico" regredir
Um caso pode passar 9 vezes e falhar na 10ª. Estratégias: temperatura 0 nos testes; rodar cada caso 3x e exigir maioria; olhar o score agregado do conjunto (estável) em vez de exigir 100% caso a caso; marcar casos historicamente instáveis. Trate a suite como um experimento estatístico, não como testes unitários.
6.3 Offline não basta — estratégias de release
- Shadow / mirroring: a nova versão processa o tráfego real em paralelo, sem servir ao usuário; você compara as saídas e roda evals antes de promover.
- Canary: 1–5% do tráfego vai para a nova versão; monitora métricas de qualidade online, feedback, erro, custo e latência; sobe gradualmente ou reverte.
- A/B test: divisão controlada com métrica de negócio (resolução no primeiro contato, conversão, CSAT) — a prova final de que "melhorou no eval" virou "melhorou para o usuário".
- Rollback rápido: a versão de prompt/modelo é config, não deploy de código — reverter deve ser um clique.
Perguntas: "Como você impede regressão quando alguém edita um prompt?" (golden set no CI, gate por score agregado e por segmento), "Como lida com o não determinismo nos testes?" (temp 0, repetição+maioria, foco no agregado), "Eval offline melhorou mas você não confia — e agora?" (shadow → canary → A/B com métrica de negócio). Ferramentas para citar: promptfoo, DeepEval, Langfuse, Braintrust, Phoenix.
✏️ Exercício 6 — Desenhe o gate
Seu time faz ~10 edições de prompt por semana em um assistente com 4 segmentos de uso. Defina uma política de CI que pegue regressões sem travar o time com falsos alarmes.
Gabarito (exemplo): Golden set de ~200 casos (50 por segmento) rodado a cada PR que toca prompt/modelo/RAG, com juiz calibrado + assertions determinísticas. Gate: bloqueia se o score global cair > 2 pp, se qualquer segmento cair > 5 pp, ou se um caso da lista "crítica" (~15 casos) regredir de PASS para FAIL. Cada caso roda 3x, conta a maioria. Casos flaky conhecidos ficam num grupo separado que reporta mas não bloqueia. Baseline recalculado a cada release aprovado. Relatório visual no PR com diff de saídas.
Observabilidade e avaliação online
Objetivo: instrumentar o sistema em produção — tracing de ponta a ponta, captura de feedback, evals sobre tráfego real e detecção de deriva de qualidade.
7.1 Tracing de LLM
Um trace registra a árvore completa de uma requisição: o span raiz (a chamada do usuário) e os spans filhos (recuperação, cada chamada de ferramenta, cada chamada ao modelo, guardrails, pós-processamento). Para cada span: entrada, saída, modelo e parâmetros, tokens de entrada/saída, custo, latência, e metadados (usuário, sessão, versão do prompt, feature flag).
- Padrão emergente: as OpenTelemetry Semantic Conventions for GenAI padronizam os nomes de atributos (
gen_ai.request.model,gen_ai.usage.input_tokensetc.), então o trace não fica preso a um fornecedor. - Ferramentas: Langfuse, Arize Phoenix, LangSmith, Braintrust, Helicone, Traceloop/OpenLLMetry — a maioria fala OTel e integra com o seu APM.
- Por que importa: quando um usuário reclama, você abre aquele trace e vê em qual passo a coisa desandou — sem trace, é impossível reproduzir.
7.2 Capturar sinal de qualidade em produção
| Sinal | Como coletar | Cuidado |
|---|---|---|
| Feedback explícito | Joinha, estrelas, "isso ajudou?" | Taxa de resposta baixa e enviesada (só quem odiou ou amou) |
| Feedback implícito | Copiou a resposta, reformulou a pergunta, abandonou, escalou para humano, "regenerar" | Sinal ruidoso; bom em agregado |
| Resultado de negócio | Ticket resolvido, compra concluída, tempo de atendimento | Atribuição: muitos fatores além do LLM |
| Evals online (LLM-as-judge) | Rodar juízes de faithfulness/relevância sobre uma amostra do tráfego real, contínuo | Custo do juiz; amostre (ex.: 5–20%) e priorize casos de risco |
| Anotação humana | Fila onde especialistas revisam uma amostra diária | Caro; reserve para o que os juízes não decidem bem |
7.3 Deriva de qualidade — o que monitorar avançado
- Regressão do provedor: o modelo por trás da API muda e seus scores online caem sem nenhum deploy seu. Só um eval online contínuo pega isso. Tenha alarme sobre a série temporal do score.
- Drift de entrada: os usuários passaram a perguntar coisas novas (produto lançou, sazonalidade) que o RAG não cobre. Monitore tópicos/embeddings das perguntas; queda de context recall online é sinal.
- Degradação de RAG: o índice ficou desatualizado, uma fonte parou de ser ingerida — faithfulness cai porque o contexto está errado.
- Custo e latência: prompt cresceu, contexto cresceu, agente entrou em loops mais longos — p95 de latência e custo por requisição são métricas de primeira classe.
- Guardrails: taxa de bloqueio subindo (ataque? mudança de comportamento?) ou falsos positivos irritando usuários.
O objetivo da observabilidade não é um dashboard bonito — é alimentar o Módulo 8. Todo caso com feedback negativo, todo trace onde um eval online falhou, toda pergunta sem boa cobertura de RAG deve fluir para uma fila de triagem que vira dataset de avaliação e backlog de melhoria.
Perguntas: "O que é um trace de LLM e o que você registra em cada span?", "Como você detecta que o modelo do provedor regrediu?" (eval online contínuo com alarme na série temporal), "Como coletar sinal de qualidade sem depender de joinha?" (feedback implícito + evals online amostrados + resultado de negócio), "O que são as OpenTelemetry GenAI conventions?".
✏️ Exercício 7 — O alarme que faltava
Numa segunda-feira, o CSAT do bot cai de 78% para 61% e fica assim. Não houve deploy. Que hipóteses você levanta e que instrumentação teria detectado antes do CSAT?
Gabarito: Hipóteses: (a) o provedor atualizou o modelo silenciosamente; (b) uma fonte do RAG parou de ser ingerida no fim de semana e o contexto ficou pobre; (c) mudança no tipo de pergunta (lançamento, promoção) que o sistema não cobre; (d) uma dependência (reranker, gateway) degradou latência e respostas estão sendo truncadas/timeout. Instrumentação que pegaria antes: eval online contínuo de faithfulness/relevância com alarme na série temporal, monitor de freshness/volume do índice de RAG, monitor de distribuição de tópicos das perguntas, e p95 de latência + taxa de timeout. Qualquer um desses dispararia horas antes de o CSAT se mover.
Melhoria contínua: do trace ao dataset
Objetivo: transformar observação em melhoria mensurável — error analysis, evolução de prompt, quando partir para fine-tuning, e experimentação disciplinada.
8.1 Error analysis: o hábito mais rentável
Antes de mexer em qualquer coisa, leia as falhas. Pegue 30–50 casos ruins (de feedback negativo, de evals que falharam), leia entrada + contexto + saída, e rotule a causa. Depois agrupe:
Análise de 40 respostas ruins do assistente de suporte: 18 (45%) recuperação falhou — o doc certo não veio no contexto 9 (22%) seguiu instrução parcialmente — ignorou o "não prometa reembolso" 7 (18%) tom errado — jurídico demais, frio 4 (10%) alucinou prazo/condição mesmo com contexto correto 2 (5%) pergunta ambígua — deveria ter pedido esclarecimento → prioridade clara: 45% é problema de RAG (chunking/embedding), não de prompt. → o 2º maior (seguir instrução) é ajuste de prompt barato. Comece por esses dois.
Sem essa contagem, times gastam semanas "melhorando o prompt" quando o problema era o índice. A análise transforma "está ruim" em uma lista priorizada de correções com impacto estimado.
8.2 O ciclo de iteração
- Error analysis → causa dominante.
- Adicione ao dataset de avaliação casos que representam essa falha (agora o eval "sente" o problema).
- Faça uma mudança dirigida (chunking, few-shot, instrução, reranker, modelo).
- Rode o eval offline: melhorou na fatia alvo sem regredir nas outras?
- Shadow/canary → confirme online → promova.
- Repita. Uma variável por vez, sempre medindo.
8.3 A escada de intervenções (barato → caro)
| Nível | Intervenção | Quando |
|---|---|---|
| 1 | Melhorar o prompt: instruções mais claras, formato, exemplos few-shot dos casos que falham | Sempre a primeira tentativa |
| 2 | Melhorar o RAG: chunking, embedding, top_k, reranker, qualidade/atualidade das fontes | Quando error analysis aponta recuperação |
| 3 | Mudar a arquitetura: decompor em passos, roteador de intenção, verificador/crítico, agente | Tarefa complexa demais para um passo só |
| 4 | Trocar de modelo (maior/mais recente) ou ajustar parâmetros | Teto de capacidade atingido; pesar custo/latência |
| 5 | Fine-tuning (SFT / preferência) | Formato/estilo/domínio muito específicos, latência/custo exigem modelo menor, e você tem centenas a milhares de exemplos bons e um eval sólido |
Fine-tune é a última opção, não a primeira. Ele custa dados rotulados, infraestrutura, e cria um artefato que você mantém (regressão, re-treino, versionamento — de volta ao MLOps clássico). Só compensa quando o ganho de qualidade/custo/latência é claro e você consegue medir que aconteceu. E fine-tune raramente resolve alucinação — isso é RAG e verificação.
8.4 Gerir os experimentos
- Prompt/config como artefato versionado, com o score de eval atrelado a cada versão (prompt registry: Langfuse, PromptLayer, Humanloop, ou uma tabela sua).
- Registro de experimento: hipótese, mudança, dataset, resultado por segmento, decisão. Seis meses depois você quer saber por que o prompt está do jeito que está.
- Não caçar ruído: diferenças pequenas no eval podem ser variância. Use tamanho de amostra suficiente e olhe intervalo de confiança antes de declarar vitória.
Pergunta que separa sênior: "Seu sistema está com qualidade ruim. Descreva seu processo." — a resposta certa começa com error analysis (ler e categorizar 30–50 falhas), não com "eu melhoraria o prompt". Depois: adicionar casos ao eval, uma mudança dirigida por vez, medir offline e online, escada barato→caro, fine-tune só por último e só com eval. Citar "prompt registry" e "registro de experimento" mostra maturidade de processo.
✏️ Exercício 8 — Priorize a correção
Error analysis de 50 falhas de um agente de agendamento: 20 "chamou a ferramenta de calendário com fuso horário errado", 15 "não recuperou a preferência do usuário", 10 "loop: repetiu a mesma busca 5x", 5 "tom". Qual sua ordem de ataque e por quê?
Gabarito: (1) Fuso horário (40%): provável bug determinístico na definição/parsing da ferramenta — correção barata, alto impacto; adicione asserts de fuso no eval. (2) Loop (20%): teto de passos + detecção de repetição no orquestrador — barato, e ainda corta custo/latência. (3) Preferência não recuperada (30%): é RAG/memória — investigar se a preferência está indexada e sendo buscada; médio esforço. (4) Tom (10%): ajuste de prompt, menor prioridade. Ordem por impacto × custo, não por tamanho do grupo isolado.
Guardrails de qualidade, SLOs e governança
Objetivo: proteger a experiência em tempo real (alucinação, PII, escopo), definir metas de qualidade acompanháveis como um SLO, e responder a incidentes de regressão — alinhado a NIST AI RMF e EU AI Act.
9.1 Guardrails em runtime (foco em qualidade)
| Guardrail | Como | Ação ao disparar |
|---|---|---|
| Detecção de alucinação / groundedness | Verificador que checa se cada afirmação da resposta está no contexto (LLM-judge rápido, NLI, ou regras de citação) | Regenerar, adicionar disclaimer, cair para "não encontrei", escalar |
| PII na saída | Scanner de padrões (CPF, cartão, e-mail, telefone) | Redigir ou bloquear |
| Fora de escopo / tópico proibido | Classificador de intenção; allowlist de assuntos | Resposta padrão de recusa educada |
| Formato / schema | Validação estrita da saída estruturada | Reparar (retry com erro) ou rejeitar |
| Toxicidade / tom | Classificador de conteúdo | Regenerar |
Ferramentas: NeMo Guardrails, Guardrails AI, Llama Guard, e os guardrails gerenciados de Bedrock/Azure. Guardrails são camadas probabilísticas — medir falso positivo (usuário legítimo bloqueado) e falso negativo é parte do trabalho, e cada guardrail adiciona latência e custo. A segurança adversarial (prompt injection, exfiltração) está na apostila de Segurança de Aplicações de IA; aqui o foco é a qualidade e a conformidade da resposta.
9.2 SLOs de qualidade
Trate qualidade como confiabilidade: defina metas explícitas, meça continuamente, e tenha error budget.
Exemplos de SLO de um assistente de suporte (medidos por eval online + amostra humana): faithfulness ≥ 97% (janela de 7 dias) answer_relevance ≥ 90% taxa de recusa indevida ≤ 2% p95 de latência ≤ 4,5 s custo por resposta ≤ US$ 0,03 feedback negativo ≤ 8% error budget: se faithfulness ficar < 97% por > 24h → congela mudanças, prioriza correção.
9.3 Incidente de regressão de qualidade
- Detecção: alarme no eval online ou no feedback, não "um cliente tuitou".
- Contenção: rollback da última versão de prompt/modelo (é config — reverte rápido); ou desligar o feature flag; ou forçar fallback para modelo/versão conhecida boa.
- Diagnóstico: traces dos casos ruins, diff da última mudança, checar se o provedor mudou o modelo, checar freshness do RAG.
- Correção e postmortem: corrige, adiciona o caso ao eval para não repetir, postmortem sem culpa. Métrica: MTTR de qualidade.
9.4 Governança e conformidade avançado
| Instrumento | O que pede de avaliação/operação |
|---|---|
| NIST AI RMF (Measure/Manage) | Métricas de risco documentadas, avaliação recorrente, monitoramento e resposta |
| EU AI Act (alto risco) | Gestão de risco, precisão/robustez adequadas ao propósito, logging, supervisão humana, monitoramento pós-mercado — tudo evidenciável |
| ISO/IEC 42001 | Sistema de gestão de IA auditável, com processos de avaliação e melhoria contínua |
| Model/System cards | Documentar propósito, dados, limitações, resultados de avaliação por segmento, riscos residuais |
Na prática: seus datasets de eval, os relatórios por segmento, o histórico de scores, os SLOs e os postmortems são a evidência de conformidade. Um bom LLMOps já produz 80% do que a auditoria pede.
Perguntas de vaga sênior: "Como você define 'bom o suficiente' para um sistema de LLM?" (SLOs de qualidade com error budget), "Como detecta e responde a uma regressão de qualidade em produção?", "Como um guardrail de groundedness funciona e qual o custo dele?", "O que o EU AI Act exige em termos de avaliação para alto risco?". Conectar LLMOps a conformidade (a evidência sai de graça do processo) é um diferencial.
✏️ Exercício 9 — Defina os SLOs
Você opera um assistente que ajuda advogados a resumir contratos. Erro factual pode ter consequência séria. Proponha 4 SLOs e o que acontece ao estourar o error budget.
Gabarito (exemplo): (1) Faithfulness ≥ 99% (medido por juiz calibrado + revisão humana de 10% do tráfego) — abaixo disso por 12h, congela mudanças e revisa. (2) Taxa de "afirmação sem fonte no contrato" = 0 tolerância em casos críticos; qualquer ocorrência gera incidente. (3) Cobertura de citação: 100% das afirmações com referência à cláusula. (4) p95 de latência ≤ 20 s (aqui latência importa menos que correção). Error budget estourado → rollback para versão validada, feature flag para revisão humana obrigatória, postmortem, caso adicionado ao eval. Design de produto: sempre exibir as cláusulas-fonte e marcar como "requer revisão do advogado".
Mercado de trabalho: roadmap, entrevistas e portfólio
Objetivo: converter o conteúdo dos módulos anteriores em aprovação — perfis, roadmap, banco de perguntas com respostas e projetos que geram entrevista.
10.1 Os perfis que contratam
| Perfil | Foco | Vem de |
|---|---|---|
| LLMOps / AI Platform Engineer | Gateway, tracing, prompt registry, CI de eval, custo/latência, deploy | MLOps, DevOps, backend |
| AI Evals Engineer | Datasets, LLM-as-judge, RAGAS, calibração, error analysis | Data science aplicada, ML, QA técnico |
| Applied AI / Forward Deployed Engineer | Construir + avaliar + iterar o sistema fim a fim com o cliente | Full-stack/backend + IA |
| AI Quality / AI QA | Processo de avaliação, regressão, anotação, SLOs | QA, test engineering |
10.2 Roadmap de estudo (8–10 semanas)
| Semanas | Foco | Entregável |
|---|---|---|
| 1–2 | Construir um app de LLM real (RAG + 1–2 ferramentas) e instrumentar tracing (Langfuse/Phoenix) — Módulos 1–2, 7 | App rodando com traces completos e captura de feedback |
| 3–4 | Avaliação offline: montar dataset de logs reais, escrever rubricas, LLM-as-judge, calibrar contra humano — Módulos 3–4 | Suite de eval com kappa do juiz documentado |
| 5 | Avaliação de RAG (RAGAS) e de agente (success rate, tool-call) — Módulo 5 | Relatório decompondo recuperação vs geração do seu app |
| 6 | CI de eval com promptfoo/DeepEval; gate por segmento; shadow/canary — Módulo 6 | Pipeline que bloqueia PR em regressão, com relatório no PR |
| 7 | Evals online + detecção de drift + alarme — Módulo 7 | Dashboard de qualidade online com alarme na série temporal |
| 8 | Ciclo de melhoria: error analysis → mudança dirigida → medição — Módulo 8 | Um "antes/depois" documentado com ganho por segmento |
| 9–10 | Guardrails de qualidade, SLOs, governança; escrita do portfólio — Módulo 9 | Repositório público + artigo com o caso completo |
10.3 Banco de perguntas de entrevista (com a resposta que aprova)
Júnior/pleno — "Por que não dá para testar um LLM como software normal?"
Porque a saída é texto aberto sem resposta certa única e o modelo é não determinístico: um assert de igualdade não serve. A solução é avaliação — dataset de casos com rubricas, juízes (humano ou LLM calibrado), e acompanhar um score agregado por segmento ao longo do tempo, com repetição para lidar com a variância.
Pleno — "Como você constrói um dataset de avaliação?"
A partir de logs de produção reais (não casos inventados), 50–100 casos bem escolhidos para começar, cobrindo distribuição típica + bordas + casos "a resposta certa é não sei". Cada caso tem critério explícito (rubrica, checklist, ou resposta de referência). Versionado, com dono, crescendo a cada bug de produção. Reportado por segmento, não só média.
Pleno — "LLM-as-a-judge: como e quais os riscos?"
Um LLM forte julga a saída contra uma rubrica, em formato pointwise (nota por critério) ou pairwise (A vs B). Riscos: viés de posição, de verbosidade, de autopreferência, leniência, compressão de escala. Mitigações: critérios binários específicos, justificativa antes do veredito, temperatura 0, juiz de família diferente, alternar ordem em pairwise, e — essencial — calibrar contra ~40 julgamentos humanos e reportar o kappa.
Pleno/sênior — "Como você avalia um RAG?"
Decompondo em recuperação (context recall — o trecho necessário foi recuperado? — e context precision) e geração (faithfulness — a resposta é sustentada pelo contexto? — e answer relevance). RAGAS cobre isso. Diagnóstico: context recall baixo → mexer em chunking/embedding/top_k/reranker; context recall alto e faithfulness baixo → mexer no prompt de geração.
Sênior — "Alguém editou um prompt e a qualidade caiu em produção sem ninguém notar. Como você evita isso?"
Offline: golden set no CI com gate por score agregado e por segmento, rodando a cada PR que toca prompt/modelo/RAG; casos críticos que bloqueiam individualmente. Release: shadow → canary (1–5%) com métricas online → A/B com métrica de negócio. Produção: eval online contínuo com alarme na série temporal (pega inclusive regressão do provedor). Rollback é config, um clique.
Sênior — "Descreva seu processo quando a qualidade está ruim"
Error analysis primeiro: ler 30–50 falhas e categorizar a causa (recuperação, seguir instrução, tom, alucinação, ambiguidade). Priorizar por impacto × custo. Adicionar casos representativos ao dataset de eval. Uma mudança dirigida por vez, subindo a escada barato→caro (prompt → RAG → arquitetura → modelo → fine-tune). Medir offline (ganho na fatia alvo sem regressão) e online (shadow/canary). Fine-tune só por último e só com eval que comprove o ganho.
Armadilha — "Rodamos MMLU e nosso modelo foi bem, então está pronto"
Benchmarks acadêmicos avaliam capacidade geral do modelo, não o seu sistema na sua tarefa com o seu RAG e prompt. Podem estar contaminados no treino. O que decide prontidão é o eval do seu caso: dataset de tráfego real, rubricas do seu domínio, faithfulness/relevância medidos, SLOs, e validação online. MMLU ajuda a escolher um modelo candidato — só isso.
10.4 Projetos de portfólio que geram entrevista
- Sistema de eval completo (âncora): um app RAG+ferramentas com dataset de avaliação a partir de dados reais/semi-sintéticos, LLM-as-judge calibrado (com o kappa reportado), decomposição RAG (RAGAS), suite no CI que bloqueia regressão, e um relatório "antes/depois" de uma melhoria dirigida por error analysis. README + artigo.
- Harness de comparação de modelos: a mesma tarefa avaliada em 4 modelos (qualidade × custo × latência), com pairwise calibrado e recomendação justificada.
- Observabilidade de LLM do zero: tracing com OpenTelemetry GenAI conventions, dashboard de qualidade online, alarme que detecta uma "regressão de provedor" simulada.
- Estudo de caso de LLM-as-judge: medir empiricamente os vieses (posição, verbosidade) num juiz e mostrar o efeito das mitigações, com números.
10.5 Ferramentas e fontes para continuar
- Frameworks de eval: DeepEval, Ragas, promptfoo, OpenAI Evals, Phoenix (Arize), TruLens, Giskard.
- Observabilidade / prompt registry: Langfuse, LangSmith, Braintrust, Helicone, PromptLayer, Humanloop; OpenLLMetry/Traceloop.
- Gateways: LiteLLM, Portkey, Kong AI Gateway, Cloudflare AI Gateway.
- Leitura: as OpenTelemetry Semantic Conventions for GenAI; o material de "evals" da OpenAI e da Anthropic; escritos de Hamel Husain e Shreya Shankar sobre eval-driven development e error analysis; o paper original de "LLM-as-a-judge" (MT-Bench / Chatbot Arena) e de G-Eval; o NIST AI RMF Generative AI Profile.
Quatro ideias sustentam LLMOps: (1) sem avaliação repetível, todo deploy é no escuro — a métrica que você acompanha ao longo do tempo é o coração da disciplina; (2) o dataset de avaliação vindo de dados reais é o ativo mais valioso do time, e cresce a cada falha; (3) error analysis antes de qualquer mudança — ler e categorizar as falhas evita meses gastos no lugar errado; (4) offline e online são complementares — o CI pega regressão de prompt, o eval online pega regressão do mundo (provedor, dados, usuários). As ferramentas mudam a cada trimestre; esse ciclo não.