# Modelo do config.yaml. Copie com `cp config.example.yaml config.yaml` e troque os # IDs de gmail_label_ids pelos da sua conta (README → setup, passo 4). # config.yaml — categorias, prompt e parâmetros da triagem. # Trocar uma categoria ou ajustar o prompt aqui NÃO exige mexer no fluxo n8n. # Este arquivo é montado dentro do container em /home/node/.n8n/config.yaml. # Modelo do Ollama (LOCAL). Precisa estar baixado: `ollama pull llama3.1`. # Alternativas boas para classificação: qwen2.5:7b, gemma2:9b, llama3.1:8b. model: llama3.1 # Endereço do Ollama visto de DENTRO do container n8n. # host.docker.internal = sua máquina (host). Ver docker-compose.yml / README. ollama_url: http://host.docker.internal:11434 # Quanto tempo o Ollama segura o modelo na RAM depois de uma chamada (~5,6 GB para o # llama3.1). Vale só DURANTE o lote: ao terminar, o fluxo manda descarregar na hora. # Curto de propósito — é a rede de segurança para o caso de o lote morrer no meio. ollama_keep_alive: "2m" # Janela de contexto. Menor = menos KV cache e mais rápido, mas NÃO pode ser menor que # o prompt: com 1024 o prompt (~1410 tokens) era truncado e o modelo perdia a lista de # categorias, passando a inventar labels ("marketing", "Oportunidade", "spam") — 1 acerto # em 16. Ao mexer nas descrições ou nas regras, meça de novo: # chars do prompt / 3.3 ≈ tokens, e deixe folga para a resposta. # Hoje o prompt está em ~1.760 tokens (8 categorias). 3072 deixa ~1.300 de folga, que # absorve um snippet longo sem risco — a margem importa porque a falha é SILENCIOSA: # nenhum erro, só labels inventados. ollama_num_ctx: 3072 # Limiar de confiança. Abaixo disso o email vai para o label de revisão (não chuta). confidence_threshold: 0.6 # Fallback de baixa confiança / erro. Não é categoria semântica. fallback_label: "_Revisar" # Multi-label: além do label primário, aplica "Ação necessária" quando needs_action=true. # Coloque false para usar somente label único. multi_label: true action_label: "Ação necessária" # Remetentes que NUNCA geram "Ação necessária", por mais que o modelo insista. # # O prompt já lista esses casos como exemplos de false e mesmo assim, na rodada de # 18/08, 4 dos 6 "Ação necessária" eram alerta automático destas plataformas (InfoJobs # "Contrata-se com urgência", Indeed "Estágio em...", Catho "CV atualizado = mais # chances", DIO "sua bolsa está reservada"). Reforçar o prompt já tinha dado o que # tinha de dar — o corte determinístico é o que resolve. # # É comparado contra o campo "From" inteiro, em minúsculas, como substring. Mantenha # específico: um domínio amplo demais aqui apaga ação legítima em silêncio. Note que # github.com e notion.so ficam DE FORA de propósito — "run failed" e "pedido de acesso" # são ação real. never_action_senders: - "catho.com.br" - "infojobs.com.br" - "indeed.com" - "99freelas.com.br" - "vagas.com.br" - "linkedin.com" - "dio.me" # Categorias semânticas. O "name" DEVE ser idêntico ao nome do label no Gmail. # # Cada descrição diz o que ENTRA e o que NÃO entra. As exclusões vieram de erros reais # medidos em 6.017 classificações (13/08/2026) — sem elas o modelo generaliza pelo TEMA # do email e as categorias viram baldes: # - "Faculdade/PUC" pegava qualquer coisa educacional (plataformas de cursos online, # MBAs, escolas livres): 101 dos 226 emails não tinham relação com a PUC. # - "Pessoal" pegava newsletter sobre psicologia/autoajuda por ser tema íntimo — o # MESMO remetente (uma newsletter de autoajuda) caía ora em Pessoal, ora em Newsletters. categories: - name: "Trabalho/Projetos" description: "desenvolvimento de software e dados que VOCÊ conduz: clientes, projetos, código. Inclui notificações das ferramentas que você usa quando exigem trabalho seu (GitHub, Vercel, deploy falhou, build quebrado, erro em produção). NÃO inclui propaganda de curso, bootcamp ou certificação — isso é Promoções. NÃO inclui alerta de login, senha ou termos de uso dessas mesmas ferramentas — isso é Contas/Segurança." - name: "Vagas/Carreira" description: "vagas de emprego, alertas de vagas (LinkedIn, Catho, InfoJobs, Indeed, 99Freelas), recrutadores, candidaturas, processos seletivos, freelas. NÃO inclui admissão ou inscrição em curso, faculdade ou MBA ('applications closing') — isso é venda de curso, ou seja, Promoções." - name: "Faculdade/PUC" description: "EXCLUSIVAMENTE a PUC-Campinas como instituição onde você estuda: secretaria, biblioteca, professores, disciplinas, matrícula, prazos e comunicados oficiais (tipicamente de @puc-campinas.edu.br). NÃO inclui nenhuma outra instituição de ensino, curso online, bootcamp, MBA, escola ou plataforma educacional — por mais acadêmico que o assunto pareça. Se vende um curso é Promoções; se é conteúdo recorrente é Newsletters." - name: "Financeiro" description: "faturas, boletos, banco, notas fiscais, cobranças, recibos, extratos, comprovantes de pagamento. NÃO inclui propaganda de banco, cartão ou crédito ('libere seu limite') — isso é Promoções." - name: "Contas/Segurança" description: "avisos automáticos sobre suas CONTAS em serviços: alerta de novo login ou acesso, verificação em duas etapas, código de verificação, redefinição de senha, mudança de termos de uso ou de política de privacidade, aviso de renovação de assinatura. São informativos e vêm de endereços noreply. NÃO inclui falha de deploy, build quebrado ou erro em produção — isso exige trabalho técnico seu e é Trabalho/Projetos." - name: "Pessoal" description: "mensagem escrita por uma PESSOA real, individualmente, para você: amigos, família, alguém respondendo você. O critério é quem escreveu e para quem, NUNCA o assunto. Texto em massa sobre vida pessoal, psicologia, autoconhecimento ou autoajuda NÃO é Pessoal — é Newsletters, mesmo soando íntimo. Aviso automático de conta ou segurança NÃO é Pessoal — é Contas/Segurança." - name: "Newsletters" description: "conteúdo recorrente enviado em massa por assinatura: blogs, digests, informativos, artigos, boletins. O critério é o FORMATO (envio em massa, periódico, sem esperar resposta), não o tema — vale para newsletter de tecnologia, carreira, psicologia ou desenvolvimento pessoal. Remetente em plataforma de newsletter (substack.com, mailchimp, beehiiv) é SEMPRE Newsletters, mesmo assinado com nome de pessoa." - name: "Promoções" description: "marketing e venda: ofertas, descontos, propaganda, cupons, venda de cursos/bootcamps/assinaturas, urgência comercial ('última chance', 'expira hoje'). Se o objetivo do email é te vender algo, é Promoções — mesmo que o produto seja educacional." # Mapeamento nome do label -> ID do label no Gmail (formato Label_123...). # O fluxo aplica labels POR ID (a API do Gmail não aceita por nome). # Preencha uma vez (ver README -> "Descobrir os IDs dos labels"). gmail_label_ids: "Trabalho/Projetos": "Label_101" "Vagas/Carreira": "Label_102" "Faculdade/PUC": "Label_103" "Financeiro": "Label_104" "Pessoal": "Label_105" "Newsletters": "Label_106" "Promoções": "Label_107" "Contas/Segurança": "Label_108" "Ação necessária": "Label_109" "_Revisar": "Label_110" # Prompt de sistema (mantém a saída em JSON puro). system_prompt: > Você é um classificador de email. Responda APENAS com um objeto JSON válido, sem markdown e sem texto antes ou depois. # Template do prompt de classificação. Placeholders: {{categories}} {{from}} {{subject}} {{snippet}} prompt_template: | Você é um classificador de email. Receberá os metadados de um email e deve atribuir EXATAMENTE UMA categoria primária da lista fornecida. CATEGORIAS (use o nome exato): {{categories}} REGRAS: - Escolha a categoria primária mais provável. Na dúvida entre duas, prefira a mais específica. - Classifique pela ORIGEM e pela INTENÇÃO do email, nunca pelo tema que ele menciona. Um email que vende um curso é Promoções, mesmo falando de educação. Um texto em massa sobre ansiedade é Newsletters, mesmo sendo um assunto íntimo. - "needs_action" = true SOMENTE se as três condições valerem ao mesmo tempo: 1. alguém específico (pessoa ou instituição) espera algo DE VOCÊ — responder, enviar documento, pagar, comparecer, confirmar; 2. existe consequência real em não fazer: perder prazo, multa, ficar de fora de um processo que já está em andamento; 3. NÃO é disparo automático em massa. Na dúvida, use false. É melhor deixar de marcar do que marcar tudo. EXEMPLOS DE false (todos já foram marcados como ação por engano): - alerta de vagas novas (Catho, InfoJobs, Indeed, 99Freelas) — é oportunidade, não obrigação; - "última chance", "expira hoje", "48 horas" de marketing — urgência comercial não é sua tarefa; - convite para conectar em rede social; - newsletter pedindo feedback, clique ou opinião; - notificação automática de deploy, build ou login bem-sucedido. EXEMPLOS DE true: - "você avançou no processo seletivo, responda até sexta"; - boleto ou fatura com vencimento; - prazo de entrega de documento da faculdade; - pessoa real fazendo uma pergunta direta a você. - "confidence" é sua certeza real, e precisa USAR A ESCALA INTEIRA: 0.9-1.0 = inequívoco (remetente e intenção não deixam dúvida); 0.7-0.8 = provável, mas outra categoria seria defensável; 0.4-0.6 = genuinamente ambíguo, você está em cima do muro; abaixo de 0.4 = não dá para decidir com o que foi fornecido. Responder 0.8 ou 0.9 para tudo é erro: emails ambíguos PRECISAM de valor baixo, é assim que eles vão para revisão manual em vez de receberem um palpite errado. - Baseie-se apenas no conteúdo fornecido. Não invente. ENTRADA: De: {{from}} Assunto: {{subject}} Trecho: {{snippet}} SAÍDA: responda APENAS com um objeto JSON, sem markdown, sem texto antes ou depois. O campo "label" tem de ser COPIADO LITERALMENTE de uma das categorias listadas acima — nunca invente um nome novo, nunca traduza, nunca resuma. Se nenhuma servir bem, escolha a menos ruim e baixe o "confidence"; a revisão manual cuida do resto. {"label": "", "needs_action": , "confidence": <0-1>, "reason": "<10 palavras no máx>"}