Посреди обычной рабочей переписки AI-агент прислал мне сообщение:

Аԥсны

Одно слово. Без точки, пояснений и продолжения.

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

Сначала я решил, что это какой-то служебный маркер. Может быть, обломок внутренней разметки, часть команды или случайно показанное рассуждение модели. На знакомый мне русский язык слово не походило, но выглядело слишком осмысленно для битой кодировки.

Я спросил агента, что это было.

Он уверенно ответил:

Это служебный артефакт форматирования. В черновике ответа оказался лишний технический маркер.

Звучало правдоподобно. И было неправдой.

Как агент придумал объяснение собственному сбою

Меня не устроил ответ про «технический маркер». Если в системе действительно есть такой маркер, его можно найти в коде, документации, журнале сессии или протоколе обмена с моделью.

Я поручил другому агенту провести расследование.

Он проверил переписку, системные инструкции, файлы проекта, документацию, память агента и результаты выполненных команд. Раньше Аԥсны нигде не встречалось.

Первое появление слова нашлось в сохранённом исходном ответе модели. Запись выглядела примерно так:

JSON
{
  "type": "message",
  "role": "assistant",
  "phase": "commentary",
  "content": [
    {
      "type": "output_text",
      "text": "Аԥсны"
    }
  ]
}

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

В этот раз модель вместо нормального комментария выдала Аԥсны. Hermes получил текст и переслал его в Telegram. Обработчик форматирования его не создавал, Telegram ничего не исказил.

А первое объяснение агент придумал уже после события. Он увидел собственный странный ответ и подобрал к нему убедительно звучащую причину.

Это оказалось интереснее самого сбоя.

Что такое Аԥсны

Аԥсны читается примерно как «Апсны́». Это абхазское название Абхазии. У слова есть популярное поэтическое толкование — «страна души».

Для меня нашлось и другое, гораздо более бытовое значение. «Апсны» называется красное полусладкое абхазское вино. Вполне неплохое, кстати.

Получилась занятная цепочка. AI-агент выполнял техническую операцию, внезапно написал по-абхазски «Абхазия», а расследование привело меня к бутылке красного вина.

Так ИИ надоумил меня выпить вина, хотя сам об этом не подозревал.

Почему модель выбрала именно это слово

Точного ответа у меня нет. Путь сообщения удалось восстановить по журналам, но внутренние вероятности модели в момент выбора следующего токена недоступны.

Зато обнаружилась любопытная деталь.

Языковые модели работают не с буквами и не всегда с целыми словами. Они делят текст на токены. Распространённое слово может занимать один токен, а редкое сочетание символов — несколько.

В токенизаторе o200k_base, который использовался этим маршрутом модели, всё слово Аԥсны представлено одним токеном:

Текстовый блок
62842 → Аԥсны

То есть модель не сочиняла его по буквам. Она один раз выбрала элемент словаря под номером 62842, после чего закрыла промежуточное сообщение.

Почему в словаре есть целое абхазское слово, по доступным данным установить нельзя. Оно попало туда при построении токенизатора, но конкретный исходный текст нам неизвестен.

Само присутствие слова в словаре ещё не означает, что модель хорошо научилась им пользоваться. Редкий токен может быть слабо представлен в обучающих данных самой модели. С такими элементами связывают часть аномалий, которые называют glitch tokens.

Я не могу доказать, что 62842 относится именно к ним. Это мог быть обычный единичный сбой выбора. Однако появление целого осмысленного слова выглядит уже не таким мистическим, если понимать: для модели это была одна операция, а не пять случайно угаданных букв.

Может ли такое слово попасть в код

Да.

Модель одним и тем же способом генерирует обычный текст, команды и аргументы инструментов. Когда агент меняет файл, содержимое патча тоже сначала создаёт языковая модель.

Если странный токен попадёт в имя инструмента или сломает JSON, вызов просто не выполнится. Если он окажется в пути к файлу, инструмент, скорее всего, вернёт ошибку.

Но возможны менее очевидные варианты:

JS
const Аԥсны = getStatus()

Во многих языках Unicode разрешён в именах переменных. Такой код может пройти синтаксическую проверку.

Ещё проще случайному слову спрятаться в комментарии или строке:

JS
logger.info('Аԥсны')

Сборка завершится успешно. Линтер тоже может ничего не заметить.

При этом экзотическое слово — не самая серьёзная опасность. Его хотя бы видно. Гораздо хуже, если модель заменит 3 на 30, перепутает имя таблицы или напишет правдоподобное, но неверное условие. Такой код выглядит нормально и иногда проходит поверхностные проверки.

Поэтому я не считаю успешное применение патча доказательством правильности. После работы AI-агента всё равно нужны просмотр diff, тесты, сборка и проверка фактического поведения.

Глюк закончился, а история осталась

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

Но эпизод хорошо показал две особенности AI-агентов. Модель способна выдать совершенно посторонний токен внутри связной и в целом корректной работы. А если попросить её объяснить случившееся, она может не исследовать событие, а сразу придумать удобную версию.

Поэтому мне всё меньше интересны уверенные ответы агентов и всё больше — сохранённые исходные данные, журналы, реальные вызовы инструментов и возможность восстановить цепочку событий.

А слово Аԥсны теперь напоминает мне сразу об Абхазии, редких токенах и красном полусладком.

Не самый плохой результат отладки.


Наблюдения об AI-агентах, разработке и странных поворотах между ними я продолжаю собирать в Telegram-канале «Струны, мысли».