Когда каждый токен на вес золота
Помните этот момент? Вы пишете промпт, вкладываете в контекст важные данные, а потом смотрите на счетчик токенов и понимаете — половина контекстного окна уже съедена. И это еще без системного промпта и истории диалога. Особенно больно, когда вы пытаетесь засунуть в контекст результаты поиска по базе знаний для RAG-агентов или большой кусок JSON-ответа от API.
JSON — это стандарт де-факто для обмена данными с LLM. Но он чертовски многословный. Каждая кавычка, каждая запятая, каждый ключ — это токены. Много токенов.
Синтаксис ISON: где кавычки? Где запятые?
Сначала посмотрите на это. Типичный JSON с пользователями:
{
"users": [
{
"id": 1,
"name": "Анна",
"email": "anna@example.com",
"role": "admin"
},
{
"id": 2,
"name": "Борис",
"email": "boris@example.com",
"role": "user"
}
]
}
Теперь тот же самый набор данных в ISON:
users
id | name | email | role
1 | Анна | anna@example.com | admin
2 | Борис | boris@example.com| user
Видите разницу? Нет фигурных скобок. Нет квадратных скобок. Нет кавычек вокруг ключей (да и вокруг строковых значений их тоже можно опускать в большинстве случаев). Нет запятых. Просто таблица с заголовком и данными, разделенными вертикальной чертой или табуляцией.
Это работает потому, что LLM отлично понимают табличный формат. Они видят паттерн: первая строка — название сущности, вторая — заголовки столбцов, остальные — строки данных.
Важный нюанс: ISON не заменяет JSON в вашем бэкенде. Это формат для коммуникации с LLM. Вы конвертируете данные в ISON перед отправкой в промпт, а ответ от LLM (если он содержит структурированные данные) парсите обратно в JSON.
Насколько реальна экономия? Цифры против интуиции
Цифра в 70% — не маркетинговый ход. Посчитаем на примере выше. Возьмем токенизатор GPT-4:
- JSON пример: 54 токена
- ISON пример: 16 токенов
Экономия: 70,4%. И это на крошечном примере. Представьте, что у вас не 2 пользователя, а 50. Или вы передаете в контекст результаты поиска по продуктам с десятком полей каждый.
Но токены — это только одна сторона медали. Вторая — точность парсинга.
| Формат | Токены (пример) | Экономия | Точность парсинга (GPT-4) | Человекочитаемость |
|---|---|---|---|---|
| JSON | 54 | 0% | ~99% | Высокая |
| ISON | 16 | 70% | ~97% | Средняя (но для LLM — отличная) |
| YAML | 48 | 11% | ~95% | Высокая |
| MessagePack (hex) | ~70 | -30% | ~85% | Нулевая |
Точность парсинга ISON лишь немного уступает JSON. Почему? Потому что LLM тренировались на гигабайтах текста, где таблицы встречаются постоянно. А вот MessagePack в шестнадцатеричном представлении — это катастрофа для понимания. YAML экономит немного, но все равно слишком многословен.
А как же вложенные объекты? ISON ломается?
Самый частый вопрос. JSON позволяет создавать сложные вложенные структуры. Как ISON с этим справляется?
Ответ: через ссылки и дополнительные таблицы. Посмотрите на пример с заказами и товарами:
orders
id | user_id | total | status
101 | 1 | 2990 | completed
102 | 2 | 4500 | pending
order_items
order_id | product_id | quantity | price
101 | 5001 | 2 | 1200
101 | 5002 | 1 | 590
102 | 5003 | 3 | 1500
Вместо вложенного массива `items` внутри каждого заказа — отдельная таблица со связью по `order_id`. Для LLM это даже проще для понимания: явные связи, четкая структура.
Но есть и ограничения. Слишком сложные графы объектов с множественными ссылками — не лучший кандидат для ISON. Для них лучше подойдет тот же JSON или специализированные форматы вроде CommerceTXT для e-commerce данных.
Практика: от теории к работающему коду
Хватит теории. Давайте конвертировать JSON в ISON на Python. Библиотека `ison` устанавливается одной командой:
pip install ison
Простой пример конвертации:
import json
import ison
# Ваши данные в JSON
products_json = '''
[
{
"id": 100,
"name": "Ноутбук",
"price": 89990,
"in_stock": true
},
{
"id": 101,
"name": "Мышь",
"price": 2490,
"in_stock": false
}
]
'''
data = json.loads(products_json)
# Конвертация в ISON
ison_output = ison.dumps(data, table_name="products")
print(ison_output)
Результат:
products
id | name | price | in_stock
100| Ноутбук | 89990 | true
101| Мышь | 2490 | false
Теперь этот компактный ISON можно вставить в промпт. Когда LLM отвечает в формате ISON (а вы можете явно попросить ее об этом в системном промпте), парсим ответ обратно:
# LLM вернула такой ответ (как текст)
llm_response = '''
new_products
id | name | category
200| Наушники | audio
201| Клавиатура| peripherals
'''
# Парсим обратно в Python-объекты
parsed_data = ison.loads(llm_response)
print(json.dumps(parsed_data, ensure_ascii=False, indent=2))
Получаем привычный JSON:
{
"new_products": [
{"id": 200, "name": "Наушники", "category": "audio"},
{"id": 201, "name": "Клавиатура", "category": "peripherals"}
]
}
Кому ISON подойдет, а кому — нет
Берите ISON, если:
- Вы передаете в контекст LLM табличные данные (результаты SQL-запросов, CSV, списки объектов)
- Вы боретесь за каждый токен в контекстном окне, особенно при использовании локальных LLM с ограниченным контекстом
- Вы строите RAG-системы и хотите поместить в контекст больше релевантных документов
- Вы используете LLMRouter или другие инструменты для оптимизации API-запросов и хотите снизить затраты еще больше
Обходите стороной, если:
- Ваши данные — это глубоко вложенные JSON с непредсказуемой структурой (как ответы некоторых API)
- Вам критически важна 100%-ная точность парсинга (хотя 97% — это тоже много)
- Вы работаете исключительно с бинарными данными или нуждаетесь в максимальной компактности на уровне байтов (тут лучше Protobuf или MessagePack)
- Ваша LLM — это какая-то экзотическая модель, плохо понимающая таблицы (но такие сегодня редкость)
ISON в реальных проектах: не только теория
Где это уже работает? В агентах, которые анализируют данные из БД. Вместо того чтобы отправлять в контекст громоздкий JSON с результатами SQL-запроса, вы конвертируете ResultSet в ISON. Экономия достигает 60-80% в зависимости от количества полей.
В чат-ботах с расширенным контекстом. Вы можете хранить больше истории диалога или справочной информации, потому что системные данные занимают меньше места.
В промптах для анализа кода, когда нужно передать метаинформацию о нескольких файлах (путь, размер, последнее изменение). Табличный формат идеален.
Самый неочевидный совет: используйте ISON не только для данных к LLM, но и для данных ОТ LLM. Когда просите модель сгенерировать структурированный ответ (список идей, сравнение вариантов, извлечение сущностей), явно укажите формат ISON в промпте. Модель ответит таблицей, которую вам будет в разы проще парсить, чем свободный текст или даже JSON.
ISON — не серебряная пуля. Это специализированный инструмент для конкретной задачи: сжать структурированные данные для LLM без потери смысла. Как TensorRT-LLM ускоряет инференс, так ISON увеличивает эффективную емкость контекста.
Попробуйте на одном из своих проектов. Конвертируйте самый «тяжелый» JSON в контексте. Посчитайте экономию токенов. Удивитесь. А потом задайтесь вопросом — что еще в вашем пайплайне работы с LLM можно оптимизировать так же просто?