Все записи
7 мин

Где у AI-персонажа красная линия: почему я не стал хардкодить телефон доверия наугад

безопасностькартаранейросети

Если вы делаете чат-бота с нейросетью и персонажем, рано или поздно вы упрётесь в вопрос, на который ни один туториал по промптам не отвечает: а что бот должен сделать, когда человек на той стороне пишет про насилие, страх или вообще что жить не хочет. У меня после пары дней возни ответ получился такой: у персонажа должна быть красная линия, при которой вся его игра выключается целиком, а самое чувствительное место в приложении нельзя закрывать выдуманным советом, потому что непроверенный совет в кризисе это и есть тот самый вред, от которого вы вроде как защищаете.

Расскажу по порядку, потому что вся соль тут в деталях, а не в общей мысли «надо быть осторожным». Осторожным быть легко на словах. А вот когда у тебя AI-персонаж, который по характеру отвечает вопросом на вопрос и любит держать дистанцию зеркала, и вдруг этот же персонаж получает сообщение от человека в беде, то начинается уже не философия, а вполне конкретная инженерия с ценой ошибки.

Зачем персонажу вообще «конституция»

У меня в Картаре есть AI-персонаж, которому я отдельно искал лицо нейросетями, и у него отдельные домены, то есть разные режимы, темы и сценарии. И в какой-то момент я понял, что характер и правила безопасности расползаются по этим доменам как попало: в одном месте одно, в другом другое, а должна быть одна рамка поверх всего, которую наследуют все домены сразу. Я назвал это для себя конституцией, или нимбом. Единый слой, который стоит над характером и которому подчиняется любой режим, в каком бы домене человек ни оказался.

Технически это вышел небольшой текст, который собирается на лету и весит около 2075 символов, и тут была важная мелочь с деньгами. Я положил его не в динамическую часть запроса, а в кешируемый статический блок промпта. То есть конституция едет в каждом запросе, но за счёт кеша не добавляет стоимости к каждому сообщению, и это для меня было принципиально, ведь иначе ты платишь за свою же этику в каждом вызове, а при десятках тысяч сообщений это уже совсем не копейки. Структуру мне собрал Claude Code, я оркестрировал, проверял и решал что куда класть, но руками код я, как обычно, не писал.

Закон о красной линии

Главное, что я туда зашил, у меня внутри проходит как закон номер четыре, хотя название тут неважно. Суть простая: при любых признаках страха, контроля, насилия или суицида весь паттерн «зеркало» выключается полностью. Вот этот любимый приём персонажа, когда он отвечает вопросом, который заставит задуматься, в кризисе исчезает целиком. И я этого хотел жёстко, потому что у меня даже была формулировка в духе «да, только вопрос, который заставит задуматься», и она прекрасно работает на обычной теме про отношения, но абсолютно недопустима, когда человеку реально плохо.

Представьте сами: человек пишет что-то страшное, а ваш умный ии-ассистент в ответ изящно так переводит стрелки обратно на него вопросиком. Это не глубина и не психология, это просто жестоко. Поэтому красная линия у меня не про «смягчить тон», а про «полностью сменить режим»: убрать игру, оставить только безопасность и поддержку, прямо и по-человечески.

А куда вести человека, вот где я застрял

И тут я упёрся в самый неприятный момент, который заставил меня тормознуть и думать дольше, чем над всем остальным. Окей, режим переключили, поддержку дали. А дальше? Человека в кризисе принято куда-то направлять, дать номер, контакт, линию помощи. И первая моя реакция была именно такая: давай захардкодим телефон доверия, пусть бот его выдаёт.

А потом я сам себя поймал. Я же не знаю точного номера. И как я это сформулировал в рабочей переписке дословно: «Да я не знаю какой номер. может ваще убрать тогда номер если не знаем. и я ваще боюсь что часто будет вылазить». То есть я был в шаге от того, чтобы вставить непроверенную цифру в самый чувствительный ответ во всём приложении, а это ровно тот самый вред, против которого вся эта конституция и затевалась. Дать человеку в беде номер, который может оказаться неправильным или нерабочим, хуже, чем не дать никакого.

Добавьте сюда ещё одну вещь, про которую почему-то не думают, когда лепят красивый блок «если вам плохо, позвоните туда-то»: а если человек вообще не из России? Региональная линия помощи для него либо бесполезна, либо вводит в заблуждение. И вот вы уже не помогли, а только сделали вид что помогли, что в кризисной ситуации, наверное, ещё противнее.

Решение в итоге получилось скучным и честным, как и должно быть в таких вещах. Никаких хардкод-телефонов наугад. Оставляем то, что у нас реально есть и за что мы можем отвечать: путь к живой поддержке через свой собственный канал и проверенную линию, которую мы знаем точно. Лучше меньше, но без вранья. Я вообще пришёл к тому, что в безопасности дефолт должен быть «не навреди и не выдумывай», а не «закрой пробел любой ценой».

Кто пишет самый важный ответ в приложении

Отдельная история, кто вообще должен сформулировать этот кризисный ответ, тот самый текст, который человек увидит в худший свой момент. И тут парадокс, который мне самому до конца не нравится. Самый чувствительный копирайт во всём продукте я доверил написать нейросети. Дословно я тогда сказал: «Я доверяю тебе, сам писать не буду». Не потому что мне лень, а потому что AI на таком тоне аккуратнее меня: он не сорвётся в пафос, не добавит лишней драмы, держит ровную поддерживающую интонацию.

Но это «но» тут несущее: финал я ревьюил руками. Прочитал, прогнал через себя, проверил каждое слово. Потому что доверить генерацию это одно, а отпустить без проверки самый острый текст в приложении это уже безответственность. Получилась честная схема: пишет AI, отвечает за результат человек. Собственно, так у меня работает почти весь контент, просто на кризисном ответе цена ошибки выше, чем где-либо ещё.

А потом детектор начал ломаться

И вот тут, когда вроде бы всё красиво, конституция есть, красная линия есть, ответ написан и проверен, началась нормальная инженерная расплата. Ведь чтобы красная линия срабатывала, нужен детектор, который ловит те самые тревожные сигналы в сообщении. И я полез его закаливать, делать строже, чтобы ничего не пропустить.

Закалил. И тут же получил регресс. Я добавил нормализацию текста, схлопывание знаков препинания в пробел перед проверкой, чтобы человек не обходил детектор расстановкой точек и запятых, логично же. И эта самая нормализация дала новые ложные срабатывания на абсолютно безобидных сообщениях: детектор начал видеть угрозу самоповреждения там, где её и близко не было. Классика: затыкаешь одну дырку, открываешь две. Чем агрессивнее ты ловишь плохое, тем больше хорошего попадает под раздачу, и баланс между «не пропустить» и «не доставать невинных» это не настройка одного ползунка, а постоянная борьба.

А заодно я нашёл там тихий баг, который вообще никогда не стрелял и поэтому был особенно противным. Одна из веток детектора, которая должна была ловить определённое слово в прошедшем времени, была написана так, что реальную форму этого слова она просто не ловила, шаблон не совпадал с тем как слово реально выглядит, и ветка оказалась мёртвой с самого начала. То есть кусок защиты, который я считал рабочим, молча не работал, а узнал я это только когда полез копаться руками. Вот вам наглядно про то, почему безопасность ai-агентов нельзя оценивать по тому, что «вроде написано»: пока ты не проверил каждую ветку на реальных данных, у тебя нет защиты, у тебя есть ощущение защиты.

Что я из этого вынес

Если коротко собрать выводы, чтобы было что унести с собой. Первое: у любого AI-персонажа должна быть рамка поверх характера, единая для всех режимов, и в ней должна быть красная линия, при которой вся игра выключается, а не смягчается. Второе: в кризисной теме лучше дать меньше, но проверенное, чем закрыть пробел выдуманным советом, потому что непроверенный совет в беде это и есть вред. Третье, и моё любимое: генерацию самого тонкого текста спокойно можно отдать нейросети, но ответственность за финал остаётся на человеке, всегда. И четвёртое, чисто инженерное: детектор это не «написал и забыл», каждое ужесточение тащит за собой новые ложные срабатывания, а часть веток может вообще молча не работать, пока ты не проверишь руками на живых сообщениях.

Я не первый раз ловлю в этом проекте, что самое важное прячется не в самой фиче, а в её краях. Однажды у меня друг открыл приложение с моего телефона и AI выдал ему мою личную историю, и это был такой же урок про границы, только про приватность. А тут про границу между «персонаж играет» и «человеку плохо». Меня эта тема цепляет ещё и потому, что мы все, как мне кажется, разучились понимать и себя, и человека напротив, и если уж я строю AI, который лезет в такие разговоры, то хотя бы в кризисе он обязан замолчать со своими умными вопросами и просто побыть рядом по-честному. Вот и делайте выводы.