Коротко
- Расписание — automation в постоянной сессии, шаги без модели — Lobster, учёт прогона — Task Flow, суждения — субагенты и llm-task со схемой.
- Человек одобряет только рискованное: чистые материалы уходят сами, спорные ждут решения в отдельном workflow.
- Честная граница: упавший шаг Lobster сам не перезапускается, таймеров в Task Flow нет, exactly-once нет, записи живут 7 дней.
Кому и когда
Вам нужен регулярный выпуск: дайджест для канала, лента новостей по нише, еженедельная сводка для команды. Источники известны, форма выпуска тоже, а читать всё руками вы больше не хотите.
Сборка подходит, если в пайплайне есть решения, которые не пишутся правилом: что из двадцати находок важно, как пересказать, нет ли в пересказе ошибки. Если решений нет и всё сводится к «скачать, отфильтровать, отправить», модель не нужна. Об этом в конце.
Всё ниже собрано по документации OpenClaw 2026.9.5. Команды и конфиги взяты из неё и собраны в одну схему; в живой инсталляции эту схему мы не прогоняли. Утилита newsroom в примерах — ваш собственный набор скриптов, как market-intel в примере из документации. Её подкоманды придуманы для иллюстрации.
Общая картина механизмов — во флагманской статье. Здесь собираем один конкретный пайплайн.
Схема потока
- Будильник. Automation (встроенный планировщик OpenClaw) по cron-выражению будит агента в именованной постоянной сессии.
- Сбор. Агент запускает Lobster-workflow (цепочку шагов-команд, которую Lobster выполняет за один вызов инструмента): проверка готовности → сбор с полями происхождения → дедупликация → отсев устаревшего → ранжирование.
- Текст. На каждую отобранную тему агент поднимает субагента (дочернюю сессию со своей задачей и, при желании, другой моделью).
- Проверка. Каждый текст проходит через llm-task (одиночный вызов модели, который обязан вернуть JSON по схеме) как судья, плюс скрипт сверяет числа с источником.
- Развилка. Чистые материалы уходят в workflow публикации без одобрения. Рискованные — в отдельный workflow с шагом
approval: required, он встаёт на паузу. - Отчёт. Итог прогона приходит в чат через announce (доставку финального ответа задания). Если делать было нечего, агент отвечает
NO_REPLYи в чат ничего не уходит.
Весь прогон отслеживается как Task Flow — долговечная запись о многошаговой работе с номером ревизии, которая переживает рестарт Gateway.
Из чего собрано
- Automations: расписание, сессии, доставка, контракт работы без присмотра.
- Task Flow, раздел «Reliable scheduled workflow pattern». Это готовый каркас нашей схемы в четыре слоя: automation для времени, постоянная сессия для контекста, Lobster для детерминированных шагов, Task Flow для учёта.
- Lobster: workflow-файлы, одобрения, resume.
- LLM Task: JSON-судья.
- Субагенты: тяжёлый шаг.
- Standing orders: полномочия агента в
AGENTS.md.
Шаги
1. Отдельный агент и его полномочия
Заведите пайплайну своего агента. Причин две: у него свой workspace, и по нему потом считается стоимость (раздел ниже).
Правила редакции запишите в его AGENTS.md как standing orders — постоянные поручения, которые агент загружает в каждую сессию. В документации каждая такая программа состоит из четырёх частей: что агенту разрешено, когда он действует, что требует одобрения, когда он останавливается и зовёт человека. Каркас:
## Программа: выпуск по расписанию
- Разрешено: собирать источники, писать тексты, публиковать чистые материалы.
- Триггер: automation «Редакция», три раза в день.
- Одобрение человека: смерть, криминал, обвинения реальных людей, медицинские советы,
материалы с одним источником, любые расхождения чисел с источником.
- Эскалация: preflight не прошёл, судья вернул ошибку, публикация упала.
- Правило: выполнить → проверить → отчитаться. «Готово» без проверки не считается.
2. Плагины
Lobster и llm-task — опциональные плагины. По документации Lobster ставится командой openclaw plugins install @openclaw/lobster. Оба инструмента добавляются агенту через tools.alsoAllow, llm-task дополнительно включается в plugins.entries. В sandbox-контексте, то есть когда инструменты агента работают в песочнице, Lobster отключён целиком. Режим с Task Flow требует и несандбоксного контекста, и привязанной сессии.
{
plugins: { entries: { "llm-task": { enabled: true } } },
agents: {
entries: {
newsroom: { tools: { alsoAllow: ["lobster", "llm-task"] } }
}
}
}
Фрагмент собран по tools/lobster.md и tools/llm-task.md. Для llm-task там же описан allowedCompletionModels — список моделей, которые судье разрешено вызывать.
3. Будильник
openclaw automations add \
--name "Редакция: выпуск" \
--agent newsroom \
--cron "0 7,13,19 * * *" \
--tz "Europe/Moscow" \
--session session:newsroom \
--timeout-seconds 1800 \
--announce \
--channel telegram \
--to "<id чата редактора>" \
--disabled \
--message "Выпуск по standing orders. Прогон без присмотра: итоговый ответ — отчёт о выпуске, а не план. Если новых тем нет, ответь ровно NO_REPLY. Спорные материалы не публикуй: запусти newsroom-publish-risky и включи в отчёт approvalId и превью. Отчёт по-русски."
Что здесь важно:
--tzобязателен. Без него cron-выражение считается по часовому поясу хоста Gateway.session:newsroom— постоянная именованная сессия: агент видит прошлые прогоны. Документация советует её, когда выпуск опирается на историю. Если каждый прогон должен начинаться с чистого листа, беритеisolated.- Контракт работы без присмотра документация формулирует для изолированных заданий: финальный ответ — результат, а не план или вопрос;
NO_REPLY, когда делать нечего; повторы — забота планировщика. Мы работаем в именованной сессии, поэтому повторяем этот контракт прямо в--message. - Язык отчёта планировщик не угадывает, его надо написать в сообщении.
--disabledсоздаёт задание выключенным. Сначала запустите его вручную (раздел «Как проверить»).
4. Сбор: workflow без модели
# workflows/newsroom-collect.lobster
name: newsroom-collect
steps:
- id: preflight
command: newsroom check --json
- id: harvest
command: newsroom harvest --json
stdin: $preflight.json
- id: dedup
command: newsroom dedup --by url,title --json
stdin: $harvest.json
- id: fresh
command: newsroom drop-stale --max-age 48h --json
stdin: $dedup.json
- id: rank
command: newsroom rank --top 5 --json
stdin: $fresh.json
В шаге preflight (проверка готовности перед запуском) документация советует проверять ключи и квоты источников, сеть, включённые инструменты агента и то, что у задания есть куда слать ошибки. Каждая запись после harvest несёт поля происхождения из того же раздела документации:
{
"sourceUrl": "https://example.com/report",
"retrievedAt": "2026-09-28T04:00:00Z",
"asOf": "2026-09-27",
"title": "…",
"content": "…"
}
sourceUrl — откуда взято, retrievedAt — когда скачано, asOf — на какую дату верны данные. По asOf шаг fresh выкидывает старьё до того, как его увидит модель.
Дедупликацию делайте по нормализованному адресу и заголовку, а не только по id записи в источнике. Иначе одна история из трёх лент превращается в три темы. Публичный openclaw-newsroom дедуплицирует как раз по URL и заголовку, в SQLite между прогонами.
Агент вызывает workflow в управляемом режиме Task Flow:
{
"action": "run",
"pipeline": "workflows/newsroom-collect.lobster",
"timeoutMs": 120000,
"flowControllerId": "newsroom",
"flowGoal": "Выпуск 07:00"
}
По умолчанию timeoutMs — 20 секунд, для сбора из сети этого мало. Вывод шага ограничен 512 000 байт (maxStdoutBytes), поэтому тексты статей лучше держать в файлах, а по конвейеру гнать ссылки на них.
5. Текст: субагенты
На каждую тему из rank агент вызывает sessions_spawn. Задание субагенту: входной JSON темы и требование сохранить в выходе sourceUrl, retrievedAt и asOf. Параметр model позволяет писать на одной модели, а судить на другой. runTimeoutSeconds не даст субагенту висеть вечно. Опрашивать детей в цикле не надо: результаты приходят событиями.
Для изолированных заданий документация обещает, что при работе с субагентами announce берёт итоговый ответ, а промежуточные сообщения родителя подавляет. Для именованной сессии это прямо не сказано, поэтому пропишите в --message: промежуточных сообщений не слать, только итоговый отчёт.
6. Проверка: судья со схемой
Документация Task Flow советует llm-task для шага модели со схемой. Но в tools/lobster.md прямо написано: вызов llm-task изнутри встроенного Lobster через openclaw.invoke сейчас ненадёжен. Поэтому судью агент вызывает сам, как обычный инструмент, между двумя workflow:
{
"prompt": "Сверь текст с источниками. Каждое утверждение: есть ли оно в источнике. Верни JSON.",
"input": { "draft": "…", "sources": [ { "sourceUrl": "…", "content": "…" } ] },
"schema": {
"type": "object",
"properties": {
"verdict": { "enum": ["clean", "risky", "reject"] },
"unsupported": { "type": "array", "items": { "type": "string" } },
"reasons": { "type": "array", "items": { "type": "string" } }
},
"required": ["verdict", "unsupported", "reasons"],
"additionalProperties": false
},
"timeoutMs": 60000
}
Судья работает без транскрипта агента, без инструментов и без запасной модели. Ответ обязан пройти схему. Если вызов вернул ошибку, считайте материал отклонённым, а не чистым. Документация велит считать вывод недоверенным без схемы и ставить одобрение перед любым шагом с побочным эффектом.
Числа сверяйте кодом, а не судьёй: скрипт вытаскивает цифры из текста и ищет их в content источника. Любое расхождение — risky.
И предупреждение про стиль-линтер. Механические правила вроде «не больше N слов в предложении» режут хорошие тексты. Пусть линтер помечает, а решает судья или человек.
7. Публикация: две дорожки
# workflows/newsroom-publish.lobster — чистые материалы, без одобрения
name: newsroom-publish
args:
batch:
default: "var/clean.json"
steps:
- id: publish
command: newsroom publish --from "$LOBSTER_ARG_BATCH" --json
# workflows/newsroom-publish-risky.lobster — только спорное
name: newsroom-publish-risky
args:
batch:
default: "var/risky.json"
steps:
- id: preview
command: newsroom publish --from "$LOBSTER_ARG_BATCH" --preview --json
approval: required
- id: publish
command: newsroom publish --from "$LOBSTER_ARG_BATCH" --json
condition: $preview.approved
Аргументы workflow Lobster передаёт в шаги переменными LOBSTER_ARG_<ИМЯ>. Второй файл агент запускает, только если судья вернул хоть один risky. Workflow встаёт на паузу со статусом needs_approval и отдаёт approvalId, а Task Flow записывает паузу как waiting.
Где человек
Только на спорном. Чистые материалы выходят без вас: так записано в standing orders, и так устроены два workflow.
Спорное приходит в отчёте прогона: превью и approvalId, короткий номер паузы, по которому вы понимаете, о каком материале речь. Ваше «да» или «нет» должно попасть к агенту в сессию session:newsroom. Как именно его туда доставить, документация не расписывает: это ваша часть сборки. Получив решение, агент вызывает resume у Lobster с flowId, текущей ревизией flowExpectedRevision и approve. В управляемом режиме Task Flow токен и approvalId можно не передавать: сохранённую точку паузы OpenClaw восстановит из самого flow. Ранние шаги при этом не повторяются.
Две оговорки из документации:
- Одобрение workflow — не слушатель ответов в мессенджере. «Да» в канале доставки само ничего не возобновит, это должен сделать агент в сессии.
- Не путайте с exec approvals — одобрениями отдельных shell-команд. Если прогон по расписанию упрётся в такое одобрение, запрос уйдёт только в Control UI и приложения, в чат-каналы он не приходит никогда. Если ни один такой клиент не подключён, запрос сразу отклоняется. Кнопка «Always allow» выдаёт постоянный грант, привязанный к агенту, заданию и команде; список —
openclaw approvals grants list.
Сколько стоит и как посчитать
Цифр за вас не назовём: стоимость зависит от моделей, числа источников и длины текстов. Посчитать можно встроенными средствами.
- Отдельный агент (шаг 1) даёт отдельную строку в учёте.
- Неделю пусть пайплайн работает, потом:
openclaw gateway usage-cost --agent newsroom --days 7
Команда собирает сводку из логов сессий. Если провайдер вернул токены без суммы, OpenClaw оценивает стоимость по ценам из локального models.json агента. Проверьте, что цены там заполнены, иначе оценка будет неполной.
- В чате с агентом есть
/usage cost— локальная сводка по логам сессий. Квоты провайдеров показываетopenclaw status --usage.
Как снижать. Документация советует рутинные задачи — отбор, классификацию — отдавать лёгкой модели через --model, а тяжёлую держать на написание. --fallbacks позволяет поднять задачу на модель посильнее, если лёгкая упала. Сбор, дедупликация и публикация в Lobster не тратят токенов вовсе.
Для ориентира — чужой опыт. Автор openclaw-newsroom оценивает свой пайплайн примерно в $5 в месяц: API Gemini Flash Lite плюс бесплатный тариф поискового сервиса Tavily. Но у него модель выбирает до семи историй из собранного и пишет к каждой аннотацию в одно предложение. Полные тексты с проверкой обойдутся дороже. Сколько — покажет usage-cost через неделю.
Жёсткого потолка расходов в этой схеме нет. Нужен лимит — ставьте его на стороне провайдера или прокси.
Как проверить, что работает
openclaw automations list
openclaw automations run <jobId> --wait # код 0 только при completionStatus: succeeded
openclaw automations runs <jobId> --limit 20
openclaw tasks flow list
openclaw tasks flow show <flowId>
openclaw tasks audit # зависшие и сломанные задачи и flow
В истории прогонов status показывает исполнение, completionStatus — прогон целиком, вместе с доставкой. Прогон с NO_REPLY пишется как успешный и с причиной подавления доставки: так видно, что агент молчал намеренно.
Когда всё сходится, openclaw automations enable <jobId>.
Как поставить на паузу и откатить
- Пауза пайплайна:
openclaw automations disable <jobId>. - Остановить застрявший прогон:
openclaw tasks flow cancel <flowId>. - Отозвать выданный грант:
openclaw approvals grants revoke <id>. - Выключить все automations на Gateway:
cron.enabled: falseв конфиге или переменнаяOPENCLAW_SKIP_CRON=1. - Откат опубликованного — забота вашего
newsroom publish. OpenClaw не отменяет побочные эффекты, которые уже случились. Делайте публикацию через выпуски и переключение ссылки, тогда откат — одно переключение.
Что ломается и когда брать другой инструмент
Что говорит сама документация:
- Шаг Lobster не повторяется. Если вызов упал или истёк после отправки, Lobster его не повторит: Gateway мог успеть выполнить действие. Повтор — решение агента или ваше.
- Task Flow хранит записи, а не время. Состояние ожидания не заводит таймер. Одобрение, которое никто не дал, будет висеть. После рестарта flow надо явно поднять и продолжить с текущей ревизией.
- Exactly-once нет. Announce повторяет отправку, только если до получателя точно ничего не дошло. Доставку со статусом
unknownне пересылают, чтобы не дублировать. Публикация вnewsroomдолжна быть идемпотентной: повторный запуск с тем же материалом не создаёт второй. - Сроки хранения. Законченные flow и записи задач живут 7 дней, история прогонов automations — тоже 7 дней и не больше 2000 строк на задание. Нужен архив выпусков — пишите его сами.
- Gateway должен работать. Расписания живут в его процессе. Слоты, пропущенные, пока Gateway лежал, по умолчанию догоняются при старте;
cron.skipMissedJobs: trueих пропускает. - Автоотключение. После 10 падений подряд задание выключается само. Оповещение об ошибках по умолчанию приходит после 2 падений подряд, не чаще раза в час, в тот же канал announce.
- Бюджет времени. Без
--timeout-secondsизолированные прогоны ограничены часовым сторожем планировщика. Ставьте таймаут явно, как в шаге 3.
Когда брать другое:
- Temporal — если нужен replay по истории событий и гарантия, что workflow дойдёт до конца ровно один раз. Например, когда публикация — это деньги или юридически значимое действие.
- n8n — если граф фиксирован, модель нужна в одном узле, а основная работа — коннекторы к сервисам.
- systemd-таймер и скрипт — если модели в пайплайне нет вовсе: скачать, отфильтровать правилом, выложить. Если такой скрипт всё же зовёт
openclaw agent, документация советуетtimeout -k 60 600 openclaw agent …илиTimeoutStopSecв юните.
OpenClaw здесь оправдан, пока суть пайплайна в суждениях: что важно, как сказать, где соврал черновик. Детерминированную обвязку он держит достаточно, чтобы суждения работали по расписанию.