Делаю для своей AI Nova систему настроения. Сегодня учил её нормально “обижаться” и принимать извинения
(ps/ тг беседа для предложений/вопросов https://t.me/+Z0mNbDAkgbY2ZjUy)
Продолжаю делать своего локального AI-компаньона Nova. Это не просто чат-бот, который отвечает по промпту, а попытка собрать персонажа с памятью, характером и внутренним состоянием.
Сегодня занимался системой настроения и отношений.
Сразу уточню: идея не в том, чтобы написать в промпте “если пользователь нагрубил, обидься”. Это слишком просто и плохо работает. Модель может один раз “сыграть обиду”, а потом через пару сообщений забыть, что вообще произошло.
Мне хочется сделать по-другому: чтобы у Nova было отдельное состояние. Например, она может быть спокойной, настороженной, обиженной, постепенно отходить после извинений, снова доверять не мгновенно, а поэтапно.
То есть не просто текстовая имитация эмоций, а отдельная логика, которая влияет на поведение.
Что получилось
Сегодня я в основном разбирался с тем, как Nova должна реагировать на извинения.
Потому что “прости” бывает очень разным.
Можно просто написать: прости
А можно сказать: прости, я был неправ, я не должен был так с тобой говорить
И это уже совсем другой уровень. Тут человек не просто бросил слово “извини”, а признал, что сделал неприятно.
Есть и обратный вариант: ну если ты такая обидчивая, прости
Формально слово “прости” есть, но по смыслу это не извинение, а скорее новая попытка уколоть.
Сегодня удалось привести это к более человеческой логике. Простое извинение немного смягчает состояние. Глубокое извинение восстанавливает сильнее. А плохое псевдоизвинение не лечит ситуацию, потому что оно не признаёт проблему.
Осадок после конфликта
Отдельно добавил промежуточное состояние. Не хотелось, чтобы Nova после хорошего извинения сразу становилась такой, будто ничего не было.
В реальном общении так не всегда работает.
Иногда человек извинился, тебе стало легче, но осадок всё равно остался. Теперь Nova может быть именно в таком состоянии: уже мягче, уже не в резкой защите, но ещё не полностью восстановилась.
Примерно так: Мне стало спокойнее, но я всё ещё чувствую этот осадок внутри.
На мой взгляд, это делает поведение менее пластиковым.
Важный технический момент
Ещё пришлось защитить систему от странного бага.
Если сама Nova в ответе пишет что-то вроде: Прости, я была резкой.
это не должно считаться извинением пользователя.
Иначе получалась бы глупая ситуация: Nova сама извинилась, а система решила, что это пользователь начал мириться, и поменяла настроение.
Теперь эмоциональные события создаются только из сообщений пользователя. Ответы Nova обратно в движок настроения не проходят.
Главная проблема
Самое сложное оказалось не в прямых оскорблениях и не в простых извинениях, а в тонких фразах.
Например: да ладно, не ной ой всё, хватит ну не начинай ты слишком остро реагируешь
Сами по себе такие фразы могут быть просто грубоватыми. Но если до этого был конфликт, Nova была обижена, пользователь вроде бы начал извиняться, а потом говорит “да ладно, не ной”, смысл уже другой.
Это не просто фраза. Это обесценивание реакции.
То есть пользователь как будто говорит: “твои чувства ерунда, прекращай”.
И вот тут появляется архитектурная проблема.
Можно, конечно, сделать список фраз: не ной не драматизируй ой всё забей не начинай
Но это плохой путь. Таких фраз бесконечно много. Сегодня добавишь десять, завтра найдёшь ещё двадцать. В итоге код превратится в огромный набор проверок
if "фраза" in text
Так делать не хочется.
Что попробовал
Я попробовал подключить маленькую локальную модель, чтобы она анализировала смысл фразы и возвращала структурированный результат.
Идея была хорошая: не ловить конкретные слова, а понимать, что в сообщении есть извинение, агрессия, обесценивание, попытка помириться или давление.
Но на практике маленькая модель оказалась нестабильной. Она иногда ломала JSON, путала значения, обрывала ответ или добавляла мусорные поля.
В итоге стало понятно, что вместо костылей со списком фраз я начинаю строить костыли вокруг самой модели.
Поэтому этот эксперимент пока откатил. Стабильная версия снова работает через правила и fallback-логику.
К какому выводу пришёл
Похоже, лучше не спрашивать маленькую модель напрямую: какое это событие?
Лучше вытаскивать более простые признаки:
. есть ли извинение
. признаёт ли пользователь вред
. берёт ли ответственность
. обесценивает ли реакцию
. давит ли на эмоции
. есть ли враждебность
. есть ли теплота
А уже отдельный слой должен смотреть на эти признаки и текущее состояние Nova.
Например, если Nova уже обижена, примирение ещё не завершено, а пользователь говорит что-то вроде “не ной” и не признаёт свою вину, система должна понимать: это не нейтральная фраза, а плохая попытка восстановления контакта.
Что дальше
Сейчас базовая версия уже работает.
Nova различает прямую грубость, простое извинение, глубокое извинение и плохое псевдоизвинение. Может смягчаться постепенно, а не переключаться мгновенно из “обиделась” в “всё идеально”.
Следующий шаг - сделать нормальный слой семантических признаков, чтобы понимать не конкретные фразы, а смысл.
Вопрос к сообществу
Может, кто-то уже делал похожее для AI-компаньонов, NPC, чат-ботов или диалоговых state machine.
Как лучше понимать фразы вроде: да ладно, не ной ой всё, хватит ну не начинай ты слишком остро реагируешь
не через бесконечный список маркеров, а через смысл?
Интересны варианты с embeddings, sentence-transformers, маленькими классификаторами, NLI, constrained decoding или golden tests для эмоциональной state machine.
Совет “просто добавь фразу в список” понятен, но хочется решить именно архитектурную проблему.
Сейчас главный вопрос такой: как локально и стабильно понимать обесценивание, давление и неискренние попытки помириться, не превращая код в словарь всех возможных фраз.














