Інтеграція OpenAI Structured Outputs для гарантованого парсингу JSON

Дані з відповідей моделі надходять у вільному вигляді — розбір зривається на живих даних. Ми проєктуємо та впроваджуємо строгі схеми відповіді під ключ: налаштовуємо правила, перевірки та відкати, щоб розбір перестав ламатися. Частка збоїв падає до нуля, а підготовка звітів прискорюється у рази.
Часті запитання

Чому OpenAI Structured Outputs зриваються на живих даних

На демо-стенді все сходиться: модель повертає об'єкт, парсер читає поля, перевірки зелені.

На живих даних строгий режим OpenAI Structured Outputs тримає форму відповіді, але не рятує від розсинхрону: структуру, передану в запиті, і структуру, за якою застосунок валідує результат, ведуть і версіонують окремо. Розбіжність проявляється не на першому запиті, а на рідкісному наборі вхідних даних.

Типовий збій розбору JSON виглядає так: відповідь обривається на обмеженні довжини посеред об'єкта, і розбір падає на незакритій дужці. Або замість даних приходить службове поле відмови, а код чекає на заповнений словник.

Ще одне джерело — пропущені ключі: якщо схема допускає відсутність поля, парсер отримує порожнє значення там, де чекає на рядок, і падає вже вище по стеку, в бізнес-логіці.

Граничні випадки у відповідях майже не потрапляють у тестові приклади: порожній список замість очікуваного набору, число приходить рядком, дата — у вільному форматі, вкладений вибір із кількох варіантів спрацьовує на гілці, яку застосунок не обробляє.

Невалідна відповідь моделі тут не аварія, а штатна поведінка на рідкісних даних, і повторний запит без перевірки ідемпотентності лише множить побічні ефекти.

Розбираємо, як це закривається: схема стає єдиним контрактом для запиту й перевірки, відповідь валідується до бізнес-логіки, а не після, і на кожен клас відмови з'являється передбачувана поведінка замість падіння.

Як строгі схеми знімають клас помилок розбору

Механізм Structured Outputs від OpenAI переносить розбір відповіді з імовірнісної області в детерміновану: модель повертає дані, що відповідають заздалегідь описаній структурі полів, а не текст, схожий на об'єкт.

Це прибирає цілий клас відмов — незакриті конструкції, пояснювальний текст навколо об'єкта, загублені вкладені поля — через які вилучення раніше обкладали регулярками й повторними запитами.

Частка успішних розборів

На вільному форматі відповідь проходить без втручання в більшості випадків, але помітний хвіст іде у відбракування: поле прийшло рядком замість числа, перелічення повернуло значення поза списком.

Зі строгою схемою частка успішних розборів тримається біля верхньої межі, бо типи, обов'язкові поля й допустимі значення перевіряються до того, як відповідь дійде до коду обробки.

Ручні правки та повторні звернення

Кожен невдалий розбір — це або ручна правка оператора, або повторний виклик моделі з уточненням, і обидва сценарії додають затримку.

Коли структура гарантована, обсяг ручних правок падає до поодиноких випадків, а повторні звернення потрібні лише для змістовних уточнень, а не для перепитування заради коректного оформлення.

Надійність вилучення полів на потоці

На великому обсязі документів важлива не середня точність, а відсутність довгого хвоста відмов.

Строгі схеми роблять поведінку передбачуваною: набір полів для вилучення однаковий для кожного документа, гілка розбору перестає бути вузьким місцем, а логіка продукту працює з уже перевіреними даними.

Схема відповіді, вільний JSON або перевірка на своїй стороні

Вилучення даних з відповіді моделі — це компроміс між свободою формулювання та передбачуваністю структури. На практиці в проєктах закріплюються три робочі режими: строга схема відповіді, вільний JSON за інструкцією в запиті й звичайний текст із розбором на стороні застосунку. Нижче — що кожен дає і де закінчується його зона застосовності.

Варіант Коли підходить Де межа
Строга схема відповіді Поля й типи відомі заздалегідь: картка товару, заявка, реквізити, перелічення із закритим набором значень Схему потрібно описувати й супроводжувати; частину обмежень на значення полів і глибоку вкладеність так не виразити, а розширити перелік значень можна лише правкою самої схеми
Вільний JSON за інструкцією Чорновий розбір, дослідницькі задачі, багато необов'язкових полів Модель то й діло додає текст навколо об'єкта, змінює регістр ключів, віддає рядок там, де очікувалося число — потрібні перевірка й повторні запити
Текст із розбором і перевіркою на стороні застосунку Нестандартні формати, дані із зовнішніх джерел, коли відповідь моделі — проміжний шар Правила розбору живуть у коді, а не в описі відповіді: їх важче змінювати й покривати тестами, зростає частка відбракованих відповідей

Режими не виключають один одного, і вибираємо ми не «найнадійніший», а відповідний за контрактом. Для запису в базу беремо строгу схему: відповідь приходить у узгодженому вигляді, і код працює з нею без розгалужень на перевірку типів.

Для проміжних кроків залишаємо вільний формат і додаємо перевірку на стороні застосунку — невалідна відповідь відбраковується й запитується заново, а не потрапляє в сховище.

Якщо відповідь потрібна для показу людині, а не для обробки, достатньо тексту: структура тут нічого не покращує.

Порядок впровадження: від аудиту відповідей до передачі

Порядок етапів той самий: спочатку вимірюємо, що модель видає зараз, потім описуємо цільову структуру відповіді, і лише після цього вмикаємо строгий режим. Так на кожному кроці є з чим порівняти результат — частка успішних розборів до й після, а не відчуття «стало краще».

  1. Аудит відповідей моделі. Вивантажуємо реальні запити й відповіді за період, розбираємо відмови розбору: невідповідність схемі, неправильний тип поля, зайвий текст навколо JSON. Підсумок — частка збоїв та їхні причини.
  2. Проєктування схеми. Описуємо обов'язкові поля, типи, перелічення, вкладеність і правила для порожніх значень; окремо — кодування дат і сум.
  3. Налаштування строгого режиму. Переводимо виклики на OpenAI Structured Outputs — режим, у якому відповідь зобов'язана відповідати схемі, — і фіксуємо поведінку при відмові.
  4. Перевірка на історичних даних. Проганяємо збережений корпус через нову конфігурацію й порівнюємо частку успішних розборів із вихідною: і за структурою, і за значеннями в полях.
  5. Обробка відмов. Задаємо правила для невалідних відповідей: повтор з уточненням, черга на ручний розбір, оповіщення при зростанні частки збоїв.
  6. Передача рішення команді. Віддаємо схеми, конфігурації викликів, набір еталонних розборів та інструкцію з правки схеми без поломки працюючих сценаріїв.

Після передачі команда змінює схему й проганяє перевірний набір сама — без нашої участі.

Артефакти: схеми, правила перевірки, регламенти

Здача — це не лише працюючий сервіс, а й набір документів, за якими його можна розвивати без нас. Схеми, правила перевірки й регламенти лежать у репозиторії поруч із кодом: під час правки логіки вони оновлюються в межах тієї ж перевірки змін, а не «колись потім». Нижче — що саме залишається в команди замовника.

  • Опис схеми відповіді — поля, типи, обов'язковість, вкладеність, допустимі значення. Схема OpenAI Structured Outputs тут єдине джерело правди: за нею будується і запит до моделі, і розбір відповіді на стороні застосунку.
  • Правила валідації полів — діапазони, формати дат і ідентифікаторів, перелічення. Перевірка йде до запису в базу, тому невалідне значення не доходить до бізнес-логіки.
  • Правила відбракування й повторів — що робити з відповіддю, яка не пройшла перевірку: повторний запит, звуження контексту або черга на ручний розбір.
  • Журнал змін схеми — версія, дата, автор і причина правки. Попередні версії залишаються доступними, щоб відтворити результат старого прогону.
  • Інструкція для розробників — як підняти середовище, додати поле, прогнати еталонні приклади до викладки.
  • Набір еталонних прикладів — пари «вхід / очікуваний результат», на яких ловиться регресія після правки схеми або формулювання запиту.
  • Регламент супроводу — хто вносить зміни, як проходить погодження, у якому порядку відкочується невдала версія.

Документи пишемо так, щоб новий інженер у команді замовника розібрався без листування з нами: стислий опис, приклад і межі застосовності.

Кейс: як прибрали збої розбору у звітності

Звітність збиралася з відповідей моделі, які потрібно було розкласти за полями: суми, періоди, категорії, посилання на первинні документи. Промпт просив «поверни JSON», але модель додавала пояснення, обгортала відповідь у текст, віддавала числа рядком.

Розбір падав на 15–20% документів, кожен збій інженер розбирав руками, а вивантаженню не довіряли: його звіряли порядково перед відправленням замовнику.

Що змінили

Схему відповіді винесли в окремий опис і передавали моделі як обов'язковий контракт, а не як прохання в тексті запиту — через OpenAI Structured Outputs.

Поле з типом «число» більше не може повернутися рядком, обов'язкові ключі не можна пропустити, зайві відбраковуються до запису в базу.

На своїй стороні продублювали перевірку за тими самими правилами й завели карантин: відповідь, яка не пройшла схему, не ламає потік, а йде в чергу на розбір.

Метрики до і після

Показник Було Стало
Документи зі збоєм розбору 15–20% менше 0,5%
Ручний розбір на день 2–3 години інженера поодинокі звернення на тиждень
Поля, що потребують правки парсера кожне нове правиться лише схема
Звірка вивантаження перед відправленням порядкова вибіркова

Стабільність вилучення даних перестала залежати від формулювань запиту: новий тип документа описується схемою за годину, а не переписуванням коду розбору.

Звіт іде замовнику без ручної звірки, бо структура відповіді гарантована на вході, і клас відмов «поле прийшло не тим типом» просто зник.

Що робити, якщо в проєкті вже є OpenAI без строгих схем

Так, це штатний сценарій: строга схема — властивість конкретного виклику, а не режим усього проєкту. У коді маршрутизації з'являється перемикач: частина звернень іде в строгий режим, де відповідь розбирається за контрактом, решта продовжує працювати як раніше, у вільному форматі.

Такий перемикач живе на рівні обгортки над викликом, тому змінювати логіку застосунку цілком не доводиться.

Першими у строгий режим має сенс переводити виклики з високою ціною помилки розбору: ті, чий результат потрапляє в базу, у розрахунок або в сповіщення користувачу. Там збій парсингу коштує найдорожче, і саме там схема дає виграш.

Відповіді, які людина все одно читає очима, можна залишити у вільному режимі — посилення контракту їм нічого не додає.

Сумісність старих відповідей вирішується явною ознакою формату: у кожного запису зберігається позначка, у якому режимі вона отримана, і парсер уміє читати обидві гілки.

Історію переписувати не потрібно — вона залишається валідною, а нова поведінка вмикається лише для свіжих даних. Це ж знімає проблему черг і кешів, у яких лежать відповіді, зроблені до переходу.

Головний ризик міграції — посилення контракту відсікає частину відповідей, які раніше проходили «на здогадці».

Модель, зобов'язана заповнити поле, іноді повертає порожнє значення або відмову, і на це потрібен заздалегідь описаний план: повтор з уточненням, деградація у вільний режим або черга на ручний розбір.

Обхідний шлях через вільний формат має залишатися робочим, інакше один збійний виклик зупинить весь потік.

Практичний порядок — вмикати строгий режим по одному маршруту, порівнюючи частку успішних розборів до й після. Перемикач дозволяє повернути попередню поведінку без випуску нової збірки, якщо частка відмов зросла. Так перехід іде поступово, а працюючий потік залишається у строю на всьому його протязі.

Технічні сумніви: схеми, повтори, відкати

Схема відповіді — це контракт між моделлю та вашою системою, а не побажання до якості тексту.

Строгий режим в OpenAI Structured Outputs гарантує збіг структури з описом полів, але навколо залишаються інженерні питання: поведінка при відхиленні, затримка, зміна полів і відповідальність після передачі.

Що буде, якщо відповідь не збіглася зі схемою?

При строгому режимі така відповідь відсікається до бізнес-логіки: невідповідність не проходить валідацію, і в обробник іде явна помилка, а не напівсирий JSON. Потім — обмежена кількість повторів, після чого запит із вихідними даними потрапляє в чергу розбору.

Наскільки схема сповільнює відповідь?

Основна частина затримки — сама генерація, а не перевірка структури. Перший виклик із новою схемою трохи дорожчий: вона компілюється. Далі час відповіді тримається в звичайному розкиді моделі — ми вимірюємо його на еталонному наборі й дивимося на повільні запити, а не на середнє.

Що якщо потрібно буде змінити поля схеми?

Схема версіонується: додавання необов'язкових полів старих споживачів не ламає, перейменування йде через період подвійного запису. Перед викатом проганяємо еталонний набір і звіряємо, що частка успішних розборів не впала.

Хто відповідає за рішення після передачі?

Віддаємо схеми, тести на еталонних наборах, опис полів і порядок відкату на попередню конфігурацію — команда може змінювати поля й підказки сама. Далі — супровід за погодженим регламентом: правки схем, розбір збоїв, оновлення перевірок.

Обговоримо задачу: розберемо ваш потік і повернемося з планом

Щоб оцінка була предметною, нам потрібні вхідні дані, а не переказ задачі: обсяг робіт визначається не числом полів у схемі відповіді, а тим, наскільки різнорідні відповіді приходять зараз і що відбувається, коли відповідь не відповідає формату.

Тому замість повного опису достатньо зрізу поточного потоку — за ним ми рахуємо обсяг і показуємо план впровадження.

Що надіслати для оцінки:

  • 15–20 реальних запитів і відповідей моделі: за ними видно розкид формулювань і де строгий формат справді потрібен;
  • цільову схему відповіді: обов'язкові поля, типи, допустимі значення, вкладеність;
  • приклади збоїв розбору: відповіді, через які падав розбір або з'їжджали дані;
  • куди йде результат — база, черга, внутрішня система, звіт: від цього залежать перевірки на виході;
  • вимоги до поведінки при невідповідності схемі: повторний запит, відмова, ручний розбір;
  • орієнтири щодо навантаження й обсягу: скільки запитів на добу і яка затримка відповіді допустима.

На старті ми фіксуємо схему й правила перевірки, описуємо обробку нештатних відповідей і розкладаємо роботу на етапи з точками контролю. Наступний крок — опишіть вашу задачу й додайте те, що є зі списку: повернемося з оцінкою обсягу робіт і планом впровадження.

Напрямки AI-розробки

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1543
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142