claude.dev 解读
AgentsLance Martin and CJ Avilla2026-10-08约 9 分钟阅读原文 ↗

Building effective agent automations

定时代理最怕静默失败,六条与平台无关的规则才是全文真正值钱的部分

主张
6
审视
5
遗漏
2
  1. 01文章用 Claude Managed Agents 搭了一个定时日报代理作为参考实现,真正值钱的是收尾那六条与平台无关的规则:用书签代替固定时间窗;读取失败要明说,不能当成没有新消息;发帖前重新核验;确认送达后才记账;每次运行都重读只读的偏好;只读权限加单次预算上限。
  2. 02这几条规则对付的是无人值守自动化特有的「静默失败」:源断了、发帖没落地、偏好过期,代理都照常产出一份看起来正常的简报,没人会发现。
  3. 03最值得先做的是:源读取失败时在成稿里点名,以及发送确认之后才推进状态。
怎么读这篇
作者主张 · Lance Martin and CJ Avilla我们的审视
01

书签取代固定时间窗

增量读取要靠每个源各自的书签,不要用固定时间窗

机制拆解

「最近 24 小时」这种固定窗口有个前提:运行准点。一旦晚跑就漏一段,早跑又会重复。书签记的是每个源最新已读条目的时间戳,存在跨运行持久化的 state 存储里(挂载在 /mnt/memory/),下次运行从书签开始读,窗口自动伸缩,覆盖上次以来的全部内容。可靠性由数据本身保证,不再依赖调度准点。

“give the agent a bookmark per source” ¶21

这一点暂无对应的审视。

02

读不到不等于没新事

源读取失败必须当作「不可读」上报,不能变成「今天没事」

机制拆解

MCP server 宕机或 token 过期时,运行照常开始,只是那个 server 的工具不见了。代理看不到这个源,于是诚实地报告「没有新消息」,错误只留在会话日志里。修法有三条规则:失败源的书签不动,保证下次补读;其余源照常写简报;简报末尾用一行点名本次没读到的源。这样失败就从日志层转到了读者眼前。

“write the brief from the other sources” ¶24

可复现性

「读取失败被报告成没有新消息」这个核心论断可以低成本自己复现。

自己验证在测试环境里故意让一个源的 token 失效,或者断开一个 MCP server,跑一次无人值守任务,看成稿里有没有点名缺失的源,还是写成了「无新动态」。加规则前后各跑一次做对照。
03

确认送达后才记账

外部副作用要先确认送达,再更新内部状态;结果不明时宁可不动

机制拆解

这本质上是分布式系统里的幂等和两阶段思路。发帖前先查频道里有没有今天的标题,防止重复发。只有 Slack 返回 ok:true 和消息 ts 才算发出,之后才推进台账和书签。结果不明就标记 maybe posted,其他状态一律不改。运行记录按 posting → posted/maybe posted 推进。权衡很明确:宁可下次重报,也不让书签跨过从没送达的条目。

“the post counts as sent only if Slack returns” ¶29

这一点暂无对应的审视。

04

发帖前逐条回源核验

读完到发出之间世界会变,发帖前要逐条回源核验

机制拆解

agent.md 第五步要求:每条准备报告的条目,发帖前都回实时源复查。已解决的删掉,有变化的改写,确认不了的也删掉,并记进运行记录的 cuts。作者的取舍是:一条过期的「仍在等你」比漏掉十条更伤信任,所以条目状态只能断言或删除,不能含糊。链接一律从源的 link 字段复制,不让模型自己拼。

“re-check the live status of each item” ¶35

遗漏

架构图注里提到有一个「有人盯着的 heartbeat」,正文却完全没讲怎么实现。文章也没讲怎么评估简报质量,例如漏报率、误报率,以及「宁缺毋滥」这条规则有没有过度删减。

自己验证去参考实现仓库里查有没有心跳或告警相关的配置;没有的话,自己定义一个「多少天没有 posted 记录就告警」的检查,并抽样人工对比原始源和简报,估算漏报。
05

偏好归人只读,状态归代理

偏好和状态拆成两个存储:偏好归人、只读、每次重读;状态归代理、可写

机制拆解

偏好如果被烤进 prompt,用户改了规则,代理还按旧规则跑。所以偏好放在代理不能写的 preferences 存储里,每次运行都重新读,读不到就停下并说明,不退回默认值。代理自己的书签、台账、对偏好的修改提议、各个源的行为笔记放在 state 里。这样「用户意图」和「代理记忆」各有写入权限,代理没法悄悄改掉用户的规则。

“Have the agent read the file fresh every run” ¶46

遗漏

作者承认被注入的指令能通过代理可写的 notes 跨运行留存,但没给任何缓解办法,比如给 state 做审计、定期清理 notes、或者让人审核 proposals。Slack 读写共用一个 token 也只给了一句「只邀请到需要的频道」,没讨论读写分离。

自己验证在测试频道里放一条看起来像指令的消息,连续跑几次,然后检查 state 里的 notes 和 proposals 有没有被写进相关内容,以及后续简报是否受影响。
06

按被注入的后果设护栏

护栏按「代理被注入后最多能做什么」来设计:只读凭据、主机 allowlist、单次运行预算

机制拆解

代理读的是别人写的消息和 issue,这些文本可能被当成指令。所以限制的是动作半径:GitHub token 和 preferences 都只读,环境只能连 allowlist 上的主机,凭据真值留在沙箱外的 vault,出站时由平台替换。作者也承认残余风险:注入仍能改变简报内容,并且能通过 notes 跨运行留存;Slack 读写共用一个 token。预算是每次运行的上限,触发后运行暂停而不是失败,所以上限设得太低,表现出来就像「简报安静了」。

“Limit what the agent could do if it followed them” ¶49

数字口径

「起点设为正常运行成本的三到五倍」只是经验值,文中没给任何分布数据。示例里的 "500"(单位是美分)也只是示意。还有一点要当心:预算是每次运行各自拿满额,不是累计上限,真实成本上限等于运行次数乘以单次上限。

自己验证同时按 cron 频率算出月度理论上限。

作者没有直接谈到这一点。

厂商视角

全文把六条规则包在 Managed Agents(beta)、ant CLI、vault、托管调度这一整套平台里讲,读起来像是非用这套平台不可。其实这六条都是通用的工程纪律,书签、确认后记账、只读偏好在本地 launchd 加 claude CLI 上一样能实现。真正平台独有的只有沙箱外凭据替换和托管调度。

自己验证逐条判断:去掉 Managed Agents 之后,这条规则在 ~/ai-morning 的现有脚本里能不能实现。能实现的就说明不依赖平台,再看迁移到托管平台到底多换来了什么(凭据隔离、不依赖本机常驻)。
01

机制聚焦

确认送达后才记账

先确认外部副作用落地再改内部状态,结果不明时宁可不动,避免漏报和重复发帖

  1. 01查重在频道近期消息里找今天的标题,已有就不发
  2. 02标记 posting发帖前先在 runs 运行记录里标为 posting
  3. 03发帖用 curl 调 chat.postMessage 发出一条简报
  4. 04确认送达Slack 返回 ok 为 true 且带 ts 才算已发出
  5. 05更新记账确认后才更新 ledger 和 bookmarks,标为 posted
  6. 06结果不明标为 maybe posted,其余状态一律不动
依据原文 ¶29 ↗
02

核心观点

01

书签取代固定时间窗

增量读取要靠每个源各自的书签,不要用固定时间窗

机制拆解

「最近 24 小时」这种固定窗口有个前提:运行准点。一旦晚跑就漏一段,早跑又会重复。书签记的是每个源最新已读条目的时间戳,存在跨运行持久化的 state 存储里(挂载在 /mnt/memory/),下次运行从书签开始读,窗口自动伸缩,覆盖上次以来的全部内容。可靠性由数据本身保证,不再依赖调度准点。

give the agent a bookmark per source¶21 ↗

02

读不到不等于没新事

源读取失败必须当作「不可读」上报,不能变成「今天没事」

机制拆解

MCP server 宕机或 token 过期时,运行照常开始,只是那个 server 的工具不见了。代理看不到这个源,于是诚实地报告「没有新消息」,错误只留在会话日志里。修法有三条规则:失败源的书签不动,保证下次补读;其余源照常写简报;简报末尾用一行点名本次没读到的源。这样失败就从日志层转到了读者眼前。

write the brief from the other sources¶24 ↗

03

确认送达后才记账

外部副作用要先确认送达,再更新内部状态;结果不明时宁可不动

机制拆解

这本质上是分布式系统里的幂等和两阶段思路。发帖前先查频道里有没有今天的标题,防止重复发。只有 Slack 返回 ok:true 和消息 ts 才算发出,之后才推进台账和书签。结果不明就标记 maybe posted,其他状态一律不改。运行记录按 posting → posted/maybe posted 推进。权衡很明确:宁可下次重报,也不让书签跨过从没送达的条目。

the post counts as sent only if Slack returns¶29 ↗

04

发帖前逐条回源核验

读完到发出之间世界会变,发帖前要逐条回源核验

机制拆解

agent.md 第五步要求:每条准备报告的条目,发帖前都回实时源复查。已解决的删掉,有变化的改写,确认不了的也删掉,并记进运行记录的 cuts。作者的取舍是:一条过期的「仍在等你」比漏掉十条更伤信任,所以条目状态只能断言或删除,不能含糊。链接一律从源的 link 字段复制,不让模型自己拼。

re-check the live status of each item¶35 ↗

05

偏好归人只读,状态归代理

偏好和状态拆成两个存储:偏好归人、只读、每次重读;状态归代理、可写

机制拆解

偏好如果被烤进 prompt,用户改了规则,代理还按旧规则跑。所以偏好放在代理不能写的 preferences 存储里,每次运行都重新读,读不到就停下并说明,不退回默认值。代理自己的书签、台账、对偏好的修改提议、各个源的行为笔记放在 state 里。这样「用户意图」和「代理记忆」各有写入权限,代理没法悄悄改掉用户的规则。

Have the agent read the file fresh every run¶46 ↗

06

按被注入的后果设护栏

护栏按「代理被注入后最多能做什么」来设计:只读凭据、主机 allowlist、单次运行预算

机制拆解

代理读的是别人写的消息和 issue,这些文本可能被当成指令。所以限制的是动作半径:GitHub token 和 preferences 都只读,环境只能连 allowlist 上的主机,凭据真值留在沙箱外的 vault,出站时由平台替换。作者也承认残余风险:注入仍能改变简报内容,并且能通过 notes 跨运行留存;Slack 读写共用一个 token。预算是每次运行的上限,触发后运行暂停而不是失败,所以上限设得太低,表现出来就像「简报安静了」。

Limit what the agent could do if it followed them¶49 ↗

03

批判性审视

厂商视角

全文把六条规则包在 Managed Agents(beta)、ant CLI、vault、托管调度这一整套平台里讲,读起来像是非用这套平台不可。其实这六条都是通用的工程纪律,书签、确认后记账、只读偏好在本地 launchd 加 claude CLI 上一样能实现。真正平台独有的只有沙箱外凭据替换和托管调度。

自己验证逐条判断:去掉 Managed Agents 之后,这条规则在 ~/ai-morning 的现有脚本里能不能实现。能实现的就说明不依赖平台,再看迁移到托管平台到底多换来了什么(凭据隔离、不依赖本机常驻)。
数字口径

「起点设为正常运行成本的三到五倍」只是经验值,文中没给任何分布数据。示例里的 "500"(单位是美分)也只是示意。还有一点要当心:预算是每次运行各自拿满额,不是累计上限,真实成本上限等于运行次数乘以单次上限。

自己验证同时按 cron 频率算出月度理论上限。
可复现性

「读取失败被报告成没有新消息」这个核心论断可以低成本自己复现。

自己验证在测试环境里故意让一个源的 token 失效,或者断开一个 MCP server,跑一次无人值守任务,看成稿里有没有点名缺失的源,还是写成了「无新动态」。加规则前后各跑一次做对照。
遗漏

作者承认被注入的指令能通过代理可写的 notes 跨运行留存,但没给任何缓解办法,比如给 state 做审计、定期清理 notes、或者让人审核 proposals。Slack 读写共用一个 token 也只给了一句「只邀请到需要的频道」,没讨论读写分离。

自己验证在测试频道里放一条看起来像指令的消息,连续跑几次,然后检查 state 里的 notes 和 proposals 有没有被写进相关内容,以及后续简报是否受影响。
遗漏

架构图注里提到有一个「有人盯着的 heartbeat」,正文却完全没讲怎么实现。文章也没讲怎么评估简报质量,例如漏报率、误报率,以及「宁缺毋滥」这条规则有没有过度删减。

自己验证去参考实现仓库里查有没有心跳或告警相关的配置;没有的话,自己定义一个「多少天没有 posted 记录就告警」的检查,并抽样人工对比原始源和简报,估算漏报。
本篇未覆盖(4)
风格