Введение
Приветствую! Я — автор портала текстовых игр в жанре "квест" questio.ru. Основная цель проекта — полностью автоматизировать роль автора игры, исключив человеческое вмешательство. Это стало возможным с появлением доступных LLM достаточной "сообразительности".
Но, как это часто бывает, разработка быстро сместилась с решения бизнес-задач на преодоление технических трудностей. В этой статье я поделюсь опытом, который, надеюсь, поможет начинающим разработчикам избежать типичных ошибок при работе с LLM (Large Language Models).
Общие проблемы
Первое, с чего я хочу начать - озвучить очевидное: промышленный продукт, стабильно выдающий корректный результат, и тестовый стенд с "надёжностью 90%" — это, как говорится, две большие разницы. Основные препятствия на пути к стабильности:
Галлюцинации — модель придумывает лишнее или нерелевантное.
Бесконечный поток — самоповтор, ведущий к исчерпанию лимита ответа.
Проблемы с интерпретацией — непонимание сложных запросов.
Время обработки — задержки из-за сложных промтов или форматов (например, JSON).
Для достижения требуемого уровня надёжности код часто приходится усложнять, перестраивать и дополнять проверками. Рассмотрим ключевые аспекты подробнее.
Локальная модель или API: есть ли разница?
Изначально проект задумывался для локальных моделей, но проблемы с точностью промптов заставили опробовать разные API-варианты (GigaChat, ChatGPT-4o). И результаты получились не однозначные. Проблем с большими моделями меньше, но они все равно есть. И также, как и локальные модели, каждая требует индивидуальной настройки (один и тот же результат достигается в разных моделях разными промтами или, что тоже самое, один и тот же промт на разных моделях дает разный результат).
Результаты сравнений:
Галлюцинации и "сваливания в бред" остались, хотя их частота снизилась.
Локальные модели обязательно требуют дополнительных запросов для уточнения и корректировки (имеется ввиду размер 7B, модельки побольше почти не требовали корректуры).
Крупные модели лучше работают с JSON
Крупные модели лучше понимают задачу, но разница оказалась гораздо скромнее, чем ожидалось
Вывод:
Крупные модели (кроме "nano"-версий) в общем случае работают лучше, но все равно не идеально. Даже под топовые модели нужна индивидуальная подстройка и большое внимание к потенциальным ошибкам.
Для текстовых квестов принципиальной разницы между локальными и API-моделями нет. Локальные решения дешевле, но требуют больше доработок. Если есть ограничения на время разработки, данный фактор становится существенным.
Примечание: Рассуждающие модели дают качественно лучшие результаты, но их стоимость делает их непрактичными для массового применения.
Галлюцинации и как с ними бороться
Под "галлюцинациями" понимаются:
Отступление от требований промта (неточное соблюдение оформления, слишком длинный ответ при требовании краткости, упущение важных деталей или придумывание того, что не было запрошено и т.д.).
Зацикливание или артефакты в ответах (бесконечное генерирование "хвоста" одними и теми же фразами, подмешивание вставок на разных языках, специальных символов).
Методы борьбы:
Ограничение размера ответа
Если ответ совпадает с лимитом, вероятно, он неполный или невалидный.
Решение:
Повторить запрос, изменив параметрtemperature
и/или увеличив лимит. И так до тех пор, пока "упор в лимит" не исчезнет. Также иногда помогает варьирование других параметров (например, штраф за повтор).-
Упрощение промтов
Комплексные промты работают нестабильно: модель может забыть часть условий. Часто в этом случае помогает замена на последовательность более простых запросов - для каждого атрибута по очереди.
Пример:Плохо: "Придумай персонажа с именем, внешностью, характером и списком предметов в инвентаре."
Лучше: "Придумай имя персонажа" → "Опиши его внешность" → "Добавь 3 предмета в инвентарь."
Поддержка русского языка
Большинство открытых моделей небольшого размера обучены на одном или нескольких европейских языках. Русскоязычные тексты если и участвовали в обучении, то явно в недостаточном количестве. Поэтому русский язык в запросе - нормально, а вот в ответе - почти всегда имеет проблемы. От явных (включение иностранных слов или их частей) до малозаметных (плохо согласованные словосочетания, повторы).
Для русского языка лучше подходят отечественные модели (GigaChat, YandexGPT) или тюнингованные (Saiga), но они хуже понимают, что от них хотят. Для таких моделей требуется тщательная разработка последовательности запросов с декомпозицией изначально комплексной задачи.
Универсальные модели (например, Llama, Gemma) могут смешивать языки или выдавать некорректные формулировки, но у них лучше с понимаем требований.
Проблемы с логикой и креативностью
Сложные текстовые конструкции и неоднозначные термины часто приводят к неожиданным результатам - LLM не до конца понимает, что с чем связано, что главное, а что второстепенное и так далее. Также к проблемам "по логике" можно отнести однообразность ответов при просьбе проявить креативность или явном запрете "не используй следующие слова/названия:...".
Решения:
Сведение к бинарным ответам ("ответь только да или нет").
-
Использование генераторов случайных вариантов на основе заранее подготовленных списков (кодом делаем небольшую выборку, а потом просим LLM выбрать наиболее подходящий из выбранных вариантов). Пример:
Вместо "Придумай название города" → "Выбери номер из списка: 1. Ривенделл, 2. Даркхольм, 3. Берег Слёз."
Такой подход позволяет заставлять модель креативить: случайным образом выбираем какой-нибудь нетипичный вариант и заставляем LLM выкрутиться. В противном случае (если "придумай сама") часто получаем одно и тоже.
JSON or not JSON?
Как известно, все современные модели поддерживают генерацию JSON в качестве ответа. Такой способ получения данных отлично подходит для различных формализаций.
Ведь мало получить ответ от LLM, надо из него еще данные нужные выцепить. Например, при формировании игрового персонажа было бы неплохо сразу получить и его тип, и имя, и описание внешнего вида, и характер.
Однако при простой текстовой формулировке "где что" в ответе LLM понять бывает очень сложно. Формат JSON решает эту проблему, раскладывая данные по полям.
Плюсы JSON:
Структурированный вывод. Легко извлекать данные (например, для игрового персонажа).
Минусы:
JSON требует времени: гарантированный вывод в JSON не является способностью LLM, это - заслуга движка, под управлением которого LLM работает. Движок перегенерирует ответ или его часть до получения корректного синтаксиса. Это приводит к тому, что запросы с JSON могут выполняться от 1 до 15 секунд против 1-2 секунд для простого текста.
Рекомендация: Для задач, где время критично, используйте простое форматирование с проверкой полноты ответа.
Итоговые рекомендации
Минимизируйте лимиты ответа (в токенах).
Проверяйте размер ответа — если совпадает с лимитом, запрос стоит повторить.
Делайте контрольные запросы для корректировки текста.
Запрещайте лишнее: добавляйте "Не пиши комментариев и пояснений".
Дробите сложные промты на несколько простых.
Давайте выбор вместо "Придумай сам" — это повышает вариативность.
Заключение
Работа с LLM требует баланса между качеством, скоростью и стоимостью. Лучшие результаты достигаются через итерации, упрощение и строгий контроль. Надеюсь, этот опыт поможет вам в ваших проектах!
Комментарии (6)
KonstProg Автор
14.08.2025 04:43Да, согласен, ситуация в этом плане постепенно меняется. Поэтому "большинство", а не "все". Т.е. если нужен качественный русский язык, сейчас это не непреодолимое препятствие, а лишь существенный ограничитель выбора.
Что касается Qwen3 - тестировали вариант 8B 100+ дневной давности - были некоторые проблемы. Ваш вариант обязательно погоняем. Среди прочих опробованных (в разных вариантах квантизации): llama3 8B, gemma2 9B, llama3.1 в разных вариантах, ministral 8B, qwen2.5, deepseek-r1 (разные дистилляции), t-lite-it-1, yandexGPT5 8b, saiga, phi 3.5, gemma3.
Politura
14.08.2025 04:43Если будете пробовать, на что стоит обратить внимание: большинство сервисов по умолчанию предлагают использовать модели с 4-м квантом. Если для больших моделей это терпимо, то у моделей на 8b параметров и меньше на таком кванте риск получить галлюцинацию уже выше, так что лучше использовать модели с 8-м квантом, или хотя-бы с 6-м.
Gromov32lvl
14.08.2025 04:43Почитал и вспомнил, как сам пытался строить такие автономные системы. Итог один: всё красиво на бумаге, а на деле куча костылей и багов. Но эксперимент интересный, видно, что автор реально покопался.
NestlyS
14.08.2025 04:43Сейчас все упирается в то, что не до конца понятно, как корректно использовать творческий потенциал нейросети без вреда. Нейросети очень несистемны, не имеют жесткой логики, но очень гибки. Они действительно неплохо придумывают новый контент или анализируют переданный, но чтобы это работало качественно надо знатно поломать голову.
Это я к чему: зависит от того, что автор хочет сделать. Если нейросеть будет просто персонажей генерировать из определенной выборки "тегов", то это одно, а если она будет описывать полноценное приключение - то это другое.
На мой взгляд в обоих случаях нейросети требуется отличный такой "костяк" игровой логики, к которому она будет обращаться для получения и изменения информации. Потому что держать игровой мир в контексте очень быстро приводит к плачевным последствиям.
Politura
Китайские Qwen3 последние модели пробовали? У них все отлично с русским языком, если спрашивать на русском, то не только отвечать будут на русском, но и думать на нем-же. Вот, очень маленькая модель, всего 4b параметров, как думает:
Финальный ответ, не полный: