П/ВИН

ИИ чат с памятью между сессиями Claude

·8 мин чтения

Я потерял три часа работы из-за того, что Claude забыл всё, что мы обсуждали накануне - архитектурные решения, договорённости, отлаженные куски кода. Новая сессия, чистый лист. Именно тогда я начал разбираться, как сделать нормальный ии чат с памятью, и в итоге написал claude-mem-observer-sessions - инструмент-наблюдатель, который создаёт поисковую память для будущих сессий Claude.

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

Зачем вообще нужна память между сессиями

LLM-модели, включая Claude, работают в рамках контекстного окна. Каждая новая сессия — чистый лист. Это фундаментальное ограничение архитектуры трансформеров: модель не имеет персистентной памяти между независимыми вызовами API. Для одноразовых задач это не проблема, но для долгосрочной разработки это катастрофа продуктивности.

Каждый раз приходится заново объяснять:

  • структуру проекта и принятые архитектурные решения
  • какие баги уже были найдены и как они были исправлены
  • договорённости по стилю кода и именованию
  • контекст бизнес-логики

Временные затраты на «онбординг» ассистента в каждой новой сессии могут составлять 10-20 минут. При интенсивной работе это часы потерянного времени в неделю.

Решений на рынке несколько: MemGPT, различные RAG-системы поверх векторных баз данных, простые текстовые файлы с контекстом. Но claude-mem-observer-sessions предлагает другой подход — специализированный агент-наблюдатель, который работает в фоне и формирует структурированные наблюдения в реальном времени.

Архитектура: наблюдатель как отдельная роль

Ключевая идея проекта — разделение ролей. Есть основная сессия (primary session), где происходит реальная работа: пишется код, обсуждается архитектура, дебажатся баги. И есть сессия-наблюдатель (observer session) — отдельный экземпляр Claude с особым системным промптом.

Наблюдатель получает сообщения из основной сессии через специальный тег <observed_from_primary_session> и его задача — не участвовать в работе, а фиксировать результаты. Принципиально важная инструкция в системном промпте:

CRITICAL: Record what was LEARNED/BUILT/FIXED/DEPLOYED/CONFIGURED,
not what you (the observer) are doing.

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

Такой подход даёт несколько преимуществ:

  1. Фокус на сути — в памяти оседают решения, а не процесс их принятия
  2. Поисковая оптимизация — структурированные факты легче индексировать и находить
  3. Нет шума — промежуточные рассуждения и итерации не засоряют память

Проблема с OAuth: когда инфраструктура подводит

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

Failed to authenticate. API Error: 401 OAuth access token has expired.
Re-authenticate to continue.

Эта ошибка повторялась буквально сотни раз подряд в нескольких сессиях подряд. Что здесь произошло и почему это важно понять?

Природа проблемы

OAuth 2.0 токены имеют ограниченное время жизни (TTL). Это стандартная практика безопасности — RFC 6749 специально предусматривает механизм refresh tokens именно для того, чтобы access tokens были короткоживущими. Когда токен истекает, все API-вызовы начинают возвращать 401.

Проблема в том, что система наблюдателя не имела корректно реализованного механизма обработки этой ошибки. Вместо того чтобы:

  1. Поймать 401
  2. Попытаться обновить токен через refresh token
  3. Повторить запрос
  4. Если refresh тоже не работает — уведомить пользователя и остановиться

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

Правильная обработка истёкших токенов

Корректная реализация retry-логики с обновлением токена выглядит примерно так:

import time
from typing import Optional
 
class APIClient:
    def __init__(self, access_token: str, refresh_token: str):
        self.access_token = access_token
        self.refresh_token = refresh_token
        self.max_retries = 3
    
    def make_request(self, endpoint: str, payload: dict) -> dict:
        for attempt in range(self.max_retries):
            try:
                response = self._call_api(endpoint, payload)
                return response
            except AuthenticationError as e:
                if e.status_code == 401 and attempt < self.max_retries - 1:
                    # Пробуем обновить токен
                    refreshed = self._refresh_access_token()
                    if not refreshed:
                        raise RuntimeError(
                            "Token refresh failed. Re-authenticate required."
                        )
                    # Небольшая пауза перед повтором
                    time.sleep(1)
                    continue
                raise
        
    def _refresh_access_token(self) -> bool:
        try:
            # Запрос к OAuth endpoint для обновления токена
            new_token = oauth_refresh(self.refresh_token)
            self.access_token = new_token
            return True
        except Exception:
            return False

Ключевые моменты: ограниченное количество попыток (max_retries), пауза между попытками, чёткое разграничение между «токен истёк, попробуем обновить» и «обновление не удалось, нужна реаутентификация».

Почему это особенно критично для агентных систем

Обычное веб-приложение при 401 просто редиректит пользователя на страницу логина. Но агентная система, работающая в фоне без прямого участия пользователя, должна уметь либо самостоятельно восстанавливаться, либо корректно завершать работу с понятным сообщением об ошибке.

Бесконечный цикл из сотен одинаковых ошибок — это не просто неудобство. Это:

  • Потеря всех наблюдений за сессию (память не записывается)
  • Потенциальный rate limiting со стороны API
  • Невозможность понять из логов, что реально происходило в основной сессии

Что наблюдатель успел зафиксировать

Несмотря на инфраструктурные проблемы, из фрагментов логов можно восстановить контекст работы, которую пытался наблюдать агент.

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

В другой сессии фигурировал контент о тарификации продукта — что входит в базовый план, что докупается отдельно. Упоминались мониторинг конкурентов, ИИ-сценарии, карусели, видео-аватары HeyGen. Это похоже на работу над описанием SaaS-продукта или его документацией.

Именно здесь проявляется ценность концепции наблюдателя: даже если основная работа была прервана или потеряна, структурированные наблюдения позволяют восстановить контекст для следующей сессии.

Git-история и версионирование памяти

Одна из интересных архитектурных идей проекта — хранить наблюдения в git-репозитории. Это даёт несколько преимуществ:

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

Поиск: git log --grep="воронки" мгновенно найдёт все сессии, где обсуждались воронки. Стандартный инструментарий разработчика работает без дополнительной инфраструктуры.

Ветки: можно вести отдельные ветки памяти для разных фич или экспериментов.

Коллаборация: несколько разработчиков могут делиться контекстом через общий репозиторий памяти.

Структура файлов наблюдений может выглядеть так:

memory/
  sessions/
    2024-01-15-auth-fixes.md
    2024-01-16-funnel-debugging.md
    2024-01-17-pricing-content.md
  index.md          # сводный индекс всех наблюдений
  decisions.md      # только архитектурные решения
  bugs.md           # известные баги и их статус

Каждый файл наблюдений содержит структурированные данные:

## Сессия 2024-01-16
 
### Контекст
Работа над маркетинговыми воронками в основном продукте.
 
### Проблема
Воронки не отрабатывают корректно — конкретный симптом уточняется.
 
### Статус
Начато исследование. Следующая сессия должна начать с анализа
логов событий воронки.
 
### Связанные файлы
- src/funnels/
- docs/funnel-architecture.md

Технические уроки и выводы

Проект claude-mem-observer-sessions поднимает несколько важных вопросов о проектировании агентных систем, которые стоит осмыслить.

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

Второй урок: разделение ролей — мощный паттерн. Идея иметь отдельного агента-наблюдателя, который не участвует в работе, а только фиксирует результаты — элегантное решение. Это похоже на паттерн Event Sourcing в архитектуре ПО: вместо того чтобы хранить текущее состояние, храним последовательность событий, из которых состояние можно восстановить. Наблюдатель — это event recorder для AI-сессий.

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

Четвёртый урок: проблема «потерянного контекста» — это инженерная задача. Многие воспринимают отсутствие памяти у LLM как фундаментальное ограничение, с которым нужно просто мириться. Но это инженерная проблема с инженерными решениями. LangChain предлагает несколько типов памяти, LlamaIndex специализируется на RAG-системах для работы с документами. claude-mem-observer-sessions — это ещё один подход, заточенный под специфику долгосрочной разработки с Claude.

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

Что дальше

Проект находится в активной разработке. Ключевые направления для улучшения:

  • Устойчивая аутентификация: реализация корректного refresh token flow с экспоненциальным backoff
  • Структурированный формат наблюдений: JSON-схема для наблюдений вместо свободного текста, что упростит поиск и индексацию
  • Векторный поиск: интеграция с векторной базой данных для семантического поиска по накопленной памяти
  • Дашборд: простой интерфейс для просмотра и поиска по истории наблюдений

Концепция агента-наблюдателя для создания персистентной памяти между AI-сессиями — это не просто удобная фича. По мере того как AI-ассистенты становятся всё более интегрированы в рабочие процессы разработчиков, инструменты для управления контекстом и памятью станут такой же необходимостью, как системы контроля версий. claude-mem-observer-sessions — один из первых шагов в этом направлении.


Полезные ссылки по теме:

Паша Вин
Паша Вин

AI-инженер, предприниматель, маркетолог. Основатель feberra.com и x10seo.ru. 13 лет в перфоманс-маркетинге, 3 года в системной интеграции AI в бизнес.