ほとんどのデータ形式は1つのオーディエンス向けに設計されました:人間またはマシン。JSONは人間寄りです。MessagePackのようなバイナリ形式はマシン寄りです。TOONはそれらの形式が発明されたときには存在しなかった第3のオーディエンスのために明示的に設計されています:大規模言語モデル。TOONのすべての構文決定はトークン効率を優先します — 最小限のトークンに最大の構造化データを詰め込んで、予算を超えることなくAIにより多くのコンテキストを渡せるようにします。このガイドはシンプルなスカラーから本当に差別化される表形式表記まで、すべてのTOON構文機能をカバーします。

TOONが異なる理由

TOONはToken-Optimised Object Notationの略です。核となるアイデアはシンプルです:データシリアライゼーション形式のようなJSONは、トークン単位のAPI料金が現実になるずっと前に設計されました。JSONはマシン間通信には問題ありませんが、ペイロードがgpt-4oプロンプトに入る200行のデータセットの場合、すべての引用符、すべての波括弧、すべての繰り返しキー名に対して支払っています。TOONはその無駄を排除します。単一のnpmパッケージとしてインストールされます —@toon-format/toon— そしてファイルは.toon拡張子を使用します。

スカラー値 — 文字列、数値、ブール値

TOONのスカラーはJSON対応物に非常に似ていますが、1つの重要な違いがあります:文字列値はカンマ、コロン、角括弧などの特殊文字を含まない限り引用符が不要です。これだけで、テキストの多いデータセットから意味のある量のトークンが削減されます。

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

文字列にカンマ、コロン、角括弧が含まれる場合は、JSONと同様にダブルクォートで囲みます。なので"New York, NY"は引用符が必要ですが、Londonは不要です。シンプルなルール、大きな節約。

オブジェクト — ノイズのないキー:値ペア

TOONオブジェクトはkey:value構文を使った波括弧を使用します。キーは決して引用符で囲まれません— それだけでJSONと比較してキーあたり2文字節約できます。ペアはカンマで区切られます。末尾のカンマなし、最後のペアの後にコロンなし。

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

同等のJSONと比較してください:

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

同じデータ、少ない文字、そしてオブジェクトの配列を扱うときにトークン節約が劇的に複合されます。その話をすると...

配列 — 順序付きの値のリスト

TOONの配列はカンマ区切り値の角括弧を使用します — JSONとまったく同じですが、ベアの文字列値には引用符がありません。

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}]

オブジェクトの配列は機能しますが、ここでTOONの必殺機能が登場します。構造化データが2、3行以上ある場合、表形式表記の方が劇的に効率的です。

表形式表記 — すべてを変える機能

表形式表記はTOONの目玉機能です。実際の作業で常に遭遇するシナリオのために設計されています:類似したオブジェクトのリスト — 製品、ユーザー、トランザクション、ログエントリ — 各行でキーを繰り返すことが純粋な無駄である場合。構文は:

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

分解すると:nameはデータセットのラベル、[count]はデータ行の数(必須 — パーサーに読む行数を正確に伝えます)、{col1,col2,...}はヘッダー行、コロン:がヘッダーを終了し、各後続のインデントされた行が1行の値です。実際の製品例:

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

そのデータをJSONオブジェクトの配列として想像してください。"id""name""price""inStock""category"を5回ずつ書くことになります — 加えてすべての波括弧、角括弧、引用符。表形式TOONの表現はこの形状のデータのトークン数で約60%小さいです。

ユーザーデータセットも同じパターンに従います:

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
カウントは必須です。改行を数えるだけの列ヘッダーCSVとは異なり、TOONの[count]は構文の一部であり、実際のデータ行数と一致しなければなりません。パーサーはこれを使ってテーブルがどこで終わるかを知ります — 特にTOONがより大きな構造内に埋め込まれている場合に便利です。TOONバリデーターを使ってカウントの不一致を即座にキャッチしてください。

ネスト — オブジェクト、配列、表形式の組み合わせ

TOONは期待通りの場所でネストをサポートします。オブジェクトは配列値を含むことができます。表形式行にはオブジェクトを含むことができます。これにより、フラットな行に完全に収まらない現実世界のデータを表現できます。

配列を含むオブジェクト:

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

1つの列にオブジェクトが埋め込まれた表形式データ(住所データ、メタデータなどに便利):

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}

可能な限りネストを浅く保ちましょう。2〜3レベルの深さまでがTOONがトークン数でまだ勝てる範囲です。深い再帰的な構造はスキーマ検証のためのより豊富なツールを持つJSONの方が適しています — それが必要な場合はMDN JSONリファレンスを参照してください。

npmパッケージでの作業

npmまたは互換パッケージマネージャーでインストールします。TOONはNode.jsとモダンブラウザで動作します。

bash
npm install @toon-format/toon

パッケージは2つの関数をエクスポートします:encodedecode。それが全体の公開API — 意図的に最小限です。

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

{ indent: 2 }オプションは行値のインデントを制御します。配列だけでなくプレーンオブジェクトやプリミティブ値にもencodeを使用できます —最もコンパクトなTOON表現を自動的に選択します。出力をTOONフォーマッターに貼り付けて検査してきれいに表示してください。

よくある間違い

これらはTOONに慣れていない開発者が、通常最初の1時間以内に遭遇するエラーです:

  • 表形式表記での間違った行カウント。products[3]と書いてから4行のデータを含めると、パーサーのバージョンによっては解析エラーが発生するか最後の行がサイレントに削除されます。行を数えて番号を最新に保ちましょう。TOONバリデーターはこれを即座に検出します。
  • オブジェクトキーを引用符で囲む。{"name":Alice}は無効なTOONです — キーは決して引用符で囲まれません。引用符を削除してください:{name:Alice}
  • ヘッダーの後のコロンを忘れる。products[2]{id,name}の後に改行があると失敗します。末尾のコロンが必要です:products[2]{id,name}:
  • キー:値ペアのコロンの周りにスペースを使用する。{name : Alice}は無効です。スペースなし:{name:Alice}
  • 引用符のない文字列値にカンマを埋め込む。製品名が"Bolts, Nuts & More"の場合、表形式行で引用符で囲む必要があります:101,"Bolts, Nuts & More",4.99,true
  • スカラーのdecodeからJSON出力を期待する。decode("42")はJSONオブジェクトではなく、JavaScriptの数値42を返します。TOONはネイティブJSタイプにデコードします。

TOONとJSONの間の変換

TOONとJSONは完全に相互変換可能です — TOONはJSONがシリアライズする同じ論理データモデルのスーパーセットです。JSON to TOONを使ってLLMに送信する前に既存のデータセットを縮小し、JSONのみの下流システムに結果を供給する必要があるときはTOON to JSONで変換して戻します。encodedecode関数はNode.jsでワークフローを自動化している場合にこれをプログラム的に処理します。基礎となるデータ構造仕様はJavaScriptのJSONグローバルの概念と密接に関連しています。

まとめ

TOON構文は意図的にコンパクトです。キーに引用符なし、テーブルでキー名の繰り返しなし、シンプルな文字列値に義務的な引用符なし。手でテーブルブロックを一度書いたら、すぐにわかるでしょう —JSONで40行かかるデータセットがTOONの8行に収まります。npmjs.com/@toon-format/toonのnpmパッケージはAPIサーフェスを小さく保ちます:encodedecode、他に学ぶことはありません。TOONフォーマッターできれいに表示し、TOONバリデーターで構文エラーをキャッチし、JSON to TOONで既存データを変換し、TOON to JSONで結果を標準形式に戻してください。