SYNX 3.7 : SYNXL apporte des flux d’enregistrements typés aux jeux de données d’IA
by APERTURESyndicate · 1 août 2026
SYNX 3.7 est disponible. La version ajoute un seul opérateur au langage et, à côté, un tout nouveau format de fichier : SYNXL — un format de flux d’enregistrements pour les jeux de données, conçu pour les deux usages auxquels on plie habituellement JSONL et CSV, et qu’ils gèrent mal.
En bref : déclarez vos champs une fois, puis diffusez des enregistrements typés. L’imbrication et le texte multiligne suivent, et les lignes mal formées sont signalées au lieu de disparaître discrètement.
Pourquoi JSONL et CSV font mal sur les jeux de données
Ouvrez n’importe quel jeu d’entraînement en JSONL et regardez ce que vous payez réellement. Chaque enregistrement répète chaque clé, chaque accolade, chaque guillemet. Sur un corpus de quelques centaines de milliers d’exemples de conversation, les seuls noms de champs représentent une part mesurable des tokens envoyés au modèle — et ils n’apportent plus rien après la première ligne.
Le texte multiligne, c’est pire. Un prompt, un extrait de code, une réponse de modèle : tout s’effondre en bruit échappé par \n, que personne ne lit et que chaque diff abîme.
CSV évite la répétition mais abandonne presque tout le reste : pas de types, pas d’imbrication, et cette question jamais tranchée que rencontre tôt ou tard toute chaîne CSV — une cellule vide, est-ce une chaîne vide ou une valeur absente ? Ajoutez une virgule dans un champ et vous voilà dans des règles de guillemets qui diffèrent d’un dialecte à l’autre.
SYNXL en un écran
!synxl 1
!fields id[type:int] ; score[type:float] ; messages[block]
1 ; 0.91
messages
- role system
content You are a helpful assistant.
- role user
content |+
def f(x):
return x + 1
2 ; 0.74
messages
- role user
content ПриветLa liste des champs est déclarée une fois. Les enregistrements commencent en colonne zéro, les champs scalaires sont séparés par ;, et tout champ marqué [block] s’ouvre sous l’enregistrement en SYNX complet : listes, objets imbriqués, texte multiligne. C’est ce qui permet d’exprimer directement des données en forme de conversation au lieu de les aplatir en chaîne échappée.
Cet exemple se projette en JSON ordinaire :
[{"id":1,"messages":[{"content":"You are a helpful assistant.","role":"system"},
{"content":"def f(x):\n return x + 1","role":"user"}],"score":0.91}, …]Ce que le format garantit réellement
Les types là où ils doivent être.
[type:int],[required],[enum:a|b|c]vivent dans l’en-tête, pas dans un fichier de schéma annexe, et ne sont pas ré-inférés à chaque ligne.Vide n’est pas rien. Un champ vide vaut
null; une chaîne vide s’écrit"". L’ambiguïté de CSV disparaît par construction.Aucune perte silencieuse. SYNX ignore discrètement une structure mal formée. SYNXL la signale — champs manquants, champs en trop, conversions échouées, clés de bloc inconnues — chacun avec un index d’enregistrement et un numéro de ligne. Un jeu de données qui perd une colonne sans le dire est pire qu’un jeu de données qui échoue bruyamment.
Les enregistrements sont indépendants. Une frontière d’enregistrement se décide sur un seul octet : le format s’ajoute sans risque, se découpe proprement et s’analyse en parallèle.
Le schéma peut évoluer en cours de fichier. Une colonne en plus ? Écrivez une nouvelle ligne
!fieldset continuez à ajouter. Les enregistrements précédents restent valides et gardent leur forme d’origine.
Conçu pour les fichiers qui ne tiennent pas en mémoire
La limite d’entrée de 16 Mio que SYNX applique à un document s’applique par enregistrement dans SYNXL : les jeux de données pèsent couramment des gigaoctets et les enregistrements sont indépendants, donc une limite sur le fichier entier ne protège rien de plus qu’une limite par enregistrement.
Le lecteur en flux ne garde qu’un seul enregistrement vivant. Mesuré avec la CLI sur un fichier de 142 Mo contenant 2,4 millions d’enregistrements, la mémoire de pointe reste plate, autour de 10 Mo, pour validate, parse et split — lire le même fichier entièrement en mémoire coûterait au moins sa propre taille.
L’autre moitié de 3.7 : |+
Le langage lui-même a gagné exactement une chose : |+, un ouvreur multiligne qui préserve l’indentation. Le | simple rogne chaque ligne de continuation, ce qui convient à la prose et détruit tout ce où les espaces comptent. |+ fixe une indentation de base sur la première ligne de contenu et conserve tout ce qui suit — code, schémas ASCII et gabarits de prompts survivent intacts à l’intérieur d’une valeur.
SYNX 3.6 reste la base d’interopérabilité gelée. La 3.7 est additive : un analyseur 3.6 demeure conforme pour tout document qui évite les constructions propres à la 3.7.
Le lire depuis du code
SYNXL existe aujourd’hui en quatre implémentations, avec la même sémantique derrière chacune :
// Rust
let doc = synx_core::synxl::parse_lines(&text)?;
for record in &doc.records { /* … */ }
// TypeScript
import { parseSynxl, streamSynxlFile } from '@aperturesyndicate/synx-format'
for (const record of streamSynxlFile('dataset.synxl')) { /* … */ }
# Python
import synx_native as synx
for record in synx.synxl_stream_file("dataset.synxl"):
train(record["messages"])Et depuis le terminal, avec des convertisseurs dans les deux sens :
synx synxl parse dataset.synxl --format ndjson
synx synxl validate dataset.synxl --constraints
synx synxl convert corpus.jsonl # jsonl → synxl
synx synxl split dataset.synxl -n 500000 # shards that are valid on their ownDisponibilité
La 3.7.1 est publiée sur crates.io, npm, PyPI et NuGet.
SYNXL lui-même est implémenté en Rust, TypeScript, Python et dans la CLI. Les analyseurs natifs C++, Dart, .NET, Go, Java et Swift prennent en charge SYNX 3.7, y compris |+, mais ne lisent pas encore .synxl — en attendant, convertissez avec la CLI ou lisez le fichier depuis l’une des quatre implémentations.
Spécification et conformité
SYNXL est versionné sur son propre axe — version 1 du format, indépendante de la version du langage — car un document SYNXL n’est pas un document SYNX : son niveau supérieur est une suite d’enregistrements et non un objet.
Le texte normatif est SYNXL-1-NORMATIVE.md, et le contrat derrière lui est une suite de 67 cas de conformité dérivés de ce texte indépendamment de toute implémentation. Le runner Rust relit en outre chaque cas accepté avec ses trois lecteurs et échoue s’ils divergent.
Documentation complète et bac à sable en ligne : synx.aperturesyndicate.com
La suite
La prise en charge de SYNXL dans les analyseurs restants, à commencer par Go et .NET. La spécification est stable et la suite de conformité est écrite : la deuxième vague relève de la mécanique et non de l’exploration — c’est précisément l’intérêt d’écrire les tests avant les implémentations.



