Когда мы в CIAN решили внедрить Claude Code в 2025, все было как в порнофильме — быстро, красиво, но после наступило жесткое похмелье. Первые две недели мы получили +30% скорости разработки, а потом чуть не уронили продакшн. Разбираю 8 граблей, на которые наступила наша команда DevOps, и как мы из них вылезли. Это не теория — это кровь и пот на клавиатуре.
Предупреждение: в статье много конфигов, которые мы выстрадали. Если вы скопируете их бездумно — Claude Code просто сломает ваш монорепозиторий. Настройки надо адаптировать под свою команду.
Проблема 1: «Дикий Запад» промптов — каждый пишет как хочет
Сначала мы просто разослали ссылку на Claude Code всей команде. Через неделю половина разработчиков писала промпты в стиле «сделай мне красиво», другая половина копировала простыни из интернета. Результат — AI генерировал код, который проходил review только через раз. Причина: отсутствие единого стиля и контекста проекта.
claude.md в корне репозитория и запретили локальные переопределения через .claude.local.md для production-веток. В этом файле описали структуру проекта, coding standards, ссылки на архитектурную документацию. Теперь любой новый участник получает единый контекст.
Пример нашего claude.md (ключевые секции):
# CIAN Project Context
## Tech Stack
- Backend: Kotlin/Spring Boot 3.4, PostgreSQL 16, Redis 7.4
- Frontend: React 19, Typescript 5.7, Next.js 15
- Infra: AWS ECS, Terraform 1.10, GitHub Actions
## Rules
- Never run commands that modify production without manual approval
- Use `kebab-case` for file names
- All public functions must have KDoc/JSDoc
- Follow the error handling pattern: Result monad for domain errors
## Sensitive directories
- /infra/prod/ — read-only for Claude
- /secrets/ — ignore completely
## Reference docs
- Architecture: docs/ARCHITECTURE.md
- Database migration guide: docs/MIGRATIONS.md
Ошибка: мы сначала положили claude.md в корень, но он не учитывал подпроекты. В монорепозитории пришлось добавить вложенные claude.md в каждом модуле, а корневой — только глобальные политики. Иначе Claude Code путал контексты: писал Kotlin-код в Python-модуле.
Проблема 2: Хранить claude.md в репозитории — а версионировать?
Мы положили claude.md в git. Классно, но через месяц все коммитили в него правки кто во что горазд. Однажды разработчик случайно добавил в секцию Sensitive directories продакшн базу данных как доступную для записи. Хорошо, что code review поймал. Тогда мы поняли: claude.md нужно не просто версионировать, а управлять им как кодом.
Rules не появилось команд, разрешающих rm -rf или запись в продакшн. Используем простой скрипт на GitHub Actions:
name: Validate claude.md
on: [pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check dangerous rules
run: |
if grep -qiE '(rm -rf|drop table|truncate|production.*write)' claude.md; then
echo "❌ Dangerous rule found in claude.md"
exit 1
fi
echo "✅ claude.md looks safe"
Кстати, статья «Claude Code: от промпта до продакшена без иллюзий» хорошо описывает, как контекст влияет на качество выхлопа. У нас без центрального claude.md было бы то же самое — иллюзия контроля.
Проблема 3: Безопасность — Claude Code увидел секреты в репозитории
Классика: кто-то случайно залил .env с продакшн-ключами. Claude Code считал этот файл и потом в промптах предлагал использовать реальные ключи. Мы заметили это только когда AI написал тест, который выводил ключ в лог. Фактически произошла утечка через AI-агента (об этом мы предупреждали в разборе утечки Claude Code).
secrets в claude.md в секцию Ignored paths. Но этого мало. Мы сделали pre-commit хук, который проверяет, что в коммит не попадают файлы с апи-ключами, и заодно добавляет в .gitignore шаблоны. Но главное — настроили Claude Code на работу через Vault (Ansible + HashiCorp Vault). Claude Code теперь никогда не видит сырые секреты, только их имена.
Плюс мы включили режим --sandbox при запуске Claude Code для production-аккаунтов (доступно с версии 0.2.8). В этом режиме AI не может выполнять команды за пределами строго заданного контекста. Это спасло нас от сценария, описанного в случае с удалением продакшена.
Проблема 4: Отсутствие изоляции — Claude Code лезет куда не надо
Даже когда мы защитили секреты, Claude Code мог случайно выполнить команду kubectl delete pod или terraform destroy. Не злонамеренно — просто AI думал, что это часть задачи. Однажды он пересоздал staging-базу, потому что разработчик попросил «обновить схему». AI выполнил DROP TABLE IF EXISTS — благо staging, а не prod.
Золотое правило: никогда не давайте Claude Code полный доступ к терминалу. На CIAN мы создали отдельного пользователя claude-bot с минимальными правами: только чтение для production, полные права только на dev-стенд. И повесили aliases на опасные команды, которые требуют подтверждения через Slack перед выполнением.
Пример конфига для .bashrc бота:
# Dangerous commands wrapper
function kubectl {
if [[ "$*" =~ (delete|drain|uncordon|taint) ]]; then
echo "⚠️ Dangerous kubectl command blocked. Ask in #devops channel."
return 1
fi
command kubectl "$@"
}
function terraform {
if [[ "$*" =~ (destroy|apply) ]] && [[ "$PWD" != *"-dev"* ]]; then
echo "❌ Terraform destroy/apply allowed only in dev directories."
return 1
fi
command terraform "$@"
}
Проблема 5: Управление плагинами — дикий хаос
К сентябрю 2025 Claude Code обзавелся кучей плагинов (анализ уязвимостей, генерация тестов, рефакторинг). Каждый разработчик ставил что хотел. Мы получили гетерогенный зоопарк: у одного плагин для Python, у другого — для Go, а общий контекст не соблюдался. CIAN — это в основном Kotlin и TypeScript, а плагины иногда лезли не туда.
claude-config. Создали отдельный Git-репозиторий, где хранится список одобренных плагинов и их версии. Claude Code при старте синхронизирует список. Если разработчик хочет новый плагин — создает PR, а мы ревьюим на безопасность.
# plugins.yaml — управляемый список плагинов
plugins:
- name: test-generator
version: 1.4.2
allow: ["**/src/main/**/*.kt", "**/*.ts"]
- name: vulnerability-scanner
version: 0.3.1
allow: ["**/*.lock", "**/package.json"]
- name: refactor-assistant
version: 2.0.0
allow: ["**/*.py", "**/*.js"]
# blocked for infra dirs
blocked: ["**/infra/**", "**/deploy/**"]
Кстати, статья про Claude Code против IBM хорошо показывает, как хаотичное внедрение плагинов может разрушить репутацию. Мы не хотели повторять этот путь.
Проблема 6: Стоимость и масштабирование — счет пришел неожиданно
Первые два месяца мы радовались. Потом пришел счет за API — $47 000 за месяц. Оказалось, два разработчика оставили Claude Code работать в цикле на ночь, агент сам себе давал задачи. AI начал рефакторить весь старый код, генерируя миллионы токенов.
Дополнительно добавили в claude.md лимит на максимальное количество шагов в одном запросе. Научный эксперимент по сравнению Claude Code и ручной разработки показал, что при грамотных лимитах AI экономит 40% времени, но без них — убыточен.
Проблема 7: CI/CD и AI-код — кто отвечает за quality?
Код, сгенерированный Claude Code, мы пускали через обычный CI. Но он часто проходил линтеры, но не проходил бизнес-тесты. Проблема: AI писал код, который компилируется, но нарушает бизнес-логику. Нужна дополнительная проверка.
[claude] (через Git hook). Если CI видит такой маркер, он запускает расширенный набор тестов: интеграционные тесты, E2E, security scan.
# .github/workflows/claude-enhanced-checks.yml
name: Claude Code Enhanced Checks
on:
pull_request:
types: [opened, synchronize]
jobs:
detect-ai:
runs-on: ubuntu-latest
outputs:
is_ai: ${{ steps.check.outputs.is_ai }}
steps:
- uses: actions/checkout@v4
- id: check
run: |
if git log -1 --format=%s | grep -q '\[claude\]'; then
echo "is_ai=true" >> $GITHUB_OUTPUT
else
echo "is_ai=false" >> $GITHUB_OUTPUT
fi
extended-tests:
needs: detect-ai
if: needs.detect-ai.outputs.is_ai == 'true'
runs-on: ubuntu-latest
steps:
- run: make integration-tests
- run: make e2e-tests
- uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
severity: 'HIGH,CRITICAL'
Статья «5 правил контроля Claude Code в production» идеально описывает наш подход — мы используем те же принципы: feature flags для AI-генеренного кода, канареечные деплои, мониторинг ошибок.
Проблема 8: Скепсис команды — «AI заменит нас»
Самый сложный барьер — человеческий. Часть разработчиков боялись, что Claude Code их заменит, часть — считали, что AI пишет говнокод. Мы провели внутреннюю серию митапов, на которых показали реальные кейсы: например, как AI помог мигрировать легаси с PHP на Kotlin, сэкономив 3 месяца. Пример разработки на Elixir с 95% покрытия убедил скептиков, что AI может быть качественным инструментом при правильном контроле.
Ошибка: мы попытались принудительно внедрить Claude Code «сверху» — это вызвало саботаж. Пришлось откатить и начинать с волонтеров. Постепенно adoption вырос до 80% за квартал.
Шаг за шагом: как мы внедряли Claude Code в CIAN
1 Аудит: найдите свои узкие места
Перед внедрением мы составили карту репозиториев, выделили критические сервисы, определили типовые задачи, которые AI будет решать. Это поможет настроить claude.md. Кейс с завода по замене контролеров ОТК вдохновил нас автоматизировать code review.
2 Создайте единое claude.md и репозиторий конфигурации
Как описано выше. Не забудьте про вложенные claude.md для монорепозитория. Все изменения — через PR.
3 Настройте песочницу и минимальные права
Отдельный пользователь, sandbox, запрет опасных команд. Подробно в проблеме 4.
4 Внедрите политику плагинов и версионирование
Через центральный репозиторий и CI-проверки (как в кейсе с n8n — автоматизация повторяющихся действий).
5 Установите лимиты и мониторинг затрат
Grafana + алерты. Не дайте AI уйти в бесконечный цикл.
6 Интегрируйте с CI/CD с AI-маркерами
Расширенные проверки для AI-кода. Feature flags для экспериментальных изменений.
7 Проведите обучение и снимите страхи
Опциональность, амбассадоры, pair programming с AI.
8 Итеративно улучшайте конфигурацию
После каждого инцидента добавляем правило в claude.md или CI. Это живой процесс.
Неочевидный совет: самый большой профит от Claude Code мы получили не в написании нового кода, а в рефакторинге легаси и автоматизации рутины. Не пытайтесь заставить AI писать всю логику с нуля — используйте его как ассистента для задач, которые команда ненавидит (миграции, рефакторинг, тесты). По нашим данным, 70% времени AI тратит на решение типовых проблем, 30% — на креатив. У нас теперь есть внутренняя поговорка: «Claude Code не заменяет разработчика, он убивает в нем задрота».