QC automático logo antes de publicar no blog — O segredo de 0 erros de publicação em 6 meses

4 min read · 1,028 words

Dicas de uso / Gerenciamento de blog / Python · Automação
Cerca de 2.300 caracteres

Quando você gerencia um blog com mais de 200 artigos, mesmo com revisão humana, sempre acaba passando algum detalhe. Resíduos de markdown (negrito exposto), violações de whitelist de emojis, fontes ausentes, tabelas vazias ou resíduos de estilos de caixa são alguns exemplos. Por isso, criamos uma etapa separada para verificar e corrigir o texto automaticamente logo antes de ele ser enviado para a API do blog.

Este artigo explica com qual intenção criamos esse sistema de QC automático, como ele funciona, quais resultados reais obtivemos e como o validamos. Resumimos os pontos essenciais para que outros administradores com o mesmo problema possam implementá-lo com apenas uma página de código.

Por que criamos isso

Durante o primeiro ano, nos deparamos frequentemente com dois tipos de incidentes.

O primeiro foi o resíduo de saída do modelo. Ao gerar o corpo do texto com LLMs, tokens de markdown como negrito, ## subtítulo ou --- muitas vezes permaneciam sem ser convertidos para HTML. Os asteriscos ficavam visíveis no site publicado.

O segundo foi o caso em que o texto estava perfeito logo após a redação, mas algum hook quebrava algo logo antes da publicação. Por exemplo, uma função que abria uma tag

extra no corpo do texto e não a fechava, quebrando o layout de cards ou da barra lateral; a inserção automática de tabelas de preços que resultava em uma

Como funciona

O ponto de controle é composto por duas etapas.

Etapa 1: Sanitize — Correções obrigatórias

Recebe o HTML e aplica as seguintes regras de forma padronizada:

  • Remoção de estilos inline perigosos (como width:800px, margin-left:-30px, position:absolute)
  • Remoção dos atributos fixos width/height das tags QC automático logo antes de publicar no blog — O segredo de 0 erros de publicação em 6 → preservando a responsividade
  • Conversão de tokens de markdown residuais para HTML (XX, --- aleatórios →
    )
  • Remoção de caracteres que violam a política de emojis (faixas U+2600–27BF, U+1F000–1FAFF)
  • Simplificação de estilos de caixa (
    com border, box-shadow, padding>20px)
  • Inserção obrigatória de uma linha de CSS seguro no contêiner do texto (max-width:100%, overflow-wrap:anywhere)

Esta etapa é um processo mecânico que não exige julgamento humano. Foi projetada para produzir o mesmo resultado consistente para qualquer artigo.

Etapa 2: Quality Gate — Bloqueio de publicação em caso de falha

Verifica automaticamente omissões que um humano perceberia. Se não passar no teste, a publicação é recusada.

  • Menos de 600 caracteres no corpo do texto → fail
  • Menos de 3 tags

    → fail (para artigos de guia/comparação)

  • 0 imagens → fail (independentemente do tipo de artigo)
  • Artigo de comparação sem

    Resultados reais

    Resultados após 6 meses de implementação:

    • Incidentes de markdown exposto: média de 4 casos por mês antes da implementação → 0 casos após
    • Quebra de layout lateral (texto cortado): média de 7 casos por mês → 0 casos
    • Tabelas ou gráficos vazios no texto: média de 3 casos por mês → 0 casos
    • Artigos bloqueados para publicação: 38 no total (todos corrigidos pelo autor e republicados com sucesso)

    Os 38 artigos bloqueados não foram perdidos. O autor simplesmente percebeu o erro com antecedência, fez os ajustes e tentou novamente, publicando-os normalmente. A distribuição dos motivos de bloqueio foi: ausência de fonte (41%) / texto muito curto (26%) / 0 imagens (21%) / outros (12%).

    Métodos de validação

    Estas foram as validações que realizamos após criar o ponto de controle:

    Teste de regressão com Golden Set — Reunimos os originais de 41 artigos que apresentaram problemas no passado para criar um "Golden Set". Comparamos automaticamente se os padrões de erro desapareciam em todos os 41 artigos após passarem pelo sanitize + quality gate. Inicialmente, 39 de 41 passaram. Analisamos os 2 casos que falharam, aprimoramos as expressões regulares (regex) e alcançamos 41 de 41 aprovações.

    Spot-check em produção — Na primeira semana de aplicação do novo sanitize, selecionamos aleatoriamente 8 dos 18 artigos publicados e fizemos o fetch direto das páginas ativas. Verificamos se ocorria rolagem horizontal, se o texto ultrapassava o contêiner ou se as imagens quebravam em duas larguras: desktop (1280px) e mobile (360px). Resultado: 8 de 8 normais.

    Idempotência de dupla passagem (Double-pass idempotency) — Verificamos se o resultado de passar o sanitize uma segunda vez sobre um conteúdo já higienizado permanecia idêntico. Essa validação serve para evitar problemas caso a cadeia de hooks de publicação seja executada duas vezes. Resultado: 100 de 100 idênticos.

    Como implementar

    Em vez de copiar o código inteiro, você pode extrair apenas um ou dois pontos essenciais e adaptá-los ao seu ambiente.

    
    import re
    
    def sanitize_pre_publish(html: str) -> tuple[str, list[str]]:
     fixes = []
     # Remove larguras inline perigosas
     html, n = re.subn(r'width\s*:\s*(?:[4-9]\d{2}|[1-9]\d{3,})px\s*;?', '', html)
     if n: fixes.append('strip_wide_width')
     # Resíduos de markdown → HTML
     html, n = re.subn(r'\*\*(.+?)\*\*', r'<strong>\1</strong>', html)
     if n: fixes.append('md_bold')
     # Remoção de emojis (se necessário)
     html, n = re.subn(r'[\U0001F300-\U0001FAFF]', '', html)
     if n: fixes.append('strip_emoji')
     return html, fixes
    
    def quality_gate(html: str, post_type: str) -> tuple[bool, list[str]]:
     fails = []
     text = re.sub(r'<[^>]+>', '', html)
     if len(text.replace(' ', '')) < 600: fails.append('too_short')
     if html.count('<h2') < 3 and post_type in ('howto', 'compare'): fails.append('few_h2')
     if '<img' not in html: fails.append('no_image')
     if 'TODO' in html or 'REDACTED' in html: fails.append('placeholder')
     return (len(fails) == 0), fails
    

    Basta chamar essas duas funções em um único lugar, logo antes da publicação. Se a função quality_gate retornar fail, bloqueie a publicação e envie o motivo para o usuário. O sanitize recebe o HTML de saída e você pode enviá-lo diretamente para a API de publicação.

    Em resumo, tudo se resume a: "um único ponto de controle antes da publicação evita todos os incidentes automaticamente". O tempo que antes era gasto com revisões manuais repetitivas desaparece por completo.

    Category Coverage Notice

    This article follows our label-specific editorial criteria. Details:

ToolSignal Pro Editorial

ToolSignal Pro는 AI·IT·소프트웨어 트렌드를 다루는 종합 IT 인사이트 매거진입니다.

이전 글 다음 글