TL;DR
Schema-guided decoding — техника, которая заставляет модель генерировать таблицы строго по заданной JSON-схеме вместо свободного markdown. Вместо "сделай таблицу как хочешь" модель получает жёсткую инструкцию: "заполни вот эти поля, вот эти значения — только числа, вот эти заголовки — только из списка".
Исследователи обнаружили парадокс: структура всегда спасает от битых таблиц, но не всегда улучшает их содержание. На задачах с числами (статистика баскетбольных игр) структура даёт +60% точности. На задачах с плотным текстом (описания ресторанов) — убивает качество на 10-15%. Причина: когда информация разбросана по тексту редко ("Хорфорд набрал 17 очков"), модель плохо её связывает без подсказок. Когда текст короткий и ёмкий ("near city centre, cheap, French cuisine"), модель лучше улавливает нюансы в свободном формате.
Вывод: Для точных числовых данных — давай схему (JSON/XML в промпте). Для текстовой информации — давай модели дышать свободно. Для задач с reasoning (агрегация из длинного текста) — схема не поможет, нужны другие техники.
Схема метода
ИССЛЕДОВАНИЕ проверяло два подхода:
ПОДХОД 1 (Unstructured):
One-shot промпт → Модель генерирует markdown-таблицу свободно
ПОДХОД 2 (Structured):
Динамическая JSON-схема → Модель генерирует строго по схеме → Парсинг в таблицу
Оба подхода получают:
- Входной текст
- Описание структуры (заголовки столбцов, число строк)
Пример применения
⚠️ Зона применения: Извлечение числовых фактов из текста, где данные разбросаны и могут путаться (финансовые отчёты, спортивная статистика, результаты исследований).
Задача: Ты аналитик венчурного фонда. Из презентаций стартапов нужно извлечь финансовые метрики в единую таблицу для сравнения.
Промпт (адаптация Structured подхода):
Извлеки финансовые показатели стартапов в таблицу. Строгие правила:
СТРУКТУРА ТАБЛИЦЫ:
- Столбцы: Стартап | MRR (руб) | Рост MoM (%) | CAC (руб) | LTV (руб) | Burn Rate (руб/мес)
- Если метрики нет в тексте — поставь null
- Все числа — только числа, без текста
- Все проценты — только число без знака %
ФОРМАТ ВЫВОДА — JSON:
{
"стартапы": [
{
"название": "...",
"MRR_руб": 123456,
"рост_MoM_процент": 15,
...
}
]
}
ВХОДНЫЕ ДАННЫЕ:
[вставь текст презентаций]
Результат: Модель выдаст валидный JSON с чёткой структурой. Каждое числовое поле будет содержать либо число, либо null — никаких "примерно 100к", "быстрый рост", "пока не считали". Таблица идеально подойдёт для загрузки в Excel и дальнейшего анализа.
Почему это работает
Слабость LLM: Модель плохо связывает разрозненные факты с конкретными сущностями. Прочитала "Альфа выросла на 20%, Бета на 15%", но через 100 токенов забудет кто на сколько. Особенно если в тексте мелькают цифры от разных компаний без чёткой разметки.
Сильная сторона LLM: Модель отлично следует явным структурным инструкциям. Дал схему "поле А — только число, поле Б — только из списка [X, Y, Z]" — она заполнит по правилам, даже если текст запутанный.
Как метод использует это: Схема превращает размытую задачу "сделай таблицу" в чёткую "заполни 5 полей типа integer для каждой компании". Модель не импровизирует формат, не додумывает столбцы — просто находит соответствия и вставляет. Это убирает ошибки связывания (перепутала компанию А и Б) и форматирования (вместо числа написала текст).
Рычаги управления:
- Плотность текста: Если информация компактная и явная ("Альфа: MRR 500к, рост 20%") → можно без схемы. Если данные размазаны по абзацам → нужна схема.
- Тип данных: Числа, даты, категории из списка → схема улучшит. Свободный текст, описания, мнения → схема может ухудшить (модель теряет нюансы формулировок).
- Строгость схемы: Можешь разрешить
nullдля отсутствующих данных или запретить (тогда модель попытается найти/вывести значение любой ценой — может начать галлюцинировать).
Шаблон промпта
Structured подход (для числовых данных):
Извлеки {тип данных} из текста в таблицу. Строгие правила:
СТРУКТУРА:
- Столбцы: {столбец_1} | {столбец_2} | ... | {столбец_N}
- Тип данных: {столбец_1} — {тип}, {столбец_2} — {тип}
- Если данных нет → поставь null
ФОРМАТ ВЫВОДА — JSON:
{
"{название_таблицы}": [
{
"{столбец_1}": значение,
"{столбец_2}": значение,
...
}
]
}
ВХОДНЫЕ ДАННЫЕ:
{текст}
Unstructured подход (для текстовых данных):
Создай таблицу из текста:
СТОЛБЦЫ: {столбец_1}, {столбец_2}, ..., {столбец_N}
Формат — markdown-таблица. Сохраняй точные формулировки из текста.
ТЕКСТ:
{текст}
Пояснения к плейсхолдерам:
{тип данных}— что извлекаем: "финансовые показатели", "характеристики товаров", "результаты экспериментов"{столбец_N}— название столбца, например "Выручка (млн руб)", "Конверсия (%)"{тип}— тип данных: integer (целое число), float (дробное), string (текст), enum (значение из списка){название_таблицы}— ключ JSON, например "компании", "продукты", "метрики"
🚀 Быстрый старт — вставь в чат:
Вот два шаблона для генерации таблиц из текста. Адаптируй тот, что подходит под мою задачу: [твоя задача].
Если данные числовые и разбросаны по тексту — используй Structured.
Если данные текстовые и плотные — используй Unstructured.
Задавай вопросы, чтобы правильно заполнить поля.
[вставить оба шаблона выше]
Модель спросит: какие столбцы нужны, какой тип данных в каждом, есть ли примеры значений. Это важно, потому что схема — это контракт между тобой и моделью: ты говоришь ЧТО ждёшь, модель гарантирует ФОРМАТ.
Ограничения
⚠️ Плотный текст с нюансами: На коротких описаниях (типа "уютное кафе в центре, недорого, французская кухня") структурированная генерация деградирует качество на 10-15%. Модель в свободном формате лучше улавливает тонкости формулировок.
⚠️ Задачи с агрегацией: Если нужно собрать информацию из длинного текста (например, посчитать сколько голов забили из 50 абзацев комментариев матча), схема не улучшит качество — модель всё равно будет ошибаться в подсчёте. Здесь проблема в reasoning, не в форматировании.
⚠️ Неизвестная структура: Метод требует знать заранее какие столбцы и типы данных нужны. Если структура таблицы неизвестна (модель должна сама понять что извлекать) — этот подход не подойдёт.
Как исследовали
Команда взяла три бенчмарка с разными характеристиками:
- E2E — короткие описания ресторанов (24 слова в среднем), простые таблицы 2 столбца
- Rotowire — статистика баскетбольных игр (308 слов), сложные таблицы с числами
- Livesum — комментарии футбольных матчей (1138 слов), требует агрегации событий
Тестировали 12 открытых моделей от 0.5B до 32B параметров (Qwen, Falcon, Phi). Каждую модель прогнали в двух режимах: свободная генерация markdown vs жёсткая схема JSON.
Главное открытие: Схема спасла даже самую маленькую модель на Rotowire. Qwen-0.5B в свободном режиме сгенерировала только 43% таблиц игроков (остальные битые). Со схемой — 99.4%! Но та же схема ухудшила результаты на E2E у топовых моделей.
Почему так: В Rotowire данные разбросаны по тексту вперемешку ("Хорфорд 17 очков, Тиг 17 очков, Вучевич 21 очко"). Без схемы модель путает кто сколько набрал — записывает статистику одного игрока другому. Схема заставляет явно привязывать каждую цифру к имени. В E2E всё компактно в одном предложении — схема излишня, модель теряет гибкость в формулировках.
Инсайт для практики: Разреженность данных в тексте — ключевой фактор. Если одни и те же метрики упоминаются для разных сущностей без чёткой разметки → нужна схема. Если каждая сущность описана плотно в одном месте → схема может навредить.
Ресурсы
Evaluating Structured Decoding for Text-to-Table Generation: Evidence from Three Datasets
https://github.com/JulianOestreich90/text2table (код эксперимента)
Julian Oestreich, Lydia Müller — Institute for Applied Informatics (InfAI) at Leipzig University
