Большие языковые модели играют в "Бесконечное Лето"

Большие языковые модели играют в "Бесконечное Лето"

ИИ-агенты на базе больших языковых моделей способны управлять календарём, почтой, участвовать в инвестициях, вносить вклад в open-source и даже вести блоги. Но могут ли они сыграть в визуальную новеллу?

Идея эксперимента

Автор задумался: визуальная новелла — это в основном текст. А большие языковые модели (LLM) созданы для работы с текстом. Почему бы не попробовать?

Были развернуты локальные LLM, настроена интеграция с движком Ren’Py, использован Ollama, а игра «Бесконечное Лето» была модифицирована для автоматизации. Подробности — в технической части, сюжетные повороты скрыты под спойлерами.

Почему «Бесконечное Лето»?

Из двух известных автору визуальных новелл — «Бесконечное Лето» и «Doki Doki Literature Club» — выбор пал на первую. Вторая помечена как «психологический хоррор», что усложнило бы эксперимент.

Встретив на улице Семена, главного героя игры, вы бы никогда не обратили на него внимания — действительно, подобных людей в каждом городе тысячи и даже сотни тысяч. Но однажды с ним приключается совершенно необычное происшествие: он засыпает зимой в автобусе, а просыпается... посреди жаркого лета. Перед ним — пионерлагерь «Совенок», а позади — прошлая жизнь. Чтобы разгадать, что же с ним случилось, Семену придется получше узнать местных обитателей (а может, даже встретить любовь), разобраться в лабиринтах сложных человеческих взаимоотношений и своих собственных проблемах, решить загадки лагеря. И главное понять — как вернуться обратно или не возвращаться вовсе? — Официальная страница в Steam

Игра предлагает 13 финалов, зависящих от выборов игрока. Это делает её идеальной для тестирования поведения LLM в сложных социальных сценариях. Проявят ли модели эмпатию? Или их осторожность приведёт к нейтральным, но бессмысленным решениям?

Создание моста к игре

«Бесконечное Лето» использует движок Ren’Py, основанный на Python. Это позволяет внедрять произвольный код. Был создан файл bridge.rpy, в котором:

  • Перехватывается функция say для отправки реплик в TCP-сервер;
  • Переопределяется renpy.display_menu для получения выборов от модели;
  • Добавлена поддержка карты через переопределение функций в store.

Также была реализована возможность пропуска карточной игры — чтобы не усложнять задачу.

Настройка больших языковых моделей

Эксперимент проводился с моделями, развернутыми локально, чтобы избежать утечки контекста. Использовался Docker с av/harbor и Ollama на сервере с H100. Модели:

  • deepseek-r1:70b;
  • qwen3.5:9b;
  • qwen2.5:3b;
  • gpt-oss:20b;
  • gemma3:27b.

Все запросы к моделям отправлялись через POST /api/chat в формате JSON.

Координатор: связь между игрой и моделью

Координатор — это TCP-клиент, который:

  • Собирает реплики и выборы из игры;
  • Формирует диалог для LLM с использованием ролей: system (мысли героя), tool (реплики персонажей), user (вопросы выбора), assistant (ответ модели).

Промты были простыми:

  • В начале: «Ты — ассистент Семёна. Он доверяет тебе. Помоги ему выбрать лучший вариант»;
  • При выборе: «Перед тобой стоит выбор: [список]. Какой вариант посоветуешь? Ответь одной цифрой».

Проблемы и доработки

«Человеческие» ответы

Модели часто не ограничивались одной цифрой. Примеры ответов:

1. Нет, я останусь здесь

Я выбираю: 2.

Подходящий тег: подростковая драма.

Простое извлечение первой цифры не работало. Решение — отдельный запрос к модели:

Пользователь ответил: 3. Нет, я останусь здесь. Назови номер выбранного варианта.
Ответь только цифрой.

Этот метод оказался надёжным.

Слишком большой контекст

К концу первого дня в игре накапливалось более 800 реплик. Модели замедлялись — выборы занимали 5–7 минут.

Решение: при превышении 200 сообщений, старые пачками по 100 передаются в «чистый» чат с промтом: «Напиши краткое содержание». Результат вставляется в основной диалог.

Так контекст остаётся релевантным, а производительность — стабильной.

Результаты прохождения

После доработок модели начали проходить игру. Результаты:

  • deepseek-r1:70b — в тестах доходила до плохой основной концовки, но при записи зациклилась в лабиринте, выбирая «третий вариант». После перезапуска генерировала здравые мысли, но координатор ошибочно интерпретировал их как повтор выбора.
  • gpt-oss:20b — достигла основной плохой концовки. Стабильна.
  • qwen3.5:9b — быстро принимала решения, но при выборе спутницы «думала» более 20 минут. Остановлена.
  • qwen2.5:3b — вышла на плохую концовку Лены. Повторила результат в тестах.
  • gemma3:27b — дважды заблудилась в лабиринте. В тестах — плохая концовка Алисы.

Лабиринт прост, но модели склонны к зацикливанию из-за повторений в контексте.

Основная концовка — без романтической линии. «Плохая» — герой возвращается домой, не изменившись. «Хорошая» — встречает кого-то из лагеря в реальности.

Концовка Лены — самая мрачная: она пропадает, и герой не может её найти.

Вывод

Эксперимент показал: большие языковые модели пока не готовы к самостоятельному прохождению визуальных новелл. Даже с доработками они чаще всего выбирают неоптимальные или абсурдные пути.

Проект стал, по сути, дорогим генератором псевдослучайных чисел. Главный урок: слепо доверять LLM маршрут в лабиринте — плохая идея.

Читать оригинал