- BrainTools - https://www.braintools.ru -

От готовых реплик к контекстной памяти: как эволюционировали AI-чаты

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

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

< — Часть I. Как поисковые системы учились понимать запросы [1]

Часть II. Как AI-чаты учились понимать запросы и поддерживать диалог

1966 год: ELIZA и иллюзия понимания

История чат-ботов уходит корнями еще в 1960-е годы. Одним из первых таких проектов стала ELIZA, которую разработал профессор Массачусетского технологического института (MIT) Джозеф Вейценбаум. В январе 1966 года он опубликовал статью с описанием программы в журнале Communications of the ACM.

Для общения с ELIZA использовали печатающий терминал, подключенный к компьютеру IBM 7094. Пользователь набирал сообщение, программа обрабатывала его и печатала ответ на том же устройстве. После этого пользователь вводил следующую реплику — получался последовательный текстовый диалог.

Поведение [2] ELIZA определялось отдельным сценарием — набором ключевых слов и правил обработки текста. Самый известный сценарий, DOCTOR, имитировал беседу с психотерапевтом: программа задавала уточняющие вопросы и возвращала собеседнику части его собственных высказываний. При этом сценарий можно было заменить, не переписывая саму ELIZA.

Технически программа находила ключевые слова, учитывала их приоритеты, выбирала связанные с ними правила и подставляла фрагменты сообщения в шаблон ответа. Она могла менять местоимения, переставлять части фразы и сохранять отдельные фрагменты беседы для последующего использования. Если подходящего правила не находилось, использовала общую реплику или возвращалась к ранее сохраненному фрагменту разговора.

Вот упрощенный пример на Python: он показывает сопоставление фразы с шаблоном и подстановку найденного фрагмента в ответ.

import re


def fear_response(match: re.Match[str]) -> str:
    # Убираем пробелы и конечные знаки препинания.
    reason = match.group(1).strip(" .!?…")

    # Если остались только знаки препинания или пустая строка,
    # просим уточнение вместо вопроса с пустым фрагментом.
    if not any(char.isalnum() for char in reason):
        return "Чего именно вы боитесь?"

    return f"Почему вы боитесь {reason}?"


RULES = [
    (
        re.compile(r"bмне грустноb", re.IGNORECASE),
        lambda _: "Почему вам грустно?",
    ),
    (
        re.compile(r"bя боюсьbs*(.*)", re.IGNORECASE),
        fear_response,
    ),
]


def reply(message: str) -> str:
    # Убираем лишние пробелы, переносы строк и табуляцию.
    message = " ".join(message.split())

    # Ищем подходящий шаблон и формируем ответ.
    for pattern, response in RULES:
        match = pattern.search(message)
        if match:
            return response(match)

    # Если совпадений нет, возвращаем общую реплику.
    return "Расскажите об этом подробнее."


print(reply("Я боюсь собак"))
# Почему вы боитесь собак?

print(reply("Я опасаюсь собак"))
# Расскажите об этом подробнее.

print(reply("Я  боюсь собак…"))
# Почему вы боитесь собак?

print(reply("Я боюсь ..."))
# Чего именно вы боитесь?

В примере две фразы выражают похожую мысль, но программа обрабатывает их по-разному: для я боюсь правило предусмотрено, а для я опасаюсь — нет. Самостоятельно установить смысловую связь между этими выражениями она не может.

ELIZA не обучалась на разговорах: расширять ее возможности нужно было через изменение сценария. Удачно подобранные правила создавали впечатление [3] осмысленного общения, хотя ответы формировались посредством преобразования текста.

1970-е — начало 2010-х: от шаблонных реплик к конкретным ответам

После ELIZA исследователи продолжили развивать диалоговые программы, чтобы получать конкретные ответы на основании известных системе данных. Одним из ранних примеров стала SHRDLU, которую Терри Виноград разработал в MIT в 1968–1970 годах. Она отвечала на вопросы о цвете, форме и расположении геометрических фигур в компьютерной сцене, учитывая предыдущие реплики. По команде пользователя программа могла переставлять эти фигуры на экране — все объекты существовали только в компьютерной модели.

В последующие десятилетия развивались системы для общения с пользователями на основе специализированных баз данных. Например, в 1990-х создавались программы, которые отвечали на вопросы об авиарейсах: пользователь указывал направление, время и другие условия, а система находила подходящие записи в базе.

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

Понимание запроса → Управление диалогом → Формирование ответа
      NLU            Dialogue Manager          NLG

NLU — Natural Language Understanding, понимание естественного языка. Модуль определяет намерение пользователя — intent, то есть тип обращения: например, узнать статус заказа или запросить отмену. Затем извлекает параметры — slots, или слоты: номер заказа, дату поездки, город назначения и другие необходимые сведения.

На условном примере чат-бота магазина сообщение «Где мой заказ A-1842?» можно преобразовать в такую структуру:

{
  "intent": "track_order",
  "slots": {
    "order_id": "A-1842"
  }
}

Здесь track_order обозначает запрос статуса заказа, а order_id содержит его номер. Разные формулировки — «Где мой заказ?» и «Что с доставкой?» — нужно было отнести к одной задаче, если в данном разговоре пользователь спрашивал об одном и том же.

Dialogue Manager — модуль управления диалогом. Он учитывает собранные сведения и определяет следующий шаг: уточнить запрос, попросить номер заказа, получить статус или запросить подтверждение отмены.

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

Ниже — упрощенный пример выбора следующего действия по типу запроса и собранным параметрам.

def choose_action(intent: str, slots: dict[str, str]) -> str:
    # Если тип обращения не поддерживается, просим уточнение.
    if intent not in {"track_order", "cancel_order"}:
        return "clarify_request"

    # Проверяем, что номер указан и не состоит из одних пробелов.
    if not slots.get("order_id", "").strip():
        return "ask_order_id"

    # Для проверки заказа выбираем получение статуса.
    if intent == "track_order":
        return "get_order_status"

    # Для отмены сначала запрашиваем подтверждение.
    return "ask_cancellation_confirmation"

Функция возвращает название следующего шага, которое обрабатывает основной код бота: при get_order_status он вызывает обработчик, запрашивающий статус в системе заказов магазина, а при clarify_request передает модулю формирования ответа просьбу уточнить вопрос. Команда ask_cancellation_confirmation только запускает запрос подтверждения; сама отмена выполняется серверной частью магазина после ответа пользователя и необходимых проверок.

NLG — Natural Language Generation, формирование ответа на естественном языке. Модуль превращает выбранный шаг или полученные данные в реплику. В сценарном боте он мог выбирать готовый шаблон: «Уточните, пожалуйста, что вы хотите узнать» — либо подставлять сведения из базы: «Заказ A-1842 передан в доставку».

Такой подход удобен, когда перечень поддерживаемых запросов ограничен и понятен: проверить доставку, подобрать рейс, отменить бронирование. Но с расширением возможностей увеличивается и объем работы. Разработчикам нужно было добавлять новые типы запросов, настраивать их распознавание, определять необходимые параметры и продумывать дополнительные ветви разговора.

При этом отдельные компоненты уже могли использовать машинное обучение [4], а не только вручную написанные правила. Однако типы поддерживаемых запросов по-прежнему задавались заранее. Бот умел работать только с теми классами запросов, которые заранее предусмотрела команда.

2013 год: Word2Vec помогает находить близкие по смыслу слова

Чтобы распознавать разные формулировки одного запроса, системам требовалось учитывать сходство между словами. В 2013 году команда исследователей Google представила Word2Vec — методы обучения числовых представлений слов. Такие представления использовались и раньше, но Word2Vec позволил обучать модели на больших объемах текста быстрее и с меньшими вычислительными затратами.

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

Для обучения использовались два подхода:

  • CBOW — модель предсказывала центральное слово по соседним словам слева и справа. Например, получив окружение «водитель припарковал … возле дома», она училась предсказывать пропущенное слово «машину». Порядок слов внутри выбранного окружения при этом не учитывался.

  • Skip-gram — модель решала обратную задачу: по выбранному слову училась предсказывать слова из его ближайшего окружения.

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

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

2014 год: Seq2Seq учится строить один текст на основе другого

Следующий этап был связан с обучением нейросети построению целой фразы на основе исходного текста. В 2014 году был представлен Sequence-to-Sequence, или Seq2Seq, — подход, при котором модель получала, например, предложение на одном языке и последовательно составляла его перевод на другом.

Система состояла из двух частей. Энкодер обрабатывал слова исходной фразы и собирал информацию о ней в числовое представление. Декодер получал это представление и строил перевод слово за словом, учитывая уже написанную часть. Обе части обучались совместно на примерах исходных предложений и переводов.

В одной из ключевых реализаций Seq2Seq, представленной в 2014 году, использовались LSTM — разновидность рекуррентных нейросетей. Такие сети обрабатывают текст последовательно: на каждом шаге получают очередное слово и обновляют внутреннее состояние, в котором сохраняется информация о ранее прочитанном. Благодаря этому при обработке продолжения фразы сеть может учитывать ее начало.

Исходное предложение
          ↓
Энкодер последовательно обрабатывает слова
          ↓
Общее числовое представление предложения
          ↓
Декодер строит перевод слово за словом
          ↓
Предложение на другом языке

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

В 2014–2015 годах для решения этой проблемы предложили механизм внимания [5]. Энкодер сохранял числовое представление каждой позиции исходного предложения с учетом окружающих слов, а декодер мог использовать эти представления на каждом шаге перевода. Перед выбором очередного слова он рассчитывал, каким частям исходного предложения придать больший вес.

Например, фразу «На столе лежит красная книга» нужно перевести как «A red book is lying on the table». Порядок слов меняется: в английском предложение начинается с книги, а в русском языке мы сначала говорим, что книга лежит «На столе». При формировании слов red book механизм внимания позволяет сильнее учитывать часть «красная книга», а при формировании on the table — переключить больший вес на «на столе». Модель не обязана двигаться по исходному предложению слева направо: перед каждым новым словом перевода она заново определяет, какие части оригинала сейчас важнее. Для этого ей доступны сохраненные энкодером представления каждого слова, а не только одно сжатое представление всей фразы.

2015 год: нейросеть начинает самостоятельно формировать реплики

Подход, который преобразовывал предложение в перевод, можно было применить и к разговору. В 2015 году Seq2Seq использовали для предсказания следующей реплики: на вход модель получала предыдущие сообщения, а на выходе формировала возможное продолжение беседы.

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

Сценарный подход:
Реплика → определение типа запроса → ветка сценария → готовый ответ

Нейросетевой подход:
Реплика и контекст → модель → последовательное построение ответа

Однако модель не всегда сохраняла логику [6] беседы: отдельный ответ мог выглядеть убедительно, но противоречить сказанному несколькими репликами раньше.

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

2017 год: Transformer ускоряет обучение и помогает учитывать связи в тексте

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

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

Как работает механизм внимания

Текст разбивается на токены — слова, части слов или знаки, которые преобразуются в числовые представления. Чтобы сохранить информацию о порядке токенов, в первоначальном Transformer к этим представлениям добавляли сведения об их позициях.

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

Зачем декодеру нужна причинная маска

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

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

Как это выглядит в коде

Расчет одной головы внимания с причинной маской можно показать на Python с библиотекой PyTorch:

import torch


def causal_attention(
    q: torch.Tensor,
    k: torch.Tensor,
    v: torch.Tensor,
) -> torch.Tensor:
    # Сравниваем токены и масштабируем полученные оценки.
    scores = (q @ k.T) / (q.shape[-1] ** 0.5)

    # Отмечаем последующие позиции, которые нужно скрыть.
    mask = torch.ones_like(scores, dtype=torch.bool).triu(diagonal=1)
    scores = scores.masked_fill(mask, float("-inf"))

    # Превращаем оценки в веса и объединяем информацию.
    weights = torch.softmax(scores, dim=-1)
    return weights @ v

Функция получает уже подготовленные матрицы Q — запросы, K — ключи и V — значения для одной последовательности и одной головы внимания. Q и K используются для оценки связей между токенами, а V содержит информацию, которую нужно объединить. Матрицы двумерные, с одинаковым числом строк — по одной на токен; Q и K также имеют одинаковое число столбцов. Здесь предполагается, что все три матрицы имеют одинаковый тип данных — torch.float32 или torch.float64 — и находятся на одном устройстве: процессоре либо графическом ускорителе.

Сначала q @ k.T рассчитывает оценки связей, а деление на квадратный корень из размерности вектора масштабирует их. Затем маска заменяет оценки для последующих позиций на минус бесконечность. После softmax эти позиции получают нулевой вес и не влияют на результат. Последняя строка объединяет информацию из V с полученными весами.

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

2018–2019 годы: одну модель начинают адаптировать к разным задачам

Архитектура Transformer позволила эффективнее обучать крупные нейросети. На ее основе развивался подход, объединявший два этапа: сначала модель изучала языковые закономерности на большом количестве текстов, а затем проходила дополнительное обучение для конкретной задачи. Это позволяло использовать уже полученные знания, не начиная обучение каждый раз с нуля.

GPT-1: сначала общее обучение, затем специализация

В 2018 году OpenAI представила первую модель GPT, позднее получившую название GPT-1. Сначала она училась предсказывать следующий токен по предыдущему тексту. Затем ее настраивали для конкретных задач с помощью размеченных примеров — данных, для которых заранее указан правильный результат.

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

После дообучения модели передают уже новые отзывы без отметок. Для сообщения «Обязательно пересмотрю, давно кино так не увлекало» ожидаемый результат — категория «положительный», хотя такой формулировки могло не быть среди обучающих примеров. Полученные оценки можно использовать, например, для подсчета доли положительных и отрицательных откликов. Так предварительно обученную GPT-1 адаптировали к конкретной задаче: по тексту отзыва определять выраженное в нем отношение к фильму.

BERT: значение слова зависит от окружения

В том же году Google представил BERT — нейросетевую модель для анализа текста на основе трансформера. Она формировала числовое представление каждого токена с учетом окружающих слов слева и справа.

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

После дообучения BERT можно было использовать для классификации текстов, поиска ответа внутри документа и определения смысловых отношений между предложениями. Его основным назначением был анализ полученного текста, а не последовательное написание длинных ответов, как у моделей GPT.

GPT-2: одна модель выполняет разные языковые задания

В 2019 году появилась GPT-2. Она продолжала предсказывать следующий токен по уже известной части текста, но стала крупнее и обучалась на материалах миллионов веб-страниц.

В экспериментах GPT-2 могла отвечать на вопросы, переводить отдельные тексты и составлять краткие изложения без дополнительного обучения специально под каждую из этих задач. Нужное поведение [7] задавали началом текста и примерами: например, после нескольких пар «вопрос — ответ» модель продолжала эту последовательность ответом на новый вопрос.

Sentence-BERT: сравнение смысла целых предложений

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

Чтобы сократить эти затраты, в 2019 году предложили Sentence-BERT, который обучался получать отдельный вектор для каждого предложения. Тексты можно было обработать заранее и сохранить их представления. Когда поступал запрос, система рассчитывала его вектор и сравнивала с сохраненными — без повторной обработки каждого текста нейросетью.

Этот принцип можно показать на более поздней многоязычной модели из библиотеки Sentence Transformers:

# Для запуска: pip install sentence-transformers

from sentence_transformers import SentenceTransformer

model = SentenceTransformer(
    "sentence-transformers/"
    "paraphrase-multilingual-MiniLM-L12-v2"
)

sentences = [
    "Почему посетители бросают корзину?",
    "Из-за чего покупатели не завершают заказ?",
    "Как изменить цвет кнопки в интерфейсе?",
]

# Получаем векторы предложений и приводим их к единичной длине.
vectors = model.encode(
    sentences,
    normalize_embeddings=True,
)

# Рассчитываем оценки сходства для всех пар предложений.
similarities = vectors @ vectors.T

print("Первый и второй запрос:", similarities[0, 1])
print("Первый и третий запрос:", similarities[0, 2])

Первое сравнение проверяет близость двух формулировок вопроса о незавершенной покупке, второе — близость вопросов на разные темы. Чем выше полученная оценка, тем более похожими модель считает тексты. Такой подход позволяет искать подходящие вопросы и документы по смыслу, а не только по совпавшим словам.

2020 год: GPT-3 использует примеры прямо из запроса

В 2020 году OpenAI представила GPT-3, крупнейшая версия которой содержала 175 миллиардов параметров. Модель могла выполнять разные задания по текстовому описанию и нескольким примерам, не проходя отдельное дообучение для каждого случая.

Пользователь мог прямо написать, какой результат ему нужен, приложить исходные данные и показать желаемый формат ответа. Например, попросить преобразовать сообщения покупателей в структурированные записи:

Для каждого обращения определи категорию проблемы и номер заказа.
Ответь в формате JSON, как в примерах ниже.

Обращение: «Заказ A-1842 обещали привезти вчера, но его нет».
Ответ: {"category": "доставка", "order_id": "A-1842"}

Обращение: «За покупку B-731 деньги сняли дважды».
Ответ: {"category": "оплата", "order_id": "B-731"}

Обращение: «Оплатил заказ C-902, а через минуту с карты снова списали ту же сумму».
Ответ:

Ожидаемое продолжение:

{"category": "оплата", "order_id": "C-902"}

Примеры показывают, как связать разные формулировки с нужной категорией, извлечь номер заказа и оформить результат. Такой способ называют обучением на примерах в контексте — in-context learning.

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

2020 год: RAG подключает к ответу внешние материалы

Параллельно решали проблему доступа к сведениям, которых модель не получила при обучении или которые успели устареть. Например, строительная компания хочет внедрить чат для сотрудников, чтобы они могли спрашивать, как согласовать проект или оформить заявку на закупку материалов. Ответы зависят от внутренних регламентов этой компании. Если документы хранятся в закрытой корпоративной базе и не использовались при обучении, готовая модель не располагает этими сведениями.

В 2020 году исследователи представили RAG — Retrieval-Augmented Generation, генерацию с использованием найденных материалов. Подход объединял языковую модель с поиском по внешней коллекции документов. В исходной работе использовался индекс материалов Wikipedia.

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

def rag_answer(question: str) -> str:
    # Преобразуем вопрос в числовое представление.
    query_vector = retriever.encode(question)

    # Находим подходящие фрагменты документов.
    passages = vector_index.search(query_vector, limit=5)

    # Передаем вопрос и найденные материалы языковой модели.
    return generator.generate(
        question=question,
        context=passages,
    )

Названия компонентов и методов здесь условные. Предполагается, что документы заранее разбиты на фрагменты, их векторы рассчитаны и сохранены в поисковом индексе. retriever преобразует вопрос в вектор, совместимый с представлениями документов. vector_index находит подходящие фрагменты и в этой схеме возвращает их тексты, а generator получает вопрос вместе с найденными материалами и формирует ответ.

RAG позволяет обновлять доступную системе информацию без переобучения самой языковой модели: новые документы добавляют в поисковый индекс, после чего система может использовать их в ответах. Однако качество результата зависит и от найденных материалов: устаревший источник или неправильно выбранный фрагмент могут привести к ошибке [8].

2022 год: InstructGPT учится точнее выполнять просьбы пользователя

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

Условный пример такого сбоя:

Просьба пользователя:
«Объясни этот договор простыми словами».
Далее приложен текст договора.

Возможное продолжение модели:
«Перечисли обязанности сторон, выдели сроки оплаты и объясни условия расторжения».

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

В InstructGPT OpenAI применила обучение с участием людей. Сначала специалисты писали примеры подходящих ответов, на которых дообучали языковую модель. Затем они сравнивали несколько сгенерированных вариантов и отмечали предпочтительные. На этих сравнениях обучали отдельную модель вознаграждения, которая предсказывала, какой ответ получит более высокую оценку. После этого основную модель дополнительно настраивали с учетом ее оценок.

# Обучаем модель на примерах запросов и подходящих ответов.
sft_model = supervised_fine_tune(
    base_model,
    demonstrations,
)

# Учим отдельную модель оценивать ответы по предпочтениям, отмеченным людьми.
reward_model = train_reward_model(
    ranked_responses,
)

# Дополнительно обучаем языковую модель, используя оценки модели вознаграждения.
assistant = reinforcement_learning(
    policy=sft_model,
    reward_model=reward_model,
)

Здесь policy обозначает обучаемую языковую модель. На последнем этапе выполняется RLHF — обучение с подкреплением [9] на основе человеческой обратной связи. В InstructGPT для этого использовали PPO — Proximal Policy Optimization: алгоритм обновлял параметры языковой модели с учетом оценок модели вознаграждения, обученной на предпочтениях людей.

На запросах, использованных в исследовании, оценщики предпочитали ответы InstructGPT с 1,3 миллиарда параметров ответам базовой GPT-3 со 175 миллиардами. Это показало, что для выполнения пользовательских запросов важен не только размер модели, но и дополнительная настройка ее поведения.

30 ноября 2022 года: ChatGPT делает диалог основным интерфейсом

Следующим шагом стало обучение модели общению в формате последовательного разговора. 30 ноября 2022 года OpenAI представила ChatGPT. При подготовке обучающих примеров специалисты разыгрывали обе стороны беседы: писали сообщения пользователя и ответы помощника. Затем варианты ответов сравнивали и использовали эти оценки для дополнительного обучения. Пользователь мог задавать уточнения, возвращаться к предыдущим репликам и просить исправить результат.

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

Историю разговора, которую передают модели при подготовке следующего ответа, можно условно представить таким списком сообщений на Python:

messages = [
    {
        "role": "system",
        "content": "Объясняй код как технический редактор.",
    },
    {
        "role": "user",
        "content": (
            "Объясни функцию с двумя циклами: "
            "первый группирует записи, второй считает суммы."
        ),
    },
    {
        "role": "assistant",
        "content": (
            "Первый цикл распределяет записи по группам. "
            "Второй подсчитывает сумму для каждой группы."
        ),
    },
    {
        "role": "user",
        "content": "А теперь подробнее только о втором цикле.",
    },
]

В этом примере system содержит общее требование к ответам, user — сообщения пользователя, а assistant — предыдущий ответ модели. Код только создает список сообщений; обращение к модели здесь не показано. Когда ей передают такую историю вместе с последним вопросом, фраза «о втором цикле» получает конкретный смысл: пользователь просит подробнее объяснить подсчет сумм.

Однако объем доступной информации ограничен контекстным окном — максимальным количеством токенов, которое модель может обработать в рамках одного обращения. Токеном может быть слово, его часть или знак. В этот лимит входят переданные сообщения, дополнительные материалы и создаваемый ответ.

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

2022–2023 годы: этика ответов и работа с изображениями

Разработчиков интересовала не только точность выполнения просьб, но и этическая сторона общения. Требовалось определить, как модель должна реагировать [10] на запросы, связанные с насилием, обманом или унижением других людей: не помогать причинять вред, но при этом объяснять причины отказа, а не просто прекращать разговор.

В декабре 2022 года Anthropic представила Constitutional AI — подход к обучению на основе принципов, сформулированных разработчиками. Эти принципы задавали требования к поведению модели. Во время обучения она составляла ответ, затем критически оценивала его по заданным правилам и исправляла обнаруженные нарушения. Полученные варианты использовали как примеры для дальнейшего дообучения.

На следующем этапе ИИ сравнивал пары ответов и определял, какой лучше соответствует этим принципам. На таких сравнениях обучали отдельную модель-оценщика, чьи оценки затем использовали для настройки отвечающей модели. Так часть работы, которую раньше выполняли люди, передавалась ИИ. Этот подход получил название RLAIF — обучение с подкреплением на основе обратной связи от искусственного интеллекта [11].

Параллельно расширялись возможности обработки входных данных. В марте 2023 года OpenAI представила GPT-4 и продемонстрировала ее способность обрабатывать текст вместе с изображениями. В сентябре компания начала открывать эту возможность пользователям ChatGPT Plus и Enterprise. Пользователь мог приложить диаграмму, фотографию или снимок документа и задать вопрос об их содержимом. Модель учитывала изображение вместе с текстом запроса и формировала письменный ответ — например, объясняла, что показано на графике.

2024 год: больше контекста, новые форматы и дополнительное время на ответ

В 2024 году развитие AI-чатов шло сразу по нескольким направлениям. Одни изменения позволяли моделям обрабатывать больше текста, кода и других данных за одно обращение. Другие улучшали работу с голосом и сложными вопросами, а также расширяли возможности поиска информации и сохранения контекста между разговорами.

Длинный контекст

В феврале 2024 года Google представил Gemini 1.5 Pro. Для модели было заявлено стандартное контекстное окно в 128 тысяч токенов, а ограниченной группе разработчиков и корпоративных клиентов предоставили тестовый доступ к окну до миллиона токенов. Это позволяло передавать модели большие документы, значительные объемы кода, длинные аудиозаписи и видео.

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

Совместная работа с текстом, изображениями и голосом

В мае 2024 года OpenAI представила GPT-4o, обученную совместно обрабатывать текст, изображения и аудио.

В прежнем голосовом режиме ChatGPT использовалась цепочка из трех моделей: одна преобразовывала речь в текст, вторая готовила письменный ответ, третья озвучивала его. GPT-4o могла непосредственно работать с аудио, получая больше информации об интонации и особенностях речи, которые теряются при обычной расшифровке. Возможности новой модели внедрялись в пользовательские продукты поэтапно.

Дополнительные вычисления для сложных вопросов

В сентябре OpenAI представила o1 — семейство моделей, обученных выполнять дополнительные шаги рассуждения перед итоговым ответом. По данным разработчиков, качество улучшалось как при увеличении объема обучения с подкреплением, так и при выделении большего времени на решение конкретного вопроса.

Обычная генерация:
Запрос → последовательное построение ответа

Режим с дополнительными рассуждениями:
Запрос → промежуточные шаги и проверка → итоговый ответ

Текст в обоих случаях формируется последовательно. Разница заключается в том, сколько вычислений система выполняет до предъявления окончательного результата. Для сложных вопросов модель может рассмотреть промежуточные варианты, заметить ошибку и изменить подход. Это требует больше времени, но способно улучшить результат.

Веб-поиск и память между разговорами

В октябре 2024 года OpenAI представила ChatGPT Search — обновленный поисковый режим с актуальными веб-источниками и ссылками в ответах. Возможность обращаться к интернету существовала в ChatGPT и раньше, но новый режим сделал поиск более тесной частью диалога. В том же году OpenAI развивала функцию сохраненной памяти [12], позволявшую переносить отдельные сведения о пользователе между беседами.

Здесь важно различать три вещи. Контекстное окно — объем данных, доступных модели при подготовке ответа. История чатов — сохраненные разговоры, которые могут находиться за пределами этого окна. Долговременная память [13] — сведения, которые система сохраняет или извлекает для использования в последующих беседах.

Большое окно позволяет обработать больше информации за один раз, а память помогает перенести нужный контекст в новый разговор. Это отдельные возможности, которые могут работать совместно.

2025 год: персонализация и выбор модели под запрос

Следующим шагом стало более широкое использование истории общения. В 2025 году ChatGPT начал учитывать не только отдельно сохраненные сведения, но и информацию из предыдущих разговоров. Gemini Advanced также получил возможность обращаться к прошлым чатам, чтобы подготавливать более подходящие ответы.

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

Другим направлением стала маршрутизация — выбор модели для обработки конкретного запроса. В августе 2025 года пользователям ChatGPT предложили режимы Fast — для быстрых ответов, Thinking — для более глубокого рассуждения и Auto — для автоматического выбора. В режиме Auto система учитывала содержание запроса и контекст разговора, чтобы определить, какую модель использовать.

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

def select_model(request):
    # Сложному вопросу выделяем режим с рассуждениями.
    if request.requires_deep_reasoning:
        return reasoning_model

    # Для короткого ответа с минимальной задержкой
    # выбираем быструю модель.
    if request.requires_low_latency:
        return fast_model

    return default_model

Функция получает готовый признак requires_deep_reasoning: True означает, что нужны дополнительные рассуждения, False — что выбран быстрый ответ. Она возвращает условное название модели, но сама не анализирует запрос и не запускает нейросеть. В реальной системе GPT-5 выбор выполнял обучаемый маршрутизатор, учитывавший сложность разговора, необходимые инструменты и указания пользователя. Пример показывает только идею выбора, а не реализацию этого механизма.

2026 год: память между беседами и более естественный голосовой диалог

Одним из направлений развития стала работа с контекстом из разных разговоров. Пользователь мог сообщить об изменениях в одном чате, а затем продолжить обсуждение в другом. Задача памяти — сохранить полезные сведения и учитывать последующие уточнения. Например, если раньше обсуждался проект на MySQL, а позже пользователь сообщил о переходе на PostgreSQL, при следующих обращениях важно опираться на обновленную информацию.

4 июня 2026 года OpenAI начала внедрять обновленную систему памяти на основе Dreaming (механизма фоновой обработки истории общения) для подписчиков Plus и Pro в США. Компания также объявила о планах расширить доступ на другие страны и тарифы Free и Go. Система сопоставляет сведения из разных бесед, объединяет их и обновляет информацию о проектах, предпочтениях и требованиях пользователя. Подготовленные сведения затем используются при формировании новых ответов.

В аккаунтах с обновленной памятью пользователь может открыть «Настройки → Персонализация → Память» и посмотреть резюме — текст с основными сведениями, которые ChatGPT учитывает при общении. Там можно выделить неточную запись и указать исправление либо описать необходимые изменения в специальном поле. Такое резюме показывает основные сохраненные сведения, но не обязательно весь контекст, доступный системе.

Google также развивал Personal Intelligence — персонализацию Gemini с использованием подключенных сервисов, в том числе Gmail и Google Photos. С разрешения пользователя система могла находить нужные сведения в письмах и фотографиях и учитывать их в ответах. Например, при обсуждении поездки — использовать информацию из письма с подтверждением бронирования. Пользователь самостоятельно выбирал, какие сервисы подключить.

Менялось и голосовое общение. В июле 2026 года OpenAI представила GPT-Live, которая стала основой обновленного ChatGPT Voice. Модель может одновременно формировать голосовой ответ и воспринимать речь пользователя. Поэтому, если пользователь перебивает ее уточнением, система может остановиться, выслушать новую реплику и скорректировать продолжение разговора.

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

Среди следующих обновлений OpenAI анонсировала поддержку видео и демонстрации экрана в GPT-Live, пока без точной даты запуска. Это должно дополнить голосовой разговор визуальным контекстом: пользователь сможет показывать то, о чем спрашивает. Google в сентябре 2026 года также объявила о скором появлении Guided vision в Gemini Live — функции, разработанной для незрячих и слабовидящих пользователей: она будет описывать изображение с камеры, помогать читать текст и голосом подсказывать, куда направить телефон, чтобы нужный объект оказался в кадре.

Заключение

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

Автор: DevRoad

Источник [14]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/35989

URLs in this post:

[1] < — Часть I. Как поисковые системы учились понимать запросы: https://habr.com/ru/articles/1082660/

[2] Поведение: http://www.braintools.ru/article/9372

[3] впечатление: http://www.braintools.ru/article/2012

[4] обучение: http://www.braintools.ru/article/5125

[5] внимания: http://www.braintools.ru/article/7595

[6] логику: http://www.braintools.ru/article/7640

[7] поведение: http://www.braintools.ru/article/5593

[8] ошибке: http://www.braintools.ru/article/4192

[9] подкреплением: http://www.braintools.ru/article/5528

[10] реагировать: http://www.braintools.ru/article/1549

[11] интеллекта: http://www.braintools.ru/article/7605

[12] памяти: http://www.braintools.ru/article/4140

[13] Долговременная память: http://www.braintools.ru/article/9500

[14] Источник: https://habr.com/ru/articles/1086352/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1086352

www.BrainTools.ru

Rambler's Top100