Продолжение серии. Первая часть: Как я перестал бояться Claude Code и научил его не ломать мои проекты
В прошлой статье я разобрал почему Claude Code ломает проекты (context drift, отсутствие CLAUDE.md, нет хуков на тесты) и как выстроить защиту от регрессий. Статья попала в топ-5 Хабра за сутки — видимо, проблема задела нерв.
Но в комментариях и в личных сообщениях всплыл вопрос, который я тогда обошёл стороной: а что с самими токенами? Контекстное окно стало миллион, но агент всё равно жрёт его как не в себя. Куда уходят токены? Почему одна и та же сессия с одним и тем же проектом каждый раз начинается с нуля?
Я работаю с 20+ проектами на нескольких VPS-серверах. После того как я замерил, куда реально уходит контекст — картина оказалась неприятной.
Анатомия слепого поиска
Задал Claude Code простой вопрос: «Какие способы оплаты поддерживает мой ХХХ-бот?»
Вот что произошло:
-
Грепнул домашнюю директорию на слово «payment» — 3 tool call’а
-
Нашёл 6 файлов-кандидатов в разных проектах, прочитал все — 6 вызовов
-
Понял что попал не в тот проект, начал искать заново — 4 вызова
-
Подключился по SSH к серверу чтобы проверить конфиг — 2 вызова
-
Ответил — 15+ вызовов инструментов, 80K+ токенов, 8 минут
Ответ занял ~800 токенов. Всё остальное — навигация. Агент потратил 99% бюджета на то, чтобы понять где искать, и 1% — на сам ответ.
Это не баг Claude Code. Это фундаментальная проблема архитектуры всех AI-агентов для кодинга. Cursor делает то же самое. Codex делает то же самое. Gemini CLI делает то же самое. У них нет карты вашего рабочего пространства, поэтому каждая сессия начинается с разведки.
С одним проектом это терпимо. С пятнадцатью — это часы контекста в день, потраченные на ориентирование.
Почему существующие решения не работают
RAG и векторный поиск
Первая мысль: «нужен RAG, закинем всё в embeddings». На рынке десятки инструментов — Cody, Sourcegraph, различные MCP-серверы для векторного поиска.
Проблема: векторный поиск ловит семантическое сходство, но не структуру. Спросите «как работает аутентификация?» — и получите 15 чанков, упоминающих «auth», «login», «token». Что он пропустит: middleware.ts вызывает refresh.ts, который зависит от jwt-config.ts. Цепочка вызовов — реальная архитектура — невидима для embeddings, потому что они ловят похожесть, а не связи.
Кроме того, RAG добавляет инфраструктуру: нужен embedding-сервер, индекс, ре-ранкинг. Сотни миллисекунд задержки на каждый запрос. Для инструмента, который должен работать со скоростью мышления агента — это слишком медленно.
Tree-sitter и статический анализ
Второй подход — парсить AST и строить граф зависимостей. Инструменты типа Hypergrep делают именно это: функции, вызовы, импорты — всё в графе.
Это хорошо работает для навигации внутри одного проекта. Но у меня пятнадцать проектов. Tree-sitter не ответит на вопрос «какие из моих проектов используют Redis?» или «где задеплоен VPN-бот?». Это разные уровни абстракции.
CLAUDE.md на каждый проект
В прошлой статье я писал про CLAUDE.md — файл с архитектурой, командами, правилами. Он решает проблему внутри проекта. Но когда агент не знает в каком проекте искать — он бессилен. Агент сначала должен найти проект, потом — прочитать его CLAUDE.md.
Решение: иерархический контекст
Все три подхода выше решают часть проблемы, но на разных уровнях. Мне нужна была система, которая покрывает все уровни сверху вниз:
Level 0: Карта проектов — знает ВСЕ проекты и серверы (~2KB, всегда в контексте)Level 1: Детали проекта — архитектура конкретного проекта (~5KB, по запросу) Level 1.5: Граф кода — структура кодовой базы (опционально, Graphify)Level 2: Исходный код — реальные файлы (только когда нужен)
Ключевой принцип: агент идёт сверху вниз, а не снизу вверх. Сначала карта → потом проект → потом код. Не grep → read all → hope for the best.
Level 0: Глобальная карта
Добавляется в глобальный файл инструкций агента (~/.claude/CLAUDE.md для Claude Code, .cursorrules для Cursor):
## Project Map| Проект | Путь | Сервер | Статус ||--------|------|--------|--------|| VPN Bot | ~/projects/vpn-bot/ | prod-1:/opt/vpn/ | LIVE || Auth Service | ~/projects/auth/ | prod-1 (Docker) | LIVE || Landing | ~/projects/landing/ | Cloudflare Pages | LIVE || DiaBot | ~/projects/diabot/ | prod-2:/opt/diabot/ | BETA || Admin Panel | ~/projects/admin/ | staging | DEV |### Серверы| Имя | IP | Назначение ||-----|-----|-----------|| prod-1 | 178.17.50.45 | Основной VPS, 3 сервиса || prod-2 | 95.85.234.200 | DiaBot + мониторинг |### ПравилоПрежде чем читать исходный код — прочитай CLAUDE.md проекта.
Это ~2KB. Загружается автоматически в каждой сессии. Агент мгновенно знает: какие проекты существуют, где они лежат, на каких серверах запущены.
Level 1: CLAUDE.md проекта
В корне каждого проекта — файл с архитектурой, стеком, ключевыми файлами, командами деплоя:
# VPN Bot — CLAUDE.md## Status: LIVE (prod-1)Telegram-бот VPN-сервиса. Подписки через Stars и CryptoBot.## StackPython 3.11, python-telegram-bot, WireGuard, aiosqlite## Key Files- bot/main.py — точка входа- bot/payments.py — Stars + CryptoBot обработка- bot/vpn_manager.py — управление WireGuard конфигами- scripts/sync_users.py — синхронизация пользователей## Deploy- Сервис: vpn-bot.service- Логи: journalctl -u vpn-bot -f- Конфиг WireGuard: /etc/wireguard/wg0.conf
~3-5KB. Агент читает его когда вы упоминаете проект — и сразу знает всю архитектуру.
Level 1.5 (опционально): Graphify
Для навигации внутри кода — Graphify превращает кодовую базу в граф знаний. Вместо grep’а агент обращается к графу и знает какой именно файл нужен:
pip install graphifyycd ~/projects/authgraphify claude install
Это отдельный уровень между «архитектура проекта» и «читать исходники». Не обязателен, но для больших проектов экономит ещё 30-50% вызовов.
Результаты: замеры
Одни и те же вопросы, одна модель (Haiku — самая дешёвая), одна машина. С иерархией и без.
Тест 1: «Какая архитектура у Проекта A?»
|
|
Слепой агент |
С иерархией |
|---|---|---|
|
Tool calls |
12 |
1 |
|
Поведение |
Grep → читает 4 файла → собирает ответ |
Читает CLAUDE.md → отвечает |
|
Точность |
Корректно |
Корректно |
Тест 2: «Какие из моих проектов используют библиотеку X?»
|
|
Слепой агент |
С иерархией |
|---|---|---|
|
Tool calls |
44 |
2 |
|
Поведение |
Сканирует весь диск |
Целевой grep в известных путях |
|
Точность |
Пропустил 1 из 3 проектов |
Нашёл все 3 |
Тест 3: «Где задеплоен Проект B? Имя сервиса? Логи?»
|
|
Слепой агент |
С иерархией |
|---|---|---|
|
Tool calls |
9 |
0 |
|
Поведение |
Читает конфиги + SSH на сервер |
Ответил из контекста |
|
SSH нужен |
Да |
Нет |
Второй тест — самый показательный. Слепой агент не просто потратил в 22 раза больше вызовов — он дал неправильный ответ, пропустив один проект. Больше контекста → более точные ответы, а не только дешевле.
Почему три файла работают лучше чем RAG
На первый взгляд это выглядит примитивно. Три markdown-файла против полноценного embedding-пайплайна с векторной базой? Но именно в простоте — сила:
Нулевая задержка. CLAUDE.md читается мгновенно — это файл на диске. RAG добавляет 200-500мс на каждый запрос к индексу.
Детерминированность. Вы знаете что агент прочитает. С RAG вы надеетесь что ре-ранкер выбрал правильные чанки. С иерархией — вы сами написали что важно.
Обновление в реальном времени. Поменяли деплой-конфиг? Обновили одну строку в CLAUDE.md. С RAG нужно переиндексировать.
Работает с любым агентом. Claude Code, Cursor, Codex, Gemini CLI — все умеют читать markdown. Не все поддерживают ваш конкретный RAG-сервер.
Масштабирование — файл на проект. 15 проектов = 15 CLAUDE.md по 5KB = 75KB суммарно. Карта проектов — 2KB. Итого 77KB структурированного контекста вместо 500KB-1MB сырых файлов.
Это не значит что RAG бесполезен. Для семантического поиска по документации, для работы с большими кодовыми базами, для ответов на вопросы типа «найди все места где мы обрабатываем ошибки оплаты» — RAG отлично работает. Но для навигации между проектами и быстрого ответа на вопрос «где что лежит» — markdown-иерархия быстрее, дешевле и надёжнее.
Бонус: индексация разговоров
Отдельная проблема: прошлые разговоры с AI содержат архитектурные решения, результаты дебага, заметки о деплое. Но агент не может их искать — каждая сессия начинается с чистого листа.
Я написал парсеры, которые конвертируют логи сессий Claude Code (.jsonl) и экспортированные чаты Claude Desktop в markdown с YAML frontmatter:
---title: "Починил webhook оплаты"date: 2026-04-14project: vpn-bottopics: ["webhook", "cryptocloud", "cloudflare"]files_touched: ["payments.py", "webhook.py"]---
Проиндексировав их через Graphify, агент может найти «что мы решили про платёжный флоу на прошлой неделе» без повторных объяснений. По сути — персистентная память между сессиями, построенная на обычных файлах.
Миллион токенов — не решение
С выходом Opus 4.6 контекстное окно выросло до миллиона токенов. Может показаться что проблема навигации исчезла: просто загрузи всё, модель разберётся.
Но исследования показывают обратное. LLM хуже работают когда окружены нерелевантной информацией — это подтверждено множеством работ. Больше контекста — не просто дороже. Это может сделать модель хуже. Явление известно как «lost in the middle»: модель лучше вспоминает информацию из начала и конца контекста, а середину теряет.
Иерархический контекст решает это элегантно: агент получает только нужные файлы, в правильном порядке, на правильном уровне детализации. Не 500KB сырого кода — а 5KB архитектуры, и только потом конкретный файл если нужен.
С чего начать (10 минут)
-
Напишите карту проектов в
~/.claude/CLAUDE.md(5 минут) — перечислите проекты, пути, серверы -
Добавьте CLAUDE.md в ваш основной проект (5 минут) — стек, ключевые файлы, деплой
-
Задайте агенту вопрос о проекте в новой сессии
-
Посмотрите как он отвечает без grep’а
Никаких зависимостей, установок, конфигураций. Три markdown-файла, которые превращают слепого агента в того, кто знает куда смотреть.
Полезные ссылки
-
Graphify — навигация по коду через граф знаний
-
Документация Claude Code: Memory — как работают CLAUDE.md и auto-memory
-
Документация Claude Code: Best Practices — рекомендации Anthropic
-
Context Engineering (Morph) — обзор подходов к управлению контекстом
-
Hypergrep — tree-sitter + граф вызовов для навигации по коду
ссылка на оригинал статьи https://habr.com/ru/articles/1024878/