Технологии
«Каждый разговор с нуля»: AWS показала ассистента с накопительной памятью на AgentCore и OpenClaw
AWS опубликовала разбор того, как собрать персонального AI-ассистента, который не забывает пользователя между разговорами. Ассистент строится на открытой агентной системе OpenClaw, запущенной на AgentCore runtime (возможность Amazon Bedrock AgentCore), а память AgentCore превращает разовые чаты в долговечные структурированные знания. Весь стек живёт в одном шаблоне CloudFormation, разворачивается одной командой и стоит несколько долларов в месяц при лёгком личном использовании.

Проблема: ассистент без памяти о вас
Готовые AI-ассистенты хорошо отвечают на отдельные вопросы, но проваливаются на другой оси — непрерывности. Если спросить у ассистента без состояния про сад, он не вспомнит, что три недели назад вы упоминали высокие грядки с быстрым дренажом, что используете только органическое удобрение или что петунии переживали жару. Каждый разговор начинается с нуля, и вся тяжесть повторного объяснения контекста ложится на пользователя.
Проблема не в качестве ответов, а в том, что у ассистента нет памяти о вас. AWS показывает, как построить персонального ассистента, который накапливает контекст с помощью OpenClaw — открытой агентной системы — работающей на AgentCore runtime, а память AgentCore превращает разовые чаты в долговечные знания.
Сквозной пример в статье — садовый ассистент Sprout, но архитектура не привязана к домену: достаточно сменить персону и манифест навыков, и тот же конвейер обслуживает бота поддержки, фитнес-тренера или внутренний help desk. Вся система живёт в одном шаблоне AWS CloudFormation, разворачивается одной командой и работает по модели потребления, что при лёгком личном использовании обходится в несколько долларов в месяц.
Как устроен конвейер запроса
Две точки входа сходятся на одном агенте. Сообщения Telegram приходят через Amazon API Gateway и webhook-функцию AWS Lambda, а запланированные задачи вроде утренних напоминаний о поливе — через Amazon EventBridge Scheduler и cronjob-функцию Lambda. Оба пути вызывают API InvokeAgentRuntime на AgentCore runtime, где тонкий процесс server.py координирует шлюз OpenClaw, память AgentCore и Amazon Bedrock Converse API. Amazon S3 даёт рабочее хранилище, AWS KMS отвечает за шифрование, AWS Secrets Manager хранит токен бота, а Amazon CloudWatch собирает логи и метрики.
AgentCore runtime использует модель оплаты по потреблению: счёт идёт за реально потребляемый агентом вычислительный ресурс, а не за время работы по стенным часам, и не берётся за время ожидания ввода-вывода. Для персонального ассистента, используемого короткими всплесками, это разница между примерно 1–2 долларами в месяц в базовом режиме и примерно 35 долларами в месяц за постоянно включённый инстанс Amazon EC2 — оценки для лёгкого личного использования по состоянию на июль 2026 года.
Контракт контейнера и OpenClaw как субстрат
Runtime требует минимального контракта контейнера: слушать порт 8080, отдавать GET /ping для проверки живости и принимать POST /invocations как точку входа агента. Сам контейнер — linux/arm64, собранный многоступенчато из официального образа OpenClaw плюс слой Python.
OpenClaw предоставляет цикл агента, использование инструментов и систему навыков. Обёртка server.py при старте контейнера запускает openclaw gateway run как подпроцесс и проверяет его здоровье, а GET /ping быстро возвращает «здоров», чтобы readiness-проба AgentCore проходила. Реальная работа происходит в POST /invocations: разобрать полезную нагрузку, извлечь память, собрать контекст, передать ход шлюзу и сохранить результат. Важная деталь: AgentCore умеет разморозить замороженный контейнер, чей подпроцесс уже завершился, поэтому путь вызова не предполагает, что шлюз жив, — он вызывает helper ensure_openclaw_ready(), который перепроверяет здоровье и при необходимости перезапускает шлюз перед передачей хода.
Две модели маршрутизируются по типу задачи: Claude Haiku 4.5 — для текста, быстрый и дешёвый на высокочастотных разговорных ходах, а Claude Sonnet 4.5 — для компьютерного зрения, где нужна более сильная мультимодальная логика для более редкой, но сложной задачи диагностики растения по фотографии. Текстовые ходы идут через шлюз OpenClaw, а графические вызывают LLM из Bedrock напрямую из server.py, передавая байты изображения как мультимодальные блоки контента. Так сделано намеренно: сборка OpenClaw внутри контейнера отбрасывала части контента image_url до того, как они доходили до Bedrock, поэтому прямой вызов Converse API гарантирует, что модель увидит настоящие пиксели. Идентификаторы моделей заданы переменными окружения MODEL_ID и VISION_MODEL_ID, так что модели можно менять на уровне развёртывания, не пересобирая образ.
Память: из разовых чатов в долговечные знания
Память AgentCore имеет два слоя. Краткосрочная память хранит каждый ход разговора как событие через CreateEvent с ключом по actorId (идентификатор чата в Telegram) и sessionId — это сырой транскрипт. Долгосрочная память создаётся асинхронно управляемыми стратегиями извлечения в долговечные структурированные записи. В примере настроены три стратегии: USER_PREFERENCE — явные предпочтения («я использую только органическое удобрение»); SEMANTIC — выведенные факты («выращивает мексиканские петунии в высокой грядке из кортена»); SUMMARIZATION — эпизодические сводки сессий.
Записи раскладываются по пространствам имён на пользователя, так что два чата никогда не смешиваются: sprout/{chat_id}/long_term для предпочтений и семантических фактов и sprout/{chat_id}/episodic/{session_id} для сводок сессий. Идентификатор чата — единственный переменный сегмент, что делает изоляцию простой для рассуждений и тестов: каждый уникальный садовод соответствует ровно одному пространству имён, и двое не пересекаются.
На каждом ходу агент извлекает релевантные долгосрочные записи, ранжирует их и вставляет в системный промпт. Вызов RetrieveMemoryRecords идёт против sprout/{chat_id}/long_term, используя сообщение пользователя как поисковый запрос, с ограничением в 50 результатов и бюджетом в 3 секунды. Если извлечение не успевает или падает, система деградирует корректно и отвечает без памяти, а не отказывает. На этапе сборки явные предпочтения ранжируются выше выведенных фактов, порядок внутри каждого класса стабилен, а результат ограничивается перед вставкой.
Метаданные отвечают на вопрос, о чём запись, тогда как пространства имён — чья это память. Ключ метаданных фильтруется на стороне сервера только если объявлен как индексируемый, и в примере используются три таких ключа: type (разделяет виды записей), section (какую грядку или зону описывает запись) и plants (что там растёт, списочный тип). У каждой записи указывается ключ, который должен совпадать с индексируемым, и extractionType — либо STRICTLY_CONSISTENT, передаваемый из события, либо LLM_INFERRED, извлекаемый из разговора. Для выведенных ключей конфигурация может ограничивать значения фиксированным списком, и Sprout делает именно так, чтобы оба пути записи создавали одинаковый словарь.
После ответа модели server.py вызывает CreateEvent с ходом пользователя и ходом ассистента; это новое событие питает стратегии извлечения, которые обогащают долгосрочное хранилище к следующему разу. Извлечение асинхронно, поэтому факт, упомянутый в этой сессии, обычно становится извлекаемым в более поздней, — и это задержку нужно проектировать заранее: краткосрочные события сессии покрывают текущий разговор, а долгосрочные записи — всё, что было раньше.
Память и зрение складываются
На сквозном примере видно, как конвейер работает целиком. За несколько разговоров вы описываете весь сад, растение за растением, обычными словами, и каждое упоминание становится событием. Стратегии извлечения вытаскивают информацию о растении, его расположении и освещённости в пространство имён долгосрочной памяти, а затем на утренний вопрос «помнишь другие растения в моём саду?» извлечение возвращает записи, сборка их ранжирует, и они попадают в системный промпт. Ассистент отвечает с учётом расположения, освещённости, конструкции грядки, поведения почвы и списка растений — ничего из этого не было в самом сообщении.
Память и зрение усиливают друг друга. Когда пользователь присылает фотографию увядающего растения, изображение уходит к Claude Sonnet 4.5, а системный промпт по-прежнему несёт всё, что знает слой памяти. Ассистент сопоставляет фото с мексиканскими петуниями, уже внесёнными в сохранённый список пользователя, и ставит диагноз стресса от увядания в контексте, а не анализирует анонимное фото растения «вслепую». Модели зрения не безошибочны: в более раннем обмене без контекста инвентаря то же растение уверенно определили как ипомею — вид с похожими воронковидными фиолетовыми цветами. Именно привязка модели зрения к собственному сохранённому инвентарю пользователя превратила правдоподобную догадку в верный персонализированный диагноз — хороший пример того, что память улучшает не только тон, но и точность.
Кэширование промптов и руководящие принципы
Вставка памяти в каждый ход делает системный промпт большим, и наивная реализация платила бы за эти токены при каждом запросе. Кэширование промптов в Amazon Bedrock решает это: ассистент строит промпт так, что стабильный префикс — персона и собранный блок памяти — идёт первым, а изменчивое сообщение пользователя — последним. Bedrock кэширует обработанный префикс между запросами, поэтому повторные ходы в разговоре пропускают пересчёт неизменной части. По данным AWS, кэширование промптов может снизить затраты до 90 процентов, а задержку — до 85 процентов для поддерживаемых моделей. Правило порядка важнее любой отдельной настройки: стабильное содержимое вперёд, изменчивое назад и детерминированный порядок внутри блока памяти, чтобы префикс действительно совпадал между запросами.
AWS формулирует набор принципов, переносимых в любой домен. Обёртывать, а не форкать: адаптировать агентный фреймворк к контракту контейнера AgentCore тонкой HTTP-обёрткой, оставаясь на пути обновлений фреймворка. Проектировать пространства имён до того, как что-то хранить: идентификатор пользователя — единственный переменный сегмент, выбранный из канального идентификатора, которому уже доверяете, например идентификатора чата. Относиться к памяти как к улучшению, а не зависимости: каждая операция памяти должна уметь упасть корректно, а отказ извлечения — дать ответ без памяти, не блокируя ответа. Маршрутизировать модели по задаче и держать их идентификаторы в переменных окружения, чтобы маршрутизация была конфигурацией, а не кодом. Ставить бюджет с первого дня: оповещение AWS Budgets на 80 и 100 процентах месячного лимита ничего не стоит и ловит сюрпризы заранее. Держать навыки мелкими и одноцелевыми — навык должен делать одно, что пользователь назвал бы одним предложением.
Как развернуть и сколько это стоит
Развернуть систему можно двумя способами. Одним шагом через Launch Stack: шаблон CloudFormation указывает на публичный образ Amazon ECR, поэтому развёртывается всё, кроме токена Telegram-бота, без лишних шагов. Либо собрать своё: скрипт scripts/deploy.sh проверяет шаблон, собирает и отправляет собственный образ ARM64 в приватный репозиторий Amazon ECR, разворачивает стек и регистрирует webhook Telegram — для полностью настраиваемой сборки.
Лёгкое личное использование обходится примерно в 5–9 долларов в месяц по состоянию на июль 2026 года: примерно 2 доллара инфраструктуры, 1–3 доллара на текстовые вызовы Haiku и 2 доллара на зрение Sonnet, со встроенным бюджетом AWS, который оповещает на 80 и 100 процентах заданного лимита. Полный исходный код лежит в открытом репозитории sample-agentcore-memory-openclaw на GitHub. Когда эксперименты закончатся, AWS советует удалить стек CloudFormation — это снимет runtime-агента, API Gateway, функции Lambda, расписание EventBridge и связанные роли IAM, — затем удалить само хранилище памяти AgentCore вместе с пространствами имён, чтобы не осталось записей пользователей, и удалить ненужные образы из приватного ECR.