Цель
Получить от локальной модели не свободный текст, а данные по строгой JSON-схеме и проверить их перед использованием в программе.
Пользовательская задача
Классифицировать обращение службы поддержки по трём полям:
category:access,billing,technicalилиother;priority:low,mediumилиhigh;summary: непустое краткое описание.
Критерии PASS/FAIL
PASS:
- Ollama возвращает JSON по схеме
SupportTicket; - Pydantic принимает корректный ответ;
- отсутствующие, лишние и недопустимые значения отклоняются;
- для проблемы со входом выбирается категория
access.
FAIL — нарушен хотя бы один из этих пунктов.
Подготовка
Из корня проекта:
uv sync --python 3.12Команда создаст .venv, установит Python 3.12, Pydantic и pytest. Системный Python при этом не изменяется.
Запуск
Сначала запустите приложение Ollama, затем выполните:
uv run python -m agent_lab.structured_output \
"Не могу войти в аккаунт, а завтра нужно отправить важный отчёт."Ожидаемая структура:
{
"category": "access",
"priority": "high",
"summary": "Клиент не может войти в аккаунт перед отправкой важного отчёта."
}Точная формулировка summary может отличаться.
Автоматическая проверка
uv run pytestТесты намеренно передают как правильные, так и неправильные данные. Pydantic должен отклонить неизвестную категорию, неправильный приоритет, отсутствующее поле и лишнее поле.
Что здесь происходит
SupportTicketописывает допустимые данные в Python.model_json_schema()превращает описание в JSON Schema для Ollama.- Ollama ограничивает структуру ответа модели этой схемой.
model_validate_json()повторно проверяет фактический ответ.- Только после успешной проверки программа использует результат.
Ограничение
Structured output гарантирует форму данных, но не истинность и не правильность классификации. Поэтому правила задачи уточняются в system prompt, а смысловая корректность отдельно проверяется evaluation-тестами.