Crate Rust publié. npm et PyPI ensuite.
Chaque modèle a son écriture la moins chère.
Même charge utile, même information, même aller-retour sans perte. Changez seulement la façon dont les symboles sont écrits et la facture en tokens bouge d'un quart. Tokendoo mesure quelle écriture coûte le moins cher pour chaque modèle, et se maintient à jour à chaque nouvelle version des modèles les plus répandus.
ratio de tokens médian, cl100k, alphabet dérivé, fixtures de référence
Ratio wire : charge compressée seule. La légende de format ajoute 97 à 174 tokens et peut effacer le gain sur les petites charges.
corpus synthétique publié · comptes cl100k_base exacts · 2026-08-06
01 / Le problème
Le JSON paie sa structure, encore et encore.
Un tableau JSON de 1 000 lignes répète ses clés 1 000 fois. Accolades, guillemets, noms de champs, chaînes répétées : l'API facture chacun d'eux, à chaque requête, au prix du token.
Le sens est dans les valeurs. Le volume, c'est surtout de la répétition qu'on peut retirer puis remettre à l'identique. C'est la seule partie que Tokendoo touche.
02 / Fonctionnement
Quatre transformations, dans l'ordre.
Chaque étape est structurelle et réversible. On ne la garde que si la charge devient plus petite. Si rien n'aide, on émet l'entrée telle quelle et on le dit dans l'en-tête.
Canonicalisation
Espaces retirés, clés triées, nombres normalisés. Une entrée déterministe pour tout ce qui suit.
{ "sku": "a-114", "qty": 2 }{"qty":2,"sku":"a-114"}Dictionnaire de clés, désactivé par défaut
Les clés répétées deviennent des ordinaux en base 36, plus une table. Sur le corpus de référence, il n'a pas passé la barre des ≥ 10 % de gain en tokens : il reste désactivé tant qu'il ne fait pas ses preuves.
{"quantity":2,"status":"active"}{"0":2,"1":"active"} k:["quantity","status"]Repli tabulaire
Un tableau d'objets de même forme devient un schéma plus des lignes de valeurs. Les clés sont écrites une fois, pas une fois par enregistrement.
[{"qty":2,"sku":"a-114"},
{"qty":1,"sku":"a-115"}]["__T",["qty","sku"], [[2,"a-114"],[1,"a-115"]]]
Internement des valeurs
Les chaînes qui se répètent rejoignent une table et sont référencées par ordinal. La table part avec la sortie, et chaque chiffre de cette page la compte.
"eu-west-1" × 40
"0" × 40 v:["eu-west-1"]
Le résultat est une chaîne T3, T388:…, plus un dictionnaire JSON. Les deux comptent dans chaque ratio. Annoncer un gain sans le dictionnaire le surestimerait.
03 / Pourquoi s'abonner
Le codec est gratuit. Savoir comment l'écrire ne l'est pas.
Les transformations tiennent en quatre cents lignes de code déterministe, publiées sous licence Apache 2.0 avec le corpus et le banc de mesure. Servez-vous. Le difficile n'est pas de compresser la charge utile, c'est de choisir les symboles vers lesquels elle est compressée.
Un symbole coûte ce que le tokenizer facture pour lui. Les caractères de contrôle semblaient évidents, un octet chacun, et se sont révélés le pire choix possible : ils ne participent à aucune fusion, donc chacun coûte un token entier sans rien encoder. Dériver les symboles du vocabulaire cible, de sorte que chacun vaille exactement un token, fait mieux encore.
| alphabet | ratio de tokens médian |
|---|---|
| caractères de contrôle | 0,6575 |
| préfixe imprimable | 0,5241 |
| base 36 nue | 0,4207 |
| dérivé du vocabulaire | 0,3868 |
Et la réponse ne se transporte pas. La table dérivée pour cl100k et celle dérivée pour un tokenizer Llama partagent 438 symboles sur 1 377 : deux tiers de l'écriture optimale d'une famille sont faux pour l'autre.
C'est tout le service. Une bibliothèque figée conserve la réponse du jour où elle a été copiée. Chaque famille de modèles qui sort est une colonne à remesurer, et un client qui applique la table de l'an dernier au modèle de cette année le paie sans jamais s'en apercevoir.
04 / Mesures
Les chiffres sur lesquels on décide.
Comptes cl100k_base exacts sur un corpus synthétique publié, mesuré le 2026-08-07 avec les réglages livrés : alphabet derived_cl100k_v1, repli tabulaire et internement activés, dictionnaire de clés désactivé. Chaque compte de sortie inclut le dictionnaire.
| fixture | nature | tokens avant | tokens après | ratio tokens | ratio octets |
|---|---|---|---|---|---|
homogeneous_100 | 100 enregistrements, un schéma | 2 903 | 1 229 | 0,4234 | 0,327 |
homogeneous_1000 | 1 000 enregistrements, un schéma | 29 003 | 8 387 | 0,2892 | 0,246 |
realistic_api | réponse d'API mixte | 3 200 | 2 415 | 0,7547 | 0,689 |
size_10k | charge mixte ≈ 10 Ko | 3 860 | 1 493 | 0,3868 | 0,304 |
size_100k | charge mixte ≈ 100 Ko | 39 983 | 11 663 | 0,2917 | 0,246 |
size_250k | charge mixte ≈ 250 Ko | 98 603 | 29 156 | 0,2957 | 0,247 |
prose_heavy | longues valeurs textuelles, structure mince | 2 965 | 2 980 | 1,0051 | 1,002 |
fixtures de référence, ratio de tokens médian 0,3868. Le corpus et le banc sont dans le dépôt ; relancer le banc reproduit chaque compte.
La dernière ligne, c'est le cas où l'outil ne fait rien. La compression structurelle n'a pas de prise sur la prose, et prose_heavy ressort 0,5 % plus gros. On garde la ligne : c'est le cas où l'outil n'aide pas, on reste transparent.
L'aller-retour est garanti dans le dépôt public : des tests par propriétés exigent que decompress(compress(x)) soit égal à x sur les valeurs JSON.
05 / Obtenir la bibliothèque
06 / Comment ça se branche
Le branchement qu'on refuse.
Ce qu'on ne fait jamais
# On ne se place jamais devant le fournisseur de modèle. # appelant ──(votre clé OpenAI/Anthropic)──▶ tokendoo-proxy ──▶ modèle ✗ # appelant ──▶ compress (local) ──▶ vous ──(votre clé)──▶ modèle ✓ # On ne reçoit jamais votre clé fournisseur. # On ne voit jamais la réponse du modèle. # On ne reçoit jamais votre charge utile.
Langage pas encore couvert ? Le codec est publié sous Apache 2.0 : environ quatre cents lignes de code déterministe. Réimplémentez-le. Il n'y aura pas d'API de compression à attendre.
07 / Zéro rétention
Rien à fuiter, par construction.
La charge utile ne quitte pas la machine. Nous ne la gardons pas, parce que nous ne la recevons jamais.
Le seul appel sortant, c'est le rafraîchissement quotidien des tables, prévu. Il porte une clé de compte et rien d'autre : pas de charge utile, pas de compteurs, pas d'identifiants.
L'avis de confidentialité, c'est cette section.
Il n'y a pas de champ de collage sur cette page, exprès. Un produit fondé sur la non-collecte des charges utiles ne vous demande pas d'envoyer du JSON pour prouver qu'il n'en garde pas.
08 / État & feuille de route
Ce qui est livré, ce qu'on mesure, ce qui est prévu.
au 2026-08-08
Livré
- tokendoo 0.1.0 sur crates.io ; documentation sur docs.rs/tokendoo
- Aller-retour sans perte sur les valeurs JSON, vérifié par plus de 1 000 cas de tests par propriétés
- Bibliothèque Rust locale ; la compression ne passe par aucun réseau
- Mode JSON uniquement ; entrées jusqu'à 256 Kio
En cours de mesure
- Si un modèle répond aussi bien sur l'entrée compressée que sur l'originale. Nous ne l'affirmons pas. Le banc existe, et les résultats seront publiés quels qu'ils soient.
- Coût de la légende qui apprend le format au modèle : 97 à 174 tokens, de quoi effacer le gain sur les petites charges. Compté, pas caché.
Prévu
- Mode code : pour être utile, il est nécessairement avec perte, ce qui casse la garantie d'aller-retour. Il attend qu'on puisse dire ce compromis clairement.
- Mode texte : la prose est à un ratio de 1,005. La compression structurelle y est inefficace.
- Bibliothèque sur npm et PyPI, à partir du même cœur Rust.
- Endpoint de distribution de tables : tables d'alphabet versionnées seulement, jamais de charges utiles. Le format filaire doit porter un identifiant de table versionnée distante ; l'en-tête T3 d'aujourd'hui encode un id d'alphabet dans les drapeaux, pas cet identifiant.
- Abonnement : tables d'alphabet à jour, par famille de modèles couverte.
09 / Prix
Vous payez les tables à jour, pas la compression.
Prévu. Structure des paliers seulement ; les prix arriveront quand les paliers existeront.
Une bibliothèque locale ne peut pas facturer l'usage honnêtement : un compteur autodéclaré se manipule, et détecter l'usage non déclaré exigerait la télémétrie que nous refusons. L'abonnement vend donc l'accès aux tables d'alphabet, comme les bases GeoIP se vendent, pas les lookups. Le moteur ne casse pas quand les tables vieillissent ; il vieillit. C'est tout l'argument.
Gratuit
Tables figées à la version de la bibliothèque. Pas de mises à jour. Elle compresse, l'aller-retour tient, elle marche hors ligne indéfiniment. Pas bridée : elle vieillit, c'est tout.
Une famille
Tables à jour pour OpenAI, Anthropic, Google ou Llama.
Toutes les familles
Tables à jour pour chaque famille que nous couvrons.
Sur mesure
Tables dérivées de vos propres charges utiles. La réponse à « vos fixtures sont synthétiques », pas un upsell premium.
Aucune facture ne dépend d'un compte de tokens : la question du tokenizer exact en production se referme.
Nous ne retenons pas une meilleure table à un client payant pour fabriquer de la rétention. L'axe, c'est la couverture, pas la cadence de mise à jour.
10 / Questions
Les objections, avant que vous ne les posiez.
Sept questions qui vous sont probablement déjà passées par la tête en lisant nos mesures.
Pourquoi ne pas simplement gzipper la charge utile ?
Le prompt caching ne règle-t-il pas déjà la question ?
1 024 tokens, et l'écriture coûte 1,25 fois le tarif de base. Il paie donc sur des préfixes stables avec un trafic soutenu, et ne fait rien pour des charges qui changent à chaque appel, un trafic sporadique, ou un contexte multi-locataire où aucun préfixe n'est partagé. Les deux se combinent d'ailleurs : écritures et lectures de cache sont facturées au token, donc compresser d'abord réduit les deux. Nous ne remplaçons pas le cache, nous réduisons l'assiette sur laquelle il est facturé.Le modèle comprend-il vraiment la forme compressée ?
Pourquoi un abonnement ? Ce sont quatre cents lignes de code.
Apache 2.0, avec le corpus et le banc de mesure. Servez-vous. Ce que l'abonnement vend n'est pas la transformation mais le fait de savoir laquelle appliquer : l'alphabet de symboles optimal est une propriété du tokenizer, pas du codec, et chaque nouvelle famille de modèles invalide la réponse. Une bibliothèque figée conserve la décision du jour où elle a été copiée. Les modèles, eux, évoluent sans cesse.Vos fixtures sont synthétiques et c'est vous qui les avez écrites.
Zéro rétention. Comment le vérifier ?
Vous ajoutez un aller-retour réseau pour économiser quelques centimes.
11 / npm et PyPI
Laissez un e-mail. Nous en envoyons un quand la bibliothèque arrive sur npm et PyPI.
Le crate Rust est publié. Un e-mail quand npm et PyPI seront là, rien avant, rien après.