12-03-03 — Avaliações Online: A/B Testing, Canary Deploys e Feedback Loops

⏱ 12 min Fontes validadas em: 2026-04-29

TL;DR

Você não valida um modelo só antes de subir — valida continuamente em produção. A/B testing compara variantes com tráfego real; canary deploy reduz o blast radius de mudanças ruins; feedback loops fecham o ciclo entre o que o modelo entrega e o que o usuário realmente queria. Sem isso, você está voando cego.

Por que avaliação offline não basta

Benchmarks e evals em dataset fixo capturam uma fotografia do passado. O mundo muda, os usuários mudam, o contexto muda. Avaliação online mede o comportamento real do modelo em condições reais — com usuários reais, queries reais e consequências reais.

⚠️ Armadilha clássica: Modelo com 92% de acurácia no eval set vai a produção e a satisfação do usuário cai 15%. O dataset de eval estava desatualizado há 6 meses. Avaliação online teria detectado isso em dias.

A/B Testing em LLMs

A/B testing divide o tráfego de produção entre duas ou mais variantes (modelo A vs modelo B, prompt A vs prompt B) e compara métricas de negócio e qualidade.

Arquitetura básica


# Exemplo: roteamento A/B com feature flag
import random

def route_request(user_id: str, request: dict) -> str:
    # Consistência por user_id: mesmo usuário sempre vai ao mesmo bucket
    bucket = hash(user_id) % 100
    
    if bucket < 10:  # 10% no variant B (canary)
        return call_model_b(request)
    else:             # 90% no variant A (stable)
        return call_model_a(request)
  
💡 Consistência é fundamental: Um usuário que recebe respostas alternando entre modelo A e B vai ter experiência degradada e vai contaminar os dados. Use hash do user_id para garantir que cada usuário sempre vá ao mesmo variant.

Métricas para comparar variants

  • Implicit feedback: click-through rate, tempo de engajamento, retenção, conversão
  • Explicit feedback: thumbs up/down, ratings, edits feitos pelo usuário na resposta
  • Business metrics: receita por sessão, churn, NPS
  • Quality metrics: latência P95, taxa de refusal, comprimento médio da resposta

Tamanho de amostra e significância

O maior erro em A/B testing é declarar vitória cedo demais. Calcule o tamanho de amostra necessário antes de começar, não depois.


from scipy import stats
import numpy as np

def min_sample_size(baseline_rate, mde, alpha=0.05, power=0.8):
    """
    baseline_rate: taxa atual (ex: 0.30 = 30% satisfação)
    mde: minimum detectable effect (ex: 0.05 = 5pp de melhora)
    """
    effect_size = mde / np.sqrt(baseline_rate * (1 - baseline_rate))
    analysis = stats.TTestIndPower()
    n = analysis.solve_power(
        effect_size=effect_size,
        alpha=alpha,
        power=power,
        alternative='two-sided'
    )
    return int(np.ceil(n))

# Ex: 30% de satisfação, quer detectar +5pp
n = min_sample_size(0.30, 0.05)
print(f"Precisa de {n} amostras por variante")  # ~1568 por variante
  

Canary Deploys

Canary deploy é uma estratégia de rollout gradual: você expõe o novo modelo/prompt a um subconjunto pequeno do tráfego antes de promover para 100%.

Stages típicos de rollout

🐦 Pipeline de canary:
1% → observar 30min → 5% → observar 1h → 20% → observar 4h → 50% → observar 12h → 100%

Em cada estágio, você monitora métricas de saúde. Se qualquer métrica romper o threshold, rollback automático.


# Pseudo-código: gate automático de canary
def canary_gate(metrics: dict, thresholds: dict) -> bool:
    """Retorna True se pode avançar, False se deve rollback"""
    
    checks = {
        "error_rate": metrics["error_rate"] <= thresholds["max_error_rate"],
        "latency_p95": metrics["latency_p95"] <= thresholds["max_latency_ms"],
        "satisfaction": metrics["satisfaction_rate"] >= thresholds["min_satisfaction"],
        "refusal_rate": metrics["refusal_rate"] <= thresholds["max_refusal_rate"],
    }
    
    failed = [k for k, v in checks.items() if not v]
    if failed:
        trigger_rollback(reason=failed)
        return False
    return True
  

Feedback Loops

Feedback loop é o mecanismo que transforma sinal de produção em melhoria do modelo. Sem ele, você coleta dados mas nunca fecha o ciclo.

Tipos de feedback loop

TipoLatênciaSinalUso
Explicit (thumbs)MinutosAlto, ruidosoFine-tuning, RLHF
Implicit (clicks)HorasMédio, abundanteRanking, retrieval
Business outcomeDias/semanasBaixo, precisoEval estratégico
Correction-basedImediatoMuito altoFine-tuning direto

Pipeline de feedback loop


# Arquitetura de coleta de feedback
class FeedbackCollector:
    def log_interaction(self, request_id, prompt, response, metadata):
        """Grava a interação com todos os dados necessários para avaliação futura"""
        self.store.write({
            "request_id": request_id,
            "timestamp": now(),
            "model_version": metadata["model_version"],
            "prompt_version": metadata["prompt_version"],
            "prompt": prompt,
            "response": response,
            "latency_ms": metadata["latency_ms"],
            "tokens_used": metadata["tokens_used"],
        })
    
    def log_feedback(self, request_id, feedback_type, value, user_id=None):
        """Vincula feedback explícito à interação original"""
        self.store.update(request_id, {
            "feedback": {
                "type": feedback_type,  # "thumbs_up", "thumbs_down", "edit", "copy"
                "value": value,
                "user_id": hash(user_id) if user_id else None,  # anonimizado
                "feedback_at": now(),
            }
        })
  
⚠️ Survivorship bias: Usuários que não dão feedback são a maioria. Um modelo que recebe 10% de thumbs down pode estar sendo abandonado pelos outros 90% antes mesmo de dar feedback. Correlacione com métricas de abandono de sessão.

Testando prompts em produção com segurança

Prompt engineering sem dados de produção é chute. Com dados, é ciência. As melhores práticas:

  1. Shadow mode: Novo prompt roda em paralelo, sem servir ao usuário. Você coleta as respostas para comparação offline antes de qualquer exposição real.
  2. Sticky canary: Usuários beta (voluntários ou internos) sempre recebem novos prompts primeiro.
  3. Rollback automatizado: Se o error rate subir mais de X% em Y minutos, volta automático. Sem intervenção humana.
  4. Feature flags por tenant: Para B2B, capacidade de ativar/desativar features por cliente sem novo deploy.

Como isso se conecta

  • 12-03-04 (Drift Detection): A/B testing detecta diferenças entre variants; drift detection detecta degradação de uma única versão ao longo do tempo.
  • 12-02-04 (Monitoramento de qualidade): As métricas de qualidade coletadas online alimentam os dashboards de monitoramento contínuo.
  • 06-xx (Fine-tuning): Feedback loops são a principal fonte de dados para ciclos de fine-tuning e RLHF.
  • 11-xx (Deployment): Canary deploy é uma estratégia de deployment — a camada de observabilidade precisa estar pronta antes de ativar qualquer rollout gradual.
  • 13-xx (Governança): Resultados de A/B testing precisam de aprovação formal antes de promoção para 100% em sistemas regulados.

Fontes

  1. Kohavi, R., Tang, D., Xu, Y. (2020). Trustworthy Online Controlled Experiments: A Practical Guide to A/B Testing. Cambridge University Press. — Referência definitiva em A/B testing.
  2. Google SRE Book. Chapter 17: Testing for Reliability. sre.google — Canary releases e progressive rollouts em escala.
  3. Anthropic. (2024). Evaluating LLM Applications in Production. anthropic.com — Framework de avaliação contínua para LLMs.
  4. Shankar, S. et al. (2024). Who Validates the Validators? Aligning LLM-Assisted Evaluation of LLM Outputs with Human Preferences. arXiv:2404.12272. — Sobre os limites de evals automatizados vs. feedback humano.
  5. Kleppmann, M. (2017). Designing Data-Intensive Applications. O'Reilly — Capítulo sobre stream processing e feedback loops em sistemas distribuídos.