Найти в Дзене
ИИ на пальцах

🔥 Забудьте о JSON: Создаем мощный двунаправленный TOON-парсер на C# для нейросетей (LLM)

Сравнение структуры TOON и JSON, демонстрирующее экономию токенов. Введение: Знакомство с TOON TOON (Token-Oriented Object Notation) — это новый формат, разработанный специально для экономии токенов в Large Language Models (LLM). Он компактен, удобочитаем, чрезвычайно легок и оптимизирован для рабочих процессов искусственного интеллекта, где важен каждый токен. По сравнению с JSON, TOON существенно уменьшает информационный шум, избегает ненужных скобок и кавычек, храня структурированные данные в плоском, эффективно расходующем токены виде. С ростом популярности AI-промптинга и агентно-ориентированных архитектур, TOON быстро становится фаворитом среди разработчиков и ML-инженеров. TOON — это не просто новый формат, это оптимизация для LLM-эпохи. В этом руководстве вы узнаете, как создать полноценный двунаправленный парсер TOON на C#: TOON → JSON: Преобразование компактного TOON в стандартный JSON. JSON → TOON: Преобразование стандартного JSON в экономичный TOON. Полностью автоматическ
Оглавление

Сравнение структуры TOON и JSON, демонстрирующее экономию токенов.
Сравнение структуры TOON и JSON, демонстрирующее экономию токенов.

Введение: Знакомство с TOON

TOON (Token-Oriented Object Notation) — это новый формат, разработанный специально для экономии токенов в Large Language Models (LLM).

Он компактен, удобочитаем, чрезвычайно легок и оптимизирован для рабочих процессов искусственного интеллекта, где важен каждый токен.

По сравнению с JSON, TOON существенно уменьшает информационный шум, избегает ненужных скобок и кавычек, храня структурированные данные в плоском, эффективно расходующем токены виде.

С ростом популярности AI-промптинга и агентно-ориентированных архитектур, TOON быстро становится фаворитом среди разработчиков и ML-инженеров.

TOON — это не просто новый формат, это оптимизация для LLM-эпохи.
TOON — это не просто новый формат, это оптимизация для LLM-эпохи.

В этом руководстве вы узнаете, как создать полноценный двунаправленный парсер TOON на C#:

  • TOON → JSON: Преобразование компактного TOON в стандартный JSON.
  • JSON → TOON: Преобразование стандартного JSON в экономичный TOON.
  • Полностью автоматическое, масштабируемое решение, которое не требует внешних зависимостей.

Это решение работает на .NET 6, .NET 8 и .NET 9.

TOON против JSON: Наглядный пример

Рассмотрим простой набор данных о продуктах, чтобы увидеть, как TOON обеспечивает экономию токенов.

TOON-формат

products[Collection]{id,name,price}
1,T-shirt,20.00
2,Jeans,55.50
3,Hat,15.00

JSON-формат

{
"products": [
{ "id": 1, "name": "T-shirt", "price": 20.00 },
{ "id": 2, "name": "Jeans", "price": 55.50 },
{ "id": 3, "name": "Hat", "price": 15.00 }
]
}

Обратите внимание, что в JSON названия ключей ("id", "name", "price") повторяются для каждого объекта, что расходует драгоценные токены. В TOON ключи определяются всего один раз в заголовке коллекции.

Шаг 1: Создание класса ToonConverter

Мы создадим вспомогательный класс, который будет включать три ключевых метода:

  • ParseToon(): Преобразует TOON в C# словарь (Dictionary).
  • ToonToJson(): Преобразует TOON в строку JSON.
  • JsonToToon(): Преобразует JSON обратно в TOON.

Создайте новый файл ToonConverter.cs и добавьте следующие директивы:

using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;

public static class ToonConverter
{
// ... Реализация методов
}

Шаг 2: Реализация TOON → Dictionary (ParseToon)

Метод ParseToon является основой, которая читает формат TOON построчно, разбивает его на коллекции и значения, а затем собирает в структуру C#:

// --------------------------------------
// 1. TOON → OBJECT (Dictionary)
// --------------------------------------
public static Dictionary<string, List<Dictionary<string, string>>> ParseToon(string toon)
{
var result = new Dictionary<string, List<Dictionary<string, string>>>();
var lines = toon.Split('\n', StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim()).ToList();

int i = 0;

while (i < lines.Count)
{
if (!lines[i].Contains("{"))
{
i++;
continue;
}

string header = lines[i];
i++;

string name = header[..header.IndexOf("[")];

string fieldBlock = header[(header.IndexOf("{") + 1)..header.IndexOf("}")];

string[] fields = fieldBlock.Split(',')
.Select(f => f.Trim()).ToArray();

var rows = new List<Dictionary<string, string>>();

while (i < lines.Count && !lines[i].Contains("{"))
{
if (string.IsNullOrWhiteSpace(lines[i]))
{
i++;
continue;
}

var vals = lines[i].Split(",").Select(v => v.Trim()).ToArray();

var obj = new Dictionary<string, string>();
for (int f = 0; f < fields.Length; f++)
obj[fields[f]] = vals[f];

rows.Add(obj);
i++;
}

result[name] = rows;
}

return result;
}

Шаг 3: Реализация TOON → JSON (ToonToJson)

Как только мы получили структурированный словарь C# из TOON, преобразование его в JSON становится тривиальной задачей благодаря встроенному классу System.Text.Json.JsonSerializer:

// --------------------------------------
// 2. TOON → JSON
// --------------------------------------
public static string ToonToJson(string toon)
{
var obj = ParseToon(toon);
return JsonSerializer.Serialize(obj, new JsonSerializerOptions { WriteIndented = true });
}

Шаг 4: Реализация JSON → TOON (JsonToToon)

Обратное преобразование (JSON → TOON) требует, чтобы мы сначала проанализировали JSON с помощью JsonNode.Parse, а затем вручную перебрали коллекции и их элементы, чтобы создать плоскую структуру TOON. Этот подход гарантирует, что мы сможем обрабатывать структурированный JSON, который был создан нашими другими методами.

// --------------------------------------
// 3. JSON → TOON
// --------------------------------------
public static string JsonToToon(string json)
{
var root = JsonNode.Parse(json).AsObject();
var sb = new StringBuilder();

foreach (var collection in root)
{
var name = collection.Key;
var array = collection.Value.AsArray();

if (array.Count == 0) continue;

// 1. Извлекаем поля из первого объекта, чтобы создать заголовок TOON
var firstObject = array.AsObject();
var fields = firstObject.Select(p => p.Key).ToList();
var fieldBlock = string.Join(",", fields);

// 2. Записываем заголовок TOON
sb.AppendLine($"{name}[Collection]{{{fieldBlock}}}");

// 3. Записываем строки данных
foreach (var item in array.OfType<JsonNode>())
{
var rowVals = new List<string>();
var itemObject = item.AsObject();
foreach (var field in fields)
{
// Извлекаем значение (или пустую строку, если значение null)
rowVals.Add(itemObject[field]?.ToString() ?? "");
}
sb.AppendLine(string.Join(",", rowVals));
}
sb.AppendLine(); // Добавляем пустую строку между коллекциями
}

return sb.ToString().Trim();
}
}

Заключение: Почему это важно

Создав этот двунаправленный парсер, вы вооружаете свои приложения C# возможностью использовать формат TOON, который становится стандартом де-факто для высокооптимизированного обмена данными с LLM.

Это не только позволяет сократить расходы на API за счет уменьшения количества токенов в промптах, но и делает структуру данных более понятной для моделей ИИ и облегчает отладку человеком.

С помощью этого простого класса ToonConverter вы можете легко переключаться между универсальностью JSON и эффективностью TOON в любой среде .NET.

Читать оригинал (Dev.to AI) ➜