Claude Code: контекст, память и субагенты (Часть 4 из 5)

Как Claude Code управляет контекстным окном, хранит память через CLAUDE.md и делегирует задачи субагентам. Часть 4 серии об архитектуре Claude Code.

Dmitrij Tamarov Dmitrij Tamarov 1 января 1970 г. · 16 мин
claude-code ai-agents architecture anthropic research

Часть 4 из 5 · Серия «Архитектура Claude Code» → /claude-code-series

7. Построение контекста и память

Как агент управляет контекстным окном и сохраняет пользовательские инструкции — центральное решение проектирования, и разные системы выбирают между файловой прозрачностью, retrieval на основе БД и непрозрачными выученными представлениями. Проектные решения здесь реализуют два принципа из Table 1: context as scarce resource with progressive management и transparent file-based configuration and memory.

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

Перед вызовом модели агентный цикл собирает контекстное окно из пула инструментов (Section 6), CLAUDE.md, авто-памяти и истории диалога. Следующие подразделы покрывают порядок сборки, иерархию CLAUDE.md и многошаговый конвейер compaction.

7.1. Сборка контекстного окна

Контекстное окно (Figure 6) собирается из следующих источников — часть на начальной сборке, часть инжектируется поздно в ходе хода:

  1. System prompt, включая модификации output style и содержимое флага --append-system-prompt.
  2. Environment info через getSystemContext() (context.ts): git-статус (пропускается в remote-режиме или при отключённых git-инструкциях) и опциональная cache-breaking-инжекция для внутренних сборок (gated by BREAK_CACHE_COMMAND). Мемоизирована раз за сессию.
  3. CLAUDE.md hierarchy через getUserContext() (context.ts): четырёхуровневая иерархия файлов инструкций (Section 7.2). Тоже мемоизирована.
  4. Path-scoped rules: условные и directory-matched правила, загружаемые лениво, когда агент читает файлы в соответствующих директориях.
  5. Auto memory: контекстно-релевантные записи памяти, предзагружаемые асинхронно.
  6. Tool metadata: описания навыков, имена MCP-инструментов и отложенные определения инструментов (через ToolSearch, по требованию).
  7. Conversation history: переносится вперёд, субъект compaction.
  8. Tool results: чтения файлов, выводы команд, сводки субагентов.
  9. Compact summaries: заменяют более старые сегменты истории.
Figure 6
Figure 6 Context construction and memory hierarchy. Sources converging on the context window include system prompt, output styles, environment info, the CLAUDE.md hierarchy (managed through directory-specific), auto memory, path-scoped rules, MCP tool names, deferred tool definitions via ToolSearch, conversation history, file reads, command outputs, tool results, subagent summaries, and compact summaries.
Рисунок 6. Построение контекста и иерархия памяти. На контекстное окно сходятся: system prompt, output styles, environment info, иерархия CLAUDE.md (управляемая от managed до directory-specific), auto memory, path-scoped rules, имена MCP-инструментов, отложенные определения инструментов через ToolSearch, история диалога, чтения файлов, выводы команд, результаты инструментов, сводки субагентов и compact summaries.
text
 ACCESS                 Context Window
 ┌────────┐             ┌──────────────────────────────────────────────────────┐
 │Read-   │             │ (1) System Layer [startup]                           │
 │only    │             │   System Prompt │ Environment Info │ Output Styles   │
 │        │             │   Skill Description │ MCP Tool Names                 │
 └────────┘             ├──────────────────────────────────────────────────────┤
 ┌────────┐             │ (2) Project Config [startup / lazy]                  │                  
 │Hot-    │             │   CLAUDE.md Hierarchy [5 levels] │                   │       ┌─────────┐
 │reload  │             │   Path-scoped Rules (.claude/rules/*)                │─Reads▶│ Claude  │
 │        │             │   Managed → OS → Project → .claude/ → local → dir    │ all   │ Model 🌟│
 └────────┘             ├──────────────────────────────────────────────────────┤       └─────────┘
 ┌────────┐             │ (3) Memory [startup]                                 │        │ 
 │Sys-    │             │   Auto Memory │ Compact Summary (replaces history)   │  Generate
 │write   │             ├──────────────────────────────────────────────────────┤        ▼ 
 │        │             │ (4) Conversation [carry forward]                     │    ┌──────────┐
 └────────┘             │   Conversation History │ Subagent Summaries          │    │ Text     │
 ┌────────┐             ├──────────────────────────────────────────────────────┤◀──│Response  │ 
 │Append  │             │ (5) Runtime [carry forward]                          │    └──────────┘
 │        │             │   Read Files │ Command Outputs │ Tool Results        │    ┌──────────┐
 └────────┘             ├──────────────────────────────────────────────────────┤◀──│Tool Calls│ 
 ┌────────┐             │ (6) On-Demand [lazy]                                 │    └──────────┘
 │Model-  │             │   Deferred Tool Definitions (full schemas on demand) │    ┌──────────┐
 │trigger │             └──────────────────────────────────────────────────────┘◀──│Tool      │ 
 │        │             Loaded Time: (1)(2)(3) at start up → (4) accumulate per     │ Search   │
 └────────┘             turn → (5) added during execution → (6) on demand via       └──────────┘
 ┌────────┐             Tool Search
 │Lazy-   │
 │load    │
 └────────┘
 ACCESS
 Mutability increases

Сборка system prompt в query.ts объединяет system-context с базовым prompt через asSystemPrompt(appendSystemContext(systemPrompt, systemContext))(). User context (CLAUDE.md и дата) добавляется в начало массива сообщений через prependUserContext(). Это разделение означает, что контент CLAUDE.md занимает иную структурную позицию в API-запросе, чем system prompt, — потенциально влияя на паттерны внимания модели.

Несколько контекстных источников инжектируются поздно, уже после построения главного окна: prefetch релевантной памяти (query.ts), дельты MCP-инструкций (только новые или изменённые серверные инструкции), дельты agent listing и уведомления о фоновых задачах. То есть контекстное окно не статично на момент сборки — оно может расти в ходе хода.

7.2. Иерархия CLAUDE.md и авто-память

Систему памяти формирует принцип проектирования: сохранённый контекст должен быть проверяем и редактируем пользователем. Файлы CLAUDE.md — plain-text Markdown, а не структурированная конфигурация или непрозрачные записи БД. Этот выбор в пользу прозрачности меняет выразительность на проверяемость: пользователь может читать, редактировать, версионировать и удалять любую инструкцию, которую видит агент (MindStudio Team, 2026). Альтернативные архитектуры памяти показывают компромисс. Retrieval-augmented-подходы используют embedding-lookup, чтобы поднимать релевантный прежний контекст, — выигрыш в гибкости ценой проверяемости: пользователь не может легко увидеть или отредактировать, что retrieval-система считает релевантным. Database-backed-память даёт структурированные запросы, но требует дополнительной инфраструктуры и непрозрачна для контроля версий. Файловый подход Claude Code делает каждую инструкцию, которую видит агент, прямо читаемой, редактируемой и коммитабельной рядом с кодовой базой. Система не использует embeddings или vector-similarity-индекс для retrieval памяти; вместо этого LLM-скан заголовков memory-файлов отбирает до пяти релевантных файлов при сборке, поднимая их с file-granularity, а не с entry-granularity. Embedding-системы могут точнее извлечь отдельные записи — ценой проверяемости и инфраструктуры под индекс.

Файлы CLAUDE.md подчиняются многоуровневой иерархии загрузки. Заголовок исходника (claudemd.ts) определяет четыре типа памяти:

  1. Managed memory (например, /etc/claude-code/CLAUDE.md на Linux): OS-level-политика для всех пользователей.
  2. User memory (~/.claude/CLAUDE.md): частные глобальные инструкции.
  3. Project memory (CLAUDE.md, .claude/CLAUDE.md и .claude/rules/*.md в корнях проектов): инструкции, закоммиченные в кодовую базу.
  4. Local memory (CLAUDE.local.md в корнях проектов): gitignored, для частных project-специфичных инструкций.

Обнаружение файлов идёт от текущей директории вверх до корня, проверяя project- и local-memory-файлы в каждой директории. Файлы ближе к текущей директории имеют более высокий приоритет (загружаются позже).

Файлы загружаются в «обратном порядке приоритета»: позже загруженные получают больше внимания модели. Для директорий от корня до CWD безусловные правила из .claude/rules/*.md загружаются активно при старте. Для вложенных директорий ниже CWD даже безусловные правила загружаются лениво, когда агент читает файлы в соответствующих директориях. Значит, набор инструкций модели может эволюционировать в ходе диалога по мере исследования новых частей кодовой базы.

Контент CLAUDE.md доставляется как user context (user-сообщение), а не как system-prompt-контент (context.ts). У этого архитектурного выбора важное следствие: поскольку контент CLAUDE.md доставляется как диалоговый контекст, а не как system-level-инструкции, compliance модели с этими инструкциями вероятностный, а не гарантированный. Правила разрешений, оцениваемые в deny-first-порядке (Section 5), обеспечивают детерминистский слой энфорсмента. Это создаёт намеренное разделение между руководством (CLAUDE.md, вероятностным) и энфорсментом (правилами разрешений, детерминистским). Функция вызывает setCachedClaudeMdContent(), чтобы закэшировать загруженный контент для классификатора авто-режима и избежать import-цикла между загрузчиком CLAUDE.md и системой разрешений.

Memory-файлы поддерживают директиву @include для модульных наборов инструкций (processMemoryFile() в claudemd.ts). Синтаксические варианты: @path, @./relative, @~/home, @/absolute. Директива работает только в листовых текстовых узлах (не внутри кодовых блоков). В реализации включаемый файл добавляется первым, потом к нему прикладываются включённые файлы; циклические ссылки предотвращаются через трекинг обработанных путей; несуществующие файлы тихо игнорируются.

7.3. Конвейер compaction

Пятислойный конвейер compaction (Section 4.3) реализует принцип «context as bottleneck» через градуированное сжатие (query.ts). Вместо единой стратегии Claude Code применяет пять слоёв последовательно, каждый со всё большей агрессивностью (три управляются feature flags: budget reduction активен всегда, auto-compact настраивается пользователем). Градуированный подход контрастирует с более простыми альтернативами: многие agent-фреймворки используют single-pass truncation (сброс самых старых сообщений) или один шаг суммаризации. Градуированный дизайн отражает принцип ленивой деградации: сначала применять наименее разрушительное сжатие, эскалируя только когда более дешёвых стратегий не хватает. Цена — сложность. Пять взаимодействующих слоёв сжатия, несколько из которых управляются feature flags, создают поведение, которое сложно полностью предсказать. Auto-compact выдаёт в транскрипт видимую сводку, microcompact выставляет boundary-маркер, а context collapse работает без видимого пользователю вывода. Более простые single-pass-подходы жертвуют информацией, но их легче осмыслить.

  1. Budget reduction (всегда активен): per-tool-result лимиты размера.
  2. Snip (HISTORY_SNIP): лёгкая обрезка старой истории.
  3. Microcompact (CACHED_MICROCOMPACT): тонкое cache-aware-сжатие.
  4. Context collapse (CONTEXT_COLLAPSE): read-time виртуальная проекция на историю.
  5. Auto-compact (включён по умолчанию, можно отключить): полная модель-генерируемая сводка.

Функция buildPostCompactMessages() (compact.ts) возвращает следующую уплотнённую выходную структуру: [boundaryMarker, ...summaryMessages, ...messagesToKeep, ...attachments, ...hookResults]. Boundary-маркер аннотируется preserved-segment-метаданными через annotateBoundaryWithPreservedSegment(), записывая headUuid, anchorUuid и tailUuid, чтобы включить read-time chain-patching. Этот преимущественно append-дизайн означает, что compaction никогда не модифицирует и не удаляет ранее записанные строки транскрипта; он только добавляет новые boundary- и summary-события.

Функция compactConversation() (compact.ts) включает несколько проектных решений. Pre-compact-хуки срабатывают первыми, позволяя hook-injected кастомные инструкции. GrowthBook feature flag контролирует, переиспользует ли compaction-путь prompt-кэш главного диалога (код комментирует эксперимент от января 2026: «fast path — 98% cache miss, стоит ~0.76% парка cache_creation»). После compaction, attachment-builders повторно объявляют runtime-состояние (планы, навыки, async-агенты) из live app state, так как compaction отбрасывает ранее прикреплённые сообщения, но не нижележащее состояние.

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

8. Делегирование субагентам и оркестрация

Мультиагентная оркестрация — ключевое измерение проектирования для агентов программирования, с выбором от parent-child-иерархий, peer-based-conversation-фреймворков (Wu et al., 2024) до graph-structured workflow engines (LangChain, Inc., 2024). Архитектура делегирования Claude Code реализует принцип isolated subagent boundaries из Table 1 вместе с аспектами deny-first with human escalation (permission override) и reversibility-weighted risk assessment (ограничения на инструменты субагентов).

Когда Claude определяет, что починка auth-теста требует сперва исследовать структуру authentication-модуля, он может делегировать это субагенту. Механизм делегирования — Agent-инструмент (AgentTool.tsx), с Task как legacy-алиасом. Модель вызывает Agent со структурированным входом: prompt делегирования, опциональный subagent-type и конфигурация режима изоляции, override-ов разрешений и рабочей директории.

8.1. Agent-инструмент и критерии делегирования

Схема входа Agent-инструмента (Figure 7) использует feature-gated поля, опуская необязательные параметры при отключении backing-функций. Поле isolation предлагает ['worktree', 'remote'] для внутренних пользователей и ['worktree'] для внешних, определяется при сборке. Поле cwd gated feature flag-ом. Поле run_in_background опускается, когда фоновые задачи отключены или включён режим fork-subagent.

Figure 7
Figure 7 Subagent isolation and delegation architecture. The Agent tool dispatches to built-in subagents (Explore, Plan, general-purpose) or custom subagents, each running in an isolated context with rebuilt permission context and independent tool sets. The Agent tool dispatches along three axes: routing (teammate), isolation (remote, worktree), and lifecycle (async, sync).
Рисунок 7. Архитектура изоляции и делегирования субагентов. Agent-инструмент отправляет запрос встроенным субагентам (Explore, Plan, general-purpose) или кастомным, каждый работает в изолированном контексте с пересобранным контекстом разрешений и независимыми наборами инструментов. Agent-инструмент отправляет по трём осям: маршрутизация (teammate), изоляция (remote, worktree) и жизненный цикл (async, sync).
text
                                      Other Built-in Tools
                                      statusline, verification
                                             +
                                    ┌────────────┐
                                    │ Explore 🔍 │
                                    │ Plan    📝 │     Isolation Sandbox
 ┌──────────┐                       │ General 🛠 │     (Context isolated for each subagent)  
 │   Main   │◀──Delegates──┐        │ Custom  ✦ │     ┌────────────────────────────────────┐ 
 │Conversa- │              │        └────────────┘     │1) Rebuilt Permission  2) Permission│
 │  tion 💬 │              ▼                           │   Context & Tool Set      Mode     │
 └──────────┘      ┌───────────┐                       │                        Override    │
      │           │  Agent    │─────────────────────▶  │ ✓ ⚙                     🔓         │
      │Read &     │ (Task/    │                       │                                    │ 
      │Write      │  legacy   │                       │ 3) Isolated Worktree   ●            │
      ▼           │  alias)   │                       │                                    │ 
 ┌──────────┐     └───────────┘                       │    Isolated Subagent Context       │ 
 │   Main   │          │                              │    ┌─────────────────────────┐     │ 
 │Transcript│◀─Insert Result                          │    │ Subagent Transcript     │     │ 
 │    📖    │                                          │    │ .jsonl + meta.json      │     │
 └──────────┘                                          │    └─────────────────────────┘     │
                                                       │    ┌─────────────────────────┐     │
                                                       │    │ Subagent Report         │     │
                                                       │    │ text + metadata         │     │
                                                       │    └─────────────────────────┘     │
                                                       └────────────────────────────────────┘

Claude Code предоставляет до шести встроенных типов субагентов, в зависимости от feature flags и точки входа:

  • Explore: прежде всего read/search-ориентированное исследование, с write- и edit-инструментами в deny-list.
  • Plan: создаёт структурированные планы; исполнение идёт через стандартную permission-model.
  • General-purpose: широко способный, используется по явному запросу (замечание: пропуск типа может направить на fork-subagent-путь).
  • Claude Code Guide: онбординг и помощь с документацией, со своим override-ом permissionMode.
  • Verification: запускает проверки валидации (тесты, linting).
  • Statusline-setup: специализирован на конфигурации строки статуса терминала.

Помимо встроенных, пользователи определяют кастомных субагентов через файлы .claude/agents/*.md, а плагины вкладывают определения агентов через loadPluginAgents.ts. Тело markdown каждого файла служит system prompt агента, а YAML frontmatter задаёт поля конфигурации: description, tools (allowlist), disallowedTools, model, effort, permissionMode, mcpServers, hooks, maxTurns, skills, memory scope, background flag и isolation mode. JSON-formatted agent definitions поддерживают те же поля плюс prompt как явное поле (loadAgentsDir.ts). Это значит, что кастомный агент может быть полностью настроенной изолированной подсистемой со своими инструментами, разрешениями, memory scope и режимом изоляции. AgentTool сидит рядом с SkillTool в базовом пуле инструментов как мета-инструмент, отправляющий к этим определениям, но эти два различаются принципиально: SkillTool инжектирует инструкции в текущее контекстное окно, а AgentTool создаёт новое изолированное. Компромисс: большинство subagent-вызовов требуют self-contained prompt, потому что default-путь не наследует историю диалога родителя (fork-subagent-путь — исключение). Conversation-based-фреймворки, разделяющие полные истории транскриптов, избегают этой стоимости, но рискуют взрывом контекста с ростом числа агентов.

8.2. Архитектура изоляции

Изоляция субагента поддерживает несколько режимов (AgentTool.tsx):

  • Worktree: создаёт временный git worktree, давая субагенту собственную копию репозитория для изменений без влияния на рабочее дерево родителя.
  • Remote (internal-only): запускается в remote Claude Code Remote-среде, всегда в фоне.
  • In-process (default): разделяет файловую систему с родителем, но работает в изолированном диалоговом контексте.

Логика override-а разрешений для субагентов (runAgent.ts) включает несколько специфичных правил. Когда субагент определяет permissionMode, override применяется, если родитель уже не в bypassPermissions, acceptEdits или auto-режиме, — потому что эти режимы всегда имеют приоритет, так как представляют явные пользовательские решения о компромиссе безопасность/автономия. Для async-агентов система определяет, избегать ли prompt-ов через каскад: canShowPermissionPrompts сперва, затем режим bubble (всегда показывать, так как он эскалирует к родительскому терминалу), потом default (sync-агенты показывают prompt-ы, async — нет). Background-агенты, которые могут показывать prompt-ы, устанавливают awaitAutomatedChecksBeforeDialog: true, обеспечивая завершение работы классификатора и хуков до прерывания пользователя.

Эти режимы изоляции занимают разные точки в пространстве проектирования. Container-based-изоляция (SWE-Agent и OpenHands (Yang et al., 2024; Wang et al., 2024b)) даёт более сильные resource boundaries, но требует container-инфраструктуры. Context-only-изоляция (conversation-based-фреймворки вроде AutoGen (Wu et al., 2024)) разделяет файловую систему, но изолирует истории диалога. Worktree-based-изоляция Claude Code даёт filesystem-level-отделение с нулевыми внешними зависимостями, используя встроенный механизм Git вместо введения контейнерной оркестрации.

Когда allowedTools явно передан в runAgent() (runAgent.ts), применяется two-tier-модель scoping разрешений. SDK-level-разрешения из --allowedTools сохраняются: «явные разрешения от SDK-consumer должны применяться ко всем агентам». Но session-level-правила заменяются объявленным allowedTools субагента. Когда allowedTools не передан (обычный путь AgentTool), session-level-правила родителя наследуются без замены.

8.3. Sidechain-транскрипты

Каждый субагент пишет свой транскрипт в отдельный .jsonl-файл с metadata-файлом .meta.json (sessionStorage.ts, runAgent.ts). Этот sidechain-дизайн означает, что истории субагентов сохраняются для отладки и аудита, но не раздувают файл сессии родителя. Только финальный текст ответа и метаданные субагента возвращаются в родительский диалоговый контекст; полная история субагента никогда не входит в контекстное окно родителя, уважая принцип «context as bottleneck».

Функция runAgent() принимает 21 параметр, покрывающих определение агента, prompt-ы, разрешения, инструменты, настройки модели, изоляцию и callback-и.

Summary-only-return-модель — намеренный выбор ради сохранения контекста: conversation-based-фреймворки, разделяющие полные истории между агентами, рискуют взрывом контекста с ростом числа агентов. Даже изолированный параллелизм контекстов несёт существенную стоимость. Agent-команды Claude Code потребляют примерно 7× токенов стандартной сессии в plan-режиме (Anthropic, 2025b), что делает summary-only-return ещё критичнее, когда субагенты ещё и в изолированных контекстах.

Для координации мультиинстансов в agent-командах harness использует file locking, а не message broker или распределённый coordination-сервис (Anthropic, 2025b). Задачи забираются из общего списка через lock-file-based-mutual-exclusion, lock-файлы лежат на предсказуемых путях файловой системы. Это жертвует пропускной способностью ради двух свойств: zero-dependency-развёртывание (никакой внешней инфраструктуры не нужно) и полная отладочность (состояние любого агента можно инспектировать, читая plain-text JSON).

9. Устойчивость и восстановление сессий

Устойчивость сессий в агентах программирования — выбор проектирования между append-only-логами, структурированными БД, checkpoint-snapshots и stateless-архитектурой, каждый со своими компромиссами в auditability, query power и deployment-сложности. Дизайн устойчивости Claude Code реализует принцип append-only durable state из Table 1. Session-scoped-разрешения живут в памяти и не сериализуются в транскрипт, поэтому resume пересобирает permission-context из CLI-args и disk-settings; запросы, которые пересобранный контекст не распознаёт, скатываются обратно к deny-first-prompting.

К этому моменту в задаче auth-test сессия содержит исходный prompt, вызовы инструментов и результаты, compact-границы и сводку субагента от исследования authentication-модуля (Section 8). Этот раздел спрашивает, какие из этих артефактов долговременно записаны и что можно восстановить потом, не перенося старые гранты разрешений сессии.

Механизмы устойчивости Claude Code пишут диалог (сообщения, результаты инструментов, compact-границы) на диск по мере событий.

9.1. Модель транскрипта

Транскрипты сессии хранятся как преимущественно append-only JSONL-файлы на project-specific-пути (с явными cleanup-rewrites как исключением) (Figure 8). Функция getTranscriptPath() (sessionStorage.ts) вычисляет его как join(projectDir, ${getSessionId()}.jsonl), где projectDir определяется сперва проверкой getSessionProjectDir() (устанавливается switchSession() при resume/branch), с фоллбэком на getProjectDir(getOriginalCwd())().

Три канала устойчивости работают независимо:

  1. Session transcripts. Записи диалога, включая user, assistant, attachment и system-сообщения, плюс compaction- и другие metadata-события. Project-scoped, один файл на сессию.
  2. Global prompt history. Только пользовательские prompt-ы, хранятся в history.jsonl в Claude-конфигурационной home-директории (history.ts). Генератор makeHistoryReader() выдаёт записи в обратном порядке через readLinesReverse(), поддерживая навигацию Up-arrow и ctrl+r.
  3. Subagent sidechains. Отдельные .jsonl + .meta.json файлы на субагента (Section 8.3).

Session-транскрипты хранят несколько видов событий помимо простых сообщений: compaction-маркеры, file-history-снимки, attribution-снимки и content-replacement-записи. Формат append-only JSONL — намеренный выбор в пользу auditability и простоты вместо query power. Каждое событие human-readable, version-controllable и реконструируемо без специализированной оснастки. Database-backed-альтернативы дали бы более богатые запросы по истории сессии, но ввели бы зависимости развёртывания и снизили прозрачность.

Система идентичности сессии связывает sessionId с sessionProjectDir, устанавливаемым вместе во время resume или branch. Путь транскрипта должен использовать ту же project-директорию, что была активна при записи сообщений, чтобы хуки не смотрели в не ту директорию.

Figure 8
Figure 8 Session persistence and context compaction. The diagram separates live session state (context window, compaction) from durable storage (session transcripts, history.jsonl, subagent sidechains, checkpoints). Resume and fork restore messages but not session-scoped permissions.
Рисунок 8. Устойчивость сессий и compaction контекста. Диаграмма разделяет live-состояние сессии (контекстное окно, compaction) от durable-хранилища (session transcripts, history.jsonl, subagent sidechains, checkpoints). Resume и fork восстанавливают сообщения, но не session-scoped-разрешения.
text
 Session ID
 ┌──────────────┐       ┌────────────┐
 │ Conversation │──────▶│ Context    │
 │  👤 </>      │       │ Window  📄 │                          Compaction Flow
 └──────────────┘       └────────────┘      ┌─────────────────────────────────────────────┐
      │                 Near Capacity       │ Old Tool    Session     Compact             │
 Durable                                    │ Outputs  ⚙  Summary  ✏  Boundary 🚩         │
 Storage                                    │ 1) Remove   2) Generate 3) Mark             │
      ▼                                     └─────────────────────────────────────────────┘
 ┌──────────────┐                  ┌──────────────┐        👤
 │Session       │                  │ Checkpoints ✓│──────▶ Rewind ◀◀
 │Transcript    │                  └──────────────┘        Resume ▶
 │.jsonl        │                                          Fork   ● 
 │History/      │
 │Subagent Logs │
 └──────────────┘
ПринципОписание
Conversations Outlive ContextПолезная жизнь сессии не должна упираться в контекстное окно модели. Транскрипт на диске записывает всё, так что compaction может перерабатывать live-вид без завершения диалога.
Conversations Outgrow a Single PathСессию не нужно запирать на одну линейную траекторию. Append-only-транскрипт позволяет пользователям откатываться, возобновлять или форкать в новую ветку без потери прежней работы.

9.2. Resume, Fork и невосстановление разрешений

Флаг --resume пересобирает диалог проигрыванием транскрипта (conversationRecovery.ts). Fork создаёт новую сессию из существующей (commands/branch/branch.ts). Однако resume и fork не восстанавливают session-scoped-разрешения; пользователи должны выдать их заново в новой сессии. Это намеренный safety-conservative-выбор: сессии трактуются как изолированные trust-домены. Восстановление ранее выданных разрешений на resume дало бы удобство, но рискует перенести устаревшие trust-решения в изменённый контекст. Архитектура предпочитает повторное предоставление вместо неявной устойчивости, принимая пользовательское трение как цену сохранения safety-инварианта: доверие всегда устанавливается в текущей сессии.

Маркер compact_boundary аккуратно спроектирован для работы с устойчивостью. Функция annotateBoundaryWithPreservedSegment() (compact.ts) записывает headUuid, anchorUuid и tailUuid в событии boundary. Эти UUID позволяют загрузчику сессии во время чтения патчить цепочку сообщений: preserved-сообщения сохраняют исходные parentUuids на диске, а загрузчик использует boundary-metadata, чтобы связать их корректно. Этот преимущественно append-дизайн означает, что compaction никогда не модифицирует и не удаляет ранее записанные строки транскрипта.

«Checkpoints» в Claude Code — это file-history-checkpoints для --rewind-files, хранятся в ~/.claude/file-history/<sessionId>/. Это file-level-снимки для отката изменений файловой системы, а не generic-checkpoint-хранилище.

Предыдущие разделы документировали ответы Claude Code на повторяющиеся вопросы проектирования. Следующий раздел противопоставляет проектные решения Claude Code с решениями архитектурно независимой системы ИИ-агентов.

← Часть 3 — Расширяемость | Часть 5 — Анализ и будущее →

Dmitrij Tamarov
Dmitrij Tamarov

AI architect

Статьи по теме