Коли ви будуєте MCP-сервери або передаєте дані в LLM, кожен токен важливий. JSON довжелезний: повторювані ключі, фігурні дужки, лапки, двокрапки. Для відповіді з 50 записів тисячі токенів йдуть тільки на структуру.
Я зіткнувся з цією проблемою, коли робив MCP-сервер для Stagent — платформи бронювань для музичних агенцій. Дані непрості: тисячі бронювань, кожне з вкладеними деталями подій, інформацією про майданчик, даними артистів і фінансовими умовами. Типовий запит повертає глибоко вкладені об'єкти, які виглядають так:
{
"id": "p6YZkB4m",
"status": "confirmed",
"artist": {
"id": "PGreBnRL",
"name": "René Bourgeois"
},
"event": {
"id": "3G5wmW4X",
"name": "Jetset Kidz",
"status": "completed",
"type": null
},
"venue": {
"name": "Aramon",
"city": null,
"country": null
},
"buyer": {
"id": "8GOePv49",
"name": "Jet Set Seven Gmbh"
},
"starts_at": "2013-06-18"
}
Це багато повторів структури, коли записів сотні. Я дивився на існуючі пакети TOON для Laravel, але жоден не працював із вкладеними об'єктами належно — вони зберігали вкладеність і пропускали найважливішу можливість оптимізації.
Тому я створив Laravel TOON.
# Що це робить
TOON (Token-Optimized Object Notation) — компактний формат, схожий на YAML. Головна фішка — інтелектуальне сплощення вкладених об'єктів. Замість збереження вкладеності він перетворює її в крапкову нотацію в заголовку:
$bookings = [
[
'id' => 'abc123',
'artist' => ['name' => 'Amelie Lens', 'id' => 'art1'],
'event' => [
'name' => 'Awakenings',
'venue' => ['city' => 'Amsterdam', 'country' => 'NL']
],
'fee' => 15000,
],
[
'id' => 'def456',
'artist' => ['name' => 'Charlotte de Witte', 'id' => 'art2'],
'event' => [
'name' => 'Tomorrowland',
'venue' => ['city' => 'Boom', 'country' => 'BE']
],
'fee' => 25000,
],
[
'id' => 'ghi789',
'artist' => ['name' => 'Adam Beyer', 'id' => 'art3'],
'event' => [
'name' => 'Time Warp',
'venue' => ['city' => 'Mannheim', 'country' => 'DE']
],
'fee' => 20000,
],
];
Toon::encode($bookings);
Вихід:
items[3]{id,artist.name,artist.id,event.name,event.venue.city,event.venue.country,fee}:
abc123,Amelie Lens,art1,Awakenings,Amsterdam,NL,15000
def456,Charlotte de Witte,art2,Tomorrowland,Boom,BE,25000
ghi789,Adam Beyer,art3,Time Warp,Mannheim,DE,20000
Шляхи типу event.venue.city та artist.name сплющуються в заголовки-колонки. Значення стають рядками. Без повторюваних ключів. Без дужок. Без зайвих лапок для простих рядків.
# Реальні бенчмарки
За даними з продакшену з понад 17,000 бронювань:
| Записи | JSON | TOON | Заощаджено | Економія |
|---|---|---|---|---|
| 10 | 2,868 | 1,223 | 1,645 | 57.4% |
| 25 | 7,355 | 3,002 | 4,353 | 59.2% |
| 50 | 14,720 | 5,924 | 8,796 | 59.8% |
| 100 | 30,316 | 12,723 | 17,593 | 58.0% |
Для типового пагінованого запиту з 50 записів це приблизно 2,200 збережених токенів на запит.
# Налаштування
Пакет має опції для додаткової економії:
// config/toon.php
return [
// Omit null, empty strings, or false values
'omit' => ['null', 'empty'],
// Strip specific keys entirely
'omit_keys' => ['created_at', 'updated_at', 'deleted_at'],
// Shorten verbose keys
'key_aliases' => [
'organization_id' => 'org_id',
'description' => 'desc',
],
// Truncate long strings
'truncate_strings' => 200,
// Control nesting depth (default: 3)
'max_flatten_depth' => 3,
];
# Використання
MCP Servers - Повертайте компактні дані у відповідях інструментів:
use MischaSigtermans\Toon\Facades\Toon;
class ListBookings extends Tool
{
public function handle(Request $request): Response
{
$bookings = Booking::query()
->with(['event.venue', 'artist', 'event.buyer'])
->limit(50)
->get()
->map(fn ($b) => $this->formatBooking($b));
return Response::text(Toon::encode([
'count' => $bookings->count(),
'bookings' => $bookings,
]));
}
}
LLM Context - Вмістіть більше в контекстне вікно моделі:
$context = Toon::encode([
'user' => $user->only(['id', 'name', 'role']),
'recent_bookings' => $bookings,
'stats' => $statistics,
]);
$response = $llm->chat("Analyze this data: {$context}");
Measure Savings - Побачте точно, скільки ви економите:
$diff = Toon::diff($data);
// Returns:
// [
// 'json_chars' => 14720,
// 'toon_chars' => 5924,
// 'saved_chars' => 8796,
// 'savings_percent' => 59.8,
// ]
# Чудово працює з Laravel MCP
Якщо ви використовуєте новий пакет Laravel MCP для відкриття додатка AI-асистентам, TOON — природний вибір. Відповіді інструментів часто повертають записи з бази, і вони швидко накопичуються. Обгорнувши відповіді у Toon::encode(), ви надсилаєте ті ж дані, але з меншим споживанням токенів, залишаючи більше місця в контексті для логіки й аналізу.
# Встановлення
composer require mischasigtermans/laravel-toon
Повна збереженість структури при круговому перетворенні. Decode повертає оригінальну структуру з тих самих типів:
$original = Toon::decode($encoded);
Дізнайтеся більше про Laravel TOON на GitHub і слідкуйте за блогом Mischa: mischa.sigtermans.me