Większość formatów danych była zaprojektowana dla jednej grupy odbiorców: ludzi lub maszyn. JSON skłania się ku ludziom. Formaty binarne jak MessagePack skłaniają się ku maszynom. TOON jest wyraźnie zaprojektowany dla trzeciej grupy odbiorców, która nie istniała, gdy te formaty zostały wynalezione: dużych modeli językowych. Każda decyzja składniowa w TOON priorytetyzuje wydajność tokenów — zmieszczenie maksymalnych danych strukturalnych w minimalnej liczbie tokenów, abyś mógł przekazać więcej kontekstu do AI bez wysadzania budżetu. Ten przewodnik obejmuje każdą cechę składni TOON, od prostych skalarów po notację tabelaryczną, która sprawia, że jest naprawdę inny.

Co sprawia, że TOON jest inny

TOON oznacza Token-Optimised Object Notation. Podstawowa idea jest prosta: formaty serializacji danych takie jak JSON zostały zaprojektowane na długo przed tym, zanim cennik API za token był czymś realnym. JSON nadaje się do komunikacji między maszynami, ale gdy Twój payload to zbiór danych 200 wierszy trafiający do promptu gpt-4o, płacisz za każdy cudzysłów, każdy nawias klamrowy i każdą powtórzoną nazwę klucza. TOON eliminuje to marnotrawstwo. Instaluje się jako pojedynczy pakiet npm — @toon-format/toon — a pliki używają rozszerzenia .toon.

Wartości skalarne — ciągi, liczby, wartości logiczne

Skalary TOON wyglądają bardzo podobnie do ich odpowiedników w JSON, z jedną ważną różnicą: wartości ciągów nie wymagają cudzysłowów, chyba że zawierają znaki specjalne takie jak przecinki, dwukropki lub nawiasy. To samo w sobie usuwa znaczący kawałek tokenów z zestawów danych bogatych w tekst.

text
// Numbers — exactly like JSON
42
3.14
-7

// Booleans — lowercase, same as JSON
true
false

// Strings — no quotes needed for simple values
hello
Alice
Widget Pro

Gdy ciąg zawiera przecinek, dwukropek lub nawias, opakuj go w cudzysłowy podwójne, tak jak w JSON. Więc "New York, NY" wymaga cudzysłowów, ale London nie. Prosta zasada, duże oszczędności.

Obiekty — pary klucz:wartość bez szumu

Obiekty TOON używają nawiasów klamrowych z składnią klucz:wartość. Klucze nigdy nie są cytowane — to samo w sobie oszczędza dwa znaki na klucz w porównaniu z JSON. Pary są oddzielone przecinkami. Bez końcowych przecinków, bez dwukropków po ostatniej parze.

text
{name:Alice,age:31,city:London,active:true}

Porównaj to z odpowiednikiem JSON:

json
{"name": "Alice", "age": 31, "city": "London", "active": true}

Te same dane, mniej znaków, a oszczędności tokenów dramatycznie się mnożą podczas pracy z tablicami obiektów. Mówiąc o tym...

Tablice — uporządkowane listy wartości

Tablice w TOON używają nawiasów kwadratowych z wartościami oddzielonymi przecinkami — dokładnie jak w JSON, tylko bez cudzysłowów przy zwykłych wartościach ciągów.

text
// Array of strings
[Alice,Bob,Carol]

// Array of numbers
[10,20,30,40,50]

// Mixed types (same rules as JSON)
[Widget Pro,29.99,true,101]

// Array of objects
[{id:1,name:Alice},{id:2,name:Bob}]

Tablice obiektów działają, ale właśnie tu pojawia się zabójcza cecha TOON. Jeśli masz więcej niż dwa lub trzy wiersze danych strukturalnych, notacja tabelaryczna jest dramatycznie bardziej wydajna.

Notacja tabelaryczna — funkcja, która zmienia wszystko

Notacja tabelaryczna to główna cecha TOON. Jest zaprojektowana dla scenariusza, który ciągle napotykasz w prawdziwej pracy: lista podobnych obiektów — produkty, użytkownicy, transakcje, wpisy logów — gdzie powtarzanie kluczy w każdym wierszu to czyste marnotrawstwo. Składnia to:

text
name[count]{col1,col2,col3,...}:
  row1val1,row1val2,row1val3
  row2val1,row2val2,row2val3

Rozkładając to: name to etykieta zestawu danych, [count] to liczba wierszy danych (wymagana — informuje parser dokładnie ile linii odczytać), {col1,col2,...} to wiersz nagłówka, dwukropek : kończy nagłówek, a każda kolejna wcięta linia to jeden wiersz wartości. Oto prawdziwy przykład produktów:

text
products[5]{id,name,price,inStock,category}:
  101,Widget Pro,29.99,true,Tools
  102,Gadget Plus,49.99,true,Electronics
  103,Thing Basic,9.99,false,Misc
  104,Super Doohickey,74.99,true,Electronics
  105,Budget Widget,14.99,true,Tools

Teraz wyobraź sobie te same dane jako tablicę obiektów JSON. Musiałbyś napisać "id", "name", "price", "inStock" i "category" pięć razy każdy — plus wszystkie otaczające nawiasy, klamry i cudzysłowy. Tabelaryczna reprezentacja TOON jest mniej więcej o 60% mniejsza w liczbie tokenów dla tego kształtu danych.

Zbiór danych użytkowników podąża tym samym wzorcem:

text
users[4]{id,username,email,role,active}:
  1,alice_dev,[email protected],admin,true
  2,bob_writer,[email protected],editor,true
  3,carol_ops,[email protected],viewer,false
  4,dan_qa,[email protected],editor,true
Liczba jest obowiązkowa. W przeciwieństwie do CSV z nagłówkiem kolumn, gdzie po prostu liczymy nowe linie, [count] TOON jest częścią składni i musi pasować do rzeczywistej liczby wierszy danych. Parser używa jej, aby wiedzieć, kiedy kończy się tabela — szczególnie przydatne gdy TOON jest osadzony wewnątrz większej struktury. Użyj Walidatora TOON, aby natychmiast wychwycić niezgodności liczby.

Zagnieżdżanie — obiekty, tablice i tabelaryczne razem

TOON obsługuje zagnieżdżanie w miejscach, których się spodziewasz. Obiekt może zawierać wartość tablicy. Wiersz tabelaryczny może zawierać obiekt. Pozwala to reprezentować dane rzeczywiste, które nie pasują idealnie do płaskich wierszy.

Obiekt zawierający tablicę:

text
{name:Alice,roles:[admin,editor],active:true}

Dane tabelaryczne z osadzonym obiektem w jednej kolumnie (przydatne dla danych adresowych, metadanych itp.):

text
orders[3]{orderId,customer,total,address}:
  1001,alice_dev,89.97,{city:London,country:UK}
  1002,bob_writer,49.99,{city:Berlin,country:DE}
  1003,carol_ops,124.50,{city:Paris,country:FR}

Utrzymuj zagnieżdżanie płytkie, gdy to możliwe. Dwa lub trzy poziomy głębokości to punkt, w którym TOON nadal wygrywa pod względem liczby tokenów. Głęboko rekurencyjne struktury są lepiej obsługiwane przez JSON, który ma bogatsze narzędzia do walidacji schematów — sprawdź referencję MDN JSON jeśli tego potrzebujesz.

Praca z pakietem npm

Zainstaluj przez npm lub dowolny kompatybilny menedżer pakietów. TOON działa w Node.js i nowoczesnych przeglądarkach.

bash
npm install @toon-format/toon

Pakiet eksportuje dwie funkcje: encode i decode. To całe publiczne API — celowo minimalne.

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

// decode: TOON string → JS value
const toonString = `products[3]{id,name,price,inStock}:
  101,Widget Pro,29.99,true
  102,Gadget Plus,49.99,true
  103,Thing Basic,9.99,false`;

const data = decode(toonString);
console.log(data);
// [
//   { id: 101, name: "Widget Pro", price: 29.99, inStock: true },
//   { id: 102, name: "Gadget Plus", price: 49.99, inStock: true },
//   { id: 103, name: "Thing Basic", price: 9.99, inStock: false }
// ]

// encode: JS value → TOON string
const users = [
  { id: 1, username: 'alice_dev', active: true },
  { id: 2, username: 'bob_writer', active: false }
];

const toon = encode(users, { indent: 2 });
console.log(toon);
// users[2]{id,username,active}:
//   1,alice_dev,true
//   2,bob_writer,false

Opcja { indent: 2 } kontroluje wcięcia wartości wierszy. Możesz również używać encode na zwykłych obiektach i wartościach prymitywnych, nie tylko tablicach — automatycznie wybiera najbardziej kompaktową reprezentację TOON. Wklej wynik do Formattera TOON, aby go sprawdzić i ładnie wydrukować.

Typowe błędy

To są błędy, które gryzą programistów nowych w TOON, zwykle w ciągu pierwszej godziny:

  • Zła liczba wierszy w notacji tabelarycznej. Napisanie products[3], ale uwzględnienie 4 wierszy danych spowoduje błąd parsowania lub ciche pominięcie ostatniego wiersza w zależności od wersji parsera. Policz swoje wiersze i aktualizuj liczbę. Walidator TOON natychmiast to wykrywa.
  • Cytowanie kluczy obiektów. {"name":Alice} to nieprawidłowy TOON — klucze nigdy nie są cytowane. Usuń cudzysłowy: {name:Alice}.
  • Zapomnienie dwukropka po nagłówku. products[2]{id,name} po którym następuje nowa linia zakończy się niepowodzeniem. Potrzebujesz końcowego dwukropka: products[2]{id,name}:.
  • Używanie spacji wokół dwukropka w parach klucz:wartość. {name : Alice} jest nieprawidłowe. Bez spacji: {name:Alice}.
  • Osadzanie przecinków w wartościach ciągów bez cudzysłowów. Jeśli nazwa produktu to "Bolts, Nuts & More", musisz ją cytować w wierszach tabelarycznych: 101,"Bolts, Nuts & More",4.99,true.
  • Oczekiwanie wyjścia JSON z decode na skalarach. decode("42") zwraca JavaScript number 42, nie obiekt JSON. TOON dekoduje do natywnych typów JS.

Konwersja między TOON a JSON

TOON i JSON są w pełni wzajemnie konwertowalne — TOON jest nadzbiorem tego samego logicznego modelu danych, który serializuje JSON. Użyj JSON do TOON, aby skurczyć istniejący zbiór danych przed wysłaniem go do LLM, i TOON do JSON, aby przekonwertować z powrotem, gdy musisz podać wynik do systemu downstream tylko JSON. Funkcje encode i decode obsługują to programatycznie, jeśli automatyzujesz przepływ pracy w Node.js. Specyfikacja podstawowej struktury danych jest ściśle powiązana z konceptami z globalnego JSON w JavaScript.

Podsumowanie

Składnia TOON jest celowo kompaktowa. Brak cytowanych kluczy, brak powtarzanych nazw kluczy w tabelach, brak obowiązkowych cudzysłowów przy prostych wartościach ciągów. Gdy już raz ręcznie napiszesz blok tabelaryczny, natychmiast zobaczysz dlaczego — zbiór danych zajmujący 40 linii JSON mieści się w 8 liniach TOON. Pakiet npm na npmjs.com/@toon-format/toon utrzymuje powierzchnię API małą: encode i decode, nic więcej do nauczenia się. Użyj Formattera TOON do ładnego wydruku, Walidatora TOON do wykrywania błędów składniowych, JSON do TOON do konwersji istniejących danych, i TOON do JSON, gdy potrzebujesz wynik z powrotem w standardowej formie.