Недавно я работал над задачей многоклассовой классификации с помощью LLM. У меня был датасет с ручной разметкой, который я использовал для замера качества. Метрики в первой итерации были очень низкие (F1 0.33), но я грешил на модель: использовал самую дешевую Gemini 3.1 flash lite.
Системный промпт мне нагенерил Codex, которого я заранее попросил использовать подход SGR. Промпт состоял из нескольких десятков строк и, упрощенно, из такой схемы вывода:
{
"label_1": true,
"label_2": false,
"label_3": false,
"label_4": true,
"reasoning": "Размышление, какие метки нужно поставить"
}Сгенерированный кодексом промпт я проверил не сразу: harness наше все! Но, спустя несколько итераций, все-таки зашел посмотреть, что там сохранилось в
.md файлике, и заметил одну неточность.Для ее понимания важно вспомнить, что GPT генерирует текст последовательно: каждый следующий токен зависит от всего доступного контекста, в том числе уже сгенерированного в ответе.
Поэтому если перед финальным ответом модель сначала сгенерировала шаги анализа, то финальный ответ будет строиться не только из исходного вопроса, а ещё и из её собственных промежуточных выводов. Это, как правило, приводит к росту качества даже у слабых моделей и сопоставимым результатам с большими моделями.
Вспомнив этот факт, я поменял всего лишь одну строчку в JSON-схеме: reasoning стал первым свойством, которое генерировала модель в ответе. И только это небольшое исправление дало прирост F1 до 0.6: теперь перед тем как расставить нужные классы
label_X модель опиралась не только на входной текст, но и учитывала свои размышления в ответе.P.S. Промпт в итоге довел до F1 0.71 на слабой модели Gemini 3.1 flash lite. А переход на более мощный Claude Sonnet 4.6 теперь дает несущественный прирост в 0.04, который не стоит своих денег