На первый взгляд ELIZA Джозефа Вейценбаума кажется чем-то примитивным. Практически набором костылей из регулярных выражений, который тупо менял местами «я» и «вы» и иногда задавал уточняющие вопросы. Да, в массовом сознании она так и осталась игрушкой из 60-х, наивной попыткой обмануть пользователя парой строк кода. И если вы думаете, что про ELIZA уже все давно сказано и разжевано, спешим вас удивить.
Почему эта программа, изначально задуманная как пародия для демонстрации поверхностности диалога с машиной, оказалась архитектурно сложнее, чем можно было предположить, и почему мы до сих пор верим в «разум» чат-ботов — разбираемся в этой статье.

Миф о «тупых регулярках»
В ИТ-фольклоре ELIZA стала практически символом фейкового ИИ, который просто парсит строку и подменяет слова местами. А вот на самом деле работала она несколько сложнее, хоть и, естественно, ни о каком ИИ тогда речи не шло.
Да и вообще — ее автор, Джозеф Вейценбаум, писал не простенького бота, а полноценный движок! И тот самый сценарий, который большинство людей путают с самой программой ELIZA, на самом деле назывался DOCTOR и выполнял роль психотерапевта. А сама ELIZA могла принимать на себя множество ролей — совсем как современные боты, которым мы можем навязать ту или иную личность. И DOCTOR был лишь одним из многих «скинов» для этого универсального фреймворка.
И что еще интереснее — судя по коду ELIZA, Вейценбаум изначально разделил движок обработки естественного языка и скрипты, определяющие поведение конкретного бота. Можно было загрузить в этот движок любой скрипт с набором ключевых слов и шаблонов, и он брал на себя обработку пользовательского ввода, приоритетов и генерацию ответов.
Иными словами, еще в эпоху перфокарт и ламповых машин, когда код нередко прибивался гвоздями под одну задачу, Вейценбаум фактически отделил логику обработки естественного языка от сценариев поведения.
Звучит знакомо, не так ли? В современных решениях мы тоже стараемся отделять универсальный механизм обработки языка от прикладной логики — системных инструкций, бизнес-логики, внешних инструментов и данных, которые определяют поведение модели в конкретной задаче. Разница лишь в масштабе.
Как это работало под капотом
Ладно, с архитектурой разобрались — движок отдельно, «личность» отдельно. Но давайте заглянем под капот и посмотрим, что именно крутилось в этом движке. Потому что дьявол, как водится, в деталях. А детали тут, мягко говоря, нетривиальные, особенно для 1965 года.
ELIZA была написана не на каком-нибудь модном Lisp (хотя он уже существовал), а на связке MAD (Michigan Algorithm Decoder) и SLIP (Symmetric LIst Processor). MAD был процедурным языком общего назначения, а SLIP — расширением для обработки списков, созданным самим Вейценбаумом.
Итак, какая вообще задача стояла перед Вейценбаумом? Представьте, что вам нужно парсить естественный язык, и у вас нет ни современных regex-движков, ни современных строковых библиотек. Только связанные списки, в которых хранились слова и элементы разбора. И вот в этих условиях Вейценбаум умудрился построить один из первых работающих диалоговых механизмов обработки естественного языка.
Ядро любого скрипта ELIZA — набор ключевых слов, каждому из которых мог быть назначен числовой ранг. Чем выше ранг, тем выше приоритет этого слова при обработке пользовательского ввода. Если ранг явно не задавался, считалось, что он равен нулю.

Например, если пользователь вводил фразу:
I had a dream about my mother
наивный парсер мог бы остановиться на первом совпадении. ELIZA же просматривала весь ввод, собирала найденные ключевые слова в специальный стек, где наверху оказывалось слово с максимальным рангом. Именно его правила обработки применялись первыми.
Если проводить исторические параллели, здесь уже можно увидеть идею приоритезации наиболее значимых элементов входного текста. Конечно, никакого обучения, матриц или вычисления весов там не было. Но сама идея, что сначала нужно определить, на что обратить внимание, а и лишь затем вокруг этого строить ответ, — появилась задолго до эпохи LLM.
Выбрав ключевое слово, ELIZA переходила к декомпозиции — сопоставлению пользовательского ввода с заранее заданными шаблонами. Каждый такой шаблон можно представить как маску с переменными фрагментами. Например, в упрощенном виде правило для ключевого слова dream могло выглядеть так:
DECOMPOSITION: I dreamed (0)
REASSEMBLY: Really, (0)?
REASSEMBLY: Have you ever fantasized (0) while you were awake?
Здесь (0) обозначает часть пользовательского ввода, захваченную шаблоном и затем подставляемую в ответ. Если пользователь вводил I dreamed I was flying, шаблон срабатывал, а вместо (0) в ответ подставлялся фрагмент I was flying, но в измененном виде — об этом чуть ниже.
Для каждого ключевого слова существовало несколько шаблонов декомпозиции, при этом использовался первый подошедший. Если подходящего шаблона не находилось или правило требовало перейти к следующему ключевому слову, ELIZA продолжала обработку, переходя к следующему ключу из стека найденных. Если подходящих ключевых слов не оставалось, срабатывало универсальное ключевое слово NONE.
Дальше в дело вступала реконструкция. Движок брал фрагмент пользовательского ввода, захваченный на этапе декомпозиции, и подставлял его в ответный шаблон. Перед вставкой фрагмент проходил через таблицу замен, которая меняла местоимения и некоторые связанные с ними формы слов, чтобы ответ звучал естественно. Например I менял на you, my на your и так далее.
Так, фраза «I am sad» после такой трансформации превращалась в «you are sad», и ответ ELIZA звучал уже грамматически корректно.
А что происходило, если пользователь молчал или писал чушь?
На этот случай у ELIZA была память. Не полноценная, конечно, и не база данных, а небольшая очередь (в статье Вейценбаума она исторически называется стеком). Но работала она совсем не так, как можно было бы подумать. ELIZA не складывала в память все сообщения пользователя подряд. Для некоторых ключевых слов существовали специальные преобразования. Когда одно из них выполнялось, система сохраняла не исходную реплику пользователя, а уже готовую фразу, которую могла использовать позже. Если в новом сообщении не находилось подходящего ответа, ELIZA иногда возвращалась к такой сохранённой фразе, создавая впечатление, что помнит разговор.
Выглядеть это могло так (пример работы восстановленной версии ELIZA на основе оригинального исходного кода):
HOW DO YOU DO. PLEASE TELL ME YOUR PROBLEM
> My mother hates me.
TELL ME MORE ABOUT YOUR FAMILY
> Derp.
DOES THAT HAVE ANYTHING TO DO WITH THE FACT THAT YOUR MOTHER HATES YOU?
Бот создавал иллюзию непрерывности беседы, время от времени возвращаясь к реплике пользователя. Конечно, ELIZA со своим небольшим стеком памяти не обладала настоящим контекстом разговора, но она уже умела возвращаться к ранее сказанному и тем самым поддерживать иллюзию непрерывного диалога.
Если собрать все в одну цепочку, каждый цикл работы ELIZA выглядел примерно так:
Сканирование — последовательно просмотреть весь ввод и найти все ключевые слова.
Формирование стека — отсортировать найденные ключевые слова по приоритету.
Выбор ключевого слова — начать обработку с элемента на вершине стека.
Декомпозиция — подобрать подходящий шаблон и выделить из реплики нужные фрагменты.
Преобразование — изменить местоимения и другие связанные формы слов, чтобы ответ звучал естественно.
Реконструкция — собрать ответ из шаблона, подставив в него преобразованные фрагменты.
Память — при необходимости сохранить подготовленную трансформацию для возможного использования в дальнейшем.
Резервный сценарий — если подходящего ответа не нашлось, использовать сохраненную трансформацию из памяти или универсальный ответ.

ELIZA как прообраз современных архитектур
Можно ли назвать ELIZA просто набором хитрых шаблонов? И да, и нет. Но это сейчас не так уж и важно. Самое интересное, что еще тогда, в 60-х Вейценбауму пришло в голову разделить механизм обработки языка и логики диалога. И не только пришло в голову — он смог это сделать.
Многие архитектурные решения ELIZA были продиктованы не только замыслом Вейценбаума, но и ограничениями вычислительной техники середины 1960-х — однопроходной обработкой текста, стековой организацией данных и крайне ограниченными ресурсами памяти. Однако сегодня ELIZA интересна не только как исторический артефакт. Она показывает, что многие архитектурные идеи, которые мы считаем характерными для современных LLM, появились задолго до этого. Изменились алгоритмы, вычислительные мощности и качество генерации. Но стремление отделить универсальный механизм обработки языка от логики конкретного приложения осталось.

Эффект Элизы — почему мы до сих пор верим в «разум» машин
И вот мы подходим к самому ироничному моменту всей этой истории. Вейценбаум вовсе не собирался изобретать существование искусственного интеллекта. Скорее наоборот — ELIZA должна была показать, насколько далеко можно зайти, используя сравнительно простые механизмы обработки текста.
Существует легендарная (и абсолютно документированная) история о том, как Вейценбаум продемонстрировал программу своей секретарше. Поиграв с ней пару минут, она повернулась к создателю и попросила его выйти из комнаты, чтобы она могла пообщаться с машиной наедине.
Позже Вейценбаум в своей знаменитой книге Computer Power and Human Reason с горечью признавался, что даже не осознавал, что даже крайне короткое знакомство с относительно простой компьютерной программой может вызвать мощные иллюзорные представления у вполне нормальных людей. Позже это явление получило название «эффект Элизы».
Вот такая фича нашего человеческого мозга. Мы эволюционно склонны искать паттерны и эмпатию вокруг себя. Если нечто говорит с нами на нашем языке, задает уточняющие вопросы и использует слова «я», «ты» и «чувствую», наш мозг по инерции докручивает картинку — ага, это существо меня понимает! Нам буквально хочется быть обманутыми, потому что это делает взаимодействие комфортным.
С момента изобретения ELIZA прошло 60 лет. Мы знаем, как работают нейросети (ну хотя бы приблизительно). Но все так же наступаем на те же самые грабли — только теперь они позолочены красивым UI, голосовым вводом и прочими приятными плюшками.
Пользователи доверяют большим языковым моделям свои медицинские данные и симптомы, просят совета при разводе или просто психологической помощи в виде «поболтать». Ведь современная LLM мастерски имитирует эмпатию. Например, фраза «Мне очень жаль, что вы с этим столкнулись. Давайте разберем эту ситуацию шаг за шагом» звучит как поддержка заботливого приятеля. Создает впечатление понимания и сочувствия. Однако сама модель не обладает субъективным опытом, эмоциями или намерениями — лишь генерирует наиболее вероятное продолжение текста на основе статистических закономерностей.
Шестьдесят лет назад ELIZA убедила людей, что понимает их. Безусловно, современные языковые модели делают это гораздо убедительнее. Но вот наша психология мало изменилась. Мы по-прежнему склонны принимать ответную речь за понимание, а естественный диалог — за наличие внутреннего мира.
Кстати, если хотите сами пощупать «ту самую» ELIZA? Запускайте восстановленную версию ELIZA прямо в браузере!
А мы по традиции предлагаем поболтать в комментариях. Как думаете, какие наши сегодняшние «прорывные» архитектурные решения будут казаться наивными через 60 лет? Ждем ваших ответов!
