CLI-агент в фоне без API

от автора

Как точечно гонять агента из подписки headless — не устроить абьюз и не снести сервер.
Точечные воркеры из подписки CLI — без превращения аккаунта в дешёвый «безлимитный API» и без сноса продакшена. Механика и числа с реального сервера; имена проектов убраны.

01 ДВА СЧЁТА
API против подписки CLI
02 HEADLESS
три флага, которые открывают дверь
03 РИСКИ
не всё автоматизировать; ToS
04 ПЯТЬ РОЛЕЙ
точечные воркеры на проде
05 ЛЕСТНИЦА
клетка от 0 до 7
06 ГРАБЛИ
что уже ломалось
07 СХЕМА СЕРВИСА
дирижёр и один такт
08 КОПИПАСТ
чеклист и промпты
09 ВЫВОД
формула с прода

У многих AI-инструментов есть два способа оплаты. Первый — API: каждый запрос считается в токенах, счёт растёт с каждым вызовом. Второй — подписка на CLI(программа в терминале: Claude Code, Antigravity, Grok CLI и похожие). Платишь фиксировано, сидишь в терминале, агент читает файлы и правит код.

Проблема: подписка обычно заточена под человека за клавиатурой. А на сервере иногда нужны короткие задачи без диалога: запустил → получил ответ → вышел. Такой режим называют headless (без «головы», без интерактивного экрана): агент работает как скрипт, а не как собеседник.

Отсюда соблазн: «подписка уже оплачена — накрутим на неё всё подряд». Так делать не надо. У провайдеров в правилах (ToS — условия использования) подписка почти всегда про человека и официальный продукт, а не про то, чтобы заменить собой платный API для ботов и массовых скриптов. Нарушение бьёт по аккаунту: 403, suspension, иногда перманентный бан. Параллельно есть второй риск — агент с shell на сервере сносит файлы, если нет клетки.

Этот выпуск — не рецепт «как бесплатно прокачать тысячи запросов». Это разбор осторожных, узких воркеров: тексты для «что нового», SEO-чат по кнопке, ночной отчёт раз в сутки, арбитраж ложного бана, автофикс с pull request без авто-мержа. Сначала — где граница здравого смысла и правила провайдеров, потом — как запускать и как держать в клетке.

РАЗДЕЛ 01

ДВА СЧЁТА ЗА ОДИН МОЗГ

Задача. Нужен ИИ в автоматике: не чат в браузере, а ответ по запросу сервиса.

Почему это важно. API удобен для встраивания, но каждый вызов — отдельная строка в биллинге. Подписка CLI уже оплачена; дублировать её pay-per-token бессмысленно, если модель та же и задача узкая.

Как. Сервис (бэкенд, systemd-демон, cron) в узких случаях не ходит в HTTP API вендора, а запускает официальный CLI-процесс с флагами «один промпт → ответ в stdout». Авторизация — как у интерактивной сессии (OAuth / login CLI), credentials — в отдельном HOME служебного пользователя.

Итог. Модель та же, что в терминале. Меняется оболочка: скрипт с таймаутом вместо человека. Это не означает «подписка = замена API на любом объёме» — см. раздел про риски.

Простая аналогия: API — такси по счётчику, когда поездок много и маршрут чужой. Подписка CLI — свой автомобиль для своих коротких поездок. Headless — автопилот на заранее прописанном маршруте: без тормозов и без прав на дорогу (ToS) заканчивается аварией.

РАЗДЕЛ 02

HEADLESS: ТРИ СЛОВА, КОТОРЫЕ ОТКРЫВАЮТ ДВЕРЬ

Почти у всех CLI один и тот же каркас:

Без «пропустить подтверждения» headless не работает: агент честно ждёт человека. С «пропустить подтверждения» без клетки headless опасен: агент может выполнить rmgit push --force, остановить сервис.

ПРАВИЛОSkip-permissions и sandbox (или эквивалент) продаются пакетом. Одно без другого — либо мёртвый воркер, либо бомба с таймером.

РАЗДЕЛ 03

НЕ НАДО АВТОМАТИЗИРОВАТЬ «ВСЁ». РИСКИ АККАУНТА

ДВЕ РАЗНЫЕ ОПАСНОСТИ

Говоря «безопасно», часто смешивают две вещи.

Клетка на диске (sandbox, non-root, clone) не защищает от второго. Даже идеальный systemd не отменяет ToS. И наоборот: «мы вроде в рамках правил» не отменяет rm -rf, если skip-permissions без ограничений.

ЧТО ПРОВАЙДЕРЫ ЯВНО НЕ ЛЮБЯТ

Картина на 2026 год (отчёты пользователей, обсуждения, заявления в docs/форумах; это не юридическая консультация — перед боем читайте актуальный ToS своего тарифа):

  • Anthropic (Claude Pro/Max). Жёстко режут OAuth-токен подписки в чужих CLI и обвязках (OpenClaw, OpenCode и аналоги). Подписка — для официальных продуктов (в т.ч. Claude Code / claude.ai); программный доступ «сбоку» — через API. Официальный headless (claude -p) обычно часть продукта; «выдернули токен и крутим как API» — высокий риск бана.

  • Google (Gemini / Antigravity). В начале 2026 были массовые 403 ToS Violation у тех, кто гонял подписку через third-party harnesses. Официально: запрет harvest / piggyback on OAuth — «подоить» авторизацию чужим инструментом. Часть аккаунтов разбанивали с recertification; повтор — путь к перманентному бану. Официальный agy / Gemini CLI — другой разговор, чем «чужой бот на вашем OAuth».

  • OpenAI (ChatGPT Plus/Pro). Риск ниже «сразу за любой скрипт», выше за heavy automation: тысячи запросов, spam-like паттерны. Официальный Codex CLI на подписке — штатный путь.

  • xAI (Grok / SuperGrok). Официально поддерживают headless в Grok Build CLI (grok -p) под скрипты на подписке — заявленный путь, не обход. Злоупотребление volume всё равно упрётся в лимиты продукта.

Общий смысл: подписка — не безлимитный API для фермы ботов. Если картина снаружи выглядит как «тысячи дешёвых токенов в обход API» — ждут детекты и баны.

ЧЕГО НЕ СТОИТ ДЕЛАТЬ

  • Не превращать один Max/Pro в бэкенд для публичного SaaS (чужие пользователи жрут ваш OAuth).

  • Не гонять тысячи однотипных запросов в сутки «потому что подписка безлимит».

  • Не тащить third-party harness, который подставляет OAuth вместо официального бинаря — зона массовых банов 2026.

  • Не обходить антифрод fingerprint’ами и «антидетектом» — это уже осознанный обход.

  • Не автоматизировать критичные деньги и доступы без человека: выплаты, массовый разбан, деплой в main, смена секретов.

Если нужен стабильный поток «как у API» — платите за API. Headless на подписке — для редких, узких, своих задач.

КАК ВЫГЛЯДЯТ «НАШИ» ЗАДАЧИ (ТОЧЕЧНО, НЕ ФЕРМА)

Ниже — не оправдание «можно всё», а калибр: маленький радиус поражения и низкая частота.

Общий рисунок: событие → один (или несколько) коротких вызовов → узкий артефакт. Не цикл «пока квота не кончится». Не витрина «бесплатный Claude для клиентов».

ТРИ ВОПРОСА ПЕРЕД КОДОМ

  1. Это официальный CLI провайдера (или его заявленный headless) — или чужая обёртка на OAuth?

  2. Частота — раз в день / по кнопке / по ошибке, или «тысячи в час»?

  3. Выход — черновик/вердикт/PR, или «сразу в прод и к клиентам»?

Два «нет» или одно «тысячи / публичный SaaS» — не headless на подписке, а API.

РАЗДЕЛ 04

ПЯТЬ РОЛЕЙ, ОДИН ПРИЁМ

На одном железе одновременно живут разные headless-воркеры. Общее — spawn официального CLI. Разница — насколько жёсткая клетка и что агенту разрешено менять.

4.1. ЧЕРНОВИК «ЧТО НОВОГО» (ТОЛЬКО ЧТЕНИЕ)

Задача. Из коммитов сделать человеческие карточки для колокольчика обновлений: без жаргона, без внутренних id.

Почему. Коммиты пишут разработчики и агенты. Пользователю нужно «появилась озвучка», а не feat(tts): wire clone voices.

Как. Скрипт берёт коммиты только с прошлого успешного запуска (курсор в state-файле). Shell отбрасывает шум (deploy, deps, sentry…). Дальше Grok CLI headless: --yolo, не больше 6 ходов, инструменты только чтение (файлы, поиск, список каталогов), прокси вычищены. Результат — markdown-черновик. В прод-список обновлений агент не пишет.

Итог. LLM переписывает смысл; человек решает, что попадёт в UI. Цена ошибки — плохой черновик, не сломанный сайт.

4.2. SEO-ЧАТ В ПАНЕЛИ АНАЛИТИКИ

Задача. В дашборде спросить про запросы и семантику — с доступом к Wordstat (частотность Яндекса).

Почему. Чистый API без tools не «знает» Wordstat. CLI с MCP (подключаемый инструмент) может вызвать его.

Как. Маленький bridge на localhost: POST → spawn Antigravity (agy) с --print и skip-permissions. HOME и workspace отдельные. --sandbox выключен, потому что Wordstat MCP ходит наружу по HTTPS. Компенсация: bridge только на 127.0.0.1, не торчит в интернет.

Итог. Подписка Gemini через Antigravity закрывает SEO-чат без отдельного API-ключа в приложении. Цена — skip-permissions + сеть MCP.

4.3. НОЧНОЙ ОТЧЁТ ПО АНАЛИТИКЕ

Задача. Раз в сутки разобрать цифры продукта и отправить сжатый отчёт в Telegram.

Почему. Человек не обязан каждую ночь открывать дашборд. Но модель не должна сама считать — она врёт в арифметике.

Как. Сначала скрипт детерминированно собирает пакет чисел. Потом веер из трёх модулей Antigravity: --print --sandbox --dangerously-skip-permissions, Gemini 3.5 Flash (High), пустой workspace, таймаут модуля порядка 9 минут. Синтез — Claude CLI (Opus, max thinking). Второе мнение — короткий DeepSeek по API (pay-per-token на маленьком объёме). В БД — только цельный отчёт.

Итог. Подписочные CLI интерпретируют; цифры — из кода.

4.4. АРБИТР ЛОЖНЫХ БАНОВ

Задача. Система безопасности банит IP. Иногда это обычный пользователь. Нужен разбор: false positive или реальная атака.

Почему. Четыре часа бана = потерянный клиент. Авторазбан всего = открытая дверь сканерам.

Как. Страница «это не я» → JSON (решения бана, кусок access-лога) →

agy --sandbox --print "<промпт + JSON>"

Таймаут 45 секунд. Ответ — строго JSON: false_positive или real_attack. Отдельный системный пользователь (не root), credentials 700/600, systemd: ProtectSystem=strict, ProtectHome=true, PrivateTmp=true. Если CLI упал — 503, попытку не сжигают.

Итог. Только классификация. Самый узкий радиус поражения из пятёрки.

4.5. АВТОФИКС ОШИБОК → PULL REQUEST

Задача. Поймать продовую ошибку, понять «баг / шум / инфра / нужен человек», при реальном баге — правка и PR без авто-мержа.

Почему. Ночной on-call без человека. Но агент, который мержит сам, опаснее ошибки, которую чинит.

Как (общие принципы).

  1. Не live-дерево прод-репо. Полный git clone в каталог под /var/tmp/... (не /tmp: часто RAM; клоны забивают tmpfs).

  2. Из env вырезают переменные с DATABASE, чтобы тесты не подключились к боевой базе.

  3. Промпт запрещает commit/push; контроль — снаружи.

  4. Вердикт в машинном блоке stdout — сервис решает, открывать ли PR.

Реализация A — Antigravity в служебной панели (поток Sentry). agy --print --dangerously-skip-permissions в клоне. Вердикты: real_bug / noise / infra / needs_human. PR только на real_bug.

Реализация B — официальный CLI DeepSeek V4 (deepcode) для демона автофикса.Триаж DeepSeek V4 Flash; фикс — deepcode + DeepSeek V4 Pro. Нюансы: deepcode требует TTY → pseudo-TTY (script); сам не выходит → маркер status: completed + kill; запасной таймаут 20 минут; в промпте запрет commit/push/PR.

Итог. Два CLI, одна философия: изолированный клон + вырезанные секреты + человек на merge.

РАЗДЕЛ 05

ЛЕСТНИЦА БЕЗОПАСНОСТИ

Не «включите sandbox и спите спокойно», а набор слоёв. Чем шире права агента, тем больше слоёв.

Практика на тех же ролях: колокольчик → 1+7; SEO → 3, без 2 (MCP); ночь → 0+2+3; арбитр → 0+2+3+6+короткий timeout; автофикс → 3…7.

CLI, установленный «на всю систему», не значит «процесс = root». Бинарь может быть в /usr/local/bin, процесс — под служебным пользователем. Credentials — в home сервиса (700), не session разработчика.

РАЗДЕЛ 06

ГРАБЛИ, КОТОРЫЕ НЕ ВЫДУМАНЫ

  1. Skip-permissions без RW-ограничений. Агент с full shell и env root = разработчик root без тормозов.

  2. ProtectHome=true и бинарь в /root/… Сервис не стартует (203/EXEC). Лечится: ProtectHome=read-only + ReadWritePaths для кэша CLI, либо бинари вне home.

  3. /tmp для клонов. Часто RAM. Песочницы — /var/tmp/... на диске.

  4. DATABASE в env родителя. Перед spawn вырезать ключи с DATABASE (и write-DSN).

  5. CLI, который «не умеет headless». Требовал TTY и не выходил → pseudo-TTY + маркер + SIGKILL.

  6. Sandbox vs MCP. Нужен внешний API — sandbox может мешать. Честно: sandbox выкл + localhost + отдельный user.

  7. Авто-merge. PR always, merge never automatic.

  8. «Подписка = бесплатный API для всего продукта». Публичный endpoint + высокая частота + third-party = бан. См. раздел 03.

РАЗДЕЛ 07

КАК ЭТО ВЫГЛЯДИТ В ГОЛОВЕ СЕРВИСА

Сервис — дирижёр. CLI — музыкант на один такт. Без метронома (timeout) и сцены (sandbox) палочку на ночь не отдают.

РАЗДЕЛ 08

ЧТО СКОПИРОВАТЬ СЕБЕ

В копируемых блоках ниже длинные тире заменены на запятые и двоеточия — удобнее в рабочих markdown-файлах. В тексте статьи тире обычные.

P01 ЧЕКЛИСТ ПЕРЕД ПЕРВЫМ HEADLESS-ВОРКЕРОМ

Чеклист headless CLI-воркера0) СТОП-фильтр ToS (если хоть один пункт "да" — бери API, не подписку):   - это публичный сервис для чужих пользователей на моём OAuth?   - ожидаются сотни/тысячи запросов в сутки без человека?   - кручу third-party CLI/harness вместо официального бинаря провайдера?   - цель: заменить платный API "дешёвой" подпиской на потоке?1) Задача точечная: по кнопке / по ошибке / раз в день, узкий выход (черновик, JSON, PR).2) Официальный CLI провайдера + его headless-флаги. Не "выдернуть токен в свой HTTP".3) Режим: один промпт, ответ в stdout (--print / -p).4) Без интерактива: skip-permissions или yolo. Рядом обязательно клетка.5) Отдельный OS-user или отдельный HOME с credentials (права 700/600).6) Рабочая директория: empty workspace ИЛИ git clone в /var/tmp/..., никогда live prod tree.7) Env: вырезать DATABASE* и лишние секреты; в логах маскировать токены.8) Tools: allowlist по минимуму. Если только текст, tools не давать.9) Timeout + kill. Если CLI не выходит сам, ловить маркер завершения.10) Успех узкий: черновик / JSON-вердикт / PR. Никакого auto-merge и auto-deploy.11) Systemd: ProtectSystem=strict, PrivateTmp, ReadWritePaths только state+sandbox.12) Мониторинг: journald, алерт на ненулевой exit, метрика "завис дольше N".13) Документ компромиссов: где sandbox выключен и почему (например MCP наружу).14) Прочитал актуальный ToS/docs тарифа (правила меняются; 2026 уже показал волны банов).

P02 КЛАССИФИКАТОР (УЗКИЙ BLAST RADIUS)

Ты классификатор. Тебе дают факты в JSON. Инструменты для записи файлов не используй.Верни ТОЛЬКО JSON одного вида:{"verdict":"false_positive|real_attack","reason":"одна-две фразы по-русски"}Не чини системы. Не предлагай команды. Не выходи за verdict/reason.Факты:<вставить JSON>

P03 ФИКС В КЛОНЕ (С ВОРОТАМИ)

Ты в ИЗОЛИРОВАННОМ клоне репозитория. Текущая папка: корень клона.Задача: минимально починить ТОЛЬКО описанную ошибку.Правила:- Никакого рефакторинга "заодно".- Не трогай миграции, .env, секреты без прямой связи с ошибкой.- НЕ делай git commit, git push, PR: только правки файлов. Коммит сделает обёртка.- В конце выведи блок:<<<VERDICT>>>{"verdict":"real_bug|noise|infra|needs_human","summary":"2-4 предложения по-русски для не-разработчика"}<<<END>>>Ошибка:<вставить>

P04 АУДИТ УЖЕ ЗАПУЩЕННОГО CLI-СЕРВИСА

Проверь headless CLI-воркер на этом сервере.Найди unit systemd / cron / bridge, команду spawn, user, HOME, cwd, флаги CLI,timeout, куда пишет, есть ли auto-merge/deploy.Выдай таблицу:слой | есть/нет | доказательство (файл/строка unit) | риск если нетСлои: non-root, sandbox/allowlist, clone not live tree, strip DATABASE,timeout kill, no auto-merge, credentials 600, listen localhost only.Не чини, пока не попросим. Только отчёт.

РАЗДЕЛ 09

ЧТО ИЗ ЭТОГО СЛЕДУЕТ

Headless CLI — не «хак вместо API» и не лицензия автоматизировать всё подряд. Это тот же агент, что в терминале, иногда встроенный в прод как короткий точечный worker. Экономия на API имеет смысл только там, где официальный CLI уместен, частота низкая, а выход узкий. Цена ошибки двойная: shell на диске и бан аккаунта.

Рабочая формула:

  1. Сначала ToS и калибр — официальный CLI, не ферма, не публичный SaaS на личном OAuth. Сомневаешься — API.

  2. --print + skip-permissions — чтобы работало без человека.

  3. Клетка по размеру задачи — от allowlist tools до clone + systemd + non-root.

  4. Узкий выход — JSON, черновик, PR; никогда «делай что хочешь с продом».

  5. Человек на необратимом — merge, деплой, разбан при сомнении.

«CLI стоит в системе» ≠ «процесс = root». Бинарь общий, процесс — служебный, home — свой, sandbox — на диске, merge — руками. И ещё: не всё, что технически запускается, стоит запускать.

ссылка на оригинал статьи https://habr.com/ru/articles/1059454/