Если сервису нужен ответ Ollama в виде JSON, в запросе к /api/chat указывают поле format: либо значение "json", либо полную JSON-схему с полями и типами. Схема сужает форму ответа, но верность содержимого она гарантировать бессильна: модель способна заполнить поле аккуратным, однако ошибочным значением. Поэтому разбор, проверку и решение о записи берёт на себя код сервиса, а человек смотрит спорные случаи. Вариант подходит для извлечения полей из заявок, писем и карточек, где результат попадает в таблицу или форму.
Поле format
Документация Ollama предлагает два режима: format: "json" даёт произвольный объект, а JSON-схема в этом же поле задаёт набор свойств, типы и обязательные поля.
Запрос уходит методом POST на http://localhost:11434/api/chat вместе с массивом сообщений. Для Python документация показывает, как получить схему из модели Pydantic через model_json_schema(), а для JavaScript — через Zod. Один источник схемы для запроса и проверки ответа избавляет от расхождений: поле, добавленное в схему, сразу видно и в запросе, и в валидаторе.
Две рекомендации из той же документации стоит перенести в код без изменений. Первая: понизить температуру, например до нуля, чтобы завершения были более предсказуемыми. Вторая: продублировать схему текстом в самом запросе, так модель лучше понимает, чего от неё ждут. Подробности о подключении локального сервера к своим сервисам вы найдёте в статье про Ollama API, а общий смысл приёма объясняет термин структурированный вывод.
Отдельная оговорка: по документации Ollama, облачный режим сейчас лишён поддержки структурированных ответов. Если ваш сервис переключается между локальным сервером и облаком, предусмотрите проверку этого условия на этапе настройки, и тогда сбой обнаружится при запуске, до встречи с пользователем.
Как составить схему
Хорошая схема описывает ровно то, что потребует следующий шаг процесса. Для заявки на ремонт это номер помещения, категория, срочность и краткая суть; для письма клиента — тема, просьба и признак жалобы. Лишние свойства провоцируют модель на выдумки: ей хочется заполнить каждое поле, даже когда данных во входном тексте нет.
- Выпишите поля, которые нужны следующему шагу: записи в таблицу, карточке или очереди.
- Для категорий задайте закрытый список допустимых значений и добавьте значение «другое» для спорных случаев.
- Сделайте необязательными те поля, которые во входе могут отсутствовать, и допустите в них пустое значение.
- Поместите схему в запрос текстом и в поле format структурой, температуру поставьте на ноль.
- Сохраните пять-десять реальных входов с эталонным разбором: на них проверяют каждое следующее изменение схемы.
Названия свойств пишите по-английски короткими идентификаторами, а смысл поля поясняйте в описании схемы по-русски: так и код читается удобно, и модель получает подсказку на языке входного текста. Закрытые списки значений работают лучше свободных строк: сервис сразу видит, что категория попала в известные, а статистика сохраняет единое написание каждого значения. Дату и сумму лучше запрашивать отдельными полями с указанием формата в описании, а нормализацию и сложение выполнять в коде. Арифметика и сверка итогов относятся к работе скрипта: модель извлекает значения, а система считает.
Вложенные структуры вроде списка позиций в заказе допустимы, но усложняют проверку: каждая позиция проходит тот же валидатор, а ошибка в одной строке отправляет в очередь всю запись. Для первого релиза хватит плоской схемы с короткими полями, вложенность добавляют после того, как команда научилась разбирать отказы. Для выбора модели сравните две-три на сохранённом наборе: критерием служит доля записей, прошедших проверку с первой попытки, и скорость ответа на вашем оборудовании.
Разбор и проверка
Ответ приходит строкой в поле содержимого сообщения. Сервис превращает её в объект и пропускает через тот же валидатор, из которого получена схема. Успешный разбор доказывает только синтаксис и соответствие типам. Что значение верно, показывает сверка с источником, и здесь работают правила кода, вера в модель тут лишняя.
| Уровень проверки | Кто проверяет | Пример сигнала |
|---|---|---|
| Синтаксис JSON | Парсер сервиса | Строка обрывается или содержит лишний текст |
| Схема и типы | Валидатор | Категория вне списка, текст вместо числа |
| Связность полей | Правила в коде | Дата завершения раньше даты начала |
| Соответствие источнику | Скрипт или человек | Значение отсутствует во входном тексте |
| Право на запись | Сервер | У сотрудника нет доступа к карточке |
Четвёртый уровень проще всего автоматизировать для чисел и идентификаторов: скрипт ищет значение во входном тексте и помечает записи, где совпадения нет. Для свободных формулировок остаётся выборочный просмотр сотрудником. Похожая схема сверки подробно описана в статье про таблицу из текста.
Повтор и очередь
Если ответ провалил проверку, сервис делает ограниченное число повторов. В повторный запрос добавляют сообщение с названием нарушенного правила: «поле category вне допустимого списка». Ограничьте число попыток двумя-тремя и сохраняйте каждую в журнал с номером версии схемы. Бесконечный цикл повторов тратит ресурсы сервера и скрывает проблему, которую лучше показать человеку.
После исчерпания попыток запись уходит в очередь ручного разбора вместе с исходным текстом, ответами модели и причиной отказа. Сотрудник исправляет значения и подтверждает запись. Частые причины попадания в очередь пригодятся для доработки схемы: если одно поле регулярно вызывает отказ, его формулировка в описании схемы требует правки.
Очередь ручного разбора заодно служит источником новых тестов: каждая исправленная сотрудником запись пополняет сохранённый набор, и следующая версия схемы проверяется уже на ней. Так набор растёт из реальных случаев, а качество схемы подтверждается данными вашего потока. Подключение такой цепочки к сценарию автоматизации показано в материале про n8n и Ollama: узел модели возвращает объект, узел проверки отправляет ветку на повтор либо в очередь.
Из каких входящих текстов вы хотели бы получать готовые поля?
Допуск в работу
Перед запуском на реальных обращениях прогоните сохранённый набор: доля записей, прошедших все уровни проверки, и список расхождений с эталоном. Допуск определяет владелец процесса: он решает, какие поля допустимо принимать автоматически, а какие всегда видит сотрудник. Запись в учётную систему идёт через сервер, который сверяет права и ждёт подтверждения для критичных полей.
В журнал заносят версию схемы, идентификатор записи, результат каждого уровня проверки и число попыток. Текст исходных писем и персональные данные клиентов остаются в исходной системе, журнал сервиса хранит одни идентификаторы. Метрику допуска записывайте до первого прогона, до того как результаты начнут влиять на ожидания: например, какая доля записей должна проходить все уровни проверки без правок и какие поля сотрудник обязан просматривать всегда. Заранее зафиксированный порог защищает от соблазна подогнать критерий под полученный результат. Права стоит проверять отдельно от формата: корректный JSON с идентификатором чужой карточки останется корректным JSON, и только сервер решает, разрешена ли запись этому сотруднику. Пилот разумно начинать с одного типа входящих документов и одного сотрудника-проверяющего; расширение на другие типы возможно после разбора очереди ручного разбора.
Возьмите десять реальных обращений одного типа, обезличьте их и запишите ожидаемый JSON вручную. Составьте схему по этим примерам и посмотрите, на каких полях модель расходится с эталоном. Если нужен маршрут с очередью, правами и приёмкой, обсудите с нами автоматизацию бизнес-процессов; состав работ определим после знакомства с потоком документов.