TOON 协议与 AIDotNet.Toon 实践指南

一、TOON 是什么

官方定义要点摘录(来源:toon-format/toon 仓库 README):

  • Token-efficient:通常比 JSON 少 30--60% 的 tokens(Key Features 列表)
  • LLM-friendly guardrails:显式长度与字段,便于验证
  • Minimal syntax:移除冗余标点(大括号、方括号、许多引号)
  • Indentation-based structure:类似 YAML,以空白缩进代替大括号
  • Tabular arrays:一次声明列头,数据按行流式书写

官方基准与工具:

  • README 的 Benchmarks 表格展示了多个数据集下的 token 节省比例;此外提供"Format Tokenization Playground"可交互比较不同格式的 token 用量
  • 当前规范版本:v1.3(README 徽章与 SPEC.md 指向的专用仓库)

规范入口与一致性:

二、为什么 TOON 相比 JSON 更省 tokens

本质原因是"以结构换冗余":在 LLM 语境下,重复的键名和标点都会占用 tokens。TOON 通过以下策略显著减少冗余(均可在 README 与语法速查中找到实例):

  • 表格数组:为均匀对象数组声明一次列头,如 users[2]{id,name}: 后续行直接写 1,Alice
  • 行内原子数组:tags[3]: a,b,c,避免多余方括号与引号
  • 键名可不加引号:安全键裸写,减少引号数量
  • 缩进代替大括号:以空白表达层级

同时,官方 README 也清晰指出边界:对于深度嵌套或非均匀结构的数据,JSON 可能更高效。这意味着在"树深且分支不规则"的任务上应优先评估 JSON。

三、语法速查与对照示例

下列示例与含义对应自 README 的 Syntax Cheatsheet 与"Why TOON"示例(术语与格式请以规范 v1.3 为准):

  • 对象

    { id: 1, name: 'Ada' } → id: 1 换行 name: Ada

  • 嵌套对象

    { user: { id: 1 } } → user: 换行缩进 id: 1

  • 行内原子数组

    { tags: ['foo', 'bar'] } → tags[2]: foo,bar

  • 表格数组(均匀对象)

    { items: [ { id: 1, qty: 5 }, { id: 2, qty: 3 } ] }

    → items[2]{id,qty}: 换行缩进 1,5 换行缩进 2,3

  • 混合或非均匀数组

    { items: [ 1, { a: 1 }, 'x' ] } → items[3]: 换行缩进 - 1 换行缩进 - a: 1 换行缩进 - x

四、AIDotNet.Toon:.NET 实现概览

AIDotNet.Toon 对齐 upstream 规范与设计,面向 .NET 提供与 System.Text.Json 风格一致的 API。关键入口如下:

实现思路(节选自源码注释与 README):

  • Encode 路径:.NET 对象 → JsonElement → Encoders 结构化写出(对象、行内原子数组、表格数组、列表回退等)
  • Decode 路径:TOON → 规范化 JSON 字符串 → System.Text.Json 反序列化为目标类型
  • 数值与特殊值:允许命名浮点字面量,经编码阶段将 NaN 与 ±Infinity 规范化为 null,-0 规范化为 0(细节见编码器与选项)

五、安装与快速开始

通过 NuGet(发布后)或源码引入本库:

bash 复制代码
dotnet add package AIDotNet.Toon
csharp 复制代码
using AIDotNet.Toon;

var options = new ToonSerializerOptions
{
    Indent = 2,
    Delimiter = ToonDelimiter.Comma,
    Strict = true,
    LengthMarker = null
};

var data = new
{
    users = new[] { new { id = 1, name = "Alice" }, new { id = 2, name = "Bob" } },
    tags = new[] { "a", "b", "c" },
    numbers = new[] { 1, 2, 3 }
};

var text = ToonSerializer.Serialize(data, options);
// users[2]{id,name}:
//   1,Alice
//   2,Bob
// tags[3]: a,b,c
// numbers[3]: 1,2,3

读取原子值:

csharp 复制代码
var s = ToonSerializer.Deserialize<string>("hello", options);   // "hello"
var n = ToonSerializer.Deserialize<double>("3.1415", options);  // 3.1415

互操作:TOON ↔ JSON ↔ .NET

csharp 复制代码
// 将 TOON 文本转为目标类型,内部先经 [C#.ToonDecoder.DecodeToJsonString()](src/AIDotNet.Toon/ToonDecoder.cs:15)
var user = ToonSerializer.Deserialize<Dictionary<string, object>>("id: 1", options);

// 将 .NET 对象经 JSON DOM 编码为 TOON
var t = ToonSerializer.Serialize(new { id = 1, name = "Ada" }, options);

六、选项与行为

统一选项入口 C#.ToonSerializerOptions 与默认预设 C#.ToonSerializerOptions.Default

  • Indent:每级缩进空格数,默认 2
  • Delimiter:分隔符,枚举 C#.ToonDelimiter,用于行内与表格;底层转换为具体字符见 C#.ToonSerializerOptions.GetDelimiterChar()
  • Strict:严格模式,校验缩进、空行、计数一致性等
  • LengthMarker:数组长度标记,仅支持 # 或 null
  • JsonOptions:直通 System.Text.Json;默认启用 AllowNamedFloatingPointLiterals,并注册转换器以将 NaN 与 ±Infinity 写出为 null

七、错误模型与定位

解码错误统一抛出 C#.ToonFormatException 并包含错误分类与位置信息:

八、进阶示例

  1. 表格数组写出
csharp 复制代码
var rows = new[] { new { id = 1, name = "alice" }, new { id = 2, name = "bob" } };
var toon = ToonSerializer.Serialize(rows, options);
// [2]{id,name}:
//   1,alice
//   2,bob
  1. 行内原子数组
csharp 复制代码
var arr = new[] { 1, 2, 3 };
var t2 = ToonSerializer.Serialize(arr, options); // "[3]: 1,2,3"
  1. 混合数组回退为列表
csharp 复制代码
var mixed = new object[] { 1, new { a = 1 }, "x" };
var t3 = ToonSerializer.Serialize(mixed, options);
// [3]:
//   - 1
//   - a: 1
//   - x

九、何时使用 TOON,何时选 JSON

基于官方 README 的定位:当你的数据是"均匀对象数组、字段重复较多、需要给 LLM 更大输入上下文"时,TOON 通常更省 tokens 且更易校验验证;当数据"深度嵌套、非均匀或树形变化大"时,JSON 可能更高效更直接。

十、数据流与实现关系图

十一、来源与参考

十二、结语

TOON 让 LLM 输入里的结构化数据更加紧凑、可校验、可读;AIDotNet.Toon 则在 .NET 世界提供熟悉的 API 体验与选项模型。建议从表格数组与行内原子数组的典型场景开始落地,并结合规范 v1.3 与测试数据持续验证。

Special thanks to the upstream project toon-format.

附:官方 Benchmarks 数据集节选

以下数字直接摘录自官方 README 的 Benchmarks「Token Efficiency」小节,原文与上下文见:https://github.com/toon-format/toon#benchmarks(其中提示这些数据集偏向 TOON 的优势场景:均匀表格化数据,真实效果取决于数据结构)。交互式对比工具:

Token 效率

⭐ GitHub Repositories ██████████████░░░░░░░░░░░ 8,745 tokens

vs JSON (-42.3%) 15,145

vs JSON compact (-23.7%) 11,455

vs YAML (-33.4%) 13,129

vs XML (-48.8%) 17,095

📈 Daily Analytics ██████████░░░░░░░░░░░░░░░ 4,507 tokens

vs JSON (-58.9%) 10,977

vs JSON compact (-35.7%) 7,013

vs YAML (-48.8%) 8,810

vs XML (-65.7%) 13,128

🛒 E-Commerce Order ████████████████░░░░░░░░░ 166 tokens

vs JSON (-35.4%) 257

vs JSON compact (-2.9%) 171

vs YAML (-15.7%) 197

vs XML (-38.7%) 271

─────────────────────────────────────────────────────────────────────

Total ██████████████░░░░░░░░░░░ 13,418 tokens

vs JSON (-49.1%) 26,379

vs JSON compact (-28.0%) 18,639

vs YAML (-39.4%) 22,136

vs XML (-56.0%) 30,494

检索准确率

4 种大型语言模型在 154 个数据检索问题上的准确率:

gpt-5-nano

→ TOON ███████████████████░ 96.1% (148/154)

CSV ██████████████████░░ 91.6% (141/154)

YAML ██████████████████░░ 91.6% (141/154)

JSON compact ██████████████████░░ 91.6% (141/154)

XML █████████████████░░░ 87.0% (134/154)

JSON █████████████████░░░ 86.4% (133/154)

claude-haiku-4-5-20251001

JSON ██████████░░░░░░░░░░ 50.0% (77/154)

YAML ██████████░░░░░░░░░░ 49.4% (76/154)

→ TOON ██████████░░░░░░░░░░ 48.7% (75/154)

XML ██████████░░░░░░░░░░ 48.1% (74/154)

CSV █████████░░░░░░░░░░░ 47.4% (73/154)

JSON compact █████████░░░░░░░░░░░ 44.2% (68/154)

gemini-2.5-flash

CSV ██████████████████░░ 87.7% (135/154)

XML ██████████████████░░ 87.7% (135/154)

→ TOON █████████████████░░░ 86.4% (133/154)

YAML ████████████████░░░░ 79.9% (123/154)

JSON compact ████████████████░░░░ 79.9% (123/154)

JSON ███████████████░░░░░ 76.6% (118/154)

grok-4-fast-non-reasoning

→ TOON ██████████░░░░░░░░░░ 49.4% (76/154)

JSON ██████████░░░░░░░░░░ 48.7% (75/154)

XML █████████░░░░░░░░░░░ 46.1% (71/154)

YAML █████████░░░░░░░░░░░ 46.1% (71/154)

JSON compact █████████░░░░░░░░░░░ 45.5% (70/154)

CSV █████████░░░░░░░░░░░ 44.2% (68/154)

注意:上述样本强调 TOON 在"均匀对象数组/表格化数据"场景的节省效果;对于深度嵌套或非均匀数据,官方 README 指出 JSON 可能更高效。建议在落地前结合自身数据结构评估与小规模验证。