Cette semaine, notre reporting d'erreurs a signalé une classe de refus que nous n'avions pas prévue : sur les sujets historiquement ou politiquement sensibles, l'API du fournisseur de modèle répond par un rejet pour politique de contenu au lieu d'une completion — même quand la requête est clairement légitime. Le refus vient de la couche propre au fournisseur, pas de la nôtre, et l'utilisateur voit un corps d'erreur brut dans une langue qu'il ne lit presque certainement pas.
Deux filtres, pas un
Chaque prompt sur OnePress passe d'abord par notre propre filtrage d'entrée — une exigence contractuelle de notre processeur de paiement, et une exigence raisonnable. Ces requêtes le franchissent, à juste titre : le travail clairement légitime est exactement le type de trafic qui devrait passer sans encombre.
Le refus vient d'un deuxième filtre que ni nous ni l'utilisateur ne contrôlons : le filtrage de contenu au niveau plateforme du fournisseur de modèle lui-même, qui inspecte le trafic par-dessus le modèle. Les requêtes qui touchent à des sujets politiquement sensibles tombent dans un territoire que la couche de conformité d'une juridiction traite comme non sûr. La même requête est un travail tout à fait ordinaire partout ailleurs.
La découverte utile : le filtre n'est pas dans le modèle
Voici la partie qui a changé notre architecture. Nous avons envoyé une requête similaire de notre cru — même classe de contenu — aux exactement mêmes poids du modèle, mais servis par un hôte différent : OpenRouter, routé vers des fournisseurs d'inférence aux États-Unis. Mêmes poids, même classe de prompt. Génération complète, aucun refus.
Le refus n'a donc jamais vécu dans le modèle. Il vit dans la couche de service — l'enveloppe de conformité qu'un fournisseur met autour de son API. Ce qui veut dire qu'on peut la contourner proprement et ouvertement, sans jamais toucher au modèle.
Ce que nous avons changé
- Chaque modèle existe désormais en double dans le sélecteur. Le jeu par défaut route via OpenRouter vers des fournisseurs d'inférence hors Chine continentale ; les mêmes quatre modèles restent disponibles sur leurs API d'origine, étiquetés (CN), pour ceux qui les préfèrent.
- Les requêtes OpenRouter portent une liste d'autorisation upstream. Nous épinglons les requêtes à des fournisseurs nommés et désactivons le fallback — si la liste épinglée ne peut pas servir, l'appel échoue bruyamment au lieu d'atterrir silencieusement sur un chemin filtré.
- Les refus du fournisseur produisent désormais un message lisible. Un refus pour politique de contenu s'explique en langage clair et pointe vers le sélecteur de modèles — fini les blocs d'erreur bruts dans une langue que l'utilisateur ne lit pas. Les trames d'erreur embarquées en plein stream, qui étaient auparavant avalées et ressemblaient à une réponse vide, remontent aussi correctement.
- Les tâches de fond ont déménagé aussi. La génération de titres et de résumés lit le même contenu de conversation, donc elle emprunte le même endpoint OpenRouter.
Les limites honnêtes
Deux compromis qui méritent d'être nommés. D'abord, tous les modèles n'ont pas de chemin non filtré : le tier flash hébergé de Qwen n'existe que derrière l'upstream d'Alibaba lui-même, donc le slot OpenRouter pour Qwen fait tourner la variante open-weight 27B — un modèle différent, et nous l'étiquetons honnêtement. Ensuite, épingler signifie qu'une liste d'autorisation totalement en échec renvoie une erreur plutôt que de dégrader vers un chemin filtré. C'est un choix délibéré : un échec visible vaut mieux qu'un changement de lieu invisible.
Le plus grand est philosophique. Pour un produit international, le chemin par défaut ne devrait probablement hériter de la ligne éditoriale d'aucune juridiction en particulier — non pas parce que le filtre est malveillant, mais parce que sa définition du « sensible » a été écrite pour un autre public. Les défauts supposent désormais le contexte de l'utilisateur, pas celui du fournisseur.
Reading this and have thoughts?
Spot a mistake, disagree, or want a follow-up? Tell us — a human reads it.
Inside OnePress — the build log
More posts like this, plus the weekly AI digest, straight to your inbox.
Get the build log in your inbox →