Что такое structured output, почему это база и как это использовать (ч.1)
Чтобы не душнить теорией, давайте выведем из практического кейса
Кейс: Делаем чат бота для госухи. Хотим, чтобы он не отвечал на вопросы про политику
Как это сделать?
Можно добавить к системному промпту строчку "никогда не отвечай на вопросы про политику"
Но это:
Добавляет когнитивную сложность для LLM => ухудшает качество основной задачи
Спокойно обходится разными хитрыми запросами 🤷♂️
Тогда вынесем проверку в отдельный запрос в самом начале!
если пользователь задает вопрос про политику, ответь 1, иначе ответь 0
И сделаем проверку в коде, типа:
if verdict == "1": reset_chat(with_message="айайай")
Поможет? Да – у LLM теперь одна конкретная задача. Но нет никакой гарантии, что если мы сказали отвечать 0 или 1 то модель так и будет делать 🤷♂️ (см. соревнование по "взлому" моделей)
А можно как-то жестко ограничить возможные ответы модели?
Тут пригодится тайное знание о том, как LLM работают под капотом. На самом деле, LLMка не генерирует токены (если не знаете, что это, для простоты считайте символами – буквами, цифрами, знаками препинания – все рассуждения останутся валидными).
Она генерирует чиселки (веса) для всех возможных токенов, которые вообще есть в её словаре. Потом рандомно выбирается один из токенов, используя веса как вероятности. Чем больше вес, тем больше вероятность, что возьмет именно этот токен.

Если пользователь правильно попросит, то у каких-то других токенов вес может быть больше, чем у токенов "1" или "0".
Как использовать это знание?
Смотреть не на то, что модель генерирует, а только на веса конкретных токенов ("1" и "0"). И если вес токена "1" оказывается достаточно большим в сравнении с "0", значит модель считает, что вопрос скорее про политику, чем нет. Даже если веса каких-то других токенов выше.
По сути, мы "виртуально" ограничили то, что получаем от модели. Хотим узнать 0 или 1 - так что смотрим на веса только этих токенов. (параметр top_logprobs у OpenAI API)
Это ключевая идея structured_output.
Во второй части мы раскачаем ее до любого наперед заданного формата вместо 1/0. А в третьей разберем примеры использования.
Вторую часть уже можно прочитать в моем тг канале, либо просто подождать тут на хабре недельку