Flux / JevModel
API de détection de spam pour formulaires et commentaires : Turnstile, Akismet ou une couche de décision Jev
Où placer un challenge (Cloudflare Turnstile), un service de réputation anti-spam (Akismet) et un contrôle typé Jev Choice/Noul face au spam de formulaires, commentaires et inscriptions, avec une file de quarantaine plutôt que des suppressions silencieuses.
Dernière mise à jour:
Réponse courte : trois couches, et Jev n’est que la dernière
- Le spam de formulaires et de commentaires prend trois formes : soumissions automatisées par des bots, motifs de spam connus, et contenus écrits par des humains dont vous ne voulez pas (démarchage hors sujet, dépôts de liens). Chacune demande un outil différent.
- Couche challenge : Cloudflare Turnstile ne protège un formulaire que si votre serveur valide chaque jeton via l’API Siteverify ; un jeton vaut 300 secondes et ne se valide qu’une fois.
- Couche réputation : comment-check d’Akismet prend api_key, blog et user_ip (obligatoires) plus les champs contenu et auteur, et répond "true" (spam) ou "false" ; toute autre réponse est une erreur, pas un verdict.
- Couche décision : JevModel ne lit que le texte envoyé et renvoie des réponses typées, par exemple un Choice entre real_inquiry / sales_pitch / spam et une probabilité Noul « à faire relire par un humain ». Sans réputation d’IP ni base de spam partagée, placez-le après les deux premières couches et mettez en quarantaine au lieu de supprimer.
Trois types de spam dans les formulaires et commentaires
« API de détection de spam » recouvre des problèmes différents, et les confondre fait supprimer de vrais prospects. D’abord, les soumissions automatisées : des scripts qui remplissent tous les formulaires. Mieux vaut les arrêter avant même de lire le texte, avec un challenge comme Cloudflare Turnstile. Ensuite, le spam connu : messages et expéditeurs correspondant à des motifs observés sur de nombreux sites, la spécialité d’un service de réputation comme Akismet. Enfin, des messages écrits par des humains dont vous ne voulez pas : démarchage via le formulaire de contact, offre d’agence SEO sous un article, inscription dont la bio n’est qu’un lien. Ils passent le challenge puisqu’une personne les envoie et ne ressemblent pas forcément à du spam classique ; la décision dépend donc de votre propre politique. Seul ce troisième type justifie un modèle de décision textuelle comme Jev. Ce guide traite des formulaires, commentaires et inscriptions ; pour le spam d’une boîte mail, laissez le filtrage à votre fournisseur, comme l’explique le guide de classification des e-mails.
Use Jev for review queuesClassification d’e-mails par IA : règles, prompts LLM ou API de décision typée pour le courrier entrantScore leads on a useful rubricCouche 1 : bloquer les soumissions automatisées avec Cloudflare Turnstile
Turnstile ajoute au formulaire un widget qui produit un jeton, et la documentation Cloudflare est claire : la validation côté serveur est obligatoire, le widget seul ne protège rien. Votre handler envoie POST https://challenges.cloudflare.com/turnstile/v0/siteverify avec la clé secrète et le jeton (l’IP du visiteur est facultative) et lit le champ success du JSON. Un jeton vaut 300 secondes, ne se valide qu’une fois (une réutilisation renvoie timeout-or-duplicate) et fait au plus 2048 caractères. Rejetez la soumission si la validation échoue, avant d’y consacrer quoi que ce soit d’autre. Cette couche ne dit rien du sens du message ; elle indique seulement si une session de navigateur a passé le challenge.
Couche 2 : vérifier le spam connu avec Akismet
L’endpoint comment-check d’Akismet, POST https://rest.akismet.com/1.1/comment-check, reçoit des champs form-encoded. api_key, blog (l’URL de votre site) et user_ip sont obligatoires ; comment_content, comment_author, comment_author_email, user_agent et comment_type sont facultatifs, et la documentation d’Akismet indique que davantage de données améliore généralement la précision. comment_type ne se limite pas aux commentaires de blog : les valeurs documentées incluent comment, forum-post, reply, contact-form, signup et message. Le corps de réponse est la chaîne littérale "true" pour du spam ou "false" sinon ; toute autre valeur, comme "invalid", est une erreur et peut arriver avec un HTTP 200 : ne la traitez pas comme un verdict. L’en-tête X-akismet-pro-tip: discard signale un spam flagrant que vous pouvez jeter sans revue. Pour les tests, Akismet documente comment_author akismet-guaranteed-spam (toujours spam), user_role administrator (jamais spam) et is_test=1 pour signaler les appels de test.
Evaluate a Jev workflowCouche 3 : une décision Jev pour les messages humains mais indésirables
Ce qui reste après les couches 1 et 2 relève surtout de votre politique : est-ce une vraie demande, du démarchage ou du spam selon votre définition ? JevModel y répond par une sortie typée. Vous envoyez le message comme state et posez des questions nommées : un Choice dont les criteria définissent real_inquiry, sales_pitch et spam avec vos mots, et une question Noul (oui/non) comme « une personne doit le voir avant qu’il soit écarté ». La réponse contient le label choisi avec une probabilité par label et une probabilité pour le Noul, sur lesquelles router. Soyez clair sur ce que cette couche n’est pas. Jev ne lit que le state envoyé : aucune réputation d’IP ou d’expéditeur, aucune base partagée de spam vu ailleurs, et JevModel n’entraîne pas de modèle sur vos signalements ; aucun entraînement personnalisé n’est proposé. Elle ne remplace ni un challenge ni Akismet, et ne doit pas être la seule raison de supprimer un message.
Choice, Score, and NoulJev probability, confidence and human-review thresholdsClassification d’intention pour texte produit et support : règles, LLM et API typéesTurnstile vs Akismet vs Jev : ce que répond chaque couche
Le tableau compare entrées et contrats de sortie d’après la documentation de chaque fournisseur. Ce n’est pas un benchmark de précision ; mesurez chaque couche sur vos propres soumissions.
Jev or rules?How to classify text with the JevModel API| Dimension | Cloudflare Turnstile | Akismet | JevModel (Jev) |
|---|---|---|---|
| Question traitée | Cette session de navigateur a-t-elle passé un challenge ? | Ce contenu et cet expéditeur ressemblent-ils à du spam connu ? | Quel label, selon vos définitions, correspond à ce texte ? |
| Entrée | Jeton du widget + clé secrète (IP facultative) | api_key, blog, user_ip obligatoires ; contenu, auteur, type facultatifs | Seulement le state envoyé et des questions nommées |
| Sortie | JSON avec success et codes d’erreur | "true" / "false" ; autres réponses = erreurs ; indication discard possible | Réponses typées : Choice avec probabilité par label, probabilité Noul, Score |
| Signaux au-delà du texte | Oui, signaux du challenge navigateur | Oui, l’IP et les champs expéditeur transmis | Non, rien hors du state |
| Meilleure place dans le flux | En premier : rejeter avant de lire | Ensuite : écarter ou signaler le spam connu | En dernier : répartir le reste dans vos files |
Exemple de code : un handler de formulaire de contact avec décision Jev
L’esquisse ci-dessous s’exécute après que Turnstile et Akismet ont laissé passer la soumission. Elle envoie le message comme state objet, pour que le modèle sache quel champ est quoi, et pose deux questions en une requête : un Choice sur le type de message et un Noul sur la nécessité d’une relecture humaine. Elle suit le contrat documenté : POST /api/v1/systemone avec une clé Bearer d’un compte vérifié, un state et des questions nommées, et une réponse avec code 0 et data.answers. Pas de champ model, car le site appelle toujours typesafe/jev-1.13 via OpenRouter. L’API n’a pas de clé d’idempotence : ne relancez pas une requête qui a peut-être réussi ; une exécution échouée est remboursée. N’envoyez que les champs utiles à la décision : nom, e-mail et téléphone n’aident généralement pas à savoir s’il s’agit de démarchage.
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
};
}
Routage : quarantaine, pas suppression
Un faux positif sur un formulaire de contact, c’est un client perdu dont vous n’entendrez jamais parler : concevez le routage autour de ce risque. Une politique praticable : real_inquiry va dans la boîte ou le CRM comme d’habitude ; spam avec une faible probabilité de revue va dans un dossier de quarantaine parcouru régulièrement ; sales_pitch va dans son propre dossier plutôt qu’à la corbeille ; tout ce qui a une forte probabilité de revue, ou sans label clairement gagnant, va dans la boîte avec une étiquette. Si l’appel Jev échoue (code non nul, timeout, INSUFFICIENT_TOKENS), laissez passer et livrez le message ; un filtre qui avale des prospects quand il est en panne est pire que pas de filtre. Fixez les seuils sur vos données : étiquetez à la main quelques centaines de soumissions passées, passez-les dans les mêmes questions et choisissez le point où les mises en quarantaine erronées deviennent assez rares pour vous. La confiance Choice décrite par TypeSafe, (p − 1/n)/(1 − 1/n), corrige selon le nombre de labels mais n’est pas une précision calibrée. Revérifiez après tout changement de définitions.
Jev probability, confidence and human-review thresholdsEvaluate a Jev workflowAI Decision Flows with Jev and human reviewChecklist avant la mise en service
1) Validez côté serveur le jeton Turnstile de chaque soumission ; ne faites jamais confiance au seul widget. 2) Traitez toute réponse Akismet autre que "true" ou "false" comme une erreur, et utilisez is_test=1 et les valeurs de test documentées pendant le développement. 3) Rédigez les criteria Jev avec vos mots, avec de vrais exemples de démarchage indésirable, et gardez un label « vraie demande » au moins aussi précis. 4) Retirez les champs personnels inutiles à la décision. 5) Mettez en quarantaine au lieu de supprimer, et laissez passer quand une couche est indisponible. 6) Étiquetez un échantillon à la main, mesurez les mises en quarantaine erronées et remesurez après chaque changement ; ne publiez pas de précision non mesurée. 7) Budgétez les tokens : chaque soumission qui atteint la couche 3 est une requête ordinaire, et les comptes vérifiés démarrent avec 100 000 tokens offerts. Pour la modération de publications avec file de revue, voir content-moderation ; pour noter de vrais prospects, voir lead-scoring.
Use Jev for review queuesScore leads on a useful rubricJevModel pricing and free Jev runsPrivate runs and historyClassification d’e-mails par IA : règles, prompts LLM ou API de décision typée pour le courrier entrantClassification d’intention pour texte produit et support : règles, LLM et API typéesJev probability, confidence and human-review thresholdsEvaluate a Jev workflowJevModel API: request and responseQuestions fréquentes
Jev peut-il remplacer Akismet comme API anti-spam ?
Non. Akismet exploite l’IP et les champs expéditeur transmis ainsi que des motifs de spam observés sur de nombreux sites ; Jev ne lit que le texte envoyé, sans base de spam partagée ni réputation d’IP. Placez Jev après un challenge et un contrôle de réputation, pour la question de politique : un message humain est-il une vraie demande, du démarchage ou du spam selon vos définitions ?
Faut-il utiliser Jev pour filtrer le spam e-mail ?
Non. Laissez le filtrage du spam de la boîte à votre fournisseur de messagerie, qui voit des signaux d’authentification et de réputation de l’expéditeur que Jev ne voit pas. Jev sert après la livraison, pour router le courrier légitime vers vos files ; voir le guide de classification des e-mails.
Comment éviter de supprimer de vrais prospects ?
Mettez en quarantaine au lieu de supprimer, donnez au démarchage son propre dossier, confiez à une personne tout ce qui a une forte probabilité de revue et laissez passer quand une couche est en erreur. Fixez les seuils sur un échantillon étiqueté à la main de vos soumissions passées et revérifiez-les après tout changement de définitions.
JevModel voit-il l’IP du visiteur ou apprend-il de mes signalements ?
Il ne voit que le state envoyé. Si vous n’y mettez ni IP, ni e-mail, ni nom, JevModel ne les a pas. Il n’existe ni endpoint de retour pour les signalements ni entraînement personnalisé ; améliorez les résultats en affinant les définitions de labels. Les exécutions restent dans votre historique, et le guide de confidentialité explique comment les supprimer.
JevModel est indépendant et n’est pas affilié à TypeSafe AI.