Зелёные тесты врут: как ИИ-мастер DnD проходит живой QA-прогон и скрипт-аудитор

Юнит-тесты AI-Мастера DnD проверяют отдельные функции на фиксированных входах, а не поведение нейросети в реальной кампании: промпт-запрет может сработать девять раз и не сработать на десятый. Поэтому баг не закрывают по зелёным тестам - только после живого QA-прохождения кампании ИИ-агентом и постфактум-проверки скриптом-аудитором.
Зелёные тесты врут: как ИИ-мастер DnD проходит живой QA-прогон и скрипт-аудитор
В одной из кампаний AI-Мастера DnD был кузнец. Обычный ролевой NPC, без имени - только профессия. Игрок попросил его позвать сына и жену, и движок вместо того, чтобы завести двух новых персонажей, переименовал самого кузнеца. Та же запись в базе, тот же ID - но теперь это “Жена кузнеца”, с флагом компаньона, которого никто не нанимал. В прозе следующего хода кузнец и его жена стояли рядом оба сразу, а в базе кузнеца уже не было. И да, 6520 юнит-тестов в этот момент были зелёные - все до одного.
Что было: баг считался закрытым, если тесты зелёные. Что стало: правило теперь стоит в каждой задаче проекта одной строкой - багфикс логики ИИ-мастера не закрывается по зелёным юнит-тестам, только после живого QA-прохождения реальной кампании.
Почему зелёные юнит-тесты не гарантируют работу ИИ-мастера
Юнит-тест проверяет одну функцию на одном фиксированном входе и получает предсказуемый ответ. Нейросеть в реальной кампании так не работает: один и тот же промпт-запрет может отработать девять раз подряд - и не сработать на десятый, в незнакомом сочетании реплик игрока. Тест этого не увидит, потому что тестирует не саму нейросеть, а код вокруг неё.
Ровно так однажды провалился фикс, который в юнит-тестах выглядел безупречно: промпт-запрет “не материализуй упомянутых, но отсутствующих NPC” держался во всех тестах, а в живой кампании фантомный NPC - “Старый Хьюго, живёт у оврага, иди к нему сам” - всё равно материализовался в сцене, хотя фикс был уже задеплоен. Про похожий баг с NPC, который однажды не отпускал игрока по всем сценам подряд, мы уже писали отдельно - корень там тоже был в том, что нейросеть вела себя иначе, чем в тестах.
Это не только особенность одного проекта. По данным Confident AI (2026), релиз ИИ-агента может выглядеть нормально в юнит-тестах и всё равно ломаться в проде - потому что агент выбрал не тот путь до того, как выдать правдоподобный финальный ответ. Юнит-тест видит последний шаг цепочки, а не всю цепочку целиком.
Как устроен живой QA-прогон кампании
Живой QA-прогон - это полное прохождение свежей кампании через тот же игровой API, которым пользуются обычные игроки: каждый ход, каждая реплика NPC и каждая запись в базе сверяются построчно, а не только финальный текст на экране игрока.
Показательный прогон занял 26 ходов игрока - 27 ответов мастера с учётом вступления - и уложился в 29 минут, с 19:39 до 20:08 по логам. Партия успела пройти через девять сцен: лесная опушка, таверна, дом, улица, снова таверна, снова опушка, деревня, скобяная лавка, площадь. Каждый ответ мастера рождался от 13 до 32 секунд, медиана - около 20. Прогон был разбит на восемь сценариев с вердиктом PASS или FAIL по каждому: утечка офф-скрин NPC в текст, вычистка компаньона при смене сцены, материализация ролевого NPC из прозы, роль поверх уже известного имени, смена локации, падежные дубли одного персонажа (“бродягу” и “бродяге” - это не два разных NPC), санитарная проверка (пустые ответы, тайминги) и качество новых имён.
Кто проходит кампанию - доброволец или сама нейросеть
Кампанию не проходит ни доброволец, ни автор лично - её играет отдельный ИИ-агент в роли QA, который делает живые ходы через служебный тестовый аккаунт по тому же API, что и настоящий игрок. Фикс в это время пишет другой агент, в роли разработчика. Получается конвейер из двух ролей на разных моделях: один чинит, другой проверяет, и ни один не судит сам себя.
Мы писали об этом, когда сравнивали ИИ-мастера с живым человеком за столом: нейросеть слабее там, где не хватает независимого взгляда со стороны. На проекте эту роль “взгляда со стороны” и закрывает отдельный QA-агент - не тот же самый, что писал фикс.
Что живой прогон нашёл, а тесты пропустили
Один живой прогон нашёл четыре новых бага, и самый опасный получил приоритет P1: известный NPC-кузнец получил чужое имя и флаг компаньона, а компаньоны в системе защиты прозы получают иммунитет от вычистки - то есть баг мог путешествовать за игроком по всем сценам необнаруженным.
Механика поломки видна прямо в логах: безымянный NPC “кузнец” получил имя “Жена кузнеца” тем же ID, occupation остался “кузнец”, is_companion стал true. Отдельно завелась новая запись “Сын кузнеца” - с этой частью всё было в порядке, дедуп отработал штатно. А вот is_companion - тот же флаг, который раньше чинили, чтобы спутник не пропадал из памяти мира через десяток ходов, - сработал теперь в обратную сторону и закрепил персонажа, которого никто не нанимал.
Второй показательный случай того же прогона мельче по приоритету, но заметнее по симптомам: гард, вычищающий из текста офф-скрин NPC, честно сработал 5 раз из 5 - ни одно чужое имя не дошло до игрока. Но в 4 случаях из 5 после вычистки в прозе оставались висячие местоимения без антецедента и непарные кавычки - предложение теряло того, о ком “он” только что говорил. Формально гард прошёл проверку, а связность текста - нет; для игрока это ощущается как “мир слегка заикается” ровно там, где кто-то только что пропал из истории.
Зачем нужен скрипт-аудитор прогона и как он сам обманулся
Скрипт-аудитор - это 245 строк кода, которые постфактум читают записи базы данных прошедшей кампании и по регулярным выражениям ищут три класса проблем: фантомов, переименования известных NPC и разрывы связности прозы. Он не играет за игрока - он разбирает то, что игрок уже прошёл, когда живой прогон закончился.
И тут же вышел забавный казус: сам аудитор дал ложный FAIL. Его регулярка на поиск найма компаньона не распознавала бытовые формулировки согласия - “по рукам”, “ладно, идём” - и сообщала, что найма не было, хотя флаг is_companion выставился штатно и по делу. Регулярку расширили по итогам того же прогона. Кто проверяет проверяющего? Здесь - тот же живой прогон, только внимательнее вчитались в его логи. Похожий класс проблемы уже разбирали на площадке - когда автоматический валидатор ответов начал глушить обычные ходы игрока, приняв их за нарушение правил. Проверяющий код нуждается в проверке живыми данными не меньше, чем сама нейросеть.
Как выглядит цикл фикс → тест → живой прогон → ретест
Цикл на проекте всегда один и тот же: сначала фикс и юнит-тесты, потом живой прогон свежей кампании; если баг нашёлся - рефикс и повторный прогон; и только когда фильтр отработал чисто на двух прогонах подряд, скрипт-аудитор выдаёт FAIL=0, и задача закрывается.
Первая версия фикса для фантомного Хьюго была промптовой - держалась в юнит-тестах, но провалилась на живом прогоне. Вторая версия отказалась от промпта в пользу обязательного поля в схеме экстрактора, которое код фильтрует до того, как NPC попадёт в сцену, - и прошла ретест 2 из 2, включая контрольную пару: одно и то же имя один раз отфильтровано, пока персонаж только упомянут в разговоре, и материализовано, как только он физически оказался в сцене. На проекте это называют паттерном: словарно-прозовые задачи стабилизируются за две итерации - первая обычно промптовая и хрупкая, вторая детерминированная и держится. По той же волне фиксов первый заход живого QA сразу дал PASS в двух задачах из трёх; третья (та самая, с Хьюго) и потребовала этой второй итерации.
Что это значит для игроков
NPC, который вдруг теряет своё имя или получает чужую роль, - это не редкость, которую можно поймать одним прогоном и забыть, а класс багов, который целенаправленно ищут перед каждым релизом отдельным QA-агентом и отдельным скриптом-проверки. Проект честно называет себя активной стройкой: баги будут - вопрос не в том, есть они или нет, а в том, ловят их молча или вслух.
Если замечаешь похожую нестыковку в своей партии - персонажа, который вдруг стал кем-то другим, или NPC, который помнит то, чего не было, - пиши в чат “Таверны Мокрый Тортл”: такие находки идут прямиком в следующую волну живого QA.
Частые вопросы
Сколько времени занимает живой QA-прогон кампании ИИ-мастера DnD?
Прогон на 26 ходов игрока занимает около 29 минут: с 19:39 до 20:08 по логам одного из живых тестов, каждый ответ мастера - от 13 до 32 секунд, медиана около 20 секунд.
Может ли скрипт-аудитор прогона ошибаться?
Да - в одном прогоне регулярка скрипта-аудитора на поиск найма NPC не распознала бытовые формулировки согласия ("по рукам", "ладно, идём") и дала ложный FAIL; её расширили по итогам того же прогона.
Чем живой QA-прогон отличается от юнит-тестов?
Юнит-тесты проверяют изолированные функции на фиксированных входах. Живой прогон - это полное прохождение свежей кампании через игровое API, где проверяется поведение нейросети вместе со всей системой, а не один вызов.
Как готовился материал: черновик собирает мой ИИ-конвейер по темам из практики таверны, факты сверяются с первоисточниками и правилами, финальную версию я читаю и правлю руками перед публикацией. Обложку тоже рисует нейросеть. Про кухню — на странице о проекте.