Agent Automation
Agent Automation 指无人值守、按调度定时运行的后台 Agent 自动化:没有人发消息触发它,而是由 cron 之类的调度周期性唤醒,从一组固定来源(Slack 频道、GitHub 仓库等)读取自上次运行以来的变化,把"你需要知道的事"投递到一个目的地(如一个 Slack 频道)。这个词目前主要来自 Anthropic 的工程语境(其文章《Building Effective Agent Automations》与 Claude Managed Agents 的 daily-brief 参考实现),尚不算完全标准化的行业术语,但对应的实践形态——定时摘要、巡检通知、后台值守——已经在各家托管 Agent 平台普遍出现(参见 Agents API)。
与交互式 Agent 相比,它的根本差异是没人盯着:MCP 工具要权限审批时没人批,来源挂了没人发现,post 失败没人重试,成本失控没人喊停。所以它的工程重点不在模型能力,而在把"读增量、报失败、确认送达、管住花钱"做成确定性规则写进 run steps。
六个组件
Anthropic 的参考实现把一个定时自动化拆成六个组件:
| 组件 | 内容 | 关键设计 |
|---|---|---|
| Sources | 命名的读取来源列表 | 只读;经 MCP 代理或 HTTPS 访问,凭证放 vault 不进沙箱 |
| Destination | 唯一可写的投递目的地 | 一个 Slack 频道;投递成功前不改任何状态 |
| Agent | 模型 + 系统 prompt + 工具的版本化配置 | agent.md 里写 run steps 和判断规则 |
| Schedule | cron 调度 | deployment.md 声明调度、时区与每轮首条消息 |
| Memory | preferences(用户只读)+ state(Agent 读写) | 书签、账本、运行记录都在 state |
| Guardrails | 能做什么、能花多少 | 只读权限、网络 allowlist、每轮预算上限 |
flowchart LR
S["Schedule(cron)"] --> A["Agent(沙箱内运行)"]
A -->|"读增量(书签→本轮窗口)"| SRC["Sources
Slack / GitHub 等"]
A -->|"确认送达后投递"| D["Destination
Slack 频道"]
MEM["Memory
preferences(只读)+ state(读写)"] <--> A
G["Guardrails
只读权限 · allowlist · 预算"] -.->|约束| A
在 Claude Managed Agents 上,Agent 只是配置文件(agent.md、deployment.md、environment.yaml、记忆 store 与 vault 的 YAML),ant apply 命令把资源创建到平台侧,之后调度运行完全在 Anthropic 基础设施上,本地不需要任何常驻进程。每轮调度触发都会开一个全新 session、全新沙箱。
增量读取:书签,不是固定时间窗口
最常见的错误是让 Agent 读"最近 24 小时":跑晚了留缺口,跑早了重复报。正确做法是给每个来源维护一个书签(bookmark)——每轮结束时把该来源读到的最新条目时间戳写进 bookmarks.json,下一轮从书签开始读。窗口随两次运行的实际间隔伸缩,天然覆盖"跑晚了的缺口",也不重复。
失败的读取 ≠ 安静的一天
如果某来源的 MCP server 挂了或 token 过期,run 仍会启动,只是缺那一路工具——Agent 什么都看不到,于是报"今天没新东西"。读者会误以为真的无事发生。规则是:来源读取失败时,书签保持不动(下次接着读)、用其余来源照常出报、并在结尾明确写一行"本次无法读取 XXX"。宁可承认读不到,不能把故障伪装成无事。
投递确认:先确认,后记账
自动化有真实副作用(往频道发消息),持久执行原则在这里体现为记账必须晚于确认:如果记了账但消息没发出去,书签已经前移,那些条目永远不会再报;如果不确定是否发出就再发一次,读者收到重复报。daily-brief 的做法分三步:
- 发帖前先在频道近期消息里查今天的标题,已存在则不重发(幂等去重);
- 只有 Slack 返回
"ok": true且带 message ts 才算发送成功; - 确认之后才更新账本和书签;结果不明就把本轮标记为 “maybe posted”,其余一律不动。
Agent 记忆里维护一份账本(ledger):每条报过的条目记录报告日期、来源、不变 ID(Slack 消息时间戳 / PR 号)和最后已知状态。已报且仍开放的条目只折叠成一行"仍在等,第 3 天",不重复展开;已关闭的静默移除。
发布前复核:世界在你读取时继续动
从读取来源到发帖之间有时间差,条目可能已经解决或状态反转。规则是在发帖前对每条要报的条目重查实时状态:已解决则删掉,仍开放但变化则改写,无法确认则删掉并记入本轮 cuts。文中给出的判断值得记住:一条过时的"还在等你处理"比十条漏报更伤信任,所以状态要么断言、要么删掉,绝不模糊措辞。所有链接都从来源自身的 link 字段复制(如 PR 的 html_url),不手工拼。
记忆双仓:偏好只读,状态读写
无人值守场景下记忆要分两仓:
- preferences(用户的,Agent 只读):读哪些频道和仓库、排除什么、长度上限、投递目的地、何时停止。每轮开始重新读文件,绝不把偏好复制进 prompt——prompt 里烤进去的副本会在你改完偏好后继续生效旧规则。读不到偏好文件时应停下来报告,而不是按默认值跑。
- state(Agent 的,读写):书签、账本、每轮运行记录、对偏好的修改建议、各来源的行为笔记(如"只返回最新 50 条")。
陈旧记忆同样危险:会把已解决的报成"仍在等",或因"已报过"而漏掉仍开放的事。
护栏:没人盯着的自动化要限权限钱
定时自动化的护栏有两类:
限制能做什么。 Agent 读的消息和 issue 是别人写的文本,可能被解读成指令(提示注入,见 OWASP Agentic AI Top 10)。原则是:只读的地方就给只读权限——GitHub token 设 read-only、preferences store 对 Agent 只读、环境只放行 allowlist 内的主机。同一 token 读写共用时(如 Slack bot),只把 bot 拉进它确实需要读写的频道。
限制能花多少。 每轮运行设预算上限(Managed Agents 的 budget),从真实运行成本出发:初始设为正常一轮的 3–5 倍,看到真实数字后再收紧。触顶的 run 是暂停而非失败(stop reason 为 budget_reached)——所以预算设太低的表现不是报错,而是简报悄悄消失。架构图里还有一点正文未展开但值得记下:护栏还包括轮数/时间上限,以及一个有人盯着的 heartbeat——后台自动化需要外部的心跳监控,沉默本身就应该触发告警。
相关概念
- AI Agent(智能体) — 自动化的执行主体
- Claude Agent SDK — Managed Agents 是其托管服务形态,自动化部署在其上
- Agents API — OpenAI 的同类托管 Agent 平台,scheduled task 是同型场景
- Agent Memory(Agent 记忆) — 书签、账本、运行记录所在的持久层
- Durable Execution(持久执行) — “先确认后记账"是副作用幂等的具体实现
- Agent Guardrails(Agent 护栏) — 限权与预算上限的分层设计
- Agent Egress Boundary — 网络 allowlist 是出站边界在自动化场景的最小形态
- Long-running Agent Harness — 同为无人值守持续运行,但面向长时任务而非周期巡检
- Agentic System Patterns(智能体设计模式) — 同出自 Anthropic 工程实践系列的前篇