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 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: 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. Resultados após 6 meses de implementação: 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%). 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. Em vez de copiar o código inteiro, você pode extrair apenas um ou dois pontos essenciais e adaptá-los ao seu ambiente. Basta chamar essas duas funções em um único lugar, logo antes da publicação. Se a funçã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:
Como funciona
width:800px, margin-left:-30px, position:absolute)width/height das tags → preservando a responsividadeX → X, --- aleatórios → )border, box-shadow, padding>20px)
max-width:100%, overflow-wrap:anywhere)
→ fail (para artigos de guia/comparação)
Resultados reais
Métodos de validação
Como implementar
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
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.