Нейросеть хорошо превращает свободный текст в структуру: из строки «Набор А, три коробки, самовывоз» получается запись с понятными полями. Но у такого результата две слабые точки. Модель охотно додумывает то, чего в тексте нет, а вежливое «вот ваш JSON» не гарантирует, что код получит корректный файл. Ниже — порядок работы, который снимает оба риска: сначала схема, потом запрет на догадки, потом проверка парсером и глазами.
Все примеры в статье учебные: заметки придуманы для разбора и не относятся к реальным заказам.
Что значит «правильный JSON» и чего он не гарантирует
JSON описан в RFC 8259. Значение в нём бывает объектом, массивом, числом, строкой или одним из трёх слов: true, false, null. Имена полей в объекте — всегда строки в двойных кавычках. Одинарные кавычки, запятая после последнего поля и комментарии в формат не входят.
Для нашей задачи важны ещё три факта из этого стандарта:
- числа записываются без ведущих нулей, а значения вроде
NaNиInfinityне допускаются; - имена внутри одного объекта желательно делать уникальными, иначе разные программы могут прочитать такой объект по-разному;
- отдельного типа «дата» в JSON нет: дата — это обычная строка, и о её формате нужно договариваться самим.
Главное следствие: корректный синтаксис ещё не означает верное содержание. Запись {"boxes": 5} читается любым парсером, но если в заметке было три коробки, это ошибка, которую парсер не увидит. Поэтому проверка делится на две части: синтаксис проверяет программа, смысл проверяет человек.
Учебная заметка и эталон
Возьмём короткую заметку, какие приходят в чат от коллег:
Набор А. Три коробки. Самовывоз. Дату согласуем.
Прежде чем что-то просить у нейросети, составьте эталон вручную. Так вы заранее знаете, что считаете правильным ответом:
{
"item": "Набор А",
"boxes": 3,
"delivery": "pickup",
"date": null
}Обратите внимание на date: в заметке сказано «дату согласуем», то есть даты пока нет. Правильный ответ здесь — null, а не выдуманное «завтра» и не пустая строка.
Шаг 1. Опишите поля словами
Схема — это короткий список: имя поля, тип и что делать, если данных нет. Для нашего примера он выглядит так:
item— строка, название набора как в тексте;boxes— целое число коробок илиnull, если число не названо;delivery— одно из трёх значений:pickup,courier,unknown;date— строка с датой илиnull, если дата не определена.
Закрытый список для delivery особенно полезен: нейросеть не придумает «самовывоз/доставка», «сам заберёт» и другие варианты, которые потом придётся разбирать отдельно.
Шаг 2. Дайте запрос с запретом на догадки
Запрос состоит из четырёх частей: задача, схема, правило для неизвестного и формат ответа.
Извлеки данные из заметки ниже и верни только один JSON-объект с полями item, boxes, delivery, date. Типы: item — строка; boxes — целое число или null; delivery — только pickup, courier или unknown; date — строка или null. Если в заметке нет явного указания, ставь null (для delivery — unknown). Ничего не додумывай и не добавляй других полей. Заметка: Набор А. Три коробки. Самовывоз. Дату согласуем.
Фраза «ничего не додумывай» работает хуже, чем конкретное правило «нет явного указания — null». Дайте модели готовое место, куда складывать неизвестное, и ей не придётся заполнять пустоту выдумкой.
Если в вашем чате ответ приходит в блоке кода или с пояснением, добавьте требование «без пояснений и без текста до и после JSON». Но даже с таким требованием не рассчитывайте на форму: проверяйте результат всегда.
Шаг 3. Попросите основания отдельным ответом
Чтобы быстро найти догадки, попросите второй ответ — таблицу оснований: для каждого поля цитата из заметки, на которую модель опиралась, или слово «нет».
Теперь для каждого поля покажи фразу из заметки, на основании которой ты его заполнил. Если фразы нет, напиши «нет».
Основания держите отдельно от JSON. Если смешать их в одном объекте, ваш код получит лишние поля, а потом кто-нибудь вручную вырежет «пояснение» и сломает структуру. По таблице видно, где модель честно написала «нет» и поставила null, а где подставила значение, которого в тексте не было.
Шаг 4. Проверьте синтаксис парсером
Откройте любой интерпретатор Python и прогоните ответ через стандартную библиотеку. Скрипт ниже проверяет, что текст разбирается как JSON, что нет лишних и пропущенных полей и что значения подходят по типам:
import json
ALLOWED_DELIVERY = {"pickup", "courier", "unknown"}
FIELDS = {"item", "boxes", "delivery", "date"}
def check(text):
data = json.loads(text) # здесь падает, если синтаксис сломан
problems = []
if not isinstance(data, dict):
return ["ответ не объект"]
if set(data) != FIELDS:
problems.append("набор полей: " + ", ".join(sorted(set(data) ^ FIELDS)))
if not isinstance(data.get("item"), str):
problems.append("item должно быть строкой")
if data.get("date") is not None and not isinstance(data["date"], str):
problems.append("date должно быть строкой или null")
boxes = data.get("boxes")
if boxes is not None and (isinstance(boxes, bool) or not isinstance(boxes, int)):
problems.append("boxes должно быть целым числом или null")
if not isinstance(data.get("delivery"), str) or data["delivery"] not in ALLOWED_DELIVERY:
problems.append("delivery вне списка")
return problems
print(check('{"item": "Набор А", "boxes": 3, "delivery": "pickup", "date": null}'))Для верной записи выведется пустой список. Для записи с "boxes": "три" или с delivery «сам заберёт» скрипт назовёт проблему. Явное исключение для bool не случайно: в Python True считается целым числом, и без этой проверки true в поле коробок прошёл бы незамеченным.
Если json.loads выдаёт ошибку, не правьте текст руками, а верните ошибку модели и попросите исправить именно синтаксис. Так вы заодно видите, как часто это случается на вашем типе заметок.
Что ловит парсер, а что нет
Парсер найдёт лишнюю запятую, одинарные кавычки, пропущенную скобку. Он не найдёт:
- число 5 вместо 3, если оба варианта правдоподобны;
courierтам, где в заметке про доставку ни слова;- дату, которую модель «вывела» из слова «скоро»;
- название набора, в которое она добавила слова.
Для этих случаев нужны основания из шага 3 и выборочная ручная проверка.
Пограничные случаи, которые стоит проверить заранее
Заготовьте несколько коротких заметок, где ответ неочевиден, и прогоните их все одним запросом:
- Случай 1: «Набор Б, коробок пока не знаем, курьер не нужен». Ожидаем
boxes: null. Что до доставки: фраза «курьер не нужен» не равна «самовывоз», поэтому осторожный ответ —unknown. Договоритесь заранее, какой вариант вам нужен, и запишите это правило в схему. - Случай 2: «Набор В — две или три коробки». Здесь два значения. Решите, что делать:
nullс пометкой для человека или отдельное поле. Нейросеть не должна выбирать молча. - Случай 3: «Код заказа 0007, набор Г». Номер с ведущими нулями — идентификатор, а не число. Если записать его как число, нули пропадут: стандарт запрещает ведущие нули в числах. Храните такие значения как строки:
"0007". - Случай 4: Заметка на двух языках или с опечатками. Проверьте, что
itemостаётся в том виде, в котором написан в тексте, а не «исправляется» молча.
Если один и тот же набор правил вы используете каждый день, не вставляйте его в каждый новый чат: храните схему в одном месте. Про то, как собрать инструкции и файлы под длинную задачу, есть отдельный разбор — проекты в ChatGPT.
Как проверять на серии
Один удачный ответ ничего не доказывает. Соберите десять заметок, из них хотя бы три — трудные, как выше. Составьте для каждой эталон, прогоните и посчитайте, сколько записей совпало полностью. Расхождения разбирайте по типам: выдуманное значение, неверный тип, нарушенный список. Затем уточните правило в запросе и прогоните снова. Если исправление ломает прежде верные записи, значит, правило надо формулировать иначе.
Что нельзя передавать нейросети и что нельзя делать автоматически
Не отправляйте в чат персональные данные, пароли и закрытые документы: для тренировки заменяйте их вымышленными. И не подключайте результат напрямую к рабочей базе или рассылке без проверки: пока вы не измерили долю ошибок на своих заметках, любой автоматический шаг — риск.
Где потренироваться
Чтобы набить руку, возьмите вымышленную заметку из этой статьи и попробуйте то же извлечение полей в русскоязычном чате. Это сервис, который принадлежит той же команде, что и этот сайт: он не разрабатывает нейросети, а даёт доступ к чату. Актуальные возможности и условия смотрите на его странице.
Частые вопросы
Можно ли просто попросить «верни JSON» без схемы?
Можно, но поля и их имена будут меняться от запроса к запросу. Для одного раза годится, для регулярной работы нужна схема с фиксированными именами и правилом для неизвестного.
Чем null лучше пустой строки?
Пустая строка выглядит как значение, а null честно говорит «данных нет». Для чисел пустая строка вообще другого типа, и код, ожидающий число, на ней сломается.
Что делать, если модель добавила лишние поля?
Явно запретите: «никаких других полей». Скрипт проверки всё равно сравнит набор полей и укажет на лишние. Если лишние поля появляются стабильно, сократите запрос и уберите из него всё, что подталкивает к комментариям.
Как хранить даты?
Договоритесь о едином формате строки, например год-месяц-день, и впишите его в схему. Стандарт JSON формат даты не задаёт, поэтому любое «естественное» написание модель может выбрать по-своему.
Коротко
Сначала эталон и схема, потом правило «неизвестное — null», потом проверка парсером и выборочная сверка с основаниями. Так вы получаете не красивый ответ, а структуру, которой можно пользоваться, и знаете, как часто она ошибается.

