Проблема и текущие решения
Делиться

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

В этой статье мы рассмотрим проблему, выясним, что необходимо для создания эффективной системы, рассмотрим различные варианты архитектуры и рассмотрим поставщиков решений с открытым исходным кодом и облачных решений, которые могут нам помочь.
Продумывание решения
Давайте сначала рассмотрим мыслительный процесс формирования памяти для студентов магистратуры права и что нам понадобится для того, чтобы он был эффективным.
Первое, что нам нужно, это чтобы LLM мог вытащить старые сообщения, чтобы рассказать нам, что было сказано. Так что мы можем спросить его: «Как назывался тот ресторан, в который ты сказал мне пойти в Стокгольме?» Это будет базовым извлечением информации.
Если вы новичок в создании систем LLM, вашей первой мыслью может быть просто сбросить каждое воспоминание в контекстное окно и позволить LLM разобраться в нем самостоятельно.
Однако эта стратегия затрудняет для магистров права понимание того, что важно, а что нет, что может привести к появлению ложных ответов.
Второй мыслью может быть сохранение каждого сообщения вместе с его резюме и использование гибридного поиска для извлечения информации при поступлении запроса.

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

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

Затем они классифицируют факт в предопределенной группе (например, профиль, предпочтения или проекты) и либо обновляют существующее воспоминание, если оно похоже, либо создают новое, если нет.
Другая часть, долговременная память, означает хранение всех сообщений и суммирование целых разговоров, чтобы к ним можно было обратиться позже. Это также есть в ChatGPT, но, как и в случае с карманной памятью, вам нужно включить это.
Здесь, если вы создаете это самостоятельно, вам нужно решить, сколько деталей сохранить, учитывая при этом раздувание памяти и растущую базу данных, о которой мы говорили ранее.
Типовые архитектурные решения
Если посмотреть на то, что делают другие, можно выбрать два основных варианта архитектуры: векторы и графы знаний.
Сначала я прошел через поисковый подход. Обычно это то, на что люди набрасываются, когда начинают. Поиск использует векторное хранилище (и часто разреженный поиск), что просто означает, что он поддерживает как семантический, так и поиск по ключевым словам.
Начать поиск просто — вы встраиваете свои документы и извлекаете их на основе вопроса пользователя.
Но делать это таким образом, как мы говорили ранее, означает, что каждый ввод неизменен. Это означает, что тексты останутся там, даже если факты изменятся.
Проблемы, которые могут возникнуть здесь, включают получение нескольких противоречивых фактов, что может сбить агента с толку. В худшем случае соответствующие факты могут быть зарыты где-то в кучах извлеченных текстов.
Агент также не будет знать, когда что-то было сказано и относилось ли это к прошлому или будущему.
Как мы уже говорили ранее, существуют способы обойти это.
Вы можете искать старые воспоминания и обновлять их, добавлять временные метки к метаданным и периодически обобщать разговоры, чтобы помочь LLM понять контекст вокруг извлеченных деталей.
Но с векторами вы также сталкиваетесь с проблемой растущей базы данных. В конце концов, вам придется обрезать старые данные или сжимать их, что может заставить вас отказаться от полезных деталей.
Если мы посмотрим на графы знаний (ГЗ), то увидим, что они представляют информацию в виде сети сущностей (узлов) и связей между ними (ребер), а не в виде неструктурированного текста, как в векторах.

Вместо перезаписи данных KG могут назначить дату invalid_at старому факту, чтобы вы могли отслеживать его историю. Они используют обходы графа для извлечения информации, что позволяет вам отслеживать отношения между несколькими переходами.
Поскольку KG могут переключаться между подключенными узлами и обновлять факты более структурированным образом, они, как правило, лучше справляются с временными и многошаговыми рассуждениями.
Однако KGs имеют свои собственные проблемы. По мере роста инфраструктура становится сложнее, и вы можете начать замечать более высокую задержку во время глубоких обходов, когда системе приходится искать нужную информацию далеко.
Независимо от того, основано ли решение на векторах или КГ, люди обычно обновляют воспоминания, а не просто продолжают добавлять новые, добавляют возможность устанавливать определенные сегменты, которые мы видели для «карманных» фактов, и часто используют LLM для обобщения и извлечения информации из сообщений перед их усвоением.
Если вернуться к изначальной цели — иметь как карманную память, так и долговременную память — можно комбинировать подходы RAG и KG, чтобы получить желаемое.
Решения текущих поставщиков (plug'n play)
Я рассмотрю несколько различных независимых решений, которые помогут вам настроить память, а также то, как они работают, какую архитектуру используют и насколько зрелыми являются их фреймворки.

Создание расширенных приложений LLM все еще очень ново, поэтому большинство этих решений были выпущены только в последние год или два. Когда вы начинаете, может быть полезно проверить, как построены эти фреймворки, чтобы получить представление о том, что вам может понадобиться.
Как упоминалось ранее, большинство из них попадают либо в категорию «KG-first», либо в категорию «vector-first».

Если сначала рассмотреть Zep (или Graphiti), решение на основе KG, то они используют LLM для извлечения, добавления, аннулирования и обновления узлов (сущностей) и ребер (связей с временными метками).

Когда вы задаете вопрос, он выполняет семантический и поиск по ключевым словам, чтобы найти соответствующие узлы, а затем переходит к связанным узлам, чтобы извлечь соответствующие факты.
Если приходит новое сообщение с противоречивыми фактами, оно обновляет узел, сохраняя при этом старый факт на месте.
Это отличается от Mem0 — решения на основе векторов, которое добавляет извлеченные факты друг на друга и использует систему саморедактирования для выявления и полной перезаписи недействительных фактов.
Letta работает похожим образом, но также включает в себя дополнительные функции, такие как основная память, где хранятся сводки разговоров вместе с блоками (или категориями), которые определяют, что должно быть заполнено.
Все решения имеют возможность устанавливать категории, где мы определяем, что должно быть зафиксировано системой. Например, если вы создаете приложение для осознанности, одной из категорий может быть «текущее настроение» пользователя. Это те же карманные корзины, которые мы видели ранее в системе ChatGPT.
Одна из вещей, о которой я говорил ранее, заключается в том, что подходы, ориентированные на векторы, имеют проблемы с временными и многошаговыми рассуждениями.
Например, если я скажу, что через два месяца перееду в Берлин, но ранее упоминал, что живу в Стокгольме и Калифорнии, поймет ли система, что теперь я живу в Берлине, если я спрошу об этом через несколько месяцев?
Может ли он распознавать закономерности? С помощью графов знаний информация уже структурирована, что упрощает для LLM использование всего доступного контекста.
В случае векторов по мере роста объема информации шум может стать слишком сильным, чтобы система могла связать точки.
Хотя Letta и Mem0 в целом более зрелые, эти две проблемы все еще могут возникать.
В случае графов знаний проблема заключается в сложности инфраструктуры по мере их масштабирования и в том, как они управляют растущими объемами информации.
Хотя я не тестировал их все досконально и некоторые моменты все еще отсутствуют (например, показатели задержки), я хочу рассказать, как они обеспечивают корпоративную безопасность, на случай, если вы планируете использовать их внутри своей компании.

Единственный найденный мной вариант облака, сертифицированный по стандарту SOC 2 Type 2, — это Zep. Однако многие из них можно размещать самостоятельно, и в этом случае безопасность зависит от вашей собственной инфраструктуры.
Эти решения все еще очень новые. Вы можете в конечном итоге создать свои собственные позже, но я бы рекомендовал протестировать их, чтобы увидеть, как они справляются с крайними случаями.
Экономика использования поставщиков
Возможность добавлять новые функции в приложения LLM — это здорово, но следует помнить, что это также влечет за собой дополнительные расходы.
Я всегда включаю раздел об экономике внедрения технологии, и этот раз не исключение. Это первое, что я проверяю, когда что-то добавляю. Мне нужно понять, как это повлияет на экономику единицы приложения в дальнейшем.
Большинство решений поставщиков позволят вам начать бесплатно. Но как только вы выйдете за рамки нескольких тысяч сообщений, расходы могут быстро вырасти.

Помните, если в вашей организации ежедневно происходит несколько сотен разговоров, то стоимость начнет расти, когда вы будете отправлять каждое сообщение через эти облачные решения.
Идеальным вариантом может стать начало с облачного решения, а затем по мере роста можно переходить на самостоятельный хостинг.
Вы также можете попробовать гибридный подход.
Например, реализуйте собственный классификатор, чтобы решить, какие сообщения стоит хранить как факты, чтобы снизить затраты, а все остальное поместите в собственное векторное хранилище для периодического сжатия и суммирования.
Тем не менее, использование фактов размером в байт в окне контекста должно быть лучше, чем вставка фрагмента истории в 5000 токенов. Предоставление LLM соответствующих фактов заранее также помогает уменьшить галлюцинации и в целом снижает затраты на генерацию LLM.
Примечания
Важно отметить, что даже при наличии систем памяти не стоит ожидать совершенства. Эти системы все равно иногда галлюцинируют или пропускают ответы.
Лучше ожидать несовершенств, чем гнаться за стопроцентной точностью — так вы убережете себя от разочарования.
Ни одна из современных систем не достигает идеальной точности, по крайней мере пока. Исследования показывают, что галлюцинации являются неотъемлемой частью LLM. Даже добавление слоев памяти не устраняет эту проблему полностью.
Источник: towardsdatascience.com























