Fluxos / JevModel

API de detecção de spam para formulários e comentários: Turnstile, Akismet ou uma camada de decisão Jev

Onde encaixar um desafio (Cloudflare Turnstile), um serviço de reputação antispam (Akismet) e uma checagem tipada Jev Choice/Noul contra spam de formulários, comentários e cadastros, com fila de quarentena em vez de exclusões silenciosas.

Última atualização:

Resposta rápida: três camadas, e o Jev é só a última

  • Spam de formulários e comentários vem em três tipos: envios automáticos de bots, padrões de spam conhecidos e conteúdo escrito por pessoas que você ainda não quer (ofertas fora do tema, links soltos). Cada um pede uma ferramenta diferente.
  • Camada de desafio: o Cloudflare Turnstile só protege um formulário se o seu servidor validar cada token pela API Siteverify; tokens valem 300 segundos e só podem ser validados uma vez.
  • Camada de reputação: o comment-check do Akismet recebe api_key, blog e user_ip (obrigatórios) e campos de conteúdo e autor, e responde "true" (spam) ou "false"; qualquer outra resposta é erro, não veredito.
  • Camada de decisão: o JevModel lê só o texto enviado e devolve respostas tipadas, como um Choice entre real_inquiry / sales_pitch / spam e uma probabilidade Noul de “precisa de um olhar humano”. Sem reputação de IP nem base compartilhada de spam, use-o depois das duas primeiras camadas e coloque em quarentena em vez de apagar.

Três tipos de spam em formulários e comentários

“API de detecção de spam” cobre problemas diferentes, e misturá-los é como leads reais acabam apagados. Primeiro, envios automáticos: scripts que preenchem qualquer formulário. O melhor é barrá-los antes de ler o texto, com um desafio como o Cloudflare Turnstile. Segundo, spam conhecido: mensagens e remetentes que batem com padrões vistos em muitos sites, para o que existe um serviço de reputação como o Akismet. Terceiro, mensagens escritas por pessoas que você ainda não quer: venda fria pelo formulário de contato, oferta de agência de SEO num post, cadastro cuja bio é só um link. Passam pelo desafio porque uma pessoa as enviou e podem não parecer spam clássico, então a decisão depende da sua própria política. Só nesse terceiro tipo um modelo de decisão de texto como o Jev acrescenta algo. Este guia trata de formulários, comentários e cadastros; para spam na caixa de entrada, deixe a filtragem com seu provedor de e-mail, como explica o guia de classificação de e-mails.

Use Jev for review queuesClassificação de e-mails com IA: regras, prompts LLM ou uma API de decisão tipada para o e-mail recebidoScore leads on a useful rubric

Camada 1: barrar envios automáticos com o Cloudflare Turnstile

O Turnstile coloca no formulário um widget que gera um token, e a documentação da Cloudflare é explícita: a validação no servidor é obrigatória; o widget sozinho não protege nada. Seu handler envia POST https://challenges.cloudflare.com/turnstile/v0/siteverify com a chave secreta e o token (o IP do visitante é opcional) e lê o campo success do JSON. Tokens valem 300 segundos, só podem ser validados uma vez (reutilizar retorna timeout-or-duplicate) e têm no máximo 2048 caracteres. Rejeite o envio se a validação falhar, antes de gastar qualquer outra coisa com ele. Esta camada não diz nada sobre o significado da mensagem; só responde se uma sessão de navegador passou no desafio.

Camada 2: checar spam conhecido com o Akismet

O endpoint comment-check do Akismet, POST https://rest.akismet.com/1.1/comment-check, recebe campos form-encoded. api_key, blog (a URL do seu site) e user_ip são obrigatórios; comment_content, comment_author, comment_author_email, user_agent e comment_type são opcionais, e a documentação do Akismet diz que mais dados costumam significar mais precisão. comment_type não se limita a comentários de blog: os valores documentados incluem comment, forum-post, reply, contact-form, signup e message. O corpo da resposta é a string literal "true" para spam ou "false" para não spam; qualquer outra coisa, como "invalid", é erro e pode chegar com HTTP 200, então não trate como veredito. O cabeçalho X-akismet-pro-tip: discard marca spam flagrante que você pode descartar sem revisão. Para testes, o Akismet documenta comment_author akismet-guaranteed-spam (sempre spam), user_role administrator (nunca spam) e is_test=1 para marcar chamadas de teste.

Evaluate a Jev workflow

Camada 3: uma decisão Jev para mensagens humanas, mas indesejadas

O que sobra depois das camadas 1 e 2 é sobretudo uma questão de política: é uma consulta real, uma venda ou spam pela sua definição? O JevModel responde com saída tipada. Você envia a mensagem como state e faz perguntas nomeadas: um Choice cujos criteria definem real_inquiry, sales_pitch e spam com suas palavras, e uma pergunta Noul (sim/não) como “uma pessoa deve olhar antes de descartar”. A resposta traz o rótulo escolhido com uma probabilidade por rótulo e uma probabilidade para o Noul, que você usa para rotear. Tenha claro o que esta camada não é. O Jev lê só o state enviado: não tem reputação de IP ou remetente, nem base compartilhada de spam visto em outros sites, e o JevModel não treina um modelo com suas denúncias; não há treinamento personalizado. Não substitui um desafio nem o Akismet, e não deve ser o único motivo para apagar uma mensagem.

Choice, Score, and NoulJev probability, confidence and human-review thresholdsClassificação de intenção em texto de produto e suporte: regras, LLMs e APIs tipadas

Turnstile vs Akismet vs Jev: o que cada camada responde

A tabela compara entradas e contratos de saída segundo a documentação de cada fornecedor. Não é benchmark de precisão; meça qualquer camada com seus próprios envios.

Jev or rules?How to classify text with the JevModel API
Turnstile vs Akismet vs Jev: o que cada camada responde
DimensãoCloudflare TurnstileAkismetJevModel (Jev)
Pergunta respondidaEsta sessão de navegador passou num desafio?Este conteúdo e remetente parecem spam conhecido?Qual rótulo seu se encaixa neste texto pelas suas definições?
EntradaToken do widget + chave secreta (IP opcional)api_key, blog, user_ip obrigatórios; conteúdo, autor e tipo opcionaisSó o state enviado e perguntas nomeadas
SaídaJSON com success e códigos de erro"true" / "false"; outras respostas são erros; possível aviso discardRespostas tipadas: Choice com probabilidade por rótulo, probabilidade Noul, Score
Sinais além do textoSim, sinais do desafio do navegadorSim, IP e campos de remetente que você enviaNão, nada fora do state
Melhor lugar no fluxoPrimeiro: rejeitar antes de lerSegundo: descartar ou marcar spam conhecidoPor último: separar o restante nas suas filas

Exemplo de código: um handler de formulário de contato com decisão Jev

O esboço abaixo roda depois que o Turnstile e o Akismet deixaram o envio passar. Ele manda a mensagem como state em objeto, para o modelo saber o que é cada campo, e faz duas perguntas numa requisição: um Choice sobre o tipo de mensagem e um Noul sobre se uma pessoa deve revisar. Segue o contrato documentado: POST /api/v1/systemone com uma chave Bearer de conta verificada, state mais perguntas nomeadas, e resposta com code 0 e data.answers. Não há campo model porque o site sempre chama typesafe/jev-1.13 via OpenRouter. A API não tem chave de idempotência, então não repita uma requisição que pode já ter dado certo; uma execução que falha é reembolsada. Envie só os campos de que a decisão precisa: nome, e-mail e telefone em geral não ajudam a saber se é uma venda.

JevModel API: request and responseChoice, Score, and NoulAI Decision Flows with Jev and human review
// Illustrative only. Runs after Turnstile and Akismet have passed the submission.
// JEVMODEL_API_KEY comes from JevModel Console -> API keys (verified account).
async function decide(form) {
  const res = await fetch("https://jevmodel.app/api/v1/systemone", {
    method: "POST",
    headers: {
      Authorization: "Bearer " + process.env.JEVMODEL_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      // Send only what the decision needs; no name, email or phone.
      state: { form: "contact", subject: form.subject, message: form.message },
      questions: {
        kind: {
          type: "choice",
          instructions: "What kind of contact-form message is this, by our definitions?",
          criteria: {
            real_inquiry: "A person asking about our product, an order, or working with us as a customer.",
            sales_pitch: "Someone selling us a service: SEO, leads, development, marketing.",
            spam: "Gibberish, link dropping, scams, or text unrelated to any business purpose.",
          },
        },
        review: {
          type: "noul",
          instructions: "Should a person read this before it is moved out of the inbox?",
          criteria: {
            true: "It might be a real customer or partner, or the intent is unclear.",
            false: "It is clearly an unsolicited pitch or spam.",
          },
        },
      },
    }),
  });
  const body = await res.json();
  if (body.code !== 0) return { route: "inbox", reason: body.message }; // fail open
  const { kind, review } = body.data.answers;
  return {
    kind: kind.choice,
    probabilities: kind.probabilities,
    needsReview: review.noul, // probability that the answer is true
  };
}

Roteamento: quarentena, não exclusão

Um falso positivo num formulário de contato é um cliente perdido de que você nunca vai saber, então desenhe o roteamento em torno disso. Uma política viável: real_inquiry vai para a caixa de entrada ou o CRM como sempre; spam com baixa probabilidade de revisão vai para uma pasta de quarentena que alguém revisa periodicamente; sales_pitch vai para uma pasta própria, não para a lixeira; tudo com alta probabilidade de revisão, ou sem rótulo claramente vencedor, vai para a caixa de entrada com uma etiqueta. Se a chamada ao Jev falhar (code diferente de zero, timeout, INSUFFICIENT_TOKENS), deixe passar e entregue a mensagem; um filtro que engole leads quando está fora do ar é pior que nenhum. Defina os limiares com seus dados: rotule à mão algumas centenas de envios antigos, rode as mesmas perguntas e escolha o ponto em que quarentenas erradas ficam raras o bastante para você. A confiança Choice descrita pela TypeSafe, (p − 1/n)/(1 − 1/n), ajusta pelo número de rótulos, mas não é precisão calibrada. Confira de novo depois de mudar definições.

Jev probability, confidence and human-review thresholdsEvaluate a Jev workflowAI Decision Flows with Jev and human review

Checklist antes de ativar

1) Valide no servidor o token do Turnstile em todo envio; nunca confie só no widget. 2) Trate qualquer resposta do Akismet diferente de "true" ou "false" como erro, e use is_test=1 e os valores de teste documentados durante o desenvolvimento. 3) Escreva os criteria do Jev com suas palavras, com exemplos reais de ofertas que você não quer, e mantenha um rótulo de consulta real pelo menos tão específico. 4) Remova campos pessoais de que a decisão não precisa. 5) Coloque em quarentena em vez de apagar, e deixe passar quando alguma camada estiver indisponível. 6) Rotule uma amostra à mão, meça quarentenas erradas e meça de novo após mudanças; não publique um número de precisão que não mediu. 7) Orce tokens: cada envio que chega à camada 3 é uma requisição comum, e contas verificadas começam com 100.000 tokens grátis. Para moderação de posts com fila de revisão, veja content-moderation; para pontuar leads reais, veja lead-scoring.

Use Jev for review queuesScore leads on a useful rubricJevModel pricing and free Jev runsPrivate runs and historyClassificação de e-mails com IA: regras, prompts LLM ou uma API de decisão tipada para o e-mail recebidoClassificação de intenção em texto de produto e suporte: regras, LLMs e APIs tipadasJev probability, confidence and human-review thresholdsEvaluate a Jev workflowJevModel API: request and response

Perguntas frequentes

O Jev pode substituir o Akismet como API de detecção de spam?

Não. O Akismet usa o IP e os campos de remetente que você envia e padrões de spam vistos em muitos sites; o Jev lê só o texto enviado e não tem base compartilhada de spam nem reputação de IP. Use o Jev depois de um desafio e de uma checagem de reputação, para a questão de política: uma mensagem humana é consulta real, venda ou spam pelas suas definições?

Devo usar o Jev para filtrar spam de e-mail?

Não. Deixe a filtragem de spam da caixa de entrada com seu provedor de e-mail, que vê sinais de autenticação e reputação do remetente que o Jev não vê. O Jev serve depois da entrega, para rotear e-mails legítimos para suas filas; veja o guia de classificação de e-mails.

Como evitar apagar leads reais?

Coloque em quarentena em vez de apagar, dê às vendas uma pasta própria, mande para uma pessoa tudo com alta probabilidade de revisão e deixe passar quando uma camada der erro. Defina limiares com uma amostra rotulada à mão dos seus envios antigos e confira de novo depois de mudar definições.

O JevModel vê o IP do visitante ou aprende com minhas denúncias de spam?

Vê só o state enviado. Se você não puser IP, e-mail ou nome, o JevModel não os tem. Não há endpoint de feedback para denúncias nem treinamento personalizado; melhore os resultados refinando as definições de rótulos. As execuções ficam no seu histórico, e o guia de privacidade explica como removê-las.

JevModel é independente e não é afiliado à TypeSafe AI.