Суть урока
В обычном режиме Claude Code — это хирург с ассистентом (ты): он предлагает, ты одобряешь. В headless (хэдлесс — браузер без окна, только в фоне) mode (официально — Agent SDK CLI) — полностью автономный хирург-робот: получил задание, выполнил, отчитался, выключился. Никакого диалога, никакого "нажми Enter", никакого экрана. Именно так Claude работает в CI/CD (си-ай/си-ди — Continuous Integration/Delivery, непрерывная интеграция и доставка) пайплайнах, GitHub Actions (ГитХаб Экшенс — система автоматизации в GitHub), cron-задачах (крон — планировщик задач по расписанию) — без человека рядом, 24/7.
Термины урока: headless (хэдлесс — браузер без окна, только в фоне), CI/CD (си-ай/си-ди — непрерывная интеграция и доставка), GitHub Actions (ГитХаб Экшенс — система автоматизации в GitHub), cron (крон — планировщик задач по расписанию), API (эй-пи-ай — интерфейс программирования), token (токен — единица текста для AI), permission (разрешение — право выполнять действие), prompt (промпт — запрос к AI), agent (агент — автономный исполнитель), workflow (воркфлоу — рабочий процесс).
Заметка из документации Anthropic: то что раньше называлось "headless mode" теперь официально называется Agent SDK CLI. Флаг
-pи все опции работают так же.
Ключевые концепции
--print/-p— Claude отвечает один раз и завершается (Agent SDK CLI mode)- Pipe (stdin) — передать данные через
cat file | claude -p "..."(лимит 10 МБ) --bare— быстрый старт без загрузки hooks/skills/MCP/CLAUDE.md (рекомендовано для CI; требуетANTHROPIC_API_KEY, вход по подписке в этом режиме не работает)--output-format— формат вывода:text,json,stream-json--json-schema— валидированный JSON по заданной схеме--max-turns N— ограничить итерации для контроля стоимости--max-budget-usd— жёсткий лимит расходов в долларах--permission-mode— управление разрешениями:dontAsk,acceptEdits,auto,bypassPermissions--allowedTools— whitelist инструментов для автоматического одобрения- GitHub Actions — официальный action
anthropics/claude-code-action@v1 - Переменные окружения —
ANTHROPIC_API_KEY,CLAUDE_CODE_OAUTH_TOKEN,CLAUDE_CODE_USE_BEDROCK,CLAUDE_CODE_USE_VERTEX
Теория
Флаг --print: выход из интерактивного режима
По умолчанию claude запускает REPL — интерактивную сессию где ты разговариваешь с Claude. Флаг --print (или -p) меняет поведение:
# Интерактивный режим (ждёт ввода)
claude
# Headless: запрос → ответ → выход
claude --print "Объясни что делает эта функция: def f(x): return x * 2"
# Короткая форма
claude -p "Сгенерируй UUID v4 на Python"Что происходит: Claude получает запрос, выполняет все нужные действия (читает файлы, запускает код, пишет результат), выводит ответ в stdout и завершает процесс с кодом 0 (успех) или ненулевым кодом (ошибка).
--bare: быстрый старт для CI/CD
Флаг --bare пропускает автозагрузку hooks, skills, plugins, MCP серверов, авто-памяти и CLAUDE.md. Это рекомендованный режим для скриптов и CI/CD — результат одинаков на любой машине, ничего "чужого" не загружается.
# Быстрый запуск без лишнего контекста
claude --bare -p "Summarize this file" --allowedTools "Read"В bare mode Claude имеет доступ к Bash, чтению и редактированию файлов. Всё остальное передаётся явно через флаги. Важно: без --bare запуск claude -p грузит хуки и MCP-серверы из .claude/settings.json и .mcp.json проекта без диалога доверия, поэтому на чужом коде в CI лучше запускать именно с --bare:
| Что нужно загрузить | Какой флаг |
|---|---|
| Системный промпт | --append-system-prompt или --append-system-prompt-file |
| Настройки | --settings <file-or-json> |
| MCP серверы | --mcp-config <file-or-json> |
| Свои суб-агенты | --agents <file-or-json> |
| Плагины | --plugin-dir <path> или --plugin-url <url> |
Из документации Anthropic:
--bareрекомендован для скриптов и станет режимом по умолчанию для-pв будущих версиях. В bare mode Claude Code не читает вход по подписке (OAuth) и системную связку ключей, поэтому нуженANTHROPIC_API_KEYиз Claude Console (или облачные ключи Bedrock и аналогов).
Pipe: stdin как входные данные
Стандартный Unix-паттерн — передавать данные через pipe. Claude Code полностью поддерживает stdin:
# Summarize лога
cat server.log | claude -p "Найди все ошибки уровня ERROR, сгруппируй по типу, покажи топ-5"
# Code review конкретного файла
cat src/payment.py | claude -p "Найди потенциальные security уязвимости в этом коде"
# Анализ git diff перед коммитом
git diff HEAD | claude -p "Напиши commit message для этих изменений в формате Conventional Commits"
# Обработка CSV
cat leads.csv | claude -p "Из этого CSV выбери строки где column 'status' = 'qualified', верни JSON массив"Pipe делает Claude частью стандартных Unix-пайплайнов — его можно встраивать в любой шелл-скрипт.
Ограничение: stdin ограничен 10 МБ. Если превысить — Claude Code завершится с ошибкой. Для больших файлов запишите данные в файл и укажите путь в промпте вместо pipe.
--output-format json: машиночитаемый вывод
Когда Claude Code работает в автоматизации, нужно парсить его ответ программно. Флаг --output-format json оборачивает вывод в JSON-структуру:
claude -p "Проверь синтаксис этого Python файла и верни список ошибок" \
--output-format json \
< src/main.pyВывод:
{
"type": "result",
"subtype": "success",
"total_cost_usd": 0.0023,
"duration_ms": 1840,
"result": "Найдено 2 ошибки:\n1. Line 14: SyntaxError — missing colon after if\n2. Line 31: IndentationError — unexpected indent"
}В скрипте парсишь через jq:
RESULT=$(cat src/main.py | claude -p "Найди синтаксические ошибки" --output-format json)
ERRORS=$(echo "$RESULT" | jq -r '.result')
COST=$(echo "$RESULT" | jq -r '.total_cost_usd')
echo "Стоимость анализа: $COST USD"
echo "Результат: $ERRORS"Три формата вывода:
| Формат | Описание | Когда использовать |
|---|---|---|
text |
Обычный текст (по умолчанию) | Человек читает |
json |
JSON с result, session_id, total_cost_usd |
Парсинг в скриптах |
stream-json |
NDJSON — по одному JSON-объекту на строку, в реальном времени | Стриминг, live-мониторинг |
--json-schema: валидированный структурированный вывод
Когда нужен ответ строго определённой структуры — используй --json-schema. Claude вернёт JSON, валидированный по указанной JSON Schema. Результат будет в поле structured_output:
# Извлечь имена функций в строго типизированном формате
claude -p "Извлеки имена функций из auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}'Парсинг структурированного вывода:
# Получить массив функций
claude -p "Извлеки функции из auth.py" \
--output-format json \
--json-schema '...' \
| jq '.structured_output'Стриминг через stream-json
Для live-мониторинга используй stream-json с --verbose и --include-partial-messages:
# Стриминг токенов в реальном времени
claude -p "Напиши стихотворение" \
--output-format stream-json \
--verbose \
--include-partial-messages \
| jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'Контроль стоимости и модели
# Указать конкретную модель (алиас)
claude -p "Сложный анализ архитектуры" --model opus
# Указать полное имя модели (пример из документации; актуальные имена на странице Актуальное сейчас)
claude -p "Анализ" --model claude-opus-5-5
# Fallback-модель при перегрузке основной (можно список через запятую)
claude -p "Запрос" --fallback-model sonnet
# Ограничить итерации (для контроля стоимости в агентных задачах)
claude -p "Пофикси баги в src/" --max-turns 3
# Жёсткий лимит расходов в долларах
claude -p "Отрефактори модуль авторизации" --max-budget-usd 2.00--max-turns особенно важен в CI/CD: если Claude пытается исправить баг бесконечно, это выйдет дорого. Ограничение в 3-5 итераций — разумный предел для автоматических задач. При достижении лимита Claude завершается с ошибкой.
--max-budget-usd — жёсткий потолок расходов. Если Claude потратил указанную сумму, он останавливается. Работает только в print mode.
Permission modes для CI/CD
В CI/CD нет человека который нажмёт "Yes". Подходы к разрешениям (режимы описаны в уроке Разрешения и безопасность). Если режим не указан, запуск -p берёт стартовый режим по умолчанию, и он может оказаться auto, поэтому задавай режим явно:
# Подход 1: Whitelist конкретных инструментов (рекомендовано)
# Claude может только читать и делать git-операции
claude -p "Проверь код" --allowedTools "Read" "Bash(git *)"
# Подход 2: dontAsk — только заранее одобренное, всё остальное отклоняется
claude -p "Проверь код" --permission-mode dontAsk
# Подход 3: acceptEdits — автоматически одобрять редактирование файлов
claude -p "Исправь lint-ошибки" --permission-mode acceptEdits
# Подход 4: auto — проверяющая модель решает за человека
claude -p "Обнови зависимости и запусти тесты" --permission-mode auto --permission-prompts none
# Подход 5: Bypass — ТОЛЬКО в изолированных контейнерах!
claude -p "Исправь всё" --dangerously-skip-permissionsПравило для CI/CD: используй минимально необходимые разрешения. --allowedTools с whitelist конкретных команд лучше чем --dangerously-skip-permissions.
Wildcard в allowedTools: Bash(git diff *) — разрешает любую команду начинающуюся с git diff. Пробел перед * важен: без него Bash(git diff*) также разрешит git diff-index.
CI/CD: GitHub Actions
Официальный GitHub Action от Anthropic
У Anthropic есть официальный GitHub Action — anthropics/claude-code-action@v1. Его можно установить одной командой прямо из Claude Code:
# В интерактивной сессии Claude Code
/install-github-appДля команды нужен установленный и авторизованный GitHub CLI (gh auth login), права администратора репозитория и репозиторий на github.com. Или настроить вручную: установить GitHub App (github.com/apps/claude), добавить в secrets репозитория ANTHROPIC_API_KEY (ключ из Claude Console) либо CLAUDE_CODE_OAUTH_TOKEN (токен подписки Pro, Max, Team или Enterprise, получается командой claude setup-token).
Базовый workflow — реагирует на @claude в комментариях PR/issues:
# .github/workflows/claude.yml
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
claude:
if: contains(github.event.comment.body, '@claude')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
# Автоматически реагирует на @claude в комментарияхАвтоматический code review на каждый PR:
# .github/workflows/claude-review.yml
name: Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: "Проанализируй этот PR на качество кода, баги и security. Оставь замечания как review comments."
claude_args: "--max-turns 5 --model sonnet"
# Для публикации замечаний прямо в PR действию нужен инструмент inline-комментариев
# (см. пример review-workflow в документации). Для автоматического ревью без своего workflow
# есть и готовая функция Code Review: code.claude.com/docs/en/code-reviewПараметры claude-code-action@v1:
| Параметр | Описание | Обязательный |
|---|---|---|
anthropic_api_key |
API ключ Anthropic | Да (для direct API), если не используешь claude_code_oauth_token |
claude_code_oauth_token |
Токен подписки (из claude setup-token) |
Нет |
prompt |
Инструкции для Claude | Нет (без него реагирует на @claude) |
claude_args |
Любые CLI-флаги Claude Code | Нет |
github_token |
GitHub token для API | Нет (по умолчанию действие работает как Claude GitHub App) |
trigger_phrase |
Фраза-триггер (по умолчанию @claude) |
Нет |
plugin_marketplaces, plugins |
Установить плагины и запускать их скиллы | Нет |
use_bedrock |
Использовать Amazon Bedrock | Нет |
use_vertex |
Использовать Google Cloud Agent Platform (ранее Vertex AI) | Нет |
use_foundry |
Использовать Microsoft Foundry | Нет |
Ручной подход — Claude CLI в GitHub Actions
Если нужен полный контроль, можно использовать claude -p напрямую:
# .github/workflows/claude-review.yml
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
code-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Claude Code
# npm-способ работает (нужен Node.js 22+); основной способ сейчас: curl -fsSL https://claude.ai/install.sh | bash
run: npm install -g @anthropic-ai/claude-code
- name: Run Claude Code Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
# Получаем diff только изменённых файлов
git diff origin/main...HEAD -- '*.py' '*.ts' '*.js' > changes.diff
# Claude анализирует изменения (--bare для чистого CI)
REVIEW=$(cat changes.diff | claude --bare -p "
Ты senior code reviewer. Проанализируй этот diff.
Найди: баги, security проблемы, нарушения SOLID.
Если всё хорошо — напиши 'LGTM'. Критичные проблемы помечай словом CRITICAL.
" --output-format json --max-turns 3 | jq -r '.result')
echo "## Claude Code Review" >> $GITHUB_STEP_SUMMARY
echo "$REVIEW" >> $GITHUB_STEP_SUMMARY
# Проверка в том же шаге: переменная REVIEW не переходит между шагами
if echo "$REVIEW" | grep -q "CRITICAL"; then
echo "Critical issues found — blocking merge"
exit 1
fiPre-commit хук с Claude
Автоматическая проверка кода перед каждым коммитом:
#!/bin/bash
# .git/hooks/pre-commit
# Получаем список изменённых Python файлов
CHANGED_PY=$(git diff --cached --name-only --diff-filter=ACM | grep '\.py$')
if [ -z "$CHANGED_PY" ]; then
exit 0 # Нет Python файлов — пропускаем
fi
echo "Claude Code проверяет изменения..."
for FILE in $CHANGED_PY; do
RESULT=$(cat "$FILE" | claude -p "
Проверь этот Python файл на:
1. Синтаксические ошибки
2. Hardcoded секреты (пароли, API ключи)
3. SQL-инъекции
Если нашёл проблему — ответь 'BLOCK: <описание>'.
Если всё чисто — ответь 'OK'.
" --bare --max-turns 1 --output-format json | jq -r '.result')
if echo "$RESULT" | grep -q "^BLOCK:"; then
echo "Проблема в $FILE:"
echo "$RESULT"
exit 1 # Блокируем коммит
fi
done
echo "Все проверки пройдены."
exit 0Установка хука:
chmod +x .git/hooks/pre-commitАвтоматическая генерация CHANGELOG
#!/bin/bash
# scripts/generate-changelog.sh
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~50")
COMMITS=$(git log ${LAST_TAG}..HEAD --oneline)
if [ -z "$COMMITS" ]; then
echo "Нет новых коммитов"
exit 0
fi
echo "Генерируем CHANGELOG с Claude..."
CHANGELOG=$(echo "$COMMITS" | claude -p "
Вот список git коммитов. Сгенерируй CHANGELOG в формате Keep a Changelog.
Сгруппируй по категориям: Added, Changed, Fixed, Removed.
Используй короткие понятные описания на русском.
Начни сразу с ## [Unreleased] — не добавляй вводный текст.
")
# Добавляем в начало CHANGELOG.md
echo "$CHANGELOG" | cat - CHANGELOG.md > /tmp/changelog_new
mv /tmp/changelog_new CHANGELOG.md
echo "CHANGELOG.md обновлён"Аутентификация и переменные окружения
Для работы без UI Claude нужен API-ключ. В CI/CD используются переменные окружения:
| Переменная | Описание |
|---|---|
ANTHROPIC_API_KEY |
API ключ Anthropic (основной способ) |
CLAUDE_CODE_USE_BEDROCK=1 |
Использовать Amazon Bedrock вместо Anthropic API |
CLAUDE_CODE_USE_VERTEX=1 |
Использовать Google Cloud (Vertex AI; в документации теперь называется Google Cloud's Agent Platform) |
CLAUDE_CODE_OAUTH_TOKEN |
Токен подписки для CI (получается командой claude setup-token) |
ANTHROPIC_MODEL |
Модель по умолчанию (переопределяется --model) |
Генерация долгоживущего токена для CI:
# Создаёт OAuth-токен и выводит его в терминал (не сохраняет)
# Требуется подписка Claude
claude setup-tokenТокен можно использовать вместо ANTHROPIC_API_KEY в CI/CD пайплайнах (через CLAUDE_CODE_OAUTH_TOKEN или параметр claude_code_oauth_token действия). Исключение: вместе с --bare токен подписки не работает, там нужен API-ключ. Для общего секрета на всю организацию документация советует API-ключ, а не токен: токен привязан к подписке человека, который его создал.
Продолжение сессий в скриптах
Можно строить цепочки вызовов которые продолжают предыдущий контекст:
# Первый запрос — анализ
claude -p "Проанализируй производительность этого проекта"
# Продолжить последний разговор
claude -p "Теперь сфокусируйся на SQL запросах" --continue
# Или через session ID для надёжности
SESSION=$(claude -p "Начни review" --output-format json | jq -r '.session_id')
claude -p "Продолжи review" --resume "$SESSION"Паттерны стоимость/скорость в headless
| Задача | Модель | max-turns | Порядок стоимости за запуск |
|---|---|---|---|
| Проверка синтаксиса | haiku | 1 | минимальный |
| Code review diff | sonnet | 1 | низкий |
| Генерация changelog | sonnet | 1 | низкий |
| Автоисправление багов | sonnet | 5 | средний |
| Сложный рефакторинг | opus | 10 | выше среднего |
Точную стоимость запуска смотри в поле total_cost_usd ответа (это оценка на стороне клиента, она может отличаться от реального счёта). Цены за токены: актуальные цены и версии: Актуальное сейчас.
Правила контроля стоимости в CI/CD:
--max-turns 1для анализа (только чтение + вывод)--max-turns 3-5для задач с изменением файлов--max-budget-usd 5.00— жёсткий потолок расходов на запуск--bare— не загружать лишний контекст (экономит время и токены)--model sonnetдля рутины,--model opusтолько для сложного
Практика
Задание: Pre-commit хук для поиска секретов
- Создай тестовый git репозиторий:
git init test-repo && cd test-repo - Создай файл
.git/hooks/pre-commitс содержимым из примера выше (упрощённый вариант — только поиск секретов) - Сделай хук исполняемым:
chmod +x .git/hooks/pre-commit - Создай файл
config.pyс текстом:python API_KEY = "sk-1234567890abcdef" # тестовый ключ DATABASE_URL = "postgresql://user:password@localhost/db" - Попробуй сделать коммит:
git add config.py && git commit -m "test"— хук должен заблокировать - Убери секреты (используй переменные окружения), повтори коммит — должен пройти
- Бонус: добавь в хук генерацию commit message через
git diff --cached | claude -p "Напиши commit message"
Цель: понять как Claude Code работает без UI и как встраивать его в автоматические пайплайны.
Инструменты и ресурсы
claude -p "..."— headless запрос (Agent SDK CLI mode)--bare— быстрый старт без контекста (рекомендовано для CI)--output-format json— структурированный вывод (result,total_cost_usd,session_id)--json-schema— валидированный структурированный вывод по JSON Schema--output-format stream-json— стриминг NDJSON--max-turns N— ограничение итераций--max-budget-usd N— жёсткий лимит расходов--allowedTools— whitelist инструментов с поддержкой wildcard--permission-mode—dontAsk,acceptEdits,bypassPermissions--continue/--resume— продолжение сессий в скриптахclaude setup-token— генерация долгоживущего OAuth-токена для CIanthropics/claude-code-action@v1— официальный GitHub Action/install-github-app— быстрая настройка GitHub App из Claude Codejq—brew install jq— парсинг JSON в bash скриптах- Документация: https://code.claude.com/docs/en/headless
Ключевые выводы
claude --bare -p "запрос"= рекомендованный формат для CI/CD.--bareдля чистого старта,-pдля headless. Никакого интерактива, одинаковый результат на любой машине.
Pipe (
cat file | claude -p "...") делает Claude частью Unix-пайплайна. Ограничение stdin — 10 МБ. Для больших данных — укажи путь к файлу в промпте.
Три уровня безопасности в CI:
--allowedTools(whitelist конкретных команд) лучше чем--permission-mode dontAskлучше чем--dangerously-skip-permissions. Используй минимально необходимые разрешения.
Официальный GitHub Action (
anthropics/claude-code-action@v1) проще ручной настройки. Реагирует на@claudeв комментариях, поддерживает skills, все CLI-флаги черезclaude_args.
Контроль расходов:
--max-turns 3+--max-budget-usd 5.00+--model sonnet= разумные лимиты для автоматических задач.
Что дальше
Отметка хранится только в этом браузере и никуда не отправляется. Мой прогресс