Недавно задумался, а что происходит при
llm.with_structured_output.Интересовали два вопроса:
1. Гарантируется ли формат?
2. А как это работает, если провайдер не умеет “вернуть JSON по схеме”
Копнув глубже, оказалось:
with_structured_output - это не одна функция, а 3 разных режима под капотом:### 1. json_schema
Провайдер применяет server-side ограничение на формат ответа (constrained decoding)
• работает только если провайдер это реально поддерживает
• через прокси (например OpenRouter) может деградировать
### 2. function_calling
Хитрый трюк:
• схема превращается в tool
• модель возвращает не текст, а вызов функции (tool_call)
• аргументы функции = ваш JSON
### 3. json_mode
Просто добавляем в промпт: “верни JSON вот в таком формате, умоляю”
### Итого
Гарантируется ли формат?
• json_schema (нативный) - почти да (но вот gemini-2.5-flash-mini через openrouter у меня не всегда)
• function_calling - почти да
• json_mode - если хорошо попросишь
LLM - это стохастический попугай. Все, что она умеет - вероятностно генерировать токены. Всегда есть шанс, что промпт проигнорируется, json будет битый или не тот.
Поэтому помним - LLM нам ничего не должна. Она как работа с сетью - в случайный момент может отвалиться. Без retry не обойтись