Как это устроено

Где живёт разговор между ходами

Если каждый ход — самодостаточный запрос, где же остальной разговор? Что записывается на каждом ходу и что не записывается никогда, дословное окно, как более старые ходы ровно один раз сворачиваются в накопительную выжимку, что происходит, когда один ход всё равно не влезает, и какие факты переживают сессию.

Каждый ход — один самодостаточный запрос: модель не хранит между ходами ничего, и то, чего нет в запросе, для неё не существует. Отсюда очевидный вопрос — если модель ничего не помнит, где тогда разговор?

Он на нашей стороне, в трёх слоях с тремя разными сроками жизни. Каждый ход собирается из них заново, а различаются слои не важностью, а тем, как далеко назад они дотягиваются.

Три слоя

one conversation over time
durable memoryfacts about this customer · survives the session, follows them across channelsships to Rotterdamrolling summaryeverything older,folded in oncecursor: never twicerecent turns, verbatim
Недавние ходы попадают в запрос дословно. То, что выпадает из этого окна, сворачивается в накопительную выжимку — один раз: курсор гарантирует, что одно и то же не будет пересказано дважды. Факты, которые стоит сохранить, извлекаются отдельно и переживают всю сессию.

Что записывается и что не записывается никогда

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

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

Дословное окно

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

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

Накопительная выжимка

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

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

У выжимки есть предел (несколько сотен токенов), она хранится в сессии и шифруется, как всё остальное. В запросе это один блок, над историей.

Когда один ход всё равно не влезает

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

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

Что переживает сессию

Все слои выше принадлежат одному разговору. Две вещи — нет:

  • Устойчивые факты о клиенте — выводятся из ходов по мере их появления, дедуплицируются, так что один и тот же факт обновляется, а не накапливается, и извлекаются по релевантности, а не по свежести. Они следуют за человеком между сессиями и между каналами. Память о клиенте — о том, как они выводятся и что вспоминается.
  • Короткий профиль — периодически обновляется по недавним сообщениям и несёт постоянный контекст, а не факты.

Поэтому новая сессия — это по-настоящему новый разговор: без истории, без выжимки, — но не беспамятный. То, что агент узнал о человеке, остаётся на месте.

Что это значит для вас

  • Сессия — это то, что держится за один и тот же session id. Веб-виджет хранит по одному на посетителя; вызывающий API решает сам. Начать новую — это способ намеренно оборвать нить, не теряя того, что узнали о клиенте.
  • Длинный разговор деградирует плавно, а не внезапно. Самые старые ходы теряют формулировки раньше, чем суть, и суть — прежде чем исчезнуть совсем.
  • Экспорт и записи показывают разговор, а не машинерию. Поскольку трафик инструментов никогда не сохранялся, вы читаете то же, что прочитал бы человек.