# ADR-001 — Classificar e rotear conteúdo predominantemente de mídia antes do multimotor ## Status Accepted --- # Contexto O pipeline atual obtém a página completamente carregada através do crawler e, posteriormente, executa múltiplos motores de extração textual. Esse desenho é adequado para artigos cujo conteúdo principal é texto. Entretanto, alguns veículos publicam páginas onde: * existe apenas uma breve introdução textual; * o conteúdo principal é um vídeo, imagem, conjunto de imagens ou conteúdo incorporado. Processar essas páginas com os motores textuais é desnecessário e pode gerar resultados pobres ou irrelevantes. A responsabilidade de identificar esses casos deve ser adicionada sem alterar o crawler e sem transformar o pipeline em uma nova arquitetura. --- # Decisão Adicionar uma etapa de classificação imediatamente após o crawl e antes do multimotor. Fluxo: ```text Crawler ↓ DOM completamente carregada ↓ Media Candidate Detection ↓ ├── sem mídia candidata │ ↓ │ multimotor atual │ └── com mídia candidata ↓ Media Content Classifier ↓ ├── text │ ↓ │ multimotor atual │ └── media ↓ JSON separado ``` --- # Detecção estrutural Antes do LLM deve existir apenas uma análise estrutural simples da DOM. Objetivo: > verificar se existe algum elemento de mídia que justifique a classificação. A análise deve operar sobre a DOM/HTML já carregada pelo crawler. É permitido utilizar: * parser HTML; * navegação por nós; * tags; * atributos estruturais; * relações entre elementos; * contagem de elementos. É proibido utilizar: * regex; * listas de palavras específicas por idioma; * heurísticas semânticas por idioma. Essa etapa não decide se a publicação é `media`. Ela decide apenas se há motivo para chamar o classificador. --- # Conteúdo enviado ao modelo O modelo deve receber uma representação compacta dos dados já existentes na página. Devem ser utilizados somente dados necessários para a decisão, como: ```text título blocos textuais relevantes presença de imagem quantidade de imagens presença de vídeo presença de elementos incorporados ``` Não enviar mídia binária. Não realizar chamadas externas para compreender a mídia. Não enviar HTML completo quando uma representação compacta da estrutura puder fornecer a mesma informação. --- # Responsabilidade do classificador O classificador responde uma única pergunta conceitual: > O texto desta publicação possui conteúdo jornalístico substancial por si próprio ou funciona essencialmente como uma breve introdução, contextualização ou descrição da mídia presente? Se o texto for substancial: ```json { "content_type": "text", "media_type": null } ``` Se a mídia for o conteúdo principal: ```json { "content_type": "media", "media_type": "..." } ``` --- # Tipos permitidos ```text video image images embed mixed ``` Não criar subtipos adicionais. --- # Regra para múltiplas imagens Não é necessário identificar tecnicamente um componente carousel. Se múltiplas imagens constituem o conteúdo principal, o resultado deve ser: ```text images ``` Independentemente de serem apresentadas como: * carousel; * slideshow; * galeria; * sequência vertical; * qualquer outra composição visual. --- # Regra para conteúdo misto Quando mais de uma categoria de mídia constituir o conteúdo principal: ```text mixed ``` Não criar precedência artificial como: ```text video > image ``` --- # Artigos textuais Um artigo continua sendo `text` mesmo contendo mídia quando existe conteúdo jornalístico textual substancial. Portanto: ```text presença de mídia ≠ classificação media ``` --- # Artigos muito curtos Uma publicação extremamente curta com uma imagem pode ser classificada como `media/image`. Não é necessário tentar preservar esse conteúdo como artigo textual apenas porque existe algum texto. --- # Posicionamento arquitetural A nova etapa deve permanecer fora de: ```text Trafilatura Newspaper4k Readability ``` Nenhum dos três motores é responsável pela classificação. O método equivalente ao atual `extract_all_engines()` somente deve ser executado depois que o novo roteamento determinar: ```text content_type = text ``` --- # Saída física Artigos textuais: ```text *_extracted.json ``` Artigos predominantemente de mídia: ```text *_media.json ``` A classificação de mídia não deve aparecer misturada aos artigos textuais processados com sucesso. --- # Dados preservados para mídia Cada registro de mídia deve preservar somente informações básicas necessárias à rastreabilidade: ```text input_meta crawled_url page_title http_status content_type media_type ``` Não existe extração de mídia nesta feature. --- # Alternativas consideradas ## Executar primeiro o multimotor e identificar mídia depois Rejeitada. Motivos: * executa trabalho desnecessário; * mistura responsabilidades; * não evita custo de processamento; * mantém páginas inadequadas dentro do pipeline textual. --- ## Usar Newspaper4k para descobrir mídia Rejeitada. Embora Newspaper4k possa expor informações de imagens e vídeos, utilizá-lo significaria executar parte do multimotor justamente nos conteúdos que a nova feature pretende desviar antes do multimotor. --- ## Classificar tudo apenas com regras Rejeitada. A decisão: ```text texto jornalístico curto ``` versus: ```text texto que apenas descreve uma mídia ``` é semântica e precisa funcionar em até 10 idiomas. Criar heurísticas específicas para resolver isso aumentaria código, manutenção e fragilidade. --- ## Utilizar regex Rejeitada e proibida por requisito. --- ## Utilizar modelo multimodal Rejeitada. O sistema não precisa entender a mídia. Precisa apenas determinar se o texto é o conteúdo principal ou se serve de introdução à mídia. --- # Consequências positivas * reduz processamento desnecessário; * mantém o multimotor focado em texto; * separa claramente conteúdos de naturezas diferentes; * mantém a implementação pequena; * evita regras linguísticas; * funciona de forma multilíngue; * não introduz nova infraestrutura; * permite evolução futura do pipeline de mídia de forma independente. --- # Consequências aceitas Alguns artigos textuais muito curtos acompanhados de imagem poderão ser classificados como `media/image`. Esse comportamento é deliberado e aceito, pois conteúdos textuais extremamente pobres não são úteis para o objetivo do pipeline textual. --- # Invariantes A implementação deve sempre preservar: ```text MEDIA → nunca executa multimotor TEXT → segue pipeline atual classification_failed → não assume TEXT → não assume MEDIA ``` E: ```text nenhuma regex nenhum download de mídia nenhuma análise multimodal nenhuma interação com carousel ```