Не промптом единым богаты: как строить stateful AI агентов
Продолжаем курс про AI агентов. Серия 3.1 Context Engineering, Sessions, Memory
Если вы освоили промпт-инжиниринг, то вы уже большой молодец. Но как только вы хотите сделать сколько-нибудь умного агента, вы столкнетесь с проблемой – просто промпта недостаточно. Вам нужно, чтобы агент запоминал и потом использовал доп информацию. Это называется инжиниринг контекста.
В UI любой современной LLM эта проблема решена за вас в рамках 1 чата, группы чатов (как в "проектах" в ChatGPT) или в целом для вас как юзера (загляните в настройки профиля в вашей LLM в раздел "memories"). Но если вы строите собсвтенного агента — то вам придется нырнуть глубже в кроличью нору. Так что ныряем 👌
Теория
Stateful — означает, что система помнит, что было раньше. По сути, именно к таким агентам мы чаще всего и стремимся. А stateless — это базовое состояние LLM. Она ничего не помнит и не знает за пределами одного своего расчета. То есть ответила на ваш вопрос, а следующий запрос — с чистого листа.
Так вот чтобы построить stateful агента нам понадобятся 3 компонента:
1. Инжиниринг контекста (Context Engineering) — подготовка и управление информацией, которая передается в LLM в рамках ее контекстного окна (=1 запроса)
2. Работа с сессиями (Session) — контейнер, который содержит историю всего диалога с LLM.
3. Работа с памятью (Memory) — механизмом, который позволяет организованно и долгосрочно хранить информацию из нескольких сессий.
Context Engineering
Чтобы помочь агенту добиться воспроизводимого качественного результата, например, для ризонинга мы наполним его контекстное окно:
• Системным промптом
• Определением тулов, которые он может дергать
• Few-Shot примерами ожидаемого результата
Для разных задач наполнение контекстного окна будет разным.
Цикл управления контекстом состоит из трех шагов:
1. Собрать необходимый контекст под конкретный запрос юзера (воспоминания, файлы и тд)
2. Собрать промпт из собранного контекста
3. Дернуть LLM и тулы, чтобы подготовить ответ пользователю
4. Загрузить получившийся контекст во временное харнилище (сессию). А потом и постоянное хранилище — память.
Sessions
Сессии — это фундаментальный блок беседы с агентом. Она состоит из:
• Событий — сообщений юзера и агента, вызова тулов, полученных данных и тд.
• Состояний — это краткосрочная память агента в рамках одной беседы. По мере развития беседы агент будет дополнять эту память событиями.
За одну сессию можно во много раз переполнить контекстное окно модели. Поэтому приходится выбирать, что оставить, а что обрезать. Для этого есть пара подходов:
• Оставить N последних событий или X токенов в контексте
• Рекурсивная суммаризация — старые части переписки суммаризуются и передаются в контекст в сжатом виде.
Memory
Память очень похожа по устройству на Сессии, но она долгосрочная. Это то, что агент запомнит навсегда (пока не почистят память).
Хранят воспоминания в разных форматах. Распространены два вида:
• Векторные БД — в них воспоминания находятся по семантической близости к запросу юзера. Подходит, когда заранее не понятно, какая будет структура воспоминаний.
• Графовые БД — из воспоминаний строится граф, где воспоминание это нода, а ребро — это связь между нодами. Подходит для случаев, где нужно больше структуры.
Чтобы менеджить воспоминания могут использоваться как встроенные во фреймворк (типа ADK) инстурменты, так и использовать внешние инструменты (типа Agent Engine Memory Bank, Mem0). А сам асинхронный цикл генерации памяти выглядит так:
• Извлечение и фильтрация — менеджер памяти использует LLM, чтобы из предоставленного контекста (истории сообщений) извлечь инфу по выбранному разработчиком топику ("описание юзера").
• Консолидация и сохранение — менеджер памяти сравнивает извлеченные знания и обновляет память (создает новые, редактирует или удаляет воспоминания).
Ну и я крайне рекомендую почитать оригинальный whitepaper, на базе которого был сделан этот пост. Ибо я попытался вынести самое важное из документа на 70 страниц... 😁
Теперь покодим!
#ИИученьесвет
Post #222
1.48K
