All news
ASCodeworksReleases

SYNX 3.7: SYNXL trae flujos de registros tipados a los conjuntos de datos de IA

by APERTURESyndicate · 1 de agosto de 2026

SYNX 3.7: SYNXL trae flujos de registros tipados a los conjuntos de datos de IA

SYNX 3.7 ya está publicado. Añade un solo operador al lenguaje y, junto a él, todo un formato de archivo nuevo: SYNXL, un formato de flujo de registros para conjuntos de datos, hecho para los dos trabajos a los que se suele forzar a JSONL y CSV y que ambos resuelven mal.

En corto: declara los campos una vez y luego transmite registros tipados. El anidamiento y el texto multilínea vienen incluidos, y las filas mal formadas se reportan en lugar de desaparecer en silencio.

Por qué JSONL y CSV duelen en los conjuntos de datos

Abre cualquier conjunto de entrenamiento en JSONL y mira por qué estás pagando en realidad. Cada registro repite cada clave, cada llave y cada comilla. En un corpus de unos cientos de miles de ejemplos de chat, solo los nombres de los campos son una parte medible de los tokens que le das al modelo, y no aportan ninguna información después de la primera línea.

El texto multilínea es peor. Un prompt, un fragmento de código, la respuesta de un modelo: todo se aplasta en ruido escapado con \n que nadie lee y que cualquier diff estropea.

CSV evita la repetición, pero renuncia a casi todo lo demás: sin tipos, sin anidamiento y con la pregunta sin resolver a la que todo pipeline de CSV llega tarde o temprano: ¿una celda vacía es una cadena vacía o un valor ausente? Añade una coma a un campo y ya estás dentro de reglas de comillas que cambian según el dialecto.

SYNXL en una pantalla

!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 lista de campos se declara una vez. Los registros empiezan en la columna cero, los campos escalares se separan con ; y cualquier campo marcado como [block] se despliega debajo del registro en SYNX completo: listas, objetos anidados, texto multilínea. Eso es lo que permite expresar datos con forma de conversación directamente, en vez de aplanarlos en una cadena escapada.

Ese ejemplo se proyecta a JSON corriente:

[{"id":1,"messages":[{"content":"You are a helpful assistant.","role":"system"},
  {"content":"def f(x):\n    return x + 1","role":"user"}],"score":0.91}, …]

Qué garantiza realmente el formato

  • Los tipos, en su sitio. [type:int], [required], [enum:a|b|c] viven en la cabecera, no en un archivo de esquema aparte, y no se infieren de nuevo en cada fila.

  • Vacío no es nada. Un campo vacío es null; una cadena vacía se escribe "". La ambigüedad del CSV desaparece por construcción.

  • Nada se pierde en silencio. SYNX se salta la estructura mal formada sin decir nada. SYNXL la reporta: campos que faltan, campos de más, conversiones fallidas, claves de bloque desconocidas, cada una con su índice de registro y su número de línea. Un conjunto de datos que pierde una columna sin avisar es peor que uno que falla a gritos.

  • Los registros son independientes. El límite de un registro se decide con un solo byte, así que el formato se puede ampliar sin riesgo, dividir en fragmentos limpios y analizar en paralelo.

  • El esquema evoluciona a mitad de archivo. ¿Has ganado una columna? Escribe una nueva línea !fields y sigue añadiendo. Los registros anteriores siguen siendo válidos y conservan su forma original.

Pensado para archivos que no caben en memoria

El límite de entrada de 16 MiB que SYNX aplica a un documento se aplica por registro en SYNXL: los conjuntos de datos ocupan gigabytes con normalidad y los registros son independientes, así que un límite para el archivo entero no protege nada que no proteja ya el límite por registro.

El lector en flujo mantiene vivo exactamente un registro. Medido con la CLI sobre un archivo de 142 MB con 2,4 millones de registros, la memoria máxima se mantiene plana en unos 10 MB en validate, parse y split: leer ese mismo archivo entero en memoria costaría al menos su propio tamaño.

La otra mitad de 3.7: |+

El lenguaje en sí ganó exactamente una cosa: |+, un abridor multilínea que conserva la sangría. El | normal recorta cada línea de continuación, lo cual está bien para la prosa y es destructivo para todo aquello donde los espacios importan. |+ fija una sangría base en la primera línea con contenido y conserva todo lo que va después, así que el código, los diagramas ASCII y los andamiajes de prompts sobreviven intactos dentro de un valor.

SYNX 3.6 sigue siendo la base congelada de interoperabilidad. La 3.7 es aditiva: un analizador de 3.6 sigue siendo conforme para todo documento que evite construcciones exclusivas de 3.7.

Cómo leerlo desde el código

Hoy SYNXL se distribuye en cuatro implementaciones, con la misma semántica detrás de cada una:

// 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"])

Y desde la terminal, con convertidores en ambos sentidos:

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 own

Disponibilidad

La 3.7.1 está publicada en crates.io, npm, PyPI y NuGet.

SYNXL en sí está implementado en Rust, TypeScript, Python y la CLI. Los analizadores nativos de C++, Dart, .NET, Go, Java y Swift admiten SYNX 3.7, incluido |+, pero todavía no leen .synxl: hasta que lo hagan, convierte con la CLI o léelo desde una de las cuatro implementaciones.

Especificación y conformidad

SYNXL se versiona en su propio eje —versión 1 del formato, independiente de la versión del lenguaje— porque un documento SYNXL no es un documento SYNX: su nivel superior es una secuencia de registros, no un objeto.

El texto normativo es SYNXL-1-NORMATIVE.md, y detrás está un conjunto de 67 casos de conformidad derivados de ese texto con independencia de cualquier implementación. El ejecutor en Rust, además, vuelve a leer cada caso aceptado con sus tres lectores y falla si no coinciden.

Documentación completa y un playground en vivo: synx.aperturesyndicate.com

Qué viene después

Soporte de SYNXL en los analizadores restantes, empezando por Go y .NET. La especificación es estable y la suite de conformidad está escrita, así que la segunda oleada es mecánica y no exploratoria, que es justo el motivo de escribir las pruebas antes que las implementaciones.

Other stories

All stories
SYNX 3.7: SYNXL trae flujos de registros tipados a los conjuntos de datos de IA | APERTURESyndicate