De deux API à un Smart API Router : règles, v29 et Deep Analyze derrière un seul endpoint

zn11 min de lecture

Jusqu'à cette semaine, zn exposait deux API. Vous en choisissiez une par requête, et les limites de votre abonnement étaient réparties entre les deux. C'était une taxe de conception sur chaque intégration : le mauvais choix donnait un faux sentiment de sécurité, et le bon choix exigeait de comprendre nos entrailles mieux que vous ne devriez avoir à le faire.

Aujourd'hui, il n'y a qu'un seul endpoint. POST /analyze route chaque requête à travers trois couches progressives — règles déterministes, porte neuronale v29 et Deep Analyze — et vous dit laquelle a décidé.

TL;DR

  • POST /analyze est désormais un Smart API Router (SAR) : Niveau 1 règles déterministes (<50 µs), Niveau 2 v29 neuronal int8 (~15–18 ms), Niveau 3 Deep Analyze (mmBERT v8, ~166 ms à chaud) pour la bande ambiguë.
  • /v30/analyze reste un alias de compatibilité. Le chemin produit POST /prod/analyze reste règles-seules pour ceux qui veulent la porte à latence ultra-faible.
  • Le router est fail-open : si Deep Analyze expire (budget de 6 s) ou échoue, vous recevez quand même le verdict v29. Une passerelle de sécurité ne doit jamais devenir la panne.
  • Les abonnements portent désormais des quotas DeepAnalyze explicites par palier, de 25/mois sur l'essai 48 h jusqu'à 30 000/mois en Growth.
  • Zéro rétention de données sur les paliers payants. La réponse inclut tier, decided_by, latency_ms et un evidence_id auditable.

Pourquoi deux API, c'était la mauvaise forme

Le premier endpoint, POST /analyze, est un moteur de règles déterministes : normalisation plus un catalogue de motifs d'injection (pi-direct et compagnie). Il répond en microsecondes, il est trivialement auditable, et quand une règle se déclenche elle a presque toujours raison. Mais les règles ne rattrapent que ce que vous avez déjà vu.

Le second endpoint, POST /v30/analyze, exécute v29 : un transformer multilingue, exporté vers ONNX et quantifié en int8, qui note le texte brut et bloque au-dessus d'un seuil calibré (τ = 0,950 après la passe de durcissement multilingue). L'échange est différent : ~15–18 ms p50 sur CPU, une couverture bien meilleure, et toujours loin du coût et de la latence d'un guard basé sur un LLM.

Les deux sont des produits honnêtes. Ensemble, c'était une mauvaise interface. Les clients devaient savoir dans quel modèle de menace ils se trouvaient pour choisir un endpoint à chaque appel, les quotas étaient séparés et les preuves des deux chemins n'étaient pas directement comparables. En pratique, les gens utilisaient le chemin rapide et perdaient silencieusement la couverture neuronale qu'ils payaient.

Un endpoint, trois cerveaux

Le router décide par requête, à découvert :

  1. Niveau 1 — Règles. Normaliser, chercher des motifs déterministes. Si une règle se déclenche, retour. Coût : microsecondes.
  2. Niveau 2 — v29 neuronal. Si les règles ne concluent pas, noter avec le modèle int8. Les cas clairement bénins ou clairement hostiles s'arrêtent ici.
  3. Niveau 3 — Deep Analyze. Seulement quand le score v29 tombe dans la bande incertaine (0,50–0,935), la requête part vers Deep Analyze, le modèle mmBERT v8 qui existe exactement pour ça : un texte qui paraît bénin à un petit encodeur mais mérite un second avis.

La fusion du verdict est simple à dessein : le router combine le score v29 et le score Deep Analyze et bloque à partir de 0,935. Chaque réponse porte désormais tier (rules, advanced, deep), decided_by, latency_ms et evidence_id, pour que vous mesuriez votre propre trafic par chemin de décision.

Avant : deux endpoints séparés. Après : un endpoint Analyze routé par le Smart API Router entre règles, v29 neuronal et Deep AnalyzeLe panneau supérieur montre les anciens POST /analyze règles et POST /v30/analyze neuronal obligeant le client à choisir. Le panneau inférieur montre un unique POST /analyze routé par le Smart API Router vers le Niveau 1 règles sous 50 microsecondes, le Niveau 2 v29 int8 environ 15 millisecondes et le Niveau 3 Deep Analyze mmBERT environ 166 millisecondes à chaud, avec un budget fail-open de 6 secondes et une réponse contenant tier, latence et evidence id.FIGURE 1 : DEUX ENDPOINTS → UN SMART API ROUTERAVANT · CHOISIR PAR REQUÊTEPOST /analyzeRègles déterministes · <50 µs · couverture par motifsPOST /v30/analyzev29 neuronal int8 · ~15–18 ms · quotas séparésAPRÈS · UN SEUL APPELPOST /analyze→ SMART API ROUTERNIVEAU 1 · RÈGLES<50 µs · déterministemotifs exacts, auditableNIVEAU 2 · v29 NEURONAL~15–18 ms · ONNX int8multilingue, forte couvertureNIVEAU 3 · DEEP ANALYZE~166 ms à chaud · mmBERT v8seulement la bande 0,50–0,935réponse : verdict · tier · decided_by · latency_ms · evidence_idfail-open : Deep a 6 s, puis le verdict v29 est renvoyé

Deep Analyze : le niveau qui a dû gagner sa place

Deep Analyze est notre détecteur multilingue mmBERT v8, exporté vers ONNX int8 et servi depuis une Lambda conteneur (3 Go de mémoire, 4 Go éphémères, plafond de 120 s). À chaud, il répond en ~166 ms. Les démarrages à froid prennent ~24 s, et c'est pourquoi il n'est jamais sur le bord synchrone d'un chemin non protégé : il ne tourne que pour la bande ambiguë, dans un budget dur de 6 s du router, et le router retombe sur v29 s'il dépasse.

Obtenir un modèle assez bon pour mériter cette place a pris plus de temps que le router lui-même. Nos articles précédents ont raconté l'histoire complète : le dataset qui nous mentait et dix-sept entraînements ratés où le modèle notait 0,498–0,509 sur tout parce que la perte ne voyait jamais d'étiquette. Le correctif était ordinaire — entraînement supervisé de bout en bout, split gelé, arrêt du réglage sur le test — et le résultat fut une porte avec FPR 0,82 %, FNR 8,20 %, AUROC 0,9958 sur le split de test gelé, à 17,9 ms p50 en int8.

Deep Analyze va plus loin sur la tranche la plus difficile. Sur nos sondes internes, il sépare les entrées adverses à 0,9999999998 tandis qu'un texte bénin mais suspect reste à 1,35e-7. Ce ne sont pas des probabilités marketing ; ce sont les chiffres que notre propre passerelle voit quand elle décide, journalisés avec un evidence_id pour chaque blocage.

Échelle de décision et budget de latence en échelle logarithmique : règles sous 50 microsecondes, v29 environ 15 millisecondes, Deep Analyze environ 166 millisecondes, budget du router 6 secondesAxe logarithmique de 10 microsecondes à 10 secondes. La barre du Niveau 1 règles finit près de 50 microsecondes. Celle du Niveau 2 v29 près de 15 millisecondes. Celle du Niveau 3 Deep Analyze près de 166 millisecondes. Une ligne pointillée marque le budget fail-open de 6 secondes. Deep Analyze ne tourne que si le score v29 tombe dans la bande 0,50 à 0,935 ; 0,935 ou plus bloque.FIGURE 2 : ÉCHELLE DE DÉCISION · BUDGET (ÉCHELLE LOG)bande v29 0,50–0,935 → Deep Analyze · score ≥0,935 → bloquerNIVEAU 1 · RÈGLEScorrespondance concluante~50 µsNIVEAU 2 · v29 NEURONALONNX int8, p50~15–18 msNIVEAU 3 · DEEP ANALYZEmmBERT v8, à chaud~166 msLIMITE FAIL-OPEN 6 s10 µs100 µs1 ms10 ms100 ms1 s10 sChaque niveau journalise tier, decided_by, latency_ms et evidence_id.Fail-open : un timeout de Deep ne devient jamais une requête échouée.

Le déployer sans casser la production

Un router devant chaque requête, c'est un déploiement qui fait peur. Nous l'avons fait en trois temps : d'abord le mode ombre, où le chemin en production et le router décidaient tous les deux et nous comparions seulement — Deep Analyze notait à côté du verdict de production sans y toucher. Puis le canary à 50 % derrière l'alias, avec des alarmes CloudWatch sur les erreurs Lambda, les fail-opens de Deep et la latence p99, reliées à SNS. Puis 100 %.

Les garanties ennuyeuses sont le point : le rollback est un changement de version d'alias, le router a 39/39 tests unitaires dont une suite d'équivalence qui prouve que le chemin routé renvoie le même verdict que l'appel direct, et le fail-open est exercé en test, pas espéré.

Abonnements : des limites plus grandes et des quotas DeepAnalyze explicites

Les anciens abonnements comptaient un seul seau d'appels et laissaient Deep Analyze en expérimentation. Le nouveau canon donne à chaque palier un quota standard et un quota DeepAnalyze au même endroit, et relève les plafonds :

Limites des abonnements : trial 100 standard et 25 DeepAnalyze, contributor 50 000 et 500, hobby 100 000 et 1 000, starter 500 000 et 5 000, growth 2 500 000 et 30 000, enterprise illimitéChaque ligne montre l'abonnement, ses appels standard mensuels et ses appels DeepAnalyze mensuels, alignés à droite avec de fins séparateurs. Les paliers payants conservent une rétention nulle ; le palier gratuit Contributor est en télémétrie optionnelle.FIGURE 3 : ABONNEMENTS · LIMITES MENSUELLESSTANDARDDEEPANALYZETrial · 48 h10025Contributor · gratuit à vie50 000500Hobby · $19100 0001 000Starter · $49500 0005 000Growth · $1992 500 00030 000Enterprise · sur mesureillimitéillimitéChaque abonnement inclut le router complet : règles, v29 et Deep Analyze.Les paliers payants gardent une rétention nulle · Contributor est en télémétrie optionnelle.

La rétention ne change pas : les paliers payants stockent zéro entrée. Nous conservons le verdict, le niveau et les hashes nécessaires à l'Evidence Vault, avec 90 jours de rétention. Le palier Contributor — gratuit à vie — est le seul à stocker l'entrée, anonymisée, et seulement parce que vous acceptez la télémétrie communautaire pour l'entraînement du modèle. Si vous utilisez un abonnement payant, vos prompts ne sont pas dans notre jeu d'entraînement. Jamais.

Ce qui change pour vous

Si vous appeliez /v30/analyze, rien ne casse : même chemin, même forme de réponse, désormais avec tier et decided_by qui indiquent d'où vient chaque verdict. Si vous appeliez /analyze en attendant uniquement les règles, passez à /prod/analyze pour le chemin déterministe — ou restez, et obtenez le router complet au même prix. Une clé, un endpoint, trois cerveaux.

Si vous voulez voir le chemin de décision sur votre propre trafic avant de vous y fier, c'est à ça que sert l'essai gratuit de 48 h : un POST, une clé d'API et une preuve pour chaque blocage.

Share