Cada token que envías a una API LLM cuesta dinero. No mucho por token — pero cuando tu prompt incluye un dataset con 50 filas de datos de usuario formateados como JSON, estás pagando por cada llave, cada nombre de clave repetido, cada comilla. En un dataset con 10 campos y 100 filas, JSON quema aproximadamente el 60-70% de sus tokens en ruido estructural. TOON fue construido para solucionar exactamente esto. Este artículo te muestra cómo usar @toon-format/toon para reducir tus recuentos de tokens de prompt — a veces en más de la mitad — sin perder ninguna estructura que el modelo necesita.

Cómo funciona la tarificación de tokens LLM

Los modelos como GPT-4o y Claude cobran por token de entrada y por token de salida. La herramienta OpenAI Tokenizer te permite pegar cualquier texto y ver exactamente cuántos tokens cuesta. En términos generales, 1 token ≈ 4 caracteres de texto en inglés — pero los caracteres estructurales de JSON (comillas, dos puntos, llaves) a menudo se tokenizan individualmente, por lo que los prompts con mucho JSON tokenizan peor que la prosa normal con el mismo recuento de caracteres. Estás pagando un impuesto estructural en cada solicitud.

Para una aplicación SaaS típica que ejecuta miles de solicitudes al día con datos estructurados en cada prompt, ese impuesto se acumula rápidamente. La arquitectura de los grandes modelos de lenguaje significa que el modelo realmente no necesita todo ese ruido de formato — puede leer datos estructurados perfectamente bien sin la verbosidad de JSON, siempre que el formato sea inequívoco y esté bien explicado.

JSON vs TOON — una comparación concreta de tokens

Hagamos esto concreto. Aquí hay un dataset de 10 usuarios en JSON:

json
[
  { "id": 1, "username": "alice_dev", "email": "[email protected]", "plan": "pro", "active": true },
  { "id": 2, "username": "bob_writer", "email": "[email protected]", "plan": "free", "active": true },
  { "id": 3, "username": "carol_ops", "email": "[email protected]", "plan": "pro", "active": false },
  { "id": 4, "username": "dan_qa", "email": "[email protected]", "plan": "team", "active": true },
  { "id": 5, "username": "eve_design", "email": "[email protected]", "plan": "pro", "active": true },
  { "id": 6, "username": "frank_sec", "email": "[email protected]", "plan": "team", "active": true },
  { "id": 7, "username": "grace_ml", "email": "[email protected]", "plan": "pro", "active": false },
  { "id": 8, "username": "henry_be", "email": "[email protected]", "plan": "free", "active": true },
  { "id": 9, "username": "iris_fe", "email": "[email protected]", "plan": "pro", "active": true },
  { "id": 10, "username": "jack_devrel", "email": "[email protected]", "plan": "team", "active": true }
]

Ese bloque JSON se tokeniza a aproximadamente 310-330 tokens. Aquí están exactamente los mismos datos en notación tabular TOON:

text
users[10]{id,username,email,plan,active}:
  1,alice_dev,[email protected],pro,true
  2,bob_writer,[email protected],free,true
  3,carol_ops,[email protected],pro,false
  4,dan_qa,[email protected],team,true
  5,eve_design,[email protected],pro,true
  6,frank_sec,[email protected],team,true
  7,grace_ml,[email protected],pro,false
  8,henry_be,[email protected],free,true
  9,iris_fe,[email protected],pro,true
  10,jack_devrel,[email protected],team,true

La versión TOON se tokeniza a aproximadamente 135-150 tokens — aproximadamente 55% menos. A escala, eso no es un error de redondeo. Si estás ejecutando 10,000 de estas consultas al día a precios de GPT-4o, la diferencia entre JSON y TOON solo en tu prompt es significativa.

El ahorro de tokens escala con filas, no columnas. Cuantas más filas tenga tu dataset, mayor es la ganancia — porque TOON paga el costo del encabezado de columna una sola vez, mientras que JSON paga el costo del nombre de clave en cada fila. Una tabla de 100 filas en TOON ahorra aproximadamente el mismo porcentaje que este ejemplo de 10 filas.

Instalación y conversión de datos en Node.js

Instala el paquete desde npm. Funciona en Node.js 18+ y navegadores modernos:

bash
npm install @toon-format/toon

La importación es una sola desestructuración:

js
import { encode, decode } from '@toon-format/toon';

// Convert a JS array/object to TOON before sending to an LLM
const users = [
  { id: 1, username: 'alice_dev', email: '[email protected]', plan: 'pro', active: true },
  { id: 2, username: 'bob_writer', email: '[email protected]', plan: 'free', active: true },
  // ... more rows
];

const toonData = encode(users, { indent: 2 });
console.log(toonData);
// users[2]{id,username,email,plan,active}:
//   1,alice_dev,[email protected],pro,true
//   2,bob_writer,[email protected],free,true

Patrón práctico: Fetch → Encode → Prompt → Decode

El flujo de trabajo para usar TOON con una API LLM es de cuatro pasos. Obtén tus datos de cualquier fuente (base de datos, API REST, archivo CSV), codifícalos a TOON, construye tu prompt y opcionalmente decodifica cualquier TOON estructurado de la respuesta del modelo.

js
import { encode, decode } from '@toon-format/toon';
import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

async function analyseUsers(users) {
  // Step 1: encode data to TOON
  const toonData = encode(users, { indent: 2 });

  // Step 2: build the prompt
  const systemPrompt = [
    'You analyse user datasets. Data is provided in TOON (Token-Optimised Object Notation).',
    'TOON tabular format: name[count]{col1,col2,...}: followed by comma-separated rows, one per line.',
    'Respond with plain prose unless asked to return data, in which case use TOON format.'
  ].join('\n');

  const userPrompt = `Here is the user dataset:\n\n${toonData}\n\nWhich plan has the most active users?`;

  // Step 3: call the API
  const response = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [
      { role: 'system', content: systemPrompt },
      { role: 'user', content: userPrompt }
    ]
  });

  return response.choices[0].message.content;
}

// Step 4 (optional): if the model returns TOON, decode it back
const rawResponse = await analyseUsers(myUserArray);
try {
  const structured = decode(rawResponse);
  console.log('Structured result:', structured);
} catch {
  console.log('Prose response:', rawResponse);
}

El mismo patrón funciona para la API de Anthropic Claude — solo cambia el cliente. La estructura del prompt y la codificación TOON son idénticas independientemente del proveedor. Puedes consultar los docs de la API de OpenAI para detalles de configuración de autenticación y selección de modelo.

Cuándo importa más

TOON rinde más en estos escenarios:

  • Grandes datasets en contexto. Cada vez que pones más de ~20 filas de datos estructurados en un prompt, la notación tabular TOON te ahorrará tokens significativos sobre arrays JSON de objetos.
  • Consultas estructuradas repetidas. Si tu aplicación hace el mismo tipo de consulta miles de veces al día (piensa: "analiza la actividad de este usuario" con un registro de usuario en cada prompt), el ahorro acumulado es sustancial.
  • Trabajos de procesamiento por lotes. Los scripts que procesan miles de registros a través de un LLM — clasificación, etiquetado, enriquecimiento, resumen — se benefician enormemente. Menos tokens por llamada significa mayor rendimiento y menor costo.
  • Tareas con limitación de ventana de contexto. Cuando intentas meter un dataset grande en una ventana de contexto de 128k junto a un prompt de sistema largo y ejemplos few-shot, cada token cuenta. TOON te permite meter más filas en la misma ventana.
  • APIs de producción sensibles al costo. Los proyectos hobby de nivel gratuito no lo notarán. Las aplicaciones de producción que sirven a usuarios de pago a escala, absolutamente sí.

La advertencia: los LLMs necesitan conocer el formato

TOON no está en los datos de entrenamiento de ningún LLM como lo está JSON. El modelo nunca ha visto un archivo .toon. Esto significa que debes incluir una breve descripción del formato en tu prompt de sistema — de lo contrario, el modelo rechazará la entrada o la analizará incorrectamente. La buena noticia es que la descripción es corta, y solo la pagas una vez por conversación o solicitud.

Una adición mínima al prompt de sistema que funciona de manera confiable:

text
Data is provided in TOON (Token-Optimised Object Notation).
TOON syntax:
- Objects: {key:value,key2:value2} — keys are never quoted
- Arrays: [val1,val2,val3]
- Tabular: name[rowCount]{col1,col2,...}:
    rowval1,rowval2,...
    rowval1,rowval2,...
Parse each row by matching values to the column headers in order.
Strings containing commas are double-quoted.

Ese bloque agrega aproximadamente 60 tokens a tu prompt de sistema — un costo único que se recupera rápidamente en cualquier dataset de más de 5-6 filas. Para aplicaciones que hacen muchas llamadas API con datos TOON, los tokens de descripción del formato se amortizan a casi cero. Usa JSON a TOON para convertir tus datos antes de construir el prompt, y el formateador TOON para verificar que se ve correcto.

Resumen

El argumento para TOON en flujos de trabajo LLM es sencillo: pagas por token, los datos estructurados en JSON son ineficientes en tokens, y TOON es una solución directa. La notación tabular sola reduce el uso de tokens en un 50-60% en datasets típicos basados en filas. El paquete npm — @toon-format/toon — es pequeño, la API es dos funciones, y la integración en una llamada API existente es un trabajo de cinco minutos. Lo único que hay que recordar es la descripción del formato en tu prompt de sistema — sin ella, el modelo está adivinando. Con ella, obtienes un modelo que lee tus datos correctamente a la mitad del costo en tokens. Empieza con JSON a TOON para convertir tus datos existentes, valídalos con el validador TOON, y usa TOON a JSON o decode() para convertir respuestas estructuradas de vuelta cuando sea necesario.