Перейти к содержимому
arckep.ru — все нейросети в одном месте без VPN Перейти
>AISTUDY_
Поддержать
AUTHORСвежий выпуск №024 → Куда внедрять агентов: фронт или тыл
Авторская колонка · CLI в фоне без APIСЕРИЯ 020
Авторская колонка · выпуск №020

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

Как точечно гонять агента из подписки headless — не устроить абьюз и не снести сервер.

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

У многих 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 на любом объёме» — см. раздел про риски.

Схема 1Три режима: API, подписка, headless

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

Раздел 02

Headless: три слова, которые открывают дверь

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

Что нужноТипичный флагЗачем простыми словами
Один промпт → поток--print / -pБез меню и «продолжить?» — как curl, только агент
Не спрашивать--dangerously-skip-permissions / --yoloИначе процесс ждёт Enter, которого нет
Урезать shell--sandbox (где есть)Агент думает, терминал ограниченнее
Не висеть вечноtimeout 45 с … 20 минЕсли завис — убить процесс
Схема 2Пакет: print + skip + клетка

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

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

Не надо автоматизировать «всё». Риски аккаунта

Две разные опасности

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

Схема 3Два удара: диск и аккаунт
ОпасностьКого бьётСуть
Сервер и данныеваш продагент удалил, запушил, подключился к боевой БД
Аккаунт у провайдераподписка / OAuthрешили, что вы превратили Plus/Pro/Max в дешёвый programmatic API

Клетка на диске (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 на подписке — для редких, узких, своих задач.

Как выглядят «наши» задачи (точечно, не ферма)

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

Схема 4Пять точечных ролей, не ферма
ЗадачаЧастотаЧто делаетПочему не ферма
Черновик «что нового»по коммитамтолько читает → markdown6 ходов, read-only, в UI не пишет
SEO-чат в панеликогда спросилидиалог через официальный agylocalhost-bridge, не публичный API
Ночная аналитикараз в сутки (~05:30)3 разбора + синтезцифры уже посчитаны кодом
Арбитр банакнопка «это не я»JSON ≤45 снет записи в репо
Автофикс → PRпо реальной ошибкеправка в клонеPR без merge; человек вливает

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

Три вопроса перед кодом

Схема 5Стоп-фильтр перед spawn
  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, попытку не сжигают.

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

Схема 6Арбитр бана: узкий контур

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.

Схема 7Автофикс: клон, не live-прод
Раздел 05

Лестница безопасности

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

Схема 8Лестница клетки 0–7
Ур.Что делаетКогда хватает
0Только текст, tools выклКлассификация, отчёт по готовым цифрам
1Allowlist 2–4 read-only, лимит ходовЧерновики контента
2Флаг sandbox CLIАналитика, арбитр бана
3Отдельный user + HOMEЛюбой долгоживущий сервис
4Clone sandbox в /var/tmpАвтофикс кода
5Strip secrets / DATABASE*Любой запуск с тестами
6Systemd hardeningДемоны 24/7
7Нет auto-mergeВсё, что меняет код или прод-контент

Практика на тех же ролях: колокольчик → 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

Как это выглядит в голове сервиса

Схема 9Дирижёр и один такт CLI
Событие (кнопка / таймер / ошибка)
        │
        ▼
  Собрать контекст (логи, JSON, коммиты, пакет цифр)
        │
        ▼
  spawn CLI  (--print + skip-permissions [+ sandbox])
        │     cwd = sandbox или empty workspace
        │     env = без DATABASE, HOME = service
        │     timeout = 45s … 20min
        ▼
  stdout → распарсить (JSON / markdown / вердикт-блок)
        │
        ├── ошибка CLI → retry / 503 / алерт
        └── успех → действие узкое:
              разбан | черновик | отчёт | PR без merge

Сервис — дирижёр. 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 — руками. И ещё: не всё, что технически запускается, стоит запускать.

APPROVED · СЕРИЯ 020 · 2026-07-10
AUTHOR COLUMN · FOLDER №20 · HEADLESS CLI · NOT A FREE API · RU

// Обсуждение

Можно писать анонимно. Укажите email, чтобы получать уведомления об ответах.