Рабочее место не-вайбкодера по методу Spec-Driven Development: запускаем Claude Code
- четверг, 30 апреля 2026 г. в 00:00:13
Привет, Хабр! Меня зовут Даниил Подольский, я программист и архитектор, разрабатываю программное обеспечение и спецификации для создания ПО в YADRO. Вот уже девять месяцев я использую методологию Spec-Driven Development (SDD) в работе и управляю AI-агентами, которые пишут код. При этом я не считаю себя вайбкодером, потому что мой подход к работе более комплексный, чем просто «общение с AI».
Это первая статья из цикла об оборудовании рабочего места SDD-кодера. Я расскажу о базовой настройке AI-агента Claude Code: что делать, если вы хотите оперативно и без перезагрузки переключать используемые модели и делать это для каждого проекта отдельно.
Spec-Driven Development (SDD) — это подход к разработке ПО, при котором весь процесс начинается с формальной спецификации (контракта) интерфейсов, форматов данных или архитектурных правил. Спецификация становится единственным «источником истины» для всех участников проекта. Подход SDD появился в 60-х годах прошлого века в недрах NASA, а в середине нулевых был стандартизован. В цикле статье мы поговорим о формате Spec-Driven Development, который обрел популярность в 2025 году, когда LLM стали активно внедряться в процессы разработки.
Недавно мой коллега написал , как организовать работу над спецификациями, если раньше такого опыта не было вообще. Ему удалось масштабировать процесс на крупный департамент, так что прочитайте, если еще не пишете спеки. Как видите, они могут пригодиться в Spec-Driven Development-методе.
Для успешного запуска нам потребуются:
Модель, или даже провайдер моделей.
Агент, а именно — Claude Code.
Claude Code Router для переключения моделей и конвертации протоколов. Ниже я объясню подробнее, в чем польза этого инструмента.
Средства управления Claude Code Router, которые мы напишем сами.
VSCode в качестве оболочки для агента и интегрированного рабочего места (да, так расшифровывается аббревиатура IDE) с плагином для Claude Code.
Для наших целей еще понадобится подключение к LLM. Инструкций, как это сделать, не будет, но будет совет: посмотрите на OpenCode Go.
Все описанные далее шаги предполагают, что вы оформили подписку на OpenCode Go и у вас в распоряжении доступ к нескольким разным моделям. Впрочем, мономодельных провайдеров почти не осталось.
На самом деле можно выбрать и другой агент. Помимо Claude Code, я пробовал RooCode, OpenCode, KiloCode. Разница между ними не очень велика, но мне проще всего оказалось работать с Claude, пока я не сделал своего агента.
В этом разделе будет первая инструкция: ставим Claude Code без соответствующей подписки. Важно: я работаю на MacOS, и моя инструкция для нее. Инструкция должна подойти и для Linux, а для Windows ее легко адаптировать.
Итак, ставим Claude Code.
Установка описана на странице Quick start. Я решил воспользоваться brew-вариантом: brew install claude-code@latest
После установки запускаем Claude и понимаем, что работает он не очень: свежеустановленный Claude Code требует подписку.

Давайте полечим его от «жадности». Создадим два файла:
mkdir -vp ~/.claude cat <<EOF > ~/.claude/settings.json { "env": { "ANTHROPIC_DEFAULT_HAIKU_MODEL": "minimax-m2.7", "ANTHROPIC_DEFAULT_SONNET_MODEL": "minimax-m2.7", "ANTHROPIC_DEFAULT_OPUS_MODEL": "minimax-m2.7", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1", "ANTHROPIC_API_KEY": "sk-nhD9IFHpqhJBd84xbjF0pNMnE7YvNj2pA0qu2lup6X3MqSP4u4rexC12mf7VA9hL", "ANTHROPIC_BASE_URL": "https://opencode.ai/zen/go", "DISABLE_TELEMETRY": "true", "DISABLE_COST_WARNINGS": "true", "CLAUDE_CODE_USE_BEDROCK": "", "API_TIMEOUT_MS": "3000000" }, "model": "minimax-m2.7" } EOF cat <<EOF > ~/.claude.json { "hasCompletedOnboarding": true } EOF
Обратите внимание на параметр ANTHROPIC_API_KEY в файле ~/.claude/settings.json — туда надо вписать ваш ключ. Тот, что указан в статье, работать не будет — я его уже удалил.
Немного о ключах доступа
Их в конфиге может быть два:
Если использовать ANTHROPIC_AUTH_TOKEN, Claude Code отправляет с каждым запросом к модели заголовок Authorization: Bearer. Все бы хорошо, но это OpenAI-совместимый способ аутентификации, и не все провайдеры его поддерживают. OpenCode Go, например, поддерживает его для OpenAI-совместимых точек доступа и не поддерживает для Anthropic-совместимых. Да, все модели доступны на OpenCode Go по двум путям и протоколам. А для Claude Code нам нужна именно Anthropic-совместимая.
Если использовать ANTHROPIC_API_KEY, Claude Code отправляет с каждым запросом к модели заголовок X-Api-Key. Это стандарт для Anthropic-совместимых точек доступа, и при указании именно его Claude Code прекрасно работает с OpenCode Go. Все бы хорошо, но некоторые провайдеры, например Z.AI, не поддерживают этот заголовок на Anthropic-совместимых точках доступа.
Вы должны понять сами, какую переменную указывать. Указать обе не получится — Claude Code будет ругаться.
Теперь запускается! Настроенный Claude Code не требует подписку:

Вы спросите: «Зачем нам нужен Claude Code Router?» И я отвечу: для двух вещей, одна важней другой:
мы хотим подключаться нашим Claude Code к OpenAI-совместимым точкам доступа, и нам нужен конвертер протокола;
мы хотим переключать модели на лету, per project.
Claude Code Router (CCR) — это прокси-сервер, который слушает на указанном адресе и порте, принимает запросы по Anthropic-протоколу и направляет их соответствующему провайдеру, при необходимости конвертируя протокол.
Когда мы выполняем команду ccr code, CCR выставляет нужные переменные окружения и запускает Claude как дочерний процесс. Что именно выставляет CCR, можно увидеть, если запустить команду ccr activate:
export ANTHROPIC_AUTH_TOKEN="test" export ANTHROPIC_BASE_URL="http://127.0.0.1:3456" export NO_PROXY="127.0.0.1" export DISABLE_TELEMETRY="true" export DISABLE_COST_WARNINGS="true" export API_TIMEOUT_MS="600000" unset CLAUDE_CODE_USE_BEDROCK
Чтобы проксирование работало, надо держать CCR-сервис запущенным. Запустить его можно командой ccr restart, а посмотреть на его состояние — командой ccr status.
Давайте поставим Claude Code Router (CCR): brew install claude-code-router.
Создаем для CCR конфигурацию:
mkdir -vp ~/.claude-code-router cat <<EOF > ~/.claude-code-router/config.json { "LOG": false, "LOG_LEVEL": "debug", "HOST": "127.0.0.1", "PORT": 3456, "API_TIMEOUT_MS": "600000", "Providers": [ { "name": "opencode", "api_base_url": "https://opencode.ai/zen/go/v1/chat/completions", "api_key": "sk-nhD9IFHpqhJBd84xbjF0pNMnE7YvNj2pA0qu2lup6X3MqSP4u4rexC12mf7VA9hL", "models": [ "glm-5.1", "glm-5", "kimi-k2.5", "kimi-k2.6", "mimo-v2-pro", "mimo-v2-omni", "mimo-v2.5-pro", "mimo-v2.5", "minimax-m2.7", "minimax-m2.5", "qwen3.6-plus", "qwen3.5-plus" ] } ], "Router": { "default": "opencode,glm-5.1", "background": "opencode,kimi-k2.5", "think": "opencode,glm-5.1", "longContext": "opencode,mimo-v2-pro", "longContextThreshold": 80000, "webSearch": "opencode,minimax-m2.5" }, "CUSTOM_ROUTER_PATH": "${HOME}/.claude-code-router/routing/custom_router.js" } EOF ccr restart
Пробуем запустить Claude Code через Claude Code Router. Для начала почистим конфиг Claude Code:
cat <<EOF > ~/.claude/settings.json { "env": { "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1" } } EOF
Теперь сам по себе Claude Code работать не сможет, но, если мы запустим его через Claude Code Router, который выставит нужные переменные, все получится.

Теперь немного уличной магии.
Нам бы хотелось, чтобы Claude Code использовал ту модель, которую мы указали для конкретного проекта. Для этого мы можем задействовать CCR. Но я внимательно изучил запросы, которые Сlaude Code передает в CCR, и не нашел ни одного признака, по которому CCR мог бы определить, к какому проекту относится конкретный запрос. В запросе есть полные имена файлов, которые добавлены в контекст, но надежным признаком я бы это не назвал.
Поэтому мы создадим shell-обертку, которая будет выставлять нужные переменные и запускать Claude:
mkdir -vp ~/.claude-code-router/routing cat << EOF > ~/.claude-code-router/routing/wrapper.sh #!/bin/sh -e eval "\$(ccr activate)" export ANTHROPIC_CUSTOM_HEADERS="X-Project-Path: \$(pwd) \$ANTHROPIC_CUSTOM_HEADERS" "\$@" EOF chmod +x ~/.claude-code-router/routing/wrapper.sh
Запускаем: ~/.claude-code-router/routing/wrapper.sh claude
Теперь у запросов, которые доезжают до CCR, есть заголовок X-Project-Path, на него можно ориентироваться.
И наконец, выбираем модели. В конфиге CCR мы указали CUSTOM_ROUTER_PATH, он должен указывать на скрипт custom_router.js. Скрипт великоват, чтобы приводить его прямо в тексте статьи, поэтому я положил его отдельным файлом. Обязательно загляните и проверьте, что я вам предложил!
Честно сказать, я не писал этот скрипт, потому что вообще не знаю JS — это не мой профиль работы, я пишу на Go. Я получил готовый скрипт от minimax+kilocode по следующему запросу:
Создай custom_router.js согласно спецификации:
Извлекает x-project-path из заголовка
Пытается открыть ${projectPath}/.claude/model.json
Если файл не загружен:
Если директория .claude не существует — возвращает null
Если существует — создает model.json со списком моделей из конфига, model = пустая строка
Проверяет актуальность списка моделей:
Если список устарел — заменяет на актуальный из конфига
Если модель из model.json отсутствует в списке — заменяет на пустую строку
Всегда перезаписывает model.json с актуальной информацией
Если model пуста — возвращает null
Возвращает модель
Как ни странно, этого оказалось достаточно, чтобы создать вполне рабочую заготовку. Я минимально отредактировал скрипт, а теперь предлагаю его вам. Короче, поступаю как настоящий вайбкодер…
Теперь у нас есть custom_router.js — маршрутизатор выбора модели на основе проекта. Что он делает:
Извлекает x-project-path из заголовков запроса.
Читает конфигурацию модели из .claude/model.json в проекте.
Если файл отсутствует, создает его со списком доступных моделей из конфига.
Если список моделей в конфиге изменился, пересоздает файл, сохраняя параметр model без изменений, включая пустую строку или некорректное значение.
Возвращает строку формата provider,model для выбора модели. Если проекта или модели нет, возвращает null для fallback.
Формат model.json:
{ "model": "provider,model-name", "models": ["provider,model1", "provider,model2"] }
Логирование ведется только при config.LOG = true, файл ~/.claude-code-router/logs/routing-YYYYMMDD.log.
VSCode или другой IDE нужен в качестве оболочки для агента. Я пробовал IntelliJ IDEA, OpenIDE, Zed. Для себя остановился на VSCode, но убойных аргументов в его пользу у меня нет. Разберемся, как настроить VSCode.
Откуда установить VSCode, расскажет поисковик или DuckDuckGo. А я хочу подсветить один момент: скорее всего, нужные плагины для VSCode без VPN или прокси ставиться не будут. Удобно иметь прописанный в настройках VSCode http proxy. Применимы ли мои советы к другой IDE, я не знаю. На первый взгляд, должно подойти, но могут потребоваться доработки.
Далее надо установить плагин anthropic.claude-code:

Настроить запуск Claude Code через обертку:

Можно пользоваться!

Выбор модели в проекте осуществляется через редактирование файла .claude/model.json, если таковой есть. Желаемую модель надо вписывать в поле model. А чтобы всегда знать, какие модели можно туда вписать, router подготовил для нас поле models, в котором перечислены все модели, определенные в конфиге CCR.
Мы настроили рабочее место и подключили дешевый провайдер OpenCode Go к агенту Claude Code, а еще научились на лету переключать модели, которые он использует. В следующей статье мы превратим наше рабочее место в станцию Spec-Driven Development-программиста, водрузив поверх сделанного SDD toolkit.