graphify в Claude Code: граф знаний вместо чтения всего репо, семантика на дешевом OpenRouter
graphify в Claude Code: граф знаний вместо чтения всего репо
В гайде по экономии токенов я коротко упомянул graphify в общем стеке. Тут — отдельно и подробно про то, как у меня настроена автоматизация: что именно держу включенным глобально и почему это не жрет токены Claude.
Проблема простая. Чтобы понять чужой (или свой полугодовой давности) код, агент читает файлы пачками — и каждый файл оседает в контексте. Дорого по input и вдобавок тянет context rot: чем больше навалено, тем хуже модель думает. graphify разрывает эту связку: один раз строит из репо граф знаний (узлы, связи, сообщества, god-nodes), который ты запрашиваешь, вместо того чтобы вываливать файлы в окно.
Все собрано в один репозиторий — suenot/claude-code-token-savers (папка graphify/, идемпотентный setup.sh, патчи, хуки).
Главный трюк: семантика на чужих токенах
Сборка графа — это куча LLM-вызовов на извлечение сущностей и связей. Если гонять их через Claude, экономия превращается в трату. Поэтому семантическое извлечение уведено на дешевый OpenRouter, а не на бюджет Claude.
~/.graphify/providers.json:
{
"openrouter": {
"base_url": "https://openrouter.ai/api/v1",
"default_model": "deepseek/deepseek-v4-flash",
"env_key": "OPENROUTER_API_KEY",
"model_env_key": "GRAPHIFY_OPENROUTER_MODEL",
"pricing": { "input": 0.09, "output": 0.18 },
"temperature": 0,
"max_tokens": 16384,
"vision": false
}
}
deepseek/deepseek-v4-flash — $0.09 / $0.18 за 1M токенов, контекст 1M. Сборка графа среднего проекта стоит ~$0.10 на OpenRouter и ноль токенов сессии Claude. Модель меняется одной переменной: export GRAPHIFY_OPENROUTER_MODEL=qwen/qwen3.7-plus.
Важная деталь: graphify install перезаписывает ~/.claude/skills/graphify/SKILL.md. В нем зашит приоритет бэкендов извлечения, и если его не восстановить — graphify свалится на Claude-субагентов и сожжет твои токены. Правильный приоритет:
- OpenRouter (если есть
OPENROUTER_API_KEY) — текстовые чанки сюда. - Gemini (если есть
GEMINI_API_KEY/GOOGLE_API_KEY). - Claude-субагенты — только как последний запасной вариант.
Установка
Нужны uv и OPENROUTER_API_KEY в окружении.
cd graphify
./setup.sh # ставит graphify, OpenRouter-бэкенд, патчи, хуки, no-media
setup.sh идемпотентный (с откатом). Под капотом, если хочется руками:
uv tool install --with watchdog "graphifyy[openai]" # openai-extra = OpenRouter; watchdog = graphify watch
mkdir -p ~/.graphify
cp providers.json ~/.graphify/providers.json
cp build-and-watch.sh stop-watch.sh precommit-graph-guard.sh ~/.graphify/ && chmod +x ~/.graphify/*.sh
PY="$(sed -n '1s/^#!//p' "$(command -v graphify)")"
"$PY" patch-global-ignore.py # глобальный слой ignore
"$PY" patch-merge-ignore.py # мерж .gitignore + .graphifyignore (а не затмевание)
"$PY" patch-no-media.py # тумблер no-media
touch ~/.graphify/no-media # медиа выключено по умолчанию
graphify install --platform claude
Авто-watch: граф сам себя обновляет
Сердце автоматизации — SessionStart-хук build-and-watch.sh. На каждом старте сессии он смотрит на проект и выбирает ветку:
- граф есть → запускает
graphify watch(дешево, только AST, без LLM) + ставит pre-commit-guard → статус “watching”. - граф не инициализирован → печатает “run
/graphify .” и ничего не делает. Это защита: случайно открытая корневая или гигантская папка не уйдет молча в индексацию и не сожрет токены. - маркер
~/.graphify/autobuild→ дополнительно авто-собирает маленькие свежие проекты через OpenRouter (потолок 500 файлов / 2M слов; больше — пропуск и просьба собрать руками).
Предохранители: пропускает $HOME, корень ФС, системные/tmp-папки, предков $HOME и любой проект с .graphify-skip. Глобальный выключатель — ~/.graphify/disable-autowatch. Ровно один watcher на проект (атомарный mkdir-лок + проверка PID). На SessionEnd его гасит stop-watch.sh. watch обновляет только код/AST-слой; доки требуют /graphify . --update.
Карта хуков в ~/.claude/settings.json (мержить, не затирать существующие):
SessionStart -> ~/.graphify/build-and-watch.sh # статус + watch
SessionEnd -> ~/.graphify/stop-watch.sh # остановить watcher
Что не попадет в граф (и почему это важно)
Граф может уехать в коммит — значит, в него нельзя пускать секреты. Три независимых механизма:
- Секреты и
.env— режутся встроенным_is_sensitiveв graphify всегда, без конфига. - Медиа — чистый тумблер без возни с ignore-файлами:
patch-no-media.pyзаставляетdetect()пропускать картинки/pdf/видео/office, когда есть~/.graphify/no-media(илиGRAPHIFY_NO_MEDIA=1). Удалил маркер — медиа снова в игре. - Затмевание
.gitignore— починено. В апстриме.graphifyignoreв папке полностью затмевал ее же.gitignore: паттерн, который есть только в.gitignore(например, секрет), все равно индексировался.patch-merge-ignore.pyделает мерж вместо замены — это PR #1364 в апстрим.
Поверх — pre-commit-guard (precommit-graph-guard.sh), который ставится в графифицированные git-репо и блокирует коммит graphify-out/graph.json, если в граф попал .gitignore-файл. Defense-in-depth от утечки секретов в закоммиченный граф. Обход — git commit --no-verify.
Как пользоваться
Один раз собрать, дальше — запрашивать:
/graphify . # собрать граф текущей папки
/graphify https://github.com/o/r # склонировать репо и собрать
/graphify url1 url2 ... # несколько репо → один кросс-репо граф
/graphify . --mode deep # тщательнее, больше INFERRED-связей
/graphify . --update # инкрементально, только новое/измененное
/graphify query "где валидируется токен и что это вызывает"
/graphify query "..." --dfs # трассировать конкретный путь, не широкий контекст
/graphify query "..." --budget 1500 # ограничить ответ N токенов
На выходе — интерактивный HTML, GraphRAG-JSON и человекочитаемый GRAPH_REPORT.md; есть --mcp (stdio-сервер для агентов) и --wiki. Дальше вместо “прочитай весь модуль auth” агент дергает граф и получает ровно нужный срез.
После апгрейда graphify
uv tool upgrade graphifyy и graphify install стирают site-packages (теряются все 3 патча detect.py) и перезаписывают SKILL.md. Лечение — снова прогнать ./setup.sh (вернет патчи, файлы, no-media-маркер) и восстановить блок приоритета бэкендов в SKILL.md. Переживают апгрейд: ~/.graphify/*, хуки в ~/.claude/settings.json, per-repo .git/hooks/pre-commit.
Итог: graphify снимает с контекста самый жирный слой — “прочитай весь репозиторий”, — и делает это за чужие копеечные токены, сам обновляясь в фоне и не утаскивая секреты в граф. Связка с rtk (input команд) и caveman (output модели) разобрана в гайде по экономии токенов.