Ogni token che invii a un'API LLM costa denaro. Non molto per token — ma quando il tuo prompt include un dataset con 50 righe di dati utente formattati come JSON, stai pagando per ogni parentesi graffa, ogni nome di chiave ripetuto, ogni virgoletta. Su un dataset con 10 campi e 100 righe, JSON brucia circa il 60–70% dei suoi token nel rumore strutturale. TOON è stato costruito per risolvere esattamente questo. Questo articolo mostra come usare @toon-format/toon per ridurre i conteggi di token dei prompt — a volte di più della metà — senza perdere alcuna struttura di cui il modello ha bisogno.

Come funziona la tariffazione dei token LLM

Modelli come GPT-4o e Claude addebitano per token di input e per token di output. Lo strumento OpenAI Tokenizer ti permette di incollare qualsiasi testo e vedere esattamente quanti token costa. In linea di massima, 1 token ≈ 4 caratteri di testo in inglese — ma i caratteri strutturali di JSON (virgolette, due punti, parentesi graffe) vengono spesso tokenizzati individualmente, quindi i prompt pesanti di JSON tokenizzano peggio di prosa semplice alla stessa lunghezza di caratteri. Stai pagando una tassa strutturale su ogni richiesta.

Per una tipica app SaaS che esegue migliaia di richieste al giorno con dati strutturati in ogni prompt, quella tassa si accumula rapidamente. L' architettura dei modelli linguistici di grandi dimensioni significa che il modello non ha genuinamente bisogno di tutto quel rumore di formattazione — può leggere dati strutturati benissimo senza la verbosità di JSON, purché il formato sia non ambiguo e ben spiegato.

JSON vs TOON — Un confronto concreto dei token

Rendiamo questo concreto. Ecco un dataset di utenti di 10 righe in 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 }
]

Quel blocco JSON tokenizza a circa 310–330 token. Ecco gli stessi identici dati in notazione tabulare 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 versione TOON tokenizza a circa 135–150 token — circa il 55% in meno. Su larga scala, questo non è un errore di arrotondamento. Se esegui 10.000 query del genere al giorno al prezzo GPT-4o, la differenza tra JSON e TOON solo nel tuo prompt è sostanziale.

Il risparmio di token scala con le righe, non con le colonne. Più righe ha il tuo dataset, maggiore è il vantaggio — perché TOON paga il costo dell'intestazione di colonna una volta, mentre JSON paga il costo del nome-chiave su ogni singola riga. Una tabella di 100 righe in TOON risparmia circa la stessa percentuale di questo esempio di 10 righe.

Installazione e conversione dei dati in Node.js

Installa il pacchetto da npm. Funziona in Node.js 18+ e nei browser moderni:

bash
npm install @toon-format/toon

L'import è una singola destrutturazione:

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

Pattern pratico: Fetch → Encode → Prompt → Decode

Il flusso di lavoro per usare TOON con un'API LLM è di quattro passi. Recupera i tuoi dati da qualsiasi sorgente (database, API REST, file CSV), codificali in TOON, costruisci il prompt e decodifica facoltativamente qualsiasi TOON strutturato dalla risposta del modello.

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);
}

Lo stesso pattern funziona per l' API Anthropic Claude — basta sostituire il client. La struttura del prompt e la codifica TOON sono identiche indipendentemente dal provider. Puoi consultare la documentazione completa dell'API OpenAI per i dettagli sulla configurazione dell'autenticazione e la selezione del modello.

Quando è più importante

TOON paga di più in questi scenari:

  • Dataset grandi nel contesto. Ogni volta che inserisci più di circa 20 righe di dati strutturati in un prompt, la notazione tabulare TOON ti farà risparmiare token significativi rispetto agli array JSON di oggetti.
  • Query strutturate ripetute. Se la tua applicazione esegue lo stesso tipo di query migliaia di volte al giorno (pensa: "analizza l'attività di questo utente" con un record utente in ogni prompt), il risparmio cumulativo è sostanziale.
  • Lavori di elaborazione batch. Script che elaborano migliaia di record attraverso un LLM — classificazione, tagging, arricchimento, sintesi — beneficiano enormemente. Meno token per chiamata significa throughput più veloce e costo inferiore.
  • Attività limitate dalla finestra di contesto. Quando stai cercando di inserire un dataset di grandi dimensioni in una finestra di contesto di 128k insieme a un lungo prompt di sistema ed esempi few-shot, ogni token conta. TOON ti permette di inserire più righe nella stessa finestra.
  • API di produzione cost-sensitive. I progetti hobbistici in tier gratuiti non lo noteranno. Le app di produzione che servono utenti paganti su larga scala assolutamente sì.

L'unica avvertenza: gli LLM devono conoscere il formato

TOON non è nei dati di training di nessun LLM nel modo in cui lo è JSON. Il modello non ha mai visto un file .toon. Questo significa che devi includere una breve descrizione del formato nel tuo prompt di sistema — altrimenti il modello rifiuterà l'input o lo analizzerà in modo errato. La buona notizia è che la descrizione è breve, e la paghi una sola volta per conversazione o richiesta.

Un'aggiunta minimale al prompt di sistema che funziona in modo affidabile:

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.

Quel blocco aggiunge circa 60 token al tuo prompt di sistema — un costo una tantum che viene rapidamente recuperato su qualsiasi dataset più grande di 5–6 righe. Per le applicazioni che effettuano molte chiamate API con dati TOON, i token della descrizione del formato vengono ammortizzati quasi a zero. Usa da JSON a TOON per convertire i dati prima di costruire il prompt, e Formattatore TOON per verificare che abbia l'aspetto corretto.

Conclusioni

Il caso per TOON nei flussi di lavoro LLM è semplice: stai pagando per token, i dati strutturati in JSON sono inefficienti in termini di token, e TOON è una soluzione diretta. La notazione tabulare da sola riduce l'utilizzo di token del 50–60% su dataset tipici basati su righe. Il pacchetto npm — @toon-format/toon — è piccolo, l'API è due funzioni, e l'integrazione in una chiamata API esistente è un lavoro da cinque minuti. L'unica cosa da ricordare è la descrizione del formato nel tuo prompt di sistema — senza di essa, il modello sta indovinando. Con essa, ottieni un modello che legge i tuoi dati correttamente alla metà del costo dei token. Inizia con da JSON a TOON per convertire i dati esistenti, validali con il Validatore TOON, e usa da TOON a JSON o decode() per convertire le risposte strutturate quando necessario.