Каталог ошибок JSON в локальных LLM и библиотека Loot-JSON | AiManual
AiManual Logo Ai / Manual.
11 Май 2026 Инструмент

Как локальные модели ломают JSON: каталог ошибок и библиотека для восстановления

Разбираем типичные сбои JSON-вывода у локальных моделей (Llama, Qwen, Mistral) и показываем, как библиотека Loot-JSN их чинит. Примеры, код, сравнение.

Вы потратили день, чтобы запустить Qwen3-VL-8B на своем ноутбуке. Настроили пайплайн извлечения данных из PDF. Модель работает, но вместо аккуратного JSON выдает:

{
   "name": "Иван Петров",
   "age": 35,
   "profession": "Разработчик",
   // Модель решила добавить комментарий
   "skills": ["JavaScript", "TypeScript", "Python"
   // Забыла закрыть массив
}

Или такой подарочек:

Конечно, вот данные в JSON: {
   "title": "Отчет",
   "date": "2026-02-03",
   "content": "Текст с кавычками \"внутри\" и переносами\nстрок"
}
Надеюсь, это поможет!

JSON.parse() падает. Пайплайн стопится. Вы лезете в дебаггер и проклинаете всех идиотов, которые придумали локальные модели. Знакомо?

К 2026 году даже маленькие модели вроде Llama 3.2 3B, Qwen3-1.5B и Mistral-Nemo научились выполнять структурированные задачи, но JSON-вывод по-прежнему хромает. В этой статье я собрал каталог типовых ошибок, которые ломают парсеры, и показываю, как библиотека Loot-JSON превращает этот хаос в рабочие данные.

Каталог ошибок: что именно ломается

Я проанализировал около 500 ответов от разных локальных моделей (эксперимент из статьи «Почему LLM ломают JSON-парсеры: бенчмарк 672 вызовов») и выделил 7 основных типов сбоев. Вот они в порядке частоты:

Тип ошибкиЧастотаПример
Лишний текст до/после JSON~35%"Вот ваш JSON: {\"key\":\"value\"} Спасибо!"
Незакрытые строки/символы~25%{"text": "Hello
Одиночные кавычки вместо двойных~15%{'key': 'value'}
Лишние запятые в конце массивов/объектов~10%{"a":1,}
Комментарии (//, /* */)~8%{//comment "key":1}
Некорректное экранирование~5%"path\to\file"
Пропущенные кавычки у ключей~2%{key: "value"}

Эти ошибки убивают до 40% вызовов JSON.parse() в типовом пайплайне. Хуже всего то, что модель может выдать идеальный JSON в одном запуске и полную кашу в следующем.

Как Loot-JSON вытаскивает данные из мусора

Библиотека Loot-JSON — это не очередной «улучшенный парсер». Это хирургический станок, который делает три вещи:

  • Вырезает JSON из окружающего текста (убирает предисловия, постскриптумы, обёртки типа «Вот данные:»)
  • Лечит синтаксические ошибки (незакрытые скобки, лишние запятые, одиночные кавычки)
  • Экранирует спецсимволы внутри строк (переносы, кавычки, обратные слеши)

Установка:

npm install loot-json
# или
bun add loot-json

Вот как это выглядит в коде. Допустим, модель ответила мешаниной:

import { lootJson } from 'loot-json';

const dirtyResponse = `Пользователь запросил данные. Вот JSON: {
  "name": "Анна",
  "age": 28
} Надеюсь, это поможет!`;

const cleanJson = lootJson(dirtyResponse);
console.log(cleanJson); // {"name":"Анна","age":28}
const data = JSON.parse(cleanJson); // Всё ок

Библиотека ищет первый объект или массив в потоке текста и пытается восстановить его до валидного состояния. Если JSON повреждён необратимо — возвращается null или выбрасывается ошибка (в зависимости от настроек).

Совет: Loot-JSON не волшебная палочка. Если модель выдала текст без единого символа { или [, библиотека бессильна. Но в 9 из 10 случаев она превращает "надеюсь это поможет" в рабочие данные.

Сравнение с альтернативами

На рынке есть несколько решений для восстановления JSON. Вот что предлагают конкуренты:

ИнструментУмеет вырезать из текстаФиксит синтаксисЭкранированиеРазмер
Loot-JSONДаДаДа~3 KB
jsonrepair (Jos de Jong)Нет (только чистый JSON)Да (лучше)Частично~5 KB
JSON.parse + try/catchНетНетНет0 KB
fast-json-parseНетНет (только safe parse)Нет~1 KB

jsonrepair — мощный инструмент, но он не умеет извлекать JSON из обрамляющего текста. Если модель обернула ответ в пояснения, jsonrepair выдаст ошибку. Loot-JSON сначала вырезает, потом чинит. По качеству исправления синтаксиса Loot-JSON чуть уступает jsonrepair (у того более богатый набор правил), но зато покрывает кейс, который встречается в 35% случаев — лишний текст вокруг.

Если ваш сценарий — строгий JSON без лишнего текста, выбирайте jsonrepair. Если же вы работаете с локальными LLM, где модель постоянно болтает — Loot-JSON незаменим.

Глубокое погружение: как Loot-JSON чинит каждую ошибку

Разберём каждый тип сбоя и покажем, как библиотека с ним справляется.

1 Лишний текст до/после

Алгоритм: пробегает строку, находит первое вхождение { или [, затем отслеживает баланс скобок до конца. Если в конце остаётся мусор — отбрасывает его. Результат — чистый JSON.

lootJson('Объяснение: {"a":1} конец');
// -> {"a":1}

2 Незакрытые строки и символы

Модель часто забывает закрыть строку или массив. Loot-JSON дописывает недостающие кавычки и скобки, анализируя контекст.

lootJson('{"text": "Hello');
// -> {"text": "Hello"}

3 Одиночные кавычки

Заменяет одинарные кавычки на двойные, но только если это не мешает логике (например, внутри строк с апострофами — но таких случаев почти нет).

lootJson("{'key': 'value'}");
// -> {"key": "value"}

4 Лишние запятые и комментарии

Удаляет запятые перед закрывающими скобками и вырезает однострочные/многострочные комментарии.

lootJson('{"a":1, /*comment*/}');
// -> {"a":1}

Подробнее о том, почему даже с параметром strict в VLLM или llama.cpp модели продолжают ошибаться, читайте в статье «Параметр strict в VLLM и llama.cpp: почему он ничего не делает и как с этим жить». Спойлер: strict не гарантирует валидный JSON, он лишь форсирует грамматику, но модели всё равно могут генерировать невалидные токены.

Когда одного парсера мало

Loot-JSON решает проблему на уровне вывода. Но часто корень зла глубже. Вы можете улучшить качество JSON на этапе промптинга или с помощью специальных протоколов. Например, SDF Protocol — это формат, который заставляет модель выдавать строго структурированные данные, практически исключая мусор. Мы в ecom.tech используем комбинацию: SDF на этапе запроса + Loot-JSON на этапе ответа. Это даёт 99.8% успешных парсингов.

Важно: Не надейтесь, что одна библиотека решит все проблемы. Если модель систематически выдаёт битый JSON — проверьте температуру, top_p и системный промпт. Иногда достаточно снизить температуру до 0.1, чтобы число ошибок упало вдвое.

Для тех, кто хочет понять, как именно LLM «думают» при генерации JSON и почему возникают типовые ошибки, рекомендую статью «Держите свой JSON: как заставить Mistral и Llama 3.1 перестать болтать и начать парсить». Там разобраны механики трансформеров, приводящие к «болтовне».

Кому подойдёт Loot-JSON?

  • Разработчикам пайплайнов ETL/ELT на локальных моделях — вытаскивать данные из PDF, emails, логов.
  • Инженерам, работающим с OpenRouter или другими прокси — даже API возвращают мусор, если модель маленькая.
  • Создателям чат-ботов с функциями — когда LLM вызывает инструменты, JSON-аргументы часто битые.
  • Исследователям, которые гоняют бенчмарки и хотят автоматически парсить сотни ответов.

Если ваш проект — ботаналитик на локальной LLM (как мы описывали в статье «Бот-аналитик на локальной LLM: как мы в ecom.tech разгрузили команду»), Loot-JSON станет обязательным слоем в пайплайне. Без него каждый десятый ответ будет ломать всю цепочку.

💡
Прогноз: В 2026–2027 годах мы увидим появление моделей, которые гарантированно выдают валидный JSON «из коробки» — через встроенные декодеры и constrained decoding. Но старые модели (Llama 2, Mistral 7B, Qwen 1.5B) будут использоваться ещё годы. Loot-JSON — это страховка на переходный период. Не выбрасывайте её, даже когда выйдет Llama 4.

Подписаться на канал