Как построить рабочую агентную автоматизацию
Как построить рабочую агентную автоматизацию
Пока AI ускоряет работу, человеку становится всё труднее услеживать за всем самому. В Anthropic эту задачу решают простые агентные автоматизации: они запускаются по расписанию, собирают контекст в фоне и сами сообщают, что важно. Но построить такую автоматизацию трудно — она может потерять доступ к источнику, и никто этого не заметит, или начать нарушать ваши правила.
Команда Anthropic показала эталонную реализацию на Claude Managed Agents (бета). Агент по расписанию читает свои источники (Slack и репозитории GitHub), запоминает, что изменилось с прошлого раза, и публикует короткую сводку. Код лежит тут: anthropics/claude-quickstarts — managed-agents/daily-brief. Ниже — разбор по частям.
Шесть компонентов
Вся система собирается из шести сущностей:
- Источники — именованный список мест, которые агент читает.
- Место назначения — одно место, куда агент может писать.
- Агент — модель, инструменты и шаги запуска в файле
agent.md. - Расписание — cron-выражение.
- Память — ваши настройки и собственная память агента.
- Ограничения — доступ только на чтение там, где агент только читает, и потолок расходов на один запуск.
Все настройки лежат в файлах. ant apply из CLI читает их, создаёт ресурсы в рабочем пространстве Claude API и записывает их идентификаторы в claude-lock.json:
daily-brief/
├── agent.md model, tools, instructions
├── deployment.md schedule, time zone, budget, input message
├── environment.yaml network allowlist
├── memory_store_preferences.yaml user preferences
├── memory_store_state.yaml the agent's bookmarks, ledger, notes, and run records
├── vault.yaml the vault that holds the credentials
├── claude-lock.json resource IDs, written by ant apply
└── slack/manifest.yaml one bot app
Когда всё настроено, автоматизация работает по расписанию на инфраструктуре Anthropic. На вашей машине ничего запускать не нужно.
Источники: отдельные права для агента
По умолчанию агент читает каналы Slack и pull request'ы GitHub. Список каналов и репозиториев лежит в файле настроек, шаблон можно расширить на другие источники.
Секреты живут в хранилищах (vaults). Агент может сослаться на учётные данные, но реальные значения остаются в хранилище — вне песочницы, где работает код Claude. Причём два пути работают по-разному:
- MCP-серверы (GitHub). Агент вызывает MCP-инструменты через прокси, который запущен вне песочницы. Прокси находит в хранилище учётные данные, чей URL совпадает с адресом сервера.
- Консоль (Slack). Агент обращается к API Slack через
curlинструментом bash прямо в песочнице. В песочнице лежит только безликая заглушка$SLACK_BOT_TOKEN. Когда запрос выходит из песочницы, платформа подставляет настоящий токен, но только для разрешённых хостов.
Хранилище создаётся одной командой, а учётные данные добавляются через TypeScript SDK:
const vaultId = process.env.VAULT_ID!; // the vault's ID, from claude-lock.json
await client.beta.vaults.credentials.create(vaultId, {
display_name: "SLACK_BOT_TOKEN",
auth: {
type: "environment_variable",
secret_name: "SLACK_BOT_TOKEN",
secret_value: process.env.SLACK_BOT_TOKEN!,
networking: { type: "limited", allowed_hosts: ["slack.com"] },
injection_location: { header: true },
},
});
Закладки вместо временного окна
Частая ошибка — просить агента прочитать «последние 24 часа». Если запуск опоздал, в сводке будет дыра, а если случился раньше — часть пунктов попадёт в неё повторно.
Правильный подход — закладка на каждый источник. В конце запуска агент записывает в файл bookmarks.json метку времени самого свежего прочитанного элемента:
{
"slack": "2026-09-14T13:02:11Z"
}
Следующий запуск начинает с этих отметок, поэтому его окно само растёт или сжимается и всегда покрывает всё, что появилось с прошлого раза. Закладки живут в хранилище памяти state — это папка с текстовыми файлами, которую платформа монтирует в каждый запуск по пути /mnt/memory/ и сохраняет между запусками. Агент читает и пишет её обычными файловыми инструментами.
Сбойное чтение не должно выглядеть как тихий день
Если MCP-сервер упал или истёк срок токена, запуск всё равно начнётся — просто без инструментов этого сервера. В журнале сессии появится ошибка, но агент не увидит ничего из этого источника и напишет, что «нового ничего нет».
Три правила в agent.md это чинят. Когда источник не читается, агент:
- не двигает его закладку;
- всё равно пишет сводку по остальным источникам;
- заканчивает сводку одной строкой о том, что именно он не смог прочитать — например,
pull requests unavailable this run.
Место назначения: одно место и подтверждение отправки
Шаблон публикует в один канал Slack, и каждый запуск добавляет датированный пост. Агент отправляет его через bash тем же токеном бота. Инструмент bash по умолчанию выполняется без запроса подтверждения, а slack.com внесён в белый список окружения агента. Отправка — это один запрос:
curl -s https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
-H "Content-Type: application/json; charset=utf-8" \
-d '{"channel": "C0123456789", "text": "Daily brief, Tue Sep 15 ..."}'
Дальше важно не испортить учёт. Запись считается отправленной только после подтверждения от Slack. Три правила не дают разойтись журналу и реальности:
- агент ищет сегодняшний заголовок среди последних сообщений канала и не публикует, если выпуск уже есть;
- пост считается отправленным, только если Slack вернул
"ok": trueи время сообщения; - журнал и закладки обновляются только после этого подтверждения.
Если результат непонятен, агент помечает запуск как «maybe posted» и больше ничего не меняет — так ничего не теряется. Сам запуск агент описывает в файле runs/<date>.md: сначала ставит «posting», потом — «posted» с идентификатором сообщения или «maybe posted».
Агент: модель, инструменты, восемь шагов
Агент в Claude Managed Agents — это конфигурация с версией: модель, системный промпт и инструменты. Каждый запуск идёт по заданным шагам и останавливается. В эталонной реализации это файл agent.md:
---
name: Daily brief
model: claude-sonnet-5-5
mcp_servers:
- type: url
name: github
url: https://api.githubcopilot.com/mcp/
tools:
- type: agent_toolset_20260401
configs:
- name: web_search
enabled: false
- name: web_fetch
enabled: false
- type: mcp_toolset
mcp_server_name: github
default_config:
permission_policy:
type: always_allow
---
Шапка задаёт имя, модель, инструменты и MCP-серверы, тело — инструкции. Инструменты MCP по умолчанию спрашивают подтверждения, а подтверждать некому, поэтому для GitHub-набора стоит always_allow, а сам токен — только для чтения.
Два шага из восьми отвечают за качество текста. Четвёртый — за краткость:
Пункт получает строку, если читатель сегодня что-то с ним сделает или если пункт меняет решение, которое он вот-вот примет. Если сомневаешься — не включай. Обычно это несколько пунктов, иногда ни одного. Счёт вроде «12 открытых ревью» пунктом не считается; ссылайся на те, что заблокированы. Пункт, который уже есть в журнале и всё ещё открыт, переносится как одна строка с пометкой «всё ждём, день 3», а не пересказывается заново; закрытый пункт просто убирается. Тему, которую файл настроек отправил в архив, не поднимай.
Пятый — за актуальность. Между чтением источников и публикацией мир успевает измениться, поэтому прямо перед отправкой агент перепроверяет живой статус каждого пункта: если вопрос решили — выбросить, если статус изменился — поправить строку, если подтвердить не удалось — тоже выбросить и записать в разбор запуска. Одно устаревшее «всё ещё ждём вас» стоит больше доверия, чем десять пропущенных пунктов. Статус пункта либо утверждается, либо пункт убирается — полутонов нет. Все ссылки копируются из поля ссылки самого источника (например, html_url у pull request или постоянная ссылка Slack), а не собираются вручную.
Расписание и часовой пояс
Сам агент — это только файл конфигурации. Его запускает развёртывание (deployment), которое называет агента, окружение и первое сообщение запуска, а также хранит расписание, хранилище секретов, хранилища памяти и бюджет. Каждый раз, когда расписание срабатывает, платформа начинает свежую сессию агента.
---
name: Daily brief
agent: ./agent.md
environment_id: ./environment.yaml
schedule:
type: cron
expression: "32 7 * * 1-5"
timezone: America/New_York
vault_ids: [vlt_...]
resources:
- path: ./memory_store_preferences.yaml
access: read_only
instructions: The reader's preferences. Re-read them every run. Never write here.
- path: ./memory_store_state.yaml
access: read_write
instructions: Your state. Bookmarks, ledger, notes, proposals, and run records.
---
Write today's brief.
The reader's time zone is America/New_York. Work out every date in that zone.
Создаётся это через ant apply deployment.md, а проверить работу, не дожидаясь расписания, можно вручную: ant beta:deployments run --deployment-id <id>, где <id> взят из claude-lock.json.
Типичная ошибка — агент называет сегодняшнее утро «вчера», потому что считает даты в часовом поясе сервера. Поле timezone задаёт момент запуска, а вторая строка тела сообщения говорит агенту, в какой зоне считать даты.
Память: два хранилища
Каждый запуск стартует в свежей песочнице без памяти о предыдущем, и без памяти обратная связь не закрепляется. Но устаревшая память тоже мешает: агент может назвать решённый пункт «всё ещё ждём» или выкинуть открытый, потому что «о нём уже сообщали». Поэтому в шаблоне два хранилища:
- preferences — ваше, для агента только на чтение: какие каналы и репозитории читать, что не включать, ограничение длины, место назначения и точка «стоп».
- state — агента, на чтение и запись: закладки, журнал того, что уже сообщали, запись по каждому запуску, предложенные изменения настроек и заметки о поведении источников (например, «возвращает только 50 новых элементов»).
Команда ant apply deployment.md создаёт хранилище preferences, но не файл внутри. Перед первым запуском запишите туда свой preferences.md через scripts/seed-preferences.sh.
Две привычки важнее остальных. Первая: не вшивайте копию настроек в промпт — агент продолжит применять правила, которые вы уже изменили. Пусть он читает файл заново каждый запуск, а если прочитать не смог — останавливается и говорит об этом, а не работает по умолчанию. Вторая: ведите журнал ledger.md по всем пунктам, о которых уже сообщали, чтобы сводка не повторялась. Одна строка — дата, источник, неизменный идентификатор (время сообщения Slack или номер pull request) и последний известный статус:
2026-09-09 slack:C0123456789 1788963600.000100 refund thread: customer waiting on a decision
2026-09-11 github 481 review blocked, day 2 (still waiting)
2026-09-11 slack:C0234567891 1789117333.000300 enterprise escalation: owner named, in progress
Ограничения: права и потолок расходов
Автоматизация работает в фоне, поэтому агента нужно ограничить и в правах, и в деньгах.
Агент читает сообщения и задачи, написанные другими людьми, а такой текст можно прочитать как инструкцию. Ограничивайте то, что агент сделал бы, если бы послушался. В примере токен GitHub и хранилище preferences доступны только на чтение, а окружение видит только хосты из своего белого списка. Подложенная инструкция всё ещё может изменить текст сводки, в том числе через заметки, которые агент хранит между запусками, — но не может ничего записать в GitHub и не может править вашими настройками. Исключение — Slack: там же токен ещё и пишет, поэтому бота стоит звать только в тех каналах, где он реально нужен.
Потолок расходов задаётся в deployment.md:
budget:
type: limit
max_list_cost:
amount: "500" # a string, in cents: S1 is $5.00
currency: USD
Начните с трёх-пяти стоимостей обычного запуска и ужимайте, когда увидите реальные цифры. Запуск, который упёрся в потолок, ставится на паузу, а не падает — поэтому слишком низкий лимит выглядит как сводка, которая просто перестала приходить. Причина остановки в этом случае — budget_reached.
Шесть правил и как начать
Эталонная реализация сводится к шести правилам:
- Читать каждый источник с закладки, а не по фиксированному временному окну.
- Сообщать о сбойном чтении как о недоступном источнике, а не как о тихом дне.
- Перепроверять каждый пункт прямо перед публикацией.
- Считать пост отправленным только после подтверждения Slack и лишь потом обновлять закладки и журнал.
- Перечитывать настройки каждый запуск из хранилища, которое агент не может редактировать.
- Давать доступ только на чтение там, где агент только читает, и ограничивать расходы каждого запуска.
Чтобы собрать такое у себя, сначала обновите Claude Code (claude update), а затем выполните в нём команду /claude-api managed-agents-onboard https://claude.dev/blog/building-effective-agent-automations/. Скилл прочитает эту статью, предложит конфигурацию, запишет файлы в папку agents/ вашего проекта и создаст ресурсы через ant apply. Это только отправная точка: источники, место назначения и настройки памяти стоит подстроить под себя.