TL;DR
Исследователи проверили могут ли маленькие открытые модели (Phi-4, Qwen2.5-14B, Gemma-3-12B) конкурировать с GPT-4o и Claude на биомедицинских вопросах. Использовали structured outputs (JSON schema для формата ответа), ensembling (объединение ответов разных моделей) и промпты с явными ограничениями ("не больше 5 элементов", "максимум 50 слов").
Главная находка: открытые модели конкурентны с проприетарными, особенно при ensembling. Для да/нет вопросов — паритет. Для сложных вопросов (список сущностей, факты) — ensemble разных открытых моделей часто бьёт одиночные GPT/Claude. Почему? Разнообразие важнее размера. Phi-4 рассуждает иначе чем Qwen, Gemma добавляет третий взгляд — вместе находят правильный ответ чаще чем одна большая модель.
Для саммари лучше всего сработал Phi-4 (открытая модель 14B параметров) — обогнал проприетарные модели по ROUGE метрикам. Когда было несколько кандидатов от разных моделей, лучший выбирали через cross-encoder reranking — модель сама оценивала какой саммари ближе к вопросу.
Схема метода
Для точных ответов (да/нет, факты, списки):
ШАГ 1: Выбор контекста
└─ Выбрать 10 релевантных сниппетов по косинусной близости (через embeddings)
ШАГ 2: Генерация ответов
├─ Для да/нет и саммари: zero-shot (без примеров)
└─ Для фактов и списков: few-shot (3 примера из прошлых вопросов)
ШАГ 3: Structured output
└─ JSON schema → модель выдаёт ответ строго в заданном формате
ШАГ 4: Ensembling (опционально)
├─ Да/нет: majority voting (большинство голосов)
└─ Факты/списки: частотный подход (берём самые частые ответы)
Для саммари:
ШАГ 1: Генерация нескольких кандидатов
└─ Разные модели → каждая генерирует саммари
ШАГ 2: Cross-encoder reranking
└─ Модель считает similarity(саммари, вопрос) → выбирает лучший
Примеры применения
Пример 1: Structured Output для точного формата
Задача: Тебе нужно собрать список конкурентов для анализа рынка. Хочешь чтобы модель выдала строго 5 компаний, без лишнего текста.
Промпт:
Проанализируй рынок онлайн-кинотеатров в России.
Верни ответ СТРОГО в JSON формате:
{
"competitors": ["компания1", "компания2", ...],
"count": число_компаний
}
Требования:
- Максимум 5 компаний
- Только действующие сервисы в России 2025
- Без объяснений, только JSON
Результат:
Модель вернёт валидный JSON с ровно 5 компаниями. Никакого "Вот анализ рынка...", никаких markdown-блоков — чистый JSON который можно сразу парсить или вставить в таблицу.
Пример 2: Ensembling для надёжного ответа
Задача: Проверяешь гипотезу для статьи. Хочешь быть уверен что ответ правильный — один запрос может ошибиться.
Промпт (3 запроса к модели):
Верно ли что Озон запустил продуктовые дарксторы в 2024 году?
Ответь только "Да" или "Нет".
Результат:
Получишь 3 ответа от модели. Если 2+ сказали "Да" → финальный ответ "Да". Это majority voting — простейший ensembling который работает для бинарных вопросов.
Для фактов (не да/нет): запусти несколько раз, собери ответы, возьми самый частый. Если все ответы разные — красный флаг, модель не уверена.
Пример 3: Промпт с явными ограничениями
Задача: Клиент просит "короткий саммари статьи". Но что такое "короткий"? 100 слов? 500? Модель додумает сама — и скорее всего напишет больше чем нужно.
Промпт:
Прочитай статью о новом законе о маркетплейсах.
Напиши саммари:
- Максимум 50 слов
- Один абзац
- Без вводных фраз ("в статье говорится...")
- Только главные изменения
Результат:
Модель выдаст текст ровно в этих рамках. Не "примерно 50", а жёстко в пределах. Explicit constraints работают лучше чем "будь краток" — модель понимает конкретные числа.
Почему это работает
Structured outputs решают проблему парсинга. LLM любит добавлять "Конечно! Вот ваш ответ...", markdown-обёртки, объяснения. JSON schema убирает двусмысленность — модель генерирует только валидный JSON, потому что токены выбираются по CFG (context-free grammar). Это не постобработка, это управление на уровне сэмплирования.
Ensembling работает потому что модели ошибаются по-разному. Phi-4 может пропустить деталь, Qwen2.5 додумать лишнее, Gemma упустить контекст. Но если все три согласны — вероятность правильного ответа резко растёт. Это как спросить трёх экспертов вместо одного.
Явные ограничения ("max 5 entities", "не больше 50 слов") дают модели конкретный таргет вместо расплывчатого "будь краток". Модель считает токены и останавливается когда подходит к лимиту. Без числа она додумывает "краткость" сама — и обычно ошибается в сторону многословия.
Рычаги управления:
- Количество элементов (5 entities, 10 snippets): уменьши для простых задач, увеличь для полноты
- Длина output (50 слов, 200 символов): чем короче — тем концентрированнее мысль
- Few-shot vs zero-shot: факты/списки любят примеры, да/нет и саммари — нет
- Количество моделей в ensemble: 3 модели — минимум для majority voting, 5-7 — для надёжности
Шаблон промпта
Structured Output (JSON)
{задача}
Верни ответ СТРОГО в JSON формате:
{
"answer": "{тип_ответа}",
"confidence": "high/medium/low"
}
Требования:
- {ограничение_1}
- {ограничение_2}
- Без объяснений, только JSON
Где:
{задача}— вопрос или инструкция{тип_ответа}— формат (строка, список, число){ограничение_N}— explicit constraints ("максимум 5 элементов", "только русские компании")
Ensembling (Majority Voting для да/нет)
{вопрос_требующий_да_или_нет}
Ответь ТОЛЬКО "Да" или "Нет". Без объяснений.
Запусти 3-5 раз. Выбери ответ который встретился чаще всего.
Промпт с ограничениями
{задача}
Формат ответа:
- Максимум {число} слов/элементов
- {стиль} ({пример: "один абзац", "список через запятую"})
- Без {что_исключить} ({пример: "вводных", "объяснений"})
Где:
{число}— жёсткий лимит (50 слов, 5 элементов){стиль}— как структурировать (абзац, список, bullet points){что_исключить}— что модель любит добавлять, но тебе не нужно
Ограничения
⚠️ Embeddings требуют код: Выбор 10 лучших сниппетов по косинусной близости — это не промпт, это Python + sentence-transformers. В чате недоступно.
⚠️ Vector database нужна инфраструктура: Поиск похожих примеров через Qdrant — это сервер, не чат. Можно симулировать вручную (скормить модели все примеры и попросить выбрать 3 похожих), но это дорого по токенам.
⚠️ Ensembling стоит денег: 3-5 запросов вместо одного = 3-5x стоимость. Для критичных решений оправдано, для рутины — перебор.
⚠️ Structured outputs не всегда нужны: Для творческих задач (статья, эссе) JSON-формат вредит. Используй только когда нужен конкретный формат для парсинга.
Как исследовали
Команда взяла BioASQ Challenge — соревнование по биомедицинским вопросам. 4 типа вопросов: да/нет, факты (назови 1-5 сущностей), списки, саммари. К каждому вопросу прилагались статьи из PubMed.
Протестировали малые открытые модели (Phi-4, Qwen2.5-14B, Gemma-3-12B) против топовых проприетарных (GPT-4o, GPT-4.1, Claude 3.5 Sonnet, Claude 3.7 Sonnet). В первых трёх батчах использовали квантизованные (4-bit) версии открытых моделей для экономии памяти. В четвёртом батче — полные версии.
Интересное: квантизация (сжатие модели в 4 раза) почти не навредила качеству. Phi-4 в 4-bit работал так же хорошо как GPT-4o.
Что измеряли:
- Точность (accuracy) для да/нет
- Strict/Lenient accuracy + MRR для фактов
- Precision/Recall/F1 для списков
- ROUGE-2 и ROUGE-SU4 для саммари
Главный инсайт: Ensemble разных семейств моделей (Phi + Qwen + Gemma) бил ensemble одного семейства (3x Claude или 3x GPT). Почему? Phi-4 обучена на одних данных, Qwen2.5 на других, Gemma на третьих. Разные "взгляды" на задачу → меньше общих ошибок.
Неожиданный результат: Для саммари Phi-4 (14B параметров) обогнал всех по ROUGE metrics в батчах 1-3. Одна маленькая открытая модель > большие проприетарные. Причина: Phi-4 обучена на "качество текста", Claude/GPT — на "полнота ответа". Для саммари важнее первое.
Контринтуитивное: Few-shot (3 примера) вредил для да/нет и саммари. Работал только для фактов и списков. Почему? Да/нет — слишком простая задача, примеры запутывают. Саммари — слишком креативная, примеры "якорят" стиль.
Ресурсы
Are Smaller Open-Weight LLMs Closing the Gap to Proprietary Models for Biomedical Question Answering? — Damian Stachura, Joanna Konieczna, Artur Nowak (Evidence Prime, Краков, Польша). CLEF 2025 Working Notes. Весь код открыт на GitHub.
