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

Память на каждого клиента

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

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

Память выводится, а не логируется

1. Turn ends

Завершается реплика в разговоре. Пока ничего не сохраняется — транскрипты не являются единицей памяти здесь.

2. Extract

Модель извлекает нормализованные записи из того, что сказал клиент — а не из ответов самого агента: факты («управляет автопарком из четырёх транспортных средств») и темы, каждая со шкалой важности, чтобы случайное замечание и жёсткое ограничение не взвешивались одинаково.

3. Batch embed

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

4. Deduplicate

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

5. Store

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

6. Recall

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

Runs after a turn. The deduplication step is what keeps recall from degrading as a relationship gets longer.

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

Вместо этого после реплики платформа просит модель извлечь нормализованные записи из того, что сказал клиент, двух видов:

  • Факты — устойчивые утверждения о клиенте. «Управляет автопарком из четырёх транспортных средств». «Продление в мае». «Предпочитает WhatsApp».
  • Темы — повторяющиеся темы, к которым возвращаются отношения, каждая с именем темы.

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

Только половина клиента в разговоре

Извлечение читает то, что сказал клиент. Ответы самого агента не подходят для формирования фактов о клиенте, и это важнее, чем кажется.

Агент, который однажды поспекулирует — предложение о том, что, вероятно, производит компания этого клиента, предложенное как догадка в одном ответе, — в противном случае будет иметь эту спекуляцию, извлечённую как устойчивый факт и прочитанную как предпосылка в каждой последующей реплике. С этого момента это уже не догадка; это то, что знает агент. Клиент видит последствия, никогда не видя причины: ответы, которые постоянно касаются неправильного бизнеса, без объяснений на экране, почему это происходит.

Есть две защиты, потому что первая — это запрос, а вторая — проверка. Извлечение показывается только половину клиента. Затем, прежде чем что-либо будет записано, программное обеспечение проверяет, есть ли у формулировки «факта» какое-либо основание в том, что клиент на самом деле сказал — проверка, которая выполняется вне модели, для каждой записи, каждой реплики.

Дедупликация — это вся игра

Клиент упоминает одно и то же в пяти разговорах. Без дедупликации вы накапливаете пять почти идентичных воспоминаний, они вытесняют всё остальное во время извлечения, и агент начинает повторяться.

Прежде чем запись будет записана, платформа ищет ту, в которую её следует объединить:

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

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

Пакетное встраивание

Одна реплика часто даёт несколько записей. Встраивание их по одной означает несколько последовательных раундов к эндпоинту встраивания — и поскольку этот эндпоинт работает с конкурентностью единица, эта последовательность блокирует встраивания запросов других пользователей позади себя.

Поэтому записи реплики встраиваются одним пакетом, а векторы передаются вниз по пути записи. Измерено на реплике с тремя записями: 117 мс последовательно против 46 мс пакетно — разница в 2,4 раза на пути, который находится между клиентом и его ответом.

Извлечение

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

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

Забывание

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

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

Так что сказать об этом работает. «Мы этого не делаем». «Это не моя компания». «Забудь то, что ты знаешь о X». Агент сопоставляет это с тем, что хранится, и удаляет найденные записи, на любом языке, без открытия страницы настроек кем-либо.

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

  • Не более нескольких записей за запрос, так что одно неверное толкование остаётся ограниченным.
  • Только записи, достаточно близкие для реального совпадения. Поиск по сходству всегда возвращает ближайшие результаты, даже на аккаунте, не содержащем ничего релевантного; без нижнего порога расстояния «забудь то, что ты знаешь о X» на нерелевантном аккаунте удалит то, что случайно оказалось на первом месте.
  • То, что было удалено, читается обратно клиенту. Тихое удаление так же плохо, как неправильное запоминание, и на этот раз единственный человек, который может сказать, было ли это правильно, уже находится в разговоре.

Удаление является постоянным — нет архива, хранящего копию того, о чём клиент попросил забыть, что является единственным прочтением этого запроса, которое имеет смысл.

Ограничение и шифрование

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

Почему это трудно прикрутить позже

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

The business argument for this, rather than the mechanism, is on Per-customer memory.