ДнД с ИИ: как баг заставил NPC ходить за героем по всем сценам, а фантомы оживать из разговоров

Баг возникал из-за soft-keep: canon-гард ловил NPC не в своей сцене, но после неудачного ретрая игроку всё равно отдавался неисправленный текст. Фикс перенёс защиту в код - механическая вычистка офф-скрин имён, эскалация гарда на четырёх выходах, материализация новых NPC из прозы и дедуп имён - а не в промпт, которому нельзя доверять на слово.
24 июля в чат тестеров упала жалоба: игрок разговаривает с NPC в лесу, а по фактам мира этот NPC “остался в доме”. В следующем ответе нарратор невозмутимо пишет “Морти, шагающий чуть поодаль” - хотя Морти в этой сцене вообще не должно быть. Для игрока это выглядит просто как баг с телепортацией: NPC как будто следует за партией из локации в локацию без единой команды “иди за нами”. Дальше выяснилось, что это только полбеды: вторая жалоба того же дня показала, что бот вообще не заводит карточки новым персонажам, которых сам придумывает в прозе - истории обрастают людьми, которых потом невозможно позвать по имени.
Разбираемся, как ИИ-мастер ДнД дошёл до такого, почему одна защита ловила баг, но не могла его исправить, и что в итоге понадобилось, чтобы починить обе стороны проблемы.
Почему нейросеть для ДнД путает, где стоит NPC
Модель знает, что Морти не в сцене - за это отвечает canon-гард, который сверяет прозу с фактами мира. Проблема была не в детекции, а в том, что происходило после неё: гард ловил офф-скрин имя, отправлял ответ на ретрай - а модель на ретрае писала то же самое имя. Игроку в итоге отдавался первый, неисправленный вариант (мы называем это soft-keep - “тихо сохранить неправильное”).
Что было → что стало на этом конкретном случае: до фикса игрок в лесу читал “Морти, шагающий чуть поодаль” - хотя по фактам мира Морти оставался в доме. После фикса при том же нарушении гард не отпускает ситуацию после одного неудачного ретрая, а вычищает офф-скрин имя из текста механически, кодом, а не второй попыткой у той же модели.
Гард видел нарушение с самого начала - дело было не в том, что он “слепой” к офф-скрин именам, а в том, что после детекции у него был только один инструмент: попросить модель переписать. А модель, которая один раз решила, что Морти идёт за партией, с высокой вероятностью повторит эту же мысль и на переписывании.
Как ИИ-мастер ДнД теряет новых персонажей из речи NPC
Второй дефект той же жалобы - зеркальный. Когда трактирщик в прозе упоминает “родителей невесты”, модель не заводит для них отдельные карточки NPC, а приклеивает их реплики к уже известному персонажу. Роли схлопываются в одно имя, и новый герой истории просто не появляется в памяти мира. Живой мастер в такой момент просто набрасывает НПС методом пятна - имя, одна деталь, одно желание; движку это решение пришлось прописывать кодом.
Про то, почему нейросети для ДнД в принципе теряют куски мира между ходами, мы отдельно разбирали в статье “Почему нейросеть для DnD забывает мир” - это тот же класс проблем, только с другой стороны: там мир забывался целиком, здесь - не успевал родиться.
Что изменили в фиксе 1 августа, чтобы NPC не телепортировались
К 1 августа собрали спеку и выкатили сразу четыре механики: код вместо модели вырезает офф-скрин имена из прозы, canon-гард ужесточается на четырёх выходах подряд при повторном нарушении, экстрактор заводит карточку персонажу из речи NPC, а дедуп отличает нового NPC от переименования старого.
Механическая вычистка (scrub_offscreen_npc) режет из прозы предложения с офф-скрин именем, если гард его поймал - на уровне кода, а не модели. Эскалация canon-гарда держит ужесточённый режим на протяжении четырёх выходов подряд, а не отпускает после одного ретрая. Материализация NPC из прозы - триггеры unknown_name и scene_change заставляют экстрактор завести карточку персонажу, которого раньше просто проглатывали. Направленный дедуп имён (name_subsumes) отличает “Жену кузнеца” как нового персонажа от простого переименования “Кузнеца” в того же самого.
Каждая из этих четырёх правок - про то же самое, о чём мы писали в статье про память спутника: пока состояние мира живёт только в промпте, оно рассыпается на длинной дистанции. Тут состояние вынесли в код - и стало держаться.
Какие фантомы вскрыло живое QA после фикса
9 августа прогнали живой QA на 26 ходах - и целевой баг закрылся: гард сработал пять раз, ни одно офф-скрин имя не дошло до игрока. Но тот же прогон вскрыл четыре побочки, и они были неприятнее исходной жалобы, потому что задели то, из-за чего люди вообще играют в ДнД с ИИ-мастером, - доверие к тому, что мир помнит своих персонажей.
Самая заметная побочка - фантомы. Экстрактор материализовал “пропавшего мальчика”, которого в этой сцене не должно быть по условию квеста, и пастуха, про которого проза прямо говорит “сейчас у себя, на краю деревни”. Потом гард, отработав как задумано, вырезал уже легитимные упоминания этих персонажей: из рассказа трактирщика исчезло имя мальчика, removed_sentences=4.
Получилось, что фикс для одной проблемы - NPC-призрак ходит по сценам - породил другую: NPC-призрак материализуется там, где его вообще не должно быть, и та же защита, которая должна беречь игрока, начала резать честные куски истории. Похожая ситуация с игроками, которые ломают модель формулировками, разобрана в статье “Как игроки словами ломают нейросеть для DnD” - модель одинаково плохо держит границу и от давления игрока, и от собственных фантазий.
Почему запрет в промпте не спас от фантомных NPC
Первая попытка - просто запретить модели материализовывать персонажей не в кадре, прямо в промпте, с примерами. Не сработало: даже усиленный запрет модель нарушала на живых прогонах. Пришлось добавить детерминированный слой - обязательное булево поле present в JSON-схеме экстрактора и жёсткий фильтр в коде до того, как персонаж попадёт в базу.
Правило внутри фильтра простое: “сомневаешься - ставь false”. Промпт можно попросить быть аккуратным, но гарантию даёт только код, который проверяет структуру ответа, а не доверяет тексту на слово.
Как вернули связность прозе после вычистки имён
У механической вычистки была своя цена: она резала текст по предложениям, а проза после такой операции разваливалась - висячие “Он…” и “Говорит,…” без подлежащего, непарные кавычки, слова без пробела на стыке удалённого куска. Пришлось добавить каскадное снятие зависимых предложений и отдельный ремонт швов на месте удаления, откалиброванный на 100 продовых записях до 0 ложных правок.
Если вырезали одно предложение - тянущиеся от него по смыслу тоже уходят под нож, иначе получается пересказ без подлежащего. Мы уже проходили похожую историю в статье про состояния в DnD 5e: там паралич тоже не держался чисто на промпте, и решением тоже стал код, а не более длинная инструкция.
Что в итоге
Сага растянулась на две недели: от первой жалобы 24 июля до чистого повторного QA 10 августа. По пути вышло три PR, юнит-сьют вырос до 6526 зелёных тестов, а ретест на свежей кампании прошёл чисто - без единого офф-скрин имени и без потерянных легитимных NPC.
Это не только наша боль. Игроки других ИИ-мастеров в отзывах пишут буквально “модель забыла имя моего персонажа на середине той же сессии” - память NPC и имён у голых LLM без внешнего хранилища состояния плывёт почти у всех, кто пробовал делать DM на чистой модели без прослойки кода (dev.to, 2026). У нас разница в том, что вместо доверия промпту мы вынесли присутствие персонажа в сцене в структурированное поле и фильтр - то есть туда, где это можно проверить, а не только попросить.
Продукт активная стройка, и эта сага - хороший пример того, как выглядит починка на проде: закрыл один баг - открыл окно на два новых, и это нормальный ритм разработки, а не провал плана. Живой QA после каждого фикса тут не формальность, а единственный способ поймать побочку раньше, чем её поймает игрок в реальной сессии.
Частые вопросы
Что такое canon-гард в ИИ-мастере ДнД?
Canon-гард - модуль, который сверяет прозу нарратора с фактами мира и ловит нарушения вроде NPC, упомянутого не в своей сцене. Раньше при нарушении он просто отправлял ответ на повторную генерацию; после фикса 1 августа 2026 года он вычищает офф-скрин имена из текста кодом и ужесточается на четырёх выходах подряд при повторных нарушениях.
Сколько заняло исправление бага с NPC в ДнД с ИИ?
От первой жалобы игрока 24 июля 2026 года до чистого повторного QA-прогона - две недели, до 10 августа. За это время вышло три PR, а юнит-сьют вырос до 6526 тестов.
Значит ли фикс, что баги с NPC в ДнД с ИИ больше не появятся?
Нет - живой QA 9 августа 2026 года, закрывший исходный баг, сразу вскрыл четыре новые побочки с фантомными NPC. Проект в активной разработке, и такие находки - обычная часть починки на проде, а не исключение.
Как готовился материал: черновик собирает мой ИИ-конвейер по темам из практики таверны, факты сверяются с первоисточниками и правилами, финальную версию я читаю и правлю руками перед публикацией. Обложку тоже рисует нейросеть. Про кухню — на странице о проекте.