· 6 мин · Разработка

Постоянная память для Claude Code: как на самом деле работает контекст между сессиями

Постоянная память для Claude Code: как на самом деле работает контекст между сессиями

В пятницу вы закрываете ноутбук после трёхчасового сеанса, в ходе которого Claude Code выполнил рефакторинг вашего модуля аутентификации, узнал, что ваша команда использует собственную Result<T> обёртку вместо выбрасывания исключений, и наконец понял, почему UserService не может импортировать из billing/. В понедельник вы начинаете новый сеанс, и Claude уверенно оборачивает новую функцию в try/catch и импортирует запрещённый модуль. Всё, что он узнал, исчезло.

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

Основная проблема: сеансы изначально не сохраняют состояние

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

  • Ваш CLAUDE.md files (project and user scope)
  • Файлы, которые Claude читает во время сеанса
  • То, что вы вводите

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

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

Архитектурный подход к постоянной памяти Claude Code

Любой серьёзный подход к постоянной памяти в Claude Code строится на одном и том же цикле из трёх этапов. Понимание каждого этапа по отдельности позволяет вам реализовать его самостоятельно, купить готовое решение или вовсе обойтись без него.

Этап 1: Сбор

Нужно отслеживать, что происходило в сессии. Claude Code предоставляет хуки жизненного цикла — команды оболочки, которые запускаются при определённых событиях. Вот те, которые нам нужны:

ХукКогда срабатываетДля чего использовать
SessionStartНачинается сессияДобавить память в контекст
SessionEndЗавершается сессияЗапустить сбор
PostToolUseПосле любого вызова инструментаПередавать подробный поток действий
StopАгент заканчивает ответСохранить контрольную точку

Минимальный хук для сбора в .claude/settings.json:

{
  "hooks": {
    "SessionEnd": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/mem/capture.sh"
          }
        ]
      }
    ]
  }
}

Хук получает через stdin JSON с описанием события. Для SessionEnd вы получаете идентификатор сессии и путь к её записи, поэтому capture.sh может прочитать полный журнал разговора:

#!/usr/bin/env bash
INPUT=$(cat)
TRANSCRIPT=$(echo "$INPUT" | jq -r '.transcript_path')
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id')

# Hand the raw transcript to the compression stage
python3 "$CLAUDE_PROJECT_DIR/.claude/mem/compress.py" \
  --transcript "$TRANSCRIPT" \
  --session "$SESSION_ID"

Распространённая ловушка: время выполнения хуков ограничено, и синхронная передача большой записи сессии в LLM приведёт к превышению этого лимита. На практике сбор лучше запускать без ожидания результата: записывать путь к записи сессии в очередь и обрабатывать её фоновым обработчиком, а не внутри хука.

Этап 2: Сжатие

Необработанные записи сессий бесполезны в качестве памяти: они огромны и полны шума — дампов файлов, потока вызовов инструментов и ваших опечаток. На этапе сжатия LLM выделяет из сессии факты, которые сохранят ценность со временем. Здесь стоит использовать вызов Haiku 4.5, а не Opus: составление сводок — именно та массовая задача с невысокой ценой ошибки, на которую рассчитаны тарифы Haiku.

import anthropic

client = anthropic.Anthropic()

PROMPT = """You are a memory compressor. From this coding session
transcript, extract ONLY durable facts worth remembering next session:
- Architectural decisions and their rationale
- Conventions discovered (naming, error handling, imports)
- Dead ends already explored (so we don't repeat them)
- Unresolved TODOs

Output JSON: a list of {fact, category, files[], confidence}.
Omit anything transient. If nothing durable happened, output []."""

resp = client.messages.create(
    model="claude-haiku-4-5",
    max_tokens=1500,
    system=PROMPT,
    messages=[{"role": "user", "content": transcript_text}],
)
memories = resp.content[0].text

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

Этап 3: Добавление в контекст

В начале сессии вы извлекаете подходящие воспоминания и добавляете их в контекст. Хук SessionStart может выводить данные в stdout, и этот вывод добавляется в контекст Claude:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "*",
        "hooks": [
          { "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/mem/inject.sh" }
        ]
      }
    ]
  }
}

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

# A tiny MCP tool the agent calls when it wants history
@mcp.tool()
def recall(query: str, files: list[str] = []) -> list[dict]:
    """Retrieve relevant memories about this codebase."""
    return memory_store.search(query, files=files, min_confidence=0.6)

На практике модель получения по запросу работает лучше модели предварительной загрузки. Вместо того чтобы угадывать при запуске, что окажется полезным, вы позволяете агенту спросить: «Мы уже работали с этим кодом биллинга?» — именно тогда, когда это важно. Хук добавляет небольшую сводку, которая всегда остаётся в контексте; MCP-сервер отвечает за адресное извлечение воспоминаний.

Где это ломается — а это действительно ломается

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

Память, сжатая с помощью ИИ, содержит галлюцинации. Сжатие выполняет сама языковая модель. Иногда она записывает как «решение» идею, которую на самом деле отвергли, или искажает обоснование выбора до противоположного. В результате при запуске в контекст попадает ложное воспоминание, которое звучит авторитетно, и агент доверяет ему больше, чем следует. Это хуже, чем отсутствие памяти, потому что ошибка подаётся уверенно. Поле confidence и проверка хранилища памяти человеком — единственные меры, которые действительно снижают этот риск.

Устаревший контекст — тихий убийца. Во вторник вы проводите рефакторинг UserService . Память за понедельник всё ещё говорит: «Аутентификация находится в UserService». Ничто не помечает эту запись как недействительную. Точность воспоминаний начинает снижаться в тот момент, когда меняется код, а однозначного сигнала для их удаления нет. Привязывайте воспоминания к хешам файлов или SHA коммитов и считайте их сомнительными при перемещении соответствующего файла.

Расходы на токены растут с каждой сессией. Добавленная память — это контекст, за который вы платите на каждом ходе, независимо от того, используется ли он. Если слой памяти добавляет 4K токенов при запуске, они увеличивают стоимость входных данных на протяжении всей сессии. Модель MCP с получением по запросу помогает, но сбор и сжатие сами по себе тоже требуют регулярных расходов.

Вот честное сравнение:

ПодходЗатраты на настройкуРегулярный расход токеновРиск устареванияЛучше всего подходит для
CLAUDE.md толькоМинутыНизкий, предсказуемыйВы контролируете егоБольшинство проектов
MCP-инструменты с ограниченной областью действияЧасыТолько по запросуНизкийТекущее состояние системы
Полноценный слой памятиДниВыше, в каждой сессииВысокийДлительная исследовательская работа

Неудобная правда: скорее всего, вам это не нужно

Прежде чем строить всё это, составьте хороший CLAUDE.md. Подготовленный вручную файл, в котором сказано «мы используем Result<T>, никогда не выбрасывайте исключения; UserService не должен импортировать billing/; аутентификация перенесена в auth/ во втором квартале», решает 80% проблемы памяти без риска галлюцинаций и с предсказуемой стоимостью. Он написан человеком, поэтому заслуживает доверия по самому способу создания.

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

Если вы всё же строите такой конвейер, именно на этапе сжатия особенно важно учитывать стоимость: частое составление сводок с помощью Haiku обходится дёшево, но только если исходная цена за токен разумна. Это одна из причин, по которым команды направляют подобные массовые фоновые задачи через таких провайдеров, как AI Prime Tech.

Практические рекомендации

  • Сессии не сохраняют состояние. Теряются именно полученные в ходе работы знания — тупиковые пути, обоснования, соглашения, — и восстанавливать их заново дорого.
  • Схема такова: сбор → сжатие → добавление в контекст. Подключайте сбор и добавление в контекст через SessionEnd/SessionStart хуки; выполняйте сбор асинхронно, чтобы избежать превышения времени выполнения хука.
  • Предпочитайте получение по запросу предварительной загрузке. Добавляйте краткую сводку при запуске, затем предоставляйте recall MCP-инструмент, чтобы агент обращался к памяти только тогда, когда это уместно.
  • Сжимайте с помощью Haiku 4.5, помечайте каждое воспоминание степенью достоверности и хешами исходных файлов, а при изменении файлов считайте соответствующие воспоминания сомнительными.
  • Автоматизированная память может лгать. Выдуманный и устаревший контекст хуже, чем его отсутствие, потому что воспринимается как авторитетный. Обеспечьте участие человека в проверке хранилища памяти.
  • Попробуйте CLAUDE.md в первую очередь. Для большинства проектов написанный вручную файл контекста вместе с инструментами с ограниченной областью действия превосходит полноценный слой памяти по стоимости, доверию и обслуживанию. Обращайтесь к постоянной памяти только тогда, когда ваша работа действительно длительная и исследовательская.
A

Этот блог публикует AI Prime Tech. Статьи готовятся с помощью ИИ; прежде чем полагаться на сведения, зависящие от версии, такие как идентификаторы моделей, цены и лимиты, сверяйте их с официальной документацией.

Получите более дешёвый доступ к API Claude

Один ключ API для Claude Opus 5.5, Sonnet 5, Haiku 4.5 и Fable 5.1, а также GPT-6 моделей. Оплата по мере использования, без подписки.

Получить ключ API →
AI Prime Tech — независимый сторонний API-шлюз. Claude™ и Anthropic® — товарные знаки Anthropic, PBC. Связь с этой компанией или одобрение с её стороны не подразумеваются.