ほとんどの開発者は、データ形式について短いメンタルリストを持っています:APIにはJSON、スプレッドシートにはCSV、 設定ファイルにはYAML、レガシーシステムを扱う場合はXMLかもしれません。しかし、AIツールの分野で静かに広まりつつある新しい形式があり、知っておく価値があります — TOON、 つまりToken-Oriented Object Notationです。これは特定の問題を解決するために一から設計されました:トークン予算を使い果たすことなく、 大規模言語モデルに構造化データを渡すという問題です。

TOONとは何か?

TOONはToken-Oriented Object Notationの略です。これはコンパクトな データシリアライゼーション形式で、 構造化データがLLMプロンプトや応答に埋め込まれる際に消費されるトークン数を最小化するために特別に設計されています。 JSONから冗長性をすべて取り除いたものと考えてください — 配列内での繰り返しのキー名なし、 冗長な引用符なし、末尾の空白なし — 構文ノイズを最小限に抑えた純粋なシグナルだけです。

npmパッケージは@toon-format/toonで、 どんなNode.jsプロジェクトやモダンバンドラーでも動作する シンプルなencode / decode APIを提供します。 TOONファイルは.toon拡張子を使用します。

なぜJSONを使わないのか?

JSONは、帯域幅が安価でランタイムが解析を処理する 機械間通信には優れています。しかし、OpenAI APIAnthropic APIへのプロンプトの一部として データを送信する場合、すべての文字が文字通り重要です。どちらのAPIもトークン単位で課金し、トークンは英語テキストの約4文字に対応します。

100件のユーザーレコードのテーブルを考えてみましょう。JSONでは、キー — "id""name""role""email" — をレコードごとに繰り返します。これは同じ構造情報の100コピーです。 TOONの表形式構文はそれらのキーを一度定義し、CSVと同様に値を行ごとにリストしますが、 オブジェクト構造は保持されます。実際のデータセットでのトークン節約は、コンパクトなJSONと比較して40〜70%になる場合があります。

経験則:プロンプトに数件以上のレコードを埋め込む場合、 TOONはほぼ常にJSONより安価です。JSON to TOONコンバーターを使って ペイロードがどれだけ小さくなるかを正確に確認してください。

TOON構文の概要

TOONは4つのコアデータ形状をサポートします:スカラー(文字列、数値、ブール値)、配列、オブジェクト、 および表形式データです。スカラーとコレクションの構文はJSONを使ったことがあれば見慣れたものです — 表形式 形式こそがTOONが本当に差別化される部分です。

シンプルなオブジェクトは外部の波括弧の空白を省略し、不要な引用符を省き、 キーと値のペアをカンマで区切ります:

text
{name:Alice,age:30,role:admin}

スカラーのシンプルな配列は期待通りの見た目です:

text
[1,2,3]

ここから面白くなります — 表形式データです。これはTOONをLLMのユースケースで魅力的にする構文です。 配列内の各オブジェクトにキーを繰り返す代わりに、ヘッダーでスキーマを一度宣言し、値を行ごとにリストします:

text
users[3]{id,name,role}:
  1,Alice,admin
  2,Bob,user
  3,Charlie,editor

このブロックは3つのユーザーオブジェクトの配列を表します — 以下のJSONと同等ですが、トークン数の何分の一かです。 ヘッダーusers[3]{id,name,role}はパーサーに伝えます:「これはusersという名前の変数で、3行あり、 各行はフィールドid、name、roleにマッピングされる」。行は純粋な値で、キーの繰り返しはありません。

json
[
  { "id": 1, "name": "Alice", "role": "admin" },
  { "id": 2, "name": "Bob",   "role": "user"  },
  { "id": 3, "name": "Charlie", "role": "editor" }
]

@toon-format/toonパッケージのインストールと使用

公式npmパッケージは、JavaScriptの値をTOON文字列にエンコードし、TOON文字列をJavaScriptオブジェクトと配列にデコードする 両方を処理します。npmレジストリから インストールしてください:

bash
npm install @toon-format/toon

パッケージは2つの関数をエクスポートします — encodedecode

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

// Decode a TOON string → JavaScript value
const toonString = `users[3]{id,name,role}:
  1,Alice,admin
  2,Bob,user
  3,Charlie,editor`;

const users = decode(toonString);
console.log(users[0].name); // "Alice"
console.log(users[1].role); // "user"

// Encode a JavaScript value → TOON string
const config = {
  model: 'gpt-4o',
  temperature: 0.7,
  maxTokens: 1024,
  stream: true
};

const toon = encode(config, { indent: 2 });
console.log(toon);
// {model:gpt-4o,temperature:0.7,maxTokens:1024,stream:true}

encode()indentオプションは、出力をきれいに表示するかどうかを制御します。 LLMプロンプトでは通常、トークンを節約するためにコンパクトな出力(インデントなし)が必要です。デバッグや人間が読みやすい .toonファイルには、{ indent: 2 }が適切にフォーマットされた出力を提供します。

実世界のユースケース:LLMへのレコード送信

ユーザーアクティビティを要約する必要がある製品分析機能を構築していると想像してください。データベースから最近の セッションレコードを取得し、自然言語での要約のためにLLMに送信したいとします。TOONを使うとこのようになります:

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

const sessions = [
  { userId: 101, action: 'login',        duration: 0,   page: '/dashboard' },
  { userId: 101, action: 'view_report',  duration: 142, page: '/reports/q1' },
  { userId: 101, action: 'export_csv',   duration: 8,   page: '/reports/q1' },
  { userId: 102, action: 'login',        duration: 0,   page: '/dashboard' },
  { userId: 102, action: 'edit_profile', duration: 37,  page: '/settings'  }
];

const toonPayload = encode(sessions);
// sessions[5]{userId,action,duration,page}:
//   101,login,0,/dashboard
//   101,view_report,142,/reports/q1
//   101,export_csv,8,/reports/q1
//   102,login,0,/dashboard
//   102,edit_profile,37,/settings

const prompt = `Summarise the following user activity. Data is in TOON format.\n\n${toonPayload}`;

5つのセッションレコードのTOON表現は、"userId""action""duration""page"をそれぞれ5回繰り返す同等のJSONよりも大幅に短いです。数百のレコードにわたる節約は 相当なものになり、低いAPIコストと速い応答時間(アテンションウィンドウで処理するトークンが少ない)に直接変換されます。

TOONの主要データ型

TOONはJavaScriptや他のほとんどの言語で既に使用しているプリミティブにきれいにマッピングされます:

  • 文字列 — 特殊文字を含まない場合は引用符なし。カンマ、コロン、空白が含まれる場合はダブルクォートで囲む。
  • 数値 — 整数と浮動小数点数はそのまま記述:423.14-7
  • ブール値 — JSONと同様にtruefalse
  • Null — 存在しないまたは未定義の値にはnullと記述。
  • 配列 — 短いリストにはインラインの角括弧構文[val1,val2,val3];オブジェクトの配列には表形式ヘッダー構文。
  • オブジェクト — 単一オブジェクトには波括弧構文{key:value,key2:value2}
  • 表形式データ — 主役:name[n]{col1,col2,...}:ヘッダーの後にカンマ区切りの行 — 同じ形状のレコードのコレクションに最適。

TOONと他の形式の使い分け

TOONは汎用インターチェンジ形式としてJSONを置き換えようとしているのではありません。特定のニッチを埋めます。 簡単な意思決定ガイドを以下に示します:

  • JSONを使用するのは、REST APIを構築したり、データベースにドキュメントを保存したり、サービス間でデータを渡す場合です。JSONは普遍的にサポートされており、ツールが充実しており、人間が読めます。
  • TOONを使用するのは、構造化データがプロンプトやLLMコンテキストウィンドウの一部であり、トークン数が重要な場合です。表形式形式は、行のレコードを扱う場合に輝きます — ユーザーリスト、ログエントリ、製品カタログ、分析イベント。
  • CSVを使用するのは、フラットな表形式データのみが必要で、コンシューマーがCSVを期待する場合(スプレッドシート、BIツール)です。CSVにはオブジェクトのネストがないため、TOONの方が表現力があります。
  • YAMLを使用するのは、コンパクトさよりも読みやすさとコメントが重要な人間が編集する設定ファイルに対してです。
  • LLMツールの出力にもTOONを使用する:LLMがあなたのツールを呼び出して構造化された結果を返す場合、それらの結果をTOONでエンコードすることでAPIコールの入出力両側でトークンを節約できます。
TOONが現在のJSONペイロードと比較してどうかわからない?JSON to TOONコンバーターにJSONを入れると、 ツールが両方の表現を並べて表示し、推定トークン数の比較も示します。

まとめ

TOON — Token-Oriented Object Notation — はLLM時代のために構築されたコンパクトなシリアライゼーション形式です。 JSONの慣れ親しんだ構造(オブジェクト、配列、スカラー)を維持しながら、レコード間で冗長なキーの繰り返しを 排除する表形式構文を導入します。結果として得られる形式は同等のJSONより40〜70%小さくなり、 OpenAI APIAnthropic API、 またはその他のトークン課金LLMサービスを使用する際のトークンコストの削減に直接つながります。

TOONを実際に試したい場合は、こちらに完全なツールスイートがあります: TOONフォーマッターを使ってTOONドキュメントをきれいに表示・検査し、 TOONバリデーターで構文エラーをキャッチし、 JSON to TOONコンバーターで既存のペイロードを移行し、 TOON to JSONコンバーターで逆方向に変換できます。 npmパッケージ@toon-format/toonencodedecodeを提供し、数分でNode.jsや ブラウザサイドのコードにTOONを統合できます。