AmigaОбучение ИИ
Модуль 3 · Автоматизируем повторяющееся · урок 6 из 10

Рутины и headless-режим

12 мин чтения▶ есть видеоверсия

Всё, что мы делали до сих пор, происходило в интерактивной сессии: вы пишете, Claude отвечает. Но многие задачи агентства повторяются и не требуют человека у терминала: прогнать линтер по всем проектам ночью, обновить зависимости в двадцати репозиториях, разобрать вчерашние ошибки из мониторинга. В этом уроке разберём headless-режим — запуск claude как обычной команды в скрипте — и три способа запускать такие команды по расписанию.

Флаг -p: Claude как команда

Флаг -p (или --print) переводит Claude Code в неинтерактивный режим: он выполняет запрос, печатает ответ и завершается. Вся механика та же — инструменты, агентный цикл, CLAUDE.md, — только без диалога.

bash
claude -p "Что делает модуль авторизации?"

Как обычная команда, claude -p читает стандартный ввод и возвращает код выхода — 0 при успехе, ненулевой при ошибке. Это значит, его можно ставить в конвейер:

bash
cat build-error.txt | claude -p "коротко объясни причину ошибки сборки" > answer.txt

Или использовать как проверку в package.json:

json
{
  "scripts": {
    "lint:claude": "git diff main | claude -p \"ты линтер опечаток. для каждой опечатки в дифе выведи файл:строка и суть. больше ничего не выводи.\""
  }
}

Через стандартный ввод можно передать до 10 МБ; для большего сохраняйте в файл и указывайте путь в запросе.

Права в неинтерактивном режиме

Спросить некого, поэтому всё, что потребовало бы подтверждения, отклоняется. Права задаются явно:

  • --allowedTools — список инструментов и шаблонов в синтаксисе правил разрешений: --allowedTools "Read,Edit,Bash(pnpm lint *)". Пробел перед * тот же, что в settings.json.
  • --permission-mode — базовый режим: acceptEdits для правок файлов, dontAsk для жёсткого списка, auto для классификатора.
  • --max-turns — ограничить число ходов агента; при превышении команда завершится с ошибкой. Страховка от бесконечных циклов.
bash
claude -p "Примени исправления линтера" --permission-mode acceptEdits --allowedTools "Bash(pnpm lint *)"

Для полностью автономных прогонов есть --dangerously-skip-permissions, но, как разбирали в уроке про режимы прав, только внутри контейнера или виртуалки.

Флаг --bare: одинаковый результат на любой машине

По умолчанию claude -p загружает всё то же, что и интерактивная сессия: хуки, навыки, плагины, MCP-серверы, автопамять, CLAUDE.md из рабочей папки и из ~/.claude. В CI это проблема: хук из чьей-то домашней папки или MCP-сервер из .mcp.json проекта запустятся без вопросов, и результат будет зависеть от машины.

Флаг --bare отключает автообнаружение всего этого. Остаются Bash, чтение и правка файлов, а нужный контекст передаётся флагами: --append-system-prompt, --settings, --mcp-config, --plugin-dir. Документация называет --bare рекомендуемым режимом для скриптов. Есть нюанс: в этом режиме не используется вход по подписке, нужна переменная ANTHROPIC_API_KEY.

bash
claude --bare -p "Кратко перескажи README.md" --allowedTools "Read"

Вывод, который можно разобрать

Флаг --output-format управляет форматом ответа:

  • text — обычный текст (по умолчанию);
  • json — один объект с полем result, идентификатором сессии, стоимостью и метаданными;
  • stream-json — по объекту на строку, события по мере генерации (вместе с --verbose).
bash
claude -p "Перечисли все API-эндпоинты" --output-format json | jq -r '.result'

Если нужна строгая структура, добавьте --json-schema с JSON Schema, и ответ появится в поле structured_output, проверенный по схеме:

bash
claude -p "Извлеки имена функций из auth.ts" \
  --output-format json \
  --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
  | jq '.structured_output'

Для скриптов, которые обрабатывают результат дальше, это удобнее, чем парсить свободный текст.

Продолжение разговора из скрипта

Каждый вызов -p создаёт сессию, к которой можно вернуться: --continue продолжает последнюю, --resume с идентификатором — конкретную.

bash
session_id=$(claude -p "Начни ревью производительности" --output-format json | jq -r '.session_id')
claude -p "Теперь сосредоточься на запросах к базе" --resume "$session_id"

Так один скрипт может вести многошаговый диалог: сначала анализ, потом уточнение, потом отчёт.

Пример: ночной прогон линтера по двадцати проектам

Задача из практики агентства: в двадцати клиентских репозиториях каждую ночь прогонять линтер и проверку типов, а утром иметь список того, что сломалось, с предложенными исправлениями в отдельных ветках. Скрипт nightly-lint.sh:

bash
#!/bin/bash
set -u
REPORT="$HOME/reports/lint-$(date +%F).md"
echo "# Линтер: $(date +%F)" > "$REPORT"

while read -r repo; do
  cd "$repo" || continue
  git checkout -q main && git pull -q
  git checkout -q -B "claude/lint-$(date +%F)"

  result=$(claude --bare -p "Запусти pnpm lint и pnpm typecheck. Исправь ошибки, не меняя поведение кода и не добавляя any или eslint-disable. Если что-то нельзя исправить безопасно — не трогай и опиши. В конце выведи одну строку: OK или FAIL, затем список изменённых файлов." \
    --permission-mode acceptEdits \
    --allowedTools "Bash(pnpm lint *),Bash(pnpm typecheck *),Bash(git diff *)" \
    --max-turns 30 \
    --output-format json)

  status=$(echo "$result" | jq -r '.result' | head -n 1)
  echo "## $repo — $status" >> "$REPORT"
  echo "$result" | jq -r '.result' | tail -n +2 >> "$REPORT"

  if ! git diff --quiet; then
    git commit -qam "lint: автоисправления $(date +%F)"
  fi
done < "$HOME/projects.txt"

Что здесь важно. Каждый репозиторий обрабатывается в своей ветке claude/..., ничего не отправляется в удалённый репозиторий — утром человек смотрит дифы и решает сам. Права ограничены линтером, проверкой типов и чтением дифа: Claude не сможет ни установить пакет, ни сделать git push. --max-turns не даст зависнуть на одном проекте. --bare гарантирует, что результат не зависит от того, чей ноутбук запустил скрипт. И запрос требует машиночитаемую первую строку — OK или FAIL, — чтобы отчёт собирался без разбора прозы.

Документация советует сначала прогнать такой скрипт на двух-трёх проектах, поправить запрос по тому, что пошло не так, и только потом запускать на всех.

Похожим циклом делается обновление зависимостей: для каждого репозитория — «обнови минорные версии, прогони тесты, при падении откати конкретный пакет и опиши» — с разрешением на pnpm update, pnpm test и git diff.

Три способа запускать по расписанию

Скрипт написан; теперь его надо запускать. Вариантов три, и они различаются тем, где работают и что им доступно.

/loop внутри сессии. Команда /loop 15m проверь, прошёл ли CI, и разбери замечания ревью повторяет запрос каждые 15 минут, пока сессия открыта. Без интервала Claude сам выбирает паузу между итерациями по обстановке. Есть /loop без запроса — встроенный сценарий «доделай незавершённое, посмотри PR текущей ветки, приберись». Задачи живут в сессии, восстанавливаются при --resume и истекают через семь дней. Это для присмотра за PR или деплоем, пока вы работаете, а не для ночных прогонов.

Локальные задачи Desktop. Приложение Claude Desktop умеет запускать задачи по расписанию на вашей машине, без открытой сессии, с доступом к локальным файлам. Машина должна быть включена. Для ночного скрипта на рабочем ноутбуке подходит, но обычный cron или systemd-таймер с вызовом nightly-lint.sh делает то же самое и не требует ничего, кроме claude в PATH.

Рутины в облаке. Рутина — сохранённая конфигурация: запрос, репозитории, коннекторы, — которая выполняется на инфраструктуре Anthropic без вашей машины. Создаётся на claude.ai/code/routines или командой /schedule в сессии: /schedule ежедневное ревью PR в 9 утра. Триггеры трёх видов: расписание (минимальный интервал — час), HTTP-запрос на эндпоинт рутины (для алертов из мониторинга и деплой-пайплайнов) и события GitHub (открыт PR, вышел релиз).

Рутина работает автономно: без запросов на подтверждение, в свежем клоне репозитория, с правом писать только в ветки с префиксом claude/. Доступ определяется тем, какие репозитории, коннекторы и сетевые правила вы ей дали, — сужайте до необходимого. Всё, что рутина делает, делается от вашего имени: коммиты, PR, сообщения в Slack. Рутины доступны на планах Pro, Max, Team и Enterprise, находятся в статусе research preview, и у них есть дневной лимит запусков. Актуальные ограничения — в документации.

Сводно:

/loop Desktop / cron Рутины
Где работает В открытой сессии На вашей машине В облаке
Нужна включённая машина Да Да Нет
Локальные файлы Да Да Нет, свежий клон
Минимальный интервал Минута Минута Час
Подтверждения Как в сессии Настраиваются Нет, автономно

Для ночного линтера по двадцати проектам естественный выбор — cron с nightly-lint.sh на сервере сборки или рутина с выбранными репозиториями, если проекты в GitHub и нужны PR. Для присмотра за своим PR — /loop. Для реакции на алерт — рутина с API-триггером.

Попробуйте сами

10–15 мин на рабочем месте
  1. Выполните в своём проекте claude -p "перечисли скрипты из package.json и что делает каждый" --output-format json | jq -r '.result'. Потом добавьте --json-schema со схемой {"scripts": [{"name": "...", "purpose": "..."}]} и посмотрите на structured_output.
  2. Напишите скрипт из двух вызовов: первый анализирует диф текущей ветки и возвращает session_id, второй через --resume просит составить описание PR. Проверьте, что второй вызов помнит первый.
  3. Возьмите nightly-lint.sh, сократите список до одного тестового репозитория и запустите руками. Прочитайте отчёт и диф. Что бы вы изменили в запросе перед прогоном на всех проектах?

Коротко

  • claude -p "запрос" — Claude как обычная команда: читает stdin, печатает результат, возвращает код выхода.
  • Права задаются флагами: --allowedTools, --permission-mode, --max-turns; для CI — --bare и ANTHROPIC_API_KEY.
  • --output-format json даёт поле result и session_id; --json-schema — проверенную структуру в structured_output.
  • Цикл for repo in ...; do claude -p ...; done с узкими правами — рабочий шаблон для массовых операций; сначала на трёх проектах, потом на всех.
  • По расписанию: /loop в сессии, cron или Desktop на своей машине, рутины в облаке с триггерами по времени, API и событиям GitHub.

Видеоверсия

Сценарий озвучки · 595 слов, ≈ 5 мин

До сих пор мы работали в интерактивной сессии: вы пишете, Claude отвечает. Но многие задачи повторяются и не требуют человека у терминала: ночью прогнать линтер по всем проектам, обновить зависимости в двадцати репозиториях, разобрать вчерашние ошибки из мониторинга. В этом ролике разберём, как запускать Claude Code как обычную команду в скрипте и как ставить такие команды на расписание.

Флаг «пэ» переводит Claude Code в неинтерактивный режим: выполнил запрос, напечатал ответ, завершился. Механика та же — инструменты, агентный цикл, файл клод-эм-дэ, — только без диалога. И ведёт он себя как обычная команда: читает стандартный ввод, возвращает код выхода. Можно направить в него лог сборки и попросить объяснить ошибку. Можно поставить в скрипты пакета как линтер опечаток на дифе.

Спросить в таком режиме некого, поэтому всё, что потребовало бы подтверждения, отклоняется. Права задаются явно: флаг со списком разрешённых инструментов в том же синтаксисе, что в файле настроек; флаг режима — принятие правок, «не спрашивать» или авто; и ограничение числа ходов — страховка от бесконечного цикла.

Для скриптов и CI есть важный флаг — «бэр». По умолчанию неинтерактивный запуск загружает всё, что и обычная сессия: хуки, плагины, MCP-серверы, автопамять из домашней папки. В CI это плохо: результат зависит от того, чей ноутбук запустил скрипт, а чужой хук выполнится без вопросов. Флаг «бэр» отключает автообнаружение. Остаются базовые инструменты, а нужный контекст передаётся флагами. Нюанс: в этом режиме не работает вход по подписке, нужен ключ API в переменной окружения.

Вывод можно получить в трёх форматах. Текст — по умолчанию. Джейсон — один объект с полем «результат», идентификатором сессии и стоимостью; из него удобно вытаскивать нужное утилитой «джей-кью». И потоковый джейсон — по объекту на строку по мере генерации. Если нужна строгая структура, добавьте флаг со схемой — ответ придёт проверенным по схеме в отдельном поле. А идентификатор сессии позволяет продолжить разговор следующим вызовом: сначала анализ, потом уточнение, потом отчёт — всё из скрипта.

Теперь пример из практики. Двадцать клиентских репозиториев, каждую ночь — линтер и проверка типов, утром — список того, что сломалось, с исправлениями в отдельных ветках. Скрипт идёт по списку репозиториев. В каждом: обновить основную ветку, создать ветку с префиксом «клод» и датой, запустить Claude с флагом «бэр» и запросом: прогони линтер и типы, исправь ошибки, не меняя поведение и не добавляя «эни», в конце выведи одну строку — «ок» или «фейл» — и список файлов. Права — только линтер, проверка типов и просмотр дифа. Ограничение ходов — тридцать. Результат в джейсоне: первая строка ответа идёт в заголовок отчёта, остальное — в тело. Если есть изменения — коммит в локальную ветку. Ничего не отправляется наружу: утром человек смотрит дифы и решает сам. Документация советует сначала прогнать такое на двух-трёх проектах, поправить запрос и только потом на всех.

Скрипт есть, его надо запускать. Три способа. Первый — команда «луп» внутри сессии: повторяет запрос с интервалом, пока сессия открыта. Это для присмотра за пул-реквестом или деплоем, пока вы работаете; задачи истекают через семь дней. Второй — на своей машине: приложение Claude Desktop умеет запускать задачи по расписанию, а обычный «крон» с вашим скриптом делает то же самое. Машина должна быть включена. Третий — рутины в облаке. Рутина — это сохранённый запрос, репозитории и коннекторы, которые выполняются на инфраструктуре Anthropic без вашей машины. Создаётся на сайте или командой «шедул» в сессии. Триггеры трёх видов: расписание с минимальным интервалом в час, эйч-ти-ти-пи-запрос на эндпоинт рутины — для алертов из мониторинга, — и события GitHub, например открытый пул-реквест. Рутина работает автономно, без подтверждений, в свежем клоне, и всё делает от вашего имени. Поэтому сужайте ей доступ до необходимого. Функция в статусе исследовательского превью, лимиты смотрите в документации.

Итого: для ночного линтера — крон на сервере сборки или рутина, если проекты в GitHub и нужны пул-реквесты. Для присмотра за своим PR — «луп». Для реакции на алерт — рутина с API-триггером.

Отметка хранится только в вашем браузере