TOON (Token-Oriented Object Notation) 格式規範¶
目次¶
1. 簡介¶
TOON 是一種專為大語言模型 (LLM) 設計的層次化、標籤化資料壓縮格式。相較於原始 JSON,它透過「重複性欄位提取」、「索引化參照」與「CSV 型標題標記」,在不損失語義的前提下節省 80%+ 的 Token(基於 tiktoken 精確計數)。
2. 核心結構特點¶
A. 區塊分組 (Grouped Structure)¶
資料依來源分為 meta, google_tasks, google_calendar, moodle 四大區塊。每個區塊下以資源 ID (如 Calendar ID) 作為鍵值。
B. 外部索引 (External Indexing)¶
為了避免在每個項目中重複寫入冗長的地點或重複規則,TOON 在區塊頂部建立索引: - location_index: 映射為 L1, L2 ...(如 L1,臺科大 教室)。 - recurrence_index: 映射為 R1, R2 ...(如 R1,每週一重複)。
C. CSV 標題標記與批量壓縮¶
每個資料列表都有一個帶有欄位定義的標題: start_here[數量]{欄位1, 欄位2, ...} 緊接著是數行簡化資料,以逗號分隔。
3. 語義分組設計 (Semantic Grouping)¶
TOON 的另一大亮點是語義感知的資料分組,不同來源採用最符合其業務語義的分組邏輯。
A. Google Calendar — 月份分組¶
按月份鍵分組("2025-11":),每月內含 start_here (當月開始的事件):
month:
"2025-11":
start_here[23]{id,summary,lid,rid,notes,st_d,st_wd,st_hm,en_m,en_d,en_wd,en_hm}:
event_id,書法及習作,L1,0,0,3,1,"13:20",same,3,1,"15:10"
實作位置:
models_toon.pybuild_toon_calendar
B. Google Tasks — 四種狀態分類 + 父子樹¶
每個 Tasklist 下按截止日期月份分組,任務再依狀態細分: - due_open: 有截止日期、尚未完成 - due_done: 有截止日期、已完成 - done: 無截止日期、但已完成(按完成時間分月) - undated: 無截止日期且未完成的任務
另外,parent_tree 記錄了父子任務的從屬關係,以節省在每支葉任務上重複記錄父任務 ID:
"Project-big":
parent_tree:
"Coding101開發"[6]: 海報&程式碼,出席資料回報,refresh掛回去,掛litellm,...
month:
"2026-03":
due_open[2]{...}:
...
undated[16]{...}:
...
實作位置:
models_toon.pybuild_toon_tasklist,_build_parent_tree
C. Moodle — Course Index + 雙層分組¶
課程名稱提取至 course_index,內部使用 c1, c2 短標識。事件按學期 (semester)→月份雙層分組:
moodle:
course_index[3]{cid,course}:
c1,EC1012301 計算機程式與應用實習
c2,EC163A011 物理(上)
semester:
"114-1":
"2025-11":
due[10]{title,description,cid,status,due_d,due_wd,due_hm}:
Week 9作業繳交截止,Masked,c1,Closed,2,7,"00:00"
實作位置:
moodle/models/models_read.pyto_toon_moodle
3. 真實資料範例 (以 Google Calendar 為例)¶
google_calendar:
"台科大課表":
location_index[1]{lid,location}:
L1,臺科大 TR-510 教室
recurrence_index[1]{rid,rule}:
R1,每週一重複
month:
"2025-10":
start_here[1]{id,summary,lid,rid,notes,st_d,st_wd,st_hm,en_m,en_d,en_wd,en_hm}:
evt_03iq,線代,L1,R1,"導師:...",13,1,"13:20",same,13,1,"15:10"
欄位說明表¶
lid / rid: 對應外部索引。若為0則代表無。- 日期/時間簡寫:
st_d: Start Day (數字)st_wd: Start Weekday (1-7)st_hm: Start Hour:Minute (如 "08:00")same關鍵字: 代表該欄位與起始時段屬性相同(例如結束日期與開始日期為同一天),大幅減少重複日期字串。
4. 壓縮機制解析¶
以下為 TOON 格式達成極致壓縮的四大核心策略,每項策略皆有對應的實作位置:
| 策略 | 說明 | 實作位置 |
|---|---|---|
| Schema-less Header | 標題行定義欄位(如 start_here[10]{id,summary,lid,...}),後續數行僅含純資料,消除所有重複 Key 字串 | utils/toon_utils.py safe_encode |
| 外部索引化 (Indexing) | 地點、重複規則提取至 location_index / recurrence_index,內部以 L1, R1 短標籤參照 | models_toon.py _build_location_index, _build_recurrence_index |
| 日期元件化 (Date Decompose) | ISO DateTime 解析並分解為 st_d(日)、st_wd(週幾 1-7)、st_hm(時分)等最小整數元件 | models_toon.py _parse_datetime_parts |
| 值歸一化 (Value Normalize) | null 以整數 0 表示;結束月份與起始相同時使用 same 關鍵字,大幅減少重複月份字串 | models_toon.py build_toon_event |
5. TOON 解讀規則(Prompt Description)¶
以下為目前使用的 TOON 解讀規則字串(提供給模型先讀索引再解讀事件/任務):
此資料為 TOON 壓縮格式,請先讀索引再解讀事件/任務列。
[共通規則]
- 0 表示無值或未提供。
- "same" 表示與當前分組 month 相同。
- weekday: 1=週一, 7=週日。
[google_tasks]
- source: tasklist 基本資訊。
- parent_tree: 父任務標題 -> 子任務標題列表。
- month[YYYY-MM] 分組語意:
- due_open: 有 due 且未完成。
- due_done: 有 due 且已完成。
- done: 無 due 且已完成(按 completed 分月)。
- undated: 無 due 且未完成。
- 任務時間欄位:due_m/done_m = same | 月份數字(1-12) | 0;due_d/done_d=日期;due_wd/done_wd=週幾;due_hm/done_hm=HH:MM 或 0。
[google_calendar]
- source: calendar 基本資訊。
- location_index: lid -> location(事件內用 lid 參照)。
- recurrence_index: rid -> recurrence rule(事件內用 rid 參照)。
- month[YYYY-MM] 分組語意:
- start_here: 事件起始時間在本月。
- end_from_past: 從前月延續到本月(欄位預留,若出現才解讀)。
- 事件時間欄位:st_d/st_wd/st_hm 為開始;en_m/en_d/en_wd/en_hm 為結束。en_m = same | 月份數字 | 0;全天事件 st_hm/en_hm="full_day"。
- lid/rid=0 表示該事件無 location/recurrence。
[moodle]
- course_index: cid -> 課程名稱。
- semester[學期][YYYY-MM].due[]: 截止事件列表。
- 每筆 due 常見欄位:title, description, cid, status, due_d, due_wd, due_hm。
6. 壓縮效益實測數據¶
根據 scripts/analyze_toon_compression.py 分析 assets/fixtures/snapshots(清洗後的真實資料)的結果: - 分析腳本: scripts/analyze_toon_compression.py - 執行/測試指令 (uv): uv run python scripts/analyze_toon_compression.py - 資料規模: Google Calendar 188 事件、Google Tasks 47 任務、Moodle 10 課程事件 - Token 計數工具: tiktoken (Encoding: o200k_base / GPT-4o) - 資料流: fixtures JSON → AllCalendarEventsSnapshot (Layer 2) → AllCalendarEventsResult.from_snapshot() (Layer 3) → ResourceContext → TOON - 完整報告: TOON_STATS_REPORT.md - TOON 成品: get_time_context_composite.toon
| 指標 | 標準 JSON | TOON 格式 | 改善幅度 |
|---|---|---|---|
| 字元數 (Chars) | 304,082 | 28,789 | -90.5% |
| 精確 Token (GPT-4o) | 96,772 | 15,800 | -83.7% |
| 資訊密度 | 1.0x | 6.1x | 大幅提升 |
格式對比:雙事件範例(欄位壓縮)¶
原始 Google Calendar API JSON(兩筆事件):
[
{
"id": "evt_a",
"summary": "書法及習作(一)",
"location": "臺科大 TR-510 教室",
"start": { "dateTime": "2025-11-03T13:20:00+08:00", "timeZone": "Asia/Taipei" },
"end": { "dateTime": "2025-11-03T15:10:00+08:00", "timeZone": "Asia/Taipei" },
"recurrence": null,
"description": null
},
{
"id": "evt_b",
"summary": "計算機程式與應用實習",
"location": "臺科大 TR-510 教室",
"start": { "dateTime": "2025-11-10T13:20:00+08:00", "timeZone": "Asia/Taipei" },
"end": { "dateTime": "2025-11-10T15:10:00+08:00", "timeZone": "Asia/Taipei" },
"recurrence": null,
"description": null
}
]
TOON 格式(兩筆事件):
location_index[1]{lid,location}:
L1,臺科大 TR-510 教室
month:
"2025-11":
start_here[2]{id,summary,lid,rid,notes,st_d,st_wd,st_hm,en_m,en_d,en_wd,en_hm}:
evt_a,書法及習作(一),L1,0,0,3,1,"13:20",same,3,1,"15:10"
evt_b,計算機程式與應用實習,L1,0,0,10,1,"13:20",same,10,1,"15:10"
關鍵差異:JSON 兩筆事件都重複完整欄位名稱與巢狀 key;TOON 只宣告一次欄位 header,後續每列只放值,並以
L1參照共享 location。
關鍵優勢¶
- 極致節省 Token: 讓 AI 能在單次請求中載入數個月份的完整排程,而非僅限於當週。
- 模型推理精準度: 結構化 CSV 格式減少了模型對冗餘欄位(大括號、引號)的注意力分散,使模型更能專注於時間判斷邏輯本身。
- 人類可讀性: 雖為資料壓縮格式,但仍具備層次化縮排,開發者在 Debug 時可透過日誌快速追蹤資料分佈。