用托管智能体做一个每天定时跑的官方更新日报:结构、权限、受限网络、预算,和跑了一周的账
本站用托管智能体做了一个日报:每天 7:30 在云端检查 Claude 的官方文档和博客,写中文简报。这篇讲它怎么搭、记忆库的权限怎么分、受限网络和预算的实际表现、出错时怎样,拿官方的安全部署指南逐条对照,并给出一周 12 次会话 7.40 美元的账。直连官方接口实测。
本站已实测,测试日期:2026-10-21。
本页目录(12 节)
托管智能体的三篇(《入门》、《环境和数据》、《进阶》)讲的是每个部件怎么用。这一篇讲怎么把它们拼成一个每天自己跑、跑得住的小项目。
例子是本站自己在用的“Claude 官方更新日报”:从 10 月 15 日起,它每天早上 7:30 在 Anthropic 的云端开一个会话,检查 Claude 的官方文档、更新日志和博客,和前一天比较,写一份中文简报,标出本站哪几篇文章受影响。简报只给站长起草快讯、改文章时参考,不发布。
文中的数字有两个来源:线上日报一周的真实运行,和为这篇另建的一套演示资源(代码和线上一样,只换了名字),专门用来演示超预算、出错这些不好等它自然发生的情况。
| 实测环境 | |
|---|---|
| 日期 | 2026-10-21 |
| SDK | Python 版 anthropic 1.13.0 |
| 模型 | 日报的智能体用 Sonnet 5.5;第十节的离线审查用 Haiku 5.5 |
| 连接方式 | 直连官方接口,用的是 Max 套餐每月赠送的 API 额度 |
| 线上日报的数据 | 北京时间 10 月 15 日 02:29 到 10 月 21 日 07:30,一共 12 次会话 |
| 演示 | 另建一套名字带 h49-demo 的资源,代码和线上一样,跑了 4 个会话,标价合计 0.64 美元;测完删除会话、记忆库和 skill,归档部署、智能体和环境 |
这组接口只在官方平台上有,中转站返回 404,见《入门》开头。
| 你想看的 | 看哪一节 |
|---|---|
| 整体怎么搭,为什么这样分工 | 一、二 |
| 记忆库的权限 | 三 |
| 网络白名单实际挡住了什么 | 四 |
| 定时部署和取回结果 | 五 |
| 超出预算、出错的时候 | 六 |
| 花了多少,简报有没有用 | 七 |
| 和本机的采集脚本比 | 八 |
| 对照官方的安全部署指南 | 九 |
| 事后审查每个会话 | 十 |
一、要解决的问题
本站原来就有一套采集脚本,跑在站长的 Mac 上,每天 8:00 和 20:00 抓官方的文档目录、更新日志和博客,告诉我们哪一页变了、贴出差异。它有两个不足:
- 只给差异,不给判断。 一天改了一百多页时,哪些是实质改动、本站哪一篇哪一段因此过时,要人一页页看。
- Mac 不开机就不跑。
日报要补的就是这两点:在云端定时跑,读差异,判断重不重要,对照本站的文章说清楚哪里要改。
为什么用托管智能体,不在自己的服务器上用 cron 跑 claude -p:
- 定时、沙箱、会话记录、预算都是现成的。 自己做要写调度、管隔离、存日志、算花费。
- 跑代码的地方和密钥分开。 智能体要读外面的网页,还要执行命令。放在自己的服务器上,它和服务器上的密钥、别的项目在一起;放在托管沙箱里,沙箱里什么凭据都没有(第九节细说)。
- 状态能跨天保存。 记忆库是现成的“上一次的内容”,不用自己搭存储。
代价是绑定在官方平台上:中转站用不了,beta 接口以后可能改。
二、整体结构:大脑、双手和会话日志分开
官方的架构
Anthropic 工程博客《Scaling Managed Agents》(4 月 8 日)讲了托管智能体为什么这样设计。最早他们把三样东西放在同一个容器里:会话记录、跑循环的 harness、执行代码的沙箱。问题是这个容器成了“宠物”:容器一坏,会话就丢了;出了问题只能进容器排查,而容器里又有用户的数据。
后来拆成三块,各自可以单独失败、单独替换:
| 部分 | 博客里的说法 | 是什么 |
|---|---|---|
| 大脑 | Claude 加 harness | 调用模型、把工具调用转给对应的地方。跑在 Anthropic 的服务器上 |
| 双手 | 沙箱和工具 | 执行命令、读写文件。对大脑来说只是一个工具:execute(name, input) → string |
| 会话 | 只追加的事件日志 | 发生过的每件事。存在大脑和双手之外 |
拆开带来几件事:
- 容器坏了不丢会话。 容器挂掉,对大脑来说就是一次工具调用出错,交给 Claude 决定要不要重试,重试时按同样的配置新开一个容器。
- harness 坏了也不丢。 会话日志在外面,新起一个 harness,读回日志,从最后一个事件接着跑。
- 凭据碰不到。 原来的设计里,Claude 生成的代码和凭据在同一个容器里,提示注入只要让 Claude 读一下环境变量就拿到了。现在 Git 的令牌在沙箱初始化时配进 remote,MCP 的令牌放在保险库里、由代理带上,沙箱里的代码拿不到。
- 会话不等于上下文窗口。 会话日志是一个上下文窗口之外的对象,harness 可以按位置取一段事件再交给 Claude,压缩、裁剪这些不可逆的处理只发生在 harness 里,原始记录一直在。
- 快。 不需要沙箱的会话不用等容器启动,首个 token 的等待时间中位数降了约 60%,p95 降了 90% 以上(claude.com 6 月的文章给的是同样的数字)。
日报对应到这三块
本站服务器(ccdemo 账号):管理脚本 brief.py,官方 key 只在这里,不进会话
│ setup 建资源;fetch 取回结果、刷新站点索引
▼
Anthropic 那边
定时部署:每天 7:30(北京时间)开一个会话,每次预算 3 美元
大脑:Sonnet 5.5 + harness,跑在 Anthropic 的服务器上
│ 工具调用:bash、read、write、edit、glob、grep
▼
双手:云端沙箱,每个会话一个新容器,网络只开 8 个主机
├─ /workspace/skills/official-diff/ skill:比较脚本 diff_sources.py
├─ /mnt/memory/chunduai-site-index/ 记忆库,只读:本站文章和它们引用的官方页
├─ /mnt/memory/chunduai-brief-baseline/ 记忆库,可写:上一次抓到的内容、最近 14 天的简报
└─ /mnt/session/outputs/ 产出:简报、JSON、比较报告
会话日志:每个事件都存在服务端,取回、查花费、事后审查都从这里来
各部件的配置:
| 部件 | 怎么配 | 为什么 |
|---|---|---|
| 智能体 | Sonnet 5.5;中文系统提示写清步骤和判断规则;内置工具默认全关,只开 bash、read、write、edit、glob、grep;联网搜索和网页抓取两个工具不开 | 抓取统一由脚本按固定网址做,省钱,每次结果可以重现 |
| skill | 一个只用 Python 标准库的脚本,四个子命令:fetch 抓取并比较、read 读一篇文章的正文、check 检查简报和 JSON、commit 写回基准 |
正文的清洗规则和本机的采集脚本一致,两边结果对得上。脚本跟着 skill 的版本走 |
| 环境 | networking: limited,allowed_hosts 只放 8 个主机,不开包管理器,不开 MCP |
见第四节 |
| 记忆库 ×2 | 站点索引只读,基准可写 | 见第三节 |
| 定时部署 | cron 30 7 * * *,时区 Asia/Shanghai,每次预算 300 美分,开始事件是一条“执行今天的检查。” |
见第五节 |
建资源的代码都在一个管理脚本里,可以重复运行:资源 ID 存在本地,配置改了才更新。核心几段(和线上一样,演示时只换了名字):
# 两个记忆库,挂到会话上时一个只读、一个可写
resources = [
{"type": "memory_store", "memory_store_id": index_id, "access": "read_only",
"instructions": "本站文章清单(articles.jsonl)和引用关系(cited.jsonl)。只读,判断哪些文章受影响时用。"},
{"type": "memory_store", "memory_store_id": base_id, "access": "read_write",
"instructions": "比较基准,只由 official-diff 的 commit 写回,不要手动修改。briefs/ 下是最近的简报。"},
]
# 环境:受限网络
env = client.beta.environments.create(name="chunduai-daily-brief", config={
"type": "cloud",
"networking": {"type": "limited",
"allowed_hosts": ["code.claude.com", "platform.claude.com", "raw.githubusercontent.com",
"github.com", "claude.dev", "claude.com", "www.anthropic.com", "chunduai.com"],
"allow_package_managers": False, "allow_mcp_servers": False}})
# 智能体:工具默认全关,只开六个
tools = [{"type": "agent_toolset_20260401", "default_config": {"enabled": False},
"configs": [{"name": n, "enabled": True} for n in ("bash", "read", "write", "edit", "glob", "grep")]}]
agent = client.beta.agents.create(name="chunduai-daily-brief", model="claude-sonnet-5-5", system=prompt,
tools=tools, skills=[{"type": "custom", "skill_id": skill_id, "version": "latest"}])
脚本做什么,模型做什么
这是整个设计里最要紧的一条:确定的事交给脚本,要判断的事交给模型。
| 步骤 | 谁做 | 说明 |
|---|---|---|
| 抓取 10 个来源,和基准比较,生成带编号的报告(C01、C02……) | 脚本 fetch |
网址固定,清洗规则固定。一个来源失败不影响别的 |
| 读报告,判断实质改动还是措辞调整、重要程度、本站哪篇受影响 | 模型 | 需要时用 read 读本站文章的正文核对 |
| 写简报(Markdown)和改动清单(JSON) | 模型 | |
| 检查 JSON | 脚本 check |
报告里每个编号必须恰好出现一次(不能漏报);受影响的文章必须在站点索引里(编不出不存在的文章);链接只能是报告里的网址或官方网站 |
| 写回基准 | 脚本 commit |
只认 check 通过时的那两个文件,check 之后再改就要重新 check |
系统提示里的步骤就是这几步,最后让它用一句话回复:日期、几条改动、几条标了“高”。
实测:演示时第一次运行只建基准。会话 2 分多钟跑完,智能体读 SKILL.md、运行 fetch、读报告、写简报、check、commit,8 次工具调用,花费 5 美分。基准记下 Claude Code 文档目录 228 页、开发平台文档 308 页、Claude 应用文档 172 页、更新日志 426 个版本,commit 往记忆库里写了 517 个文件。这一步是整次运行里最慢的。skill 在沙箱里的路径是 /workspace/skills/<skill 名>。
三、两个记忆库:一个只读,一个可写
| 站点索引 | 基准 | |
|---|---|---|
| 挂载方式 | read_only |
read_write |
| 放什么 | 本站每篇已发布文章的网址、标题、一句说明、是否实测、测试日期(articles.jsonl);每个官方网址被哪几篇文章引用(cited.jsonl) |
每个来源上一次的目录(lists/)、被比较页面的正文(pages/)、状态(state.json)、最近 14 天的简报(briefs/) |
| 谁来写 | 服务器上的管理脚本,每次手动运行和取回结果时从部署用的仓库重新生成 | 只有 skill 的 commit |
| 规模 | 4 个文件 | 500 多个文件 |
为什么站点索引只读。 官方文档提醒过:读外部网页的智能体可能被网页里的文字诱导,往记忆里写东西,之后的会话会把它当成可信的记忆读出来。站点索引是“本站有哪些文章”的依据,check 也靠它判断受影响的文章是不是真的存在,所以它必须改不了。
为什么基准可以写。 基准必须每天更新。它被写坏的后果有限:最坏是某一天多报或漏报,下一次 commit 就会按当天抓到的内容覆盖。记忆库的每次改动都留一个版本,保留 30 天,真出了问题可以把旧版本写回去。
两条容易忽略的规则:
- 单个记忆最大 100 kB。 超过的正文拆成
name.txt、name.p2.txt几段存,读的时候拼回来。方案阶段数过,当时要比的 333 页里有 29 页要拆。 - 没变的文件不重写。 每次写都会多一个记忆版本,第一次建基准写几百个文件要几分钟;之后每天只重写有改动的,10 月 20 日改动多的那天写了 164 个。
“只由 commit 写回”只是约定,不是权限。 基准是可写挂载,沙箱里任何命令都能改它。我们靠两点兜底:系统提示里写明不要改 /mnt/memory/ 下的文件;脚本的 commit 只在 check 通过后才写。
实测(演示会话里让智能体逐条运行命令):
$ touch /mnt/memory/h49-demo-site-index/probe.txt
touch: cannot touch '/mnt/memory/h49-demo-site-index/probe.txt': Read-only file system
$ test -w /mnt/memory/h49-demo-baseline && echo baseline-writable
baseline-writable
读基准是允许的,而且有用。演示时我们在基准里人为删掉了 40 页正文各一行,制造出 40 条“正文改了”。智能体没有照单全收:它直接到 /mnt/memory/h49-demo-baseline/pages/ 下看了基准文件,发现 40 页的差异形状一样(基准里对应位置是两个空行,今天的页面中间多一行),在简报里写“这是基准少存了一段,不是官方改了文档”,并建议站长检查基准。判断是对的。另一次报告里某页的差异被截断了,它也是拿基准里存的旧正文和当天的页面自己补比了一遍,在“说明”里注明“上面写的是完整的”。
四、受限网络:实际挡住了什么
环境是 limited,allowed_hosts 列了 8 个主机:日报要抓的 7 个官方网站,加上 chunduai.com(读本站文章)。包管理器和 MCP 都没开,联网搜索和网页抓取两个工具也没开,所以沙箱出去的路只有 bash 里的命令。
实测(演示会话里用 curl 逐个访问):
| 访问 | 结果 |
|---|---|
| 日报的 10 个来源(在 7 个官方网站上) | 都取到了 |
https://chunduai.com/llms.txt |
200 |
https://raw.githubusercontent.com/python/cpython/main/README.rst(和日报无关的公开仓库) |
200 |
example.com、www.google.com、pypi.org |
不通,域名解析不了:curl: (6) Could not resolve host |
api.anthropic.com |
能解析,但被出口拦下,返回 403 |
| 往只读的站点索引里写文件 | Read-only file system |
api.anthropic.com 的 403 带着说明:
HTTP/2 403
x-deny-reason: host_not_allowed
Host not in allowlist: api.anthropic.com. Add this host to your network egress settings to allow access.
所以白名单外有两种失败:大多数主机连域名都解析不了;api.anthropic.com 能解析,由出口代理拒绝。脚本里两种都表现为请求失败。
一个来源取不到时。 演示的 skill 里故意加了一个白名单外的来源(PyPI 的更新订阅)。每次运行它都失败,别的来源照常比较,报告的“说明”里写一行:
- 白名单外的来源(演示用)(https://pypi.org/rss/updates.xml)没有取到(URLError)
连续 3 次取不到,这一行后面会加上“已经连续 3 次取不到,要看看是不是改了网址”。线上 10 月 21 日真遇到过:anthropic.com 把工程博客从 /engineering/ 搬到 /research/,脚本只认旧前缀,一篇也对不上,报了 ValueError。别的来源照常出了简报,当天改了脚本。
白名单里有两个“谁都能发布内容”的主机。 github.com 和 raw.githubusercontent.com 是为了取 Claude Code 的 CHANGELOG.md 和版本发布的订阅。上面的实测说明,放行是按主机的,任何公开仓库的文件都能取到。官方的安全指南明确建议避开这类共享托管的域名(第九节)。这两个主机现在还在白名单里;10 月 21 日核对,Claude Code 文档站有一页 changelog.md,由 GitHub 上的 CHANGELOG.md 生成,以后可以改从这里取,把这两个主机去掉。
五、定时部署和取回结果
部署就是“建会话需要的全部配置”加一个时间表,接口用法见《环境和数据》第十一节。日报的部署:cron 30 7 * * *,时区 Asia/Shanghai,预算 300 美分(每次运行单独算,不是累计)。
线上 6 次定时运行实际开始的时间(北京时间):10-16 07:34:49、10-17 07:36:42、10-18 07:34:33、10-19 07:34:41、10-20 07:30:21、10-21 07:30:33。官方说会随机推迟,最多两次运行间隔的 15%、不超过 9 分钟,实际推迟了 21 秒到 6 分 42 秒。
两个踩过的坑:
- 部署钉住了智能体的版本。 10 月 15 日改了一次提示词,智能体升到版本 3,定时运行用的还是版本 2。现在管理脚本每次更新智能体后,都检查部署上的版本和预算,不一致就改过去。官方的安全指南也提到了这一点:改了智能体的配置,只有新会话生效,部署要指到新版本。
- 产出文件要过一会儿才列得出来。 会话空闲后,简报和 JSON 两个文件前后差一秒才出现在文件列表里,第一次只取回了 JSON。取回的脚本改成等两个文件都出现再下载,最多等一分钟。
取回结果:手动,不加定时任务。 站长每次看采集结果时,在服务器上运行一次 brief.py fetch:用 deployment_runs.list 找出部署开过的会话,下载还没取的产出(简报、JSON、比较报告、改动清单),把事件存一份精简记录,最后刷新站点索引。简报在会话的产出和基准的 briefs/ 里都有,隔几天再取也不会丢。不用 webhook,因为要在服务器上开一个公网的 HTTPS 接收地址。
实测(演示):为了不等到第二天,演示的部署用了每 15 分钟一次的时间表:
deployment = client.beta.deployments.create(
name="h49-demo-brief",
agent={"type": "agent", "id": agent_id, "version": 2}, # 钉住版本
environment_id=env_id, resources=resources,
initial_events=[{"type": "user.message", "content": [{"type": "text", "text": "执行今天的检查。"}]}],
budget={"type": "limit", "max_list_cost": {"amount": "100", "currency": "USD"}},
schedule={"type": "cron", "expression": "*/15 * * * *", "timezone": "Asia/Shanghai"},
)
- 返回的部署是
active,schedule.upcoming_runs_at列出接下来 5 次的时间(UTC),vault_ids是空的。 - 14:00 那次实际在 14:01:26 开始,推迟 86 秒。15 分钟间隔的 15% 是 135 秒,在范围内。
- 运行记录里
trigger_context是{"type": "schedule", "scheduled_at": "2026-10-21T06:00:00Z"},带着会话 ID 和钉住的智能体版本。会话带着部署上的 1 美元预算。 - 这次碰上了官方当天下午真实的改动(权限页、沙箱页和 Claude Code 2.1.306),18 次工具调用、3 分多钟写完,花费 25 美分。
brief.py fetch从运行记录找到这个会话,取回了四个文件。
六、超出预算和出错的时候
超出预算:线上真遇到过
10 月 16 日和 17 日,定时运行连着两天在写简报之前花光了当时 1.5 美元的预算:
| 日期 | 改动 | 工具调用 | 花费 | 结果 |
|---|---|---|---|---|
| 10-16 | 107 条 | 52 次 | 1.54 美元 | 停在 budget_reached,只留下比较报告,没有简报 |
| 10-17 | 154 条 | 51 次 | 1.53 美元 | 同上 |
花费比上限多了 3 到 4 美分。这是规则:预算在两次模型请求之间检查,越线的那一次请求会跑完。
为什么会超:提示词要求每条改动都读引用它的本站文章,智能体还整段读了 20 多万字的报告,上下文越来越长。每次工具调用都要把整个上下文重读一遍,10 月 16 日那次光是读缓存就有 747 万 token。
基准没写回,所以改动越积越多。 基准只在简报通过检查后才写回。10 月 17 日的比较仍然从 10 月 15 日算起,报告从 107 条涨到 154 条,不修的话每天都会失败。
改法(10 月 17 日):
- 提示词加了“改动多的时候”一节:超过 30 条时不整份读报告,先
grep出全部标题,只读新页、新版本、目录标题改了的、看标题就可能涉及默认值、参数、价格、限额的差异;只给可能标“高”的条目读文章,每条最多 1 篇、一次最多 8 篇;没核对的合成一两条,简报里单列“没有逐条核对的改动”;工具调用到 30 次左右还没开始写简报,就停止查证。 - 预算从 1.5 美元调到 3 美元。
改完以后,10 月 17 日下午补跑一次,166 条改动花了 0.74 美元;10 月 20 日 128 条改动 0.89 美元,10 月 21 日 297 条改动 1.32 美元,都在预算内写完了。
演示:到了预算会怎样,怎么接着跑
在演示的基准里人为制造 46 条改动(删掉 6 个版本,改 40 页正文),预算只给 3 美分:
- 5 次工具调用后停下,花费 4 美分(超了 1 美分)。会话是
idle,原因budget_reached。 - 产出里只有
fetch写的比较报告和改动清单,没有简报。基准没动:更新日志还是少 6 个版本。 - 再发一条消息让它接着写,返回 400:
session budget reached: consumed list cost has met `budget.max_list_cost`; only `user.tool_confirmation`,
`user.tool_result`, `user.custom_tool_result`, and `user.interrupt` are accepted until the budget is raised
(rejected `user.message` at events[0])
- 用
client.beta.sessions.update(会话 ID, budget={"type": "limit", "max_list_cost": {"amount": "100", "currency": "USD"}})把预算调到 1 美元。不用再发消息,事件流里多了一个session.updated,它自己接着干:读差异、写简报、check、commit,最后花费 26 美分。基准里的版本数回到了 426。
所以一次定时运行到了预算,有两种补救:
- 调高这次会话的预算,它从停下的地方接着干。适合差一点就写完的情况。
- 改好提示词再开一个新会话。 上下文已经很长、接着跑也会很贵的时候用这个。线上 10 月 17 日用的是这种。
另一个要注意的现象:做完了也可能显示 budget_reached。 演示里另一次只有 2 条改动、预算给 5 美分,智能体写完简报、check、commit 都成功了,最后一句总结还没说,正好碰到上限,会话的停止原因也是 budget_reached。所以判断一次运行成没成,要看产出(简报和 JSON 在不在、commit 有没有执行),不能只看停止原因。
出错的几种情况
| 情况 | 会怎样 | 日报怎么处理 |
|---|---|---|
| 某个来源取不到 | 别的来源照常比较,“说明”里写一行 | 连续 3 次加提醒,见第四节 |
| 简报的格式不对 | check 逐条列出问题 |
智能体改到通过为止。这一周 10 次写了简报的运行,check 都是第一次就通过 |
| 写完简报后又改了它 | commit 拒绝写回 |
commit 比对 check 时记下的哈希 |
| 中途出错或超出预算 | 基准不动 | 下一次把两次之间的改动一起报出来,改动不会丢 |
| 站点索引过时 | 会误判“本站没有文章写过” | 10 月 15 日遇到一次(索引在新文章发布前刷新的),之后每次手动运行先刷新索引 |
| 部署启动不了会话 | 记一条失败的运行记录,部署自动暂停(见下) | fetch 列运行记录时会打印“部署有一次没有启动” |
实测:部署启动不了会话时。 演示的部署跑完 14:00 那次以后,我们把它用的环境归档,等 14:15 的触发:
- 14:15:19 记了一条运行记录,
session_id是空的,error.type是environment_archived_error,error.message是“environmentenv_…is archived”。 - 部署自动变成
paused,paused_reason是{"type": "error", "error": {"type": "environment_archived_error"}}。之后的定时触发不再发生,要修好再手动unpause。 - 这时再用
deployments.run手动触发,接口不报错,返回的同样是一条带error的运行记录(trigger_context是manual)。所以手动触发之后也要看返回里的error和session_id,不能只看请求成功没有。 - 管理脚本的
fetch列运行记录时打印了一行“部署有一次没有启动:… environment_archived_error …”。 - 测完把这个部署归档:
archived_at有了值,upcoming_runs_at变空,paused_reason被清掉,status却显示active。判断一个部署有没有归档,看archived_at。
官方文档说,归档的环境、保险库这类不可恢复的错误会这样自动暂停;被限流这类可恢复的错误只记一条失败,不暂停,等下一个时间点。归档智能体则会把部署一起归档,不留运行记录。
七、花了多少,简报有没有用
统计的时间段是北京时间 10 月 15 日 02:29 到 10 月 21 日 07:30。花费取自每个会话的 usage.list_cost(按标价算):
| 北京时间 | 怎么开的 | 改动 | 简报 | 工具调用 | 花费(美元) |
|---|---|---|---|---|---|
| 10-15 02:29 | 手动,建基准,之后在同一会话里验证网络 | — | 只写建立基准的说明 | 8 | 0.06 |
| 10-15 02:34 | 手动,人为制造两处改动 | 6 | 3 条 | 14 | 0.20 |
| 10-15 07:18 | 手动,第一次真实运行 | 44 | 10 条(高 1、中 4) | 24 | 0.62 |
| 10-15 07:32 | 部署,手动触发一次 | 0 | 没有改动 | 7 | 0.07 |
| 10-15 22:53 | 部署,手动触发 | 7 | 5 条(中 1) | 17 | 0.28 |
| 10-16 07:34 | 定时 | 107 | 超预算,没有 | 52 | 1.54 |
| 10-17 07:36 | 定时 | 154 | 超预算,没有 | 51 | 1.53 |
| 10-17 14:01 | 手动补跑(新提示词,预算 3 美元) | 166 | 13 条(高 2、中 5) | 29 | 0.74 |
| 10-18 07:34 | 定时 | 0 | 没有改动 | 6 | 0.07 |
| 10-19 07:34 | 定时 | 3 | 2 条,都是低 | 8 | 0.08 |
| 10-20 07:30 | 定时 | 128 | 11 条(高 2、中 2) | 36 | 0.89 |
| 10-21 07:30 | 定时 | 297 | 20 条(高 3、中 10) | 39 | 1.32 |
| 合计 | 7.40 |
几点观察:
- 没改动的日子 7、8 美分,改动多的日子 0.9 到 1.5 美元。6 次定时运行合计 5.43 美元,平均每天约 0.9 美元。方案里估的是每月 8 到 15 美元,按这一周算要 20 到 30 美元。这一周正好碰上官方文档改动特别多(三天各一两百页),平常的月份会低一些,但估算偏乐观。
- 钱几乎都花在上下文上。 按 Sonnet 5.5 的标价拆开 12 次会话:写缓存 3.01 美元,读缓存 2.53 美元,输出 1.79 美元,会话运行时长(每小时 0.08 美元)一共 5 美分。花费大致等于“工具调用的次数 × 当时上下文的长度”,所以控制成本的办法是少读、早写,而不是缩短运行时间。
- 当初怕的运行时长费可以不管。 12 次会话实际在跑的时间合计约 39 分钟。
简报有几条真用上了:
“建议处理”指简报里建议写快讯、改文章或写新教程的条目:
| 运行 | 建议处理的 | 用上的 |
|---|---|---|
| 10-15 02:34(人为制造改动的测试,碰巧遇到真实改动) | 2 条 | 都用上了:OpenTelemetry 写成新教程;2.1.300 那条引出一条快讯和两篇文章的补充 |
| 10-15 07:18 | 4 条 | 3 条文章修改都做了。另 1 条误判:说“本站没有文章写过”、建议写快讯,其实当天刚发布,原因是站点索引旧了 |
| 10-15 22:53 | 1 条(新文档页) | 用上了:快讯补了四处 |
| 10-17 补跑 | 6 条 | 主会话已经人工核对过这批改动,结论大多重合;简报多指出的 2 处都改了。它漏了 claude -p 默认权限模式的变化(更新日志被截断,见下) |
| 10-19 | 0 条 | 判断正确:2.1.303 只有一句“修复和可靠性改进”,另一条是公司新闻 |
| 10-20 | 3 条 | 都用上了。另有一条它定为“不处理”的(Agent SDK 子代理页),核对后也要改 |
| 10-21 | 7 条 | 都引出了修改:3 条“高”、2.1.305 的快讯、dontAsk 和 mod 那条(改了 9 篇),另两条补进了文章 |
简报点名的条目大多数是对的,但改动多的日子,简报覆盖不了全部:
- 10 月 20 日简报建议处理 3 条,站长按完整正文逐页核对后,一共改了 36 篇文章;桌面应用界面大改这类改动,被简报当成了措辞调整。
- 10 月 21 日简报建议处理 7 条,逐页核对后改了 52 篇。只在标题里有 routine 的那篇被列为受影响,另外十来篇提到 routine 的没有列。
- 原因之一是比较报告在改动多时每页只留前 1500 字差异,智能体看到前面一段就下了“没有实质改动”的结论。
- 10 月 17 日漏掉的那条,是因为每个版本的更新日志只留前 3000 字,
claude -p默认权限模式的改动排在第 30 条,被截掉了。现在脚本先列新增、改动、删除,最后才列修复,上限提到 5000 字。
所以在本站的用法里,简报是起点,不是结论:它点名的先处理,“没有逐条核对的改动”那一节也要看完。
八、和本机的采集脚本对照
两套是独立跑的,每次看采集结果时放在一起比:
| 本机采集(Mac,8:00 和 20:00) | 日报(云端,7:30) | |
|---|---|---|
| 范围 | 官方来源,加上 X 上的推文、Codex 的文档 | 只有 Claude 的官方来源 |
| 看到的页面 | 10-19、10-20、10-21 三天逐页比,两边一致 | 同左 |
| 早晚 | 正文一天只在第一次运行时比 | 10 月 15 日新出的 4 页 OpenTelemetry 文档,日报比本机早约 5.5 小时报出;正文改动常常早半天 |
| 改动多时 | 每页列出差异,人自己判断 | 合成十几二十条,标出重要程度和受影响的文章 |
| 都漏了的 | 10 月 15 日 claude.com 的 OpenTelemetry 发布博客:本机因为网站地图没有日期,日报因为博客发在建基准之前 | 同左 |
| 一起坏的 | 10 月 21 日工程博客搬家:本机把四十来篇旧文章当新文章又报了一遍 | 同一天,工程博客这个来源报错 |
| 要什么条件 | Mac 开着 | 不依赖 Mac |
结论:两边看到的东西基本一样,日报的价值在“判断”和“不依赖 Mac”。它代替不了逐页核对,但能让人先看最要紧的几条。
九、对照官方的安全部署指南
10 月 14 日,开发平台文档加了三页安全部署指南:一页按重要性列出限制智能体能访问什么、能做什么的设置;一页讲这些设置为什么重要、沙箱能防什么防不了什么;一页讲事后审查和监控。下面拿日报的设置逐条对照。
逐条对照
| 指南的建议(按重要性排) | 日报现在 | 对上了吗 |
|---|---|---|
| 用云端环境,除非工具必须跑在自己控制的机器上 | 云端 | 对上 |
网络用 limited,只列需要的主机;只列自己运营或信任的主机,避开通配符和任何人都能发布内容的共享托管域名 |
limited,8 个主机,没有通配符,包管理器和 MCP 都没开 |
大体对上。github.com、raw.githubusercontent.com 属于共享托管,见第四节 |
| 密钥都放进保险库,只在请求头里替换,只对需要的主机替换;不要把 Claude API 的 key 交给智能体 | 会话里没有任何凭据:不挂保险库,系统提示、智能体定义和消息里都没有 key | 对上,而且更彻底:这个任务根本用不着凭据 |
| 应用调 Claude API 用只限一个工作区的身份,能用 Workload Identity Federation 就用 | 管理脚本用一把建在单独工作区里的 API key,工作区设了每月花费上限;没有用 WIF | 部分对上 |
联网搜索和网页抓取都设 allowed_domains |
这两个工具没开 | 对上,而且更彻底 |
read、glob、grep 用 always_allow;bash、write、edit 用 auto;改动无法在沙箱外撤回的工具用 always_ask |
六个工具都是工具集默认的 always_allow |
没对上,下面实测了改成 auto 会怎样 |
| 工具集默认全关,只开需要的 | 默认全关,开了六个;但默认的权限策略没改,还是 always_allow |
对上。指南的例子还把默认策略设成 always_ask,以后新开的工具不会自动放行 |
读不可信输入的智能体,不要同时拿着 always_allow 的强力工具;记忆库能只读就只读 |
读的是官方网页(按指南的定义,团队以外的人写的内容都算不可信),手里有 always_allow 的 bash;站点索引只读,基准可写 |
部分对上。基准必须可写。能接受的理由:沙箱里没有凭据,网络出不去,最坏是一天的简报写错 |
| 每个会话和部署都设预算,事先想好怎么停 | 部署每次 3 美元;管理脚本有 pause、archive |
对上 |
| 可选:离线审查每个会话 | 原来没有 | 这次补做了,见第十节 |
| 订阅 webhook,盯空闲、到预算、终止、部署启动失败;把要留的事件存到自己那边,不用的会话删掉 | 没有 webhook;fetch 时列出部署的运行记录,启动失败的那次会打印出来;事件存了一份精简记录;会话都还留着 |
部分对上 |
把 bash、write、edit 改成 auto 会怎样
auto 的意思是每次调用由服务端判断:放行、拒绝,或者暂停等人批准。演示的智能体按指南出了版本 2:
tools = [{"type": "agent_toolset_20260401",
"default_config": {"enabled": False, "permission_policy": {"type": "always_ask"}},
"configs": [{"name": n, "enabled": True, "permission_policy": {"type": "always_allow"}} for n in ("read", "glob", "grep")]
+ [{"name": n, "enabled": True, "permission_policy": {"type": "auto"}} for n in ("bash", "write", "edit")]}]
client.beta.agents.update(agent_id, version=1, tools=tools) # 返回版本 2;部署也要指过去
上一节那次定时运行用的就是版本 2。事件里每个 agent.tool_use 都带一个 evaluated_permission 字段,18 次调用全是 "allow":15 次 bash(运行比较脚本、grep 报告、用 diff 对比基准、读本站文章、写简报并 check、commit 写回记忆库),2 次 read,1 次 glob。没有一次暂停,也没有被拒。
所以对日报来说,按指南改成 auto 没有代价:正常的活照样跑完。它的用处在万一被诱导、要做说明之外的事时,服务端会先判断一次。我们没有构造这样的诱导,auto 会拒什么、什么时候会停下来等批准,这次没有看到。指南提醒了两件相关的事:暂停的会话会一直等下去,没人值守的会话要有人回应或者打断它;auto 不是人工检查点,必须由人过目的工具要用 always_ask。
这套设置防得住什么,防不住什么
指南的第二页列了四类风险。放到日报上:
| 风险 | 日报里会怎样 |
|---|---|
| 不可信的输入诱导智能体 | 官方页面或本站文章里如果有诱导的文字,它手里能用的只有 bash 和读写文件:网络只能到 8 个主机,没有凭据可偷,站点索引改不了。能被改坏的是可写的基准和当天的简报 |
| 沙箱里的代码用了凭据 | 沙箱里没有凭据 |
| 网络开着,数据被送出去 | 只开 8 个主机。沙箱里的数据也都是公开的:官方文档和本站已发布的文章 |
| Claude 为了完成任务,走了意料之外的一步 | 这一周见到的大多在预料之内,比如自己写一段 Python 汇总报告、直接读基准文件核对差异。审查报出过一次它绕过脚本、直接用 curl 取更新日志,为的是看全一段被截断的版本说明,主机在白名单里(第十节) |
指南里还有两句话值得记住。日报能放心,靠的都是“沙箱里没有值钱的东西”:
- 不要把绝不能离开沙箱的数据放进沙箱。 设置只能降低风险,智能体仍然可以把它读得到的数据写进回复或工具输出。
- 这些设置互相不能替代。 比如限制了主机,并不能阻止智能体在允许的主机上使用凭据。
另一点:在云端环境里,用 read 读文件时,会顺带把那个目录到工作目录之间的 CLAUDE.md、AGENTS.md 当成指令加载,除了关掉 read 没有开关。日报读的文件是我们自己的 skill 和脚本生成的文件(报告、本站文章的正文),不会出现这两个名字的文件。
还有防不住的一类:内容本身写错。 网页被改得似是而非,简报就会跟着写错。这一类靠的是简报不发布、由人核对后再动文章。
/claude-api managed-agents-secure
指南里提到,Claude Code 自带的 Claude API skill 有一个 managed-agents-secure 命令,会对照这份指南检查一个智能体、它的环境和保险库,只报告、不改动。前提是装好 ant 命令行并登录到智能体所在的工作区。
本站服务器上没有装 ant(装软件要另外授权),所以没能完整跑一次。在服务器上用官方 key 跑了一次 claude -p "/claude-api managed-agents-secure"(Claude Code 2.1.304,Sonnet 5.5,花费约 0.20 美元),它先读了这份指南,然后问要检查哪个智能体,说可以运行 ant beta:agents list --transform '{id,name}' 查 ID,并说明这条命令它不会替你运行。上面的逐条对照是我们照着指南手工做的。
十、事后审查:要不要给日报加
指南怎么说
监控那一页给了两件可选的事:
- 离线审查。 一个和被审会话分开的任务,在事件写完以后读每个会话的事件,找出超出授权的行为。长会话的事件太多,人看不过来,所以让 Claude 读。Claude Cookbook 里有一份完整的做法(把一个智能体允许做什么写成一页说明,先用 60 条正则规则和 7 条结构规则扫一遍,再让 Claude 读,默认用 Haiku 5.5,审 20 个示例会话按标价约 10 美分)。
- webhook。 订阅
session.status_idled(任何原因的空闲)、session.budget_reached、session.status_terminated、deployment_run.failed、deployment.paused这些事件。webhook 可能漏送,所以同时还要定期列一遍会话,检查空闲的那些。
还列了托管智能体保留哪些数据:会话记录保留到你删除为止(归档也保留);沙箱状态保留 30 天;会话的产出文件随会话删除;上传的文件、记忆库、保险库不随会话删除。托管智能体目前不适用零数据保留(ZDR),也不在 HIPAA BAA 的范围内。
我们做了一个最小的版本
Cookbook 的代码在 GitHub 上,要拉仓库,这次没有用。我们按同样的思路写了一个最小版本(不是 Cookbook 的代码):
- 用几句话写下日报智能体本来该做什么:只用脚本访问网络、只访问 8 个主机、不直接改记忆库、不读环境变量和凭据、不装软件包、不照网页里的文字行事。Cookbook 特别提醒,要按你的意图写,不要照抄智能体的配置,否则配置里的错误会变成“允许的”,审查就查不出来了。
- 规则先扫一遍:工具调用里出现白名单外的主机、往
/mnt/memory/写、读环境变量或凭据、装软件包、用了说明之外的工具。 - 把会话精简成一行一个事件(工具的输入留全,结果只留开头),连同说明和规则命中的地方交给 Haiku 5.5,让它给出“正常、看一下、当天处理”三档之一和证据。
审了线上 12 次会话和演示的 4 次,结果:
| 会话 | 结论 | 它指出的 |
|---|---|---|
| 线上 8 次 | 正常 | 没有 |
| 10-15 02:29(建基准,之后在同一会话里做了网络测试) | 看一下 | 访问 example.com、往只读的站点索引写文件。这是我们自己让它做的测试,审查也注明了“由用户在第 32 个事件里明确要求” |
| 10-15 02:34(人为制造改动的测试) | 看一下 | 智能体为了看 2.1.300 那一段的全文,直接用 curl 取了 GitHub 上的 CHANGELOG.md,没有经过脚本 |
| 10-17 补跑、10-20 | 看一下 | 读本站文章比提示词规定的多了一篇,是智能体自己在简报里写明的 |
| 演示 4 次 | 看一下 3 次,当天处理 1 次 | 都和演示时故意加的白名单外来源、网络测试有关;另指出“40 页差异是基准缺行”这个判断没有别的来源交叉验证 |
16 个会话合计约 16 万输入 token、2 万输出 token,按 Haiku 5.5 的标价约 2.6 美分,平均一个会话 0.2 美分。规则这一层第一版写得太宽,rm 没加词边界,把路径里的 platform 当成了删除命令,改过一次。
几点体会:
- 说明写得比提示词严,审查就会报出提示词允许的事。 提示词只说“只访问报告里出现的网址”,
CHANGELOG.md的网址就在报告里,所以那次直接curl并不违反提示词;审查按我们写的“只通过脚本访问网络”判了“看一下”。这正是 Cookbook 说要按意图写说明的原因:它报出来的是“和你想的不一样”,不只是“违规”。 - 线上这一周没有安全上的问题。 报出来的都是“没完全照提示词做”,比如多读一篇文章。这类信息对改提示词有用。
- 便宜到可以每次都跑。 比起日报自己一次几美分到一美元多,审查的花费可以忽略。
结论
- 离线审查:值得加。 打算放进
brief.py fetch:每取回一个会话就审一次,“看一下”以上的在取回时打印出来,和简报一起看。还没有改线上的脚本,等站长定。 - webhook:先不加。 要在服务器上开一个公网的 HTTPS 接收地址,日报又不需要实时处理。指南自己也说 webhook 可能漏送、还要定期列会话;
fetch本来就会列部署的运行记录,启动失败的那次会打印出来。 - 数据保留:现在的做法够用。 会话都留着,里面只有公开的内容;产出文件在
fetch时已经下载到服务器;两个记忆库不随会话删除,不再用时要单独删。
自己做一个时,值得照抄的几条
- 抓取和比较交给脚本,判断交给模型。 网址、清洗规则固定,结果能重现,也省钱。
- 让脚本检查模型的产出。 每个编号恰好写一次、受影响的文章必须存在,这两条让它既漏不了也编不出。
- 写回状态放在检查通过之后。 中途出错或超预算,下一次会把改动一起报出来,不会丢。
- 共享的参考资料用只读挂载。 能写的只留必须写的那一个。
- 预算按改动最多的那一天定,并在提示词里写清楚超量时怎么取舍。 只调高预算不改提示词,上下文还是会越滚越长。
- 判断成没成看产出,不看停止原因。 做完了也可能是
budget_reached。 - 改了智能体,记得让部署跟着改版本。
- 第一次建基准时,和已有的副本对一遍。 日报第一次建基准之前,官方已经改了 109 页,这些改动进了基准,两边都漏看了。
- 白名单只放需要的主机,能避开共享托管的域名就避开。
- 会话里不放凭据。 用不着就别放,比任何替换和限制都可靠。
Anthropic 销售团队用托管智能体做售前助手的文章(9 月 30 日)里有两条经验,可以拿来对照:
- 智能体每改一次就是一个新版本。 他们内部测试一周就到了 v7,出了问题可以让新会话指回旧版本。日报一周也从版本 1 改到了版本 4,回退的办法一样。
- 给目标,不给一长串规则。 他们发现一句话讲清目标,比把每条规则列成流程图效果好。日报的提示词反而是一步步写死的:它的步骤本来就固定,判断规则也要和
check对得上,超预算以后加的“改动多的时候”更是硬规则。两种写法适用的任务不一样。
这次实测没有覆盖到的
- 线上数据只有一周。 原计划试满两周,这篇提前写了。改动多的日子和没改动的日子都遇到了,但一周的平均花费不一定代表平常。
- 保险库、MCP、webhook、Workload Identity Federation 都没有用到。 日报不需要凭据和 MCP;webhook 要一个公网的 HTTPS 接收地址。
/claude-api managed-agents-secure没有完整跑一次,原因见第九节。- 离线审查用的是自己写的最小版本,Cookbook 的完整做法没有跑。
- 没有用真的恶意网页测试提示注入。 第四节只验证了网络和记忆库的边界,诱导本身没有测。
- 自托管沙箱不在这篇的范围里,见《进阶》第五节。
- 价格和各项上限以官方文档为准,这是 beta 功能,可能调整。演示的每种情况只跑了一次。
来源
- Scaling Managed Agents: Decoupling the brain from the hands(Anthropic 工程博客)
- Secure your Managed Agents deployment(Claude 开发平台文档)
- Security risks and sandbox boundaries(Claude 开发平台文档)
- Review and monitor agent sessions(Claude 开发平台文档)
- Scheduled deployments(Claude 开发平台文档)
- Session budgets(Claude 开发平台文档)
- Using agent memory(Claude 开发平台文档)
- Cloud environment setup(Claude 开发平台文档)
- Subscribe to webhooks(Claude 开发平台文档)
- Pricing(Claude 开发平台文档)
- The evolution of agentic surfaces: building with Claude Managed Agents(claude.com)
- How Anthropic's sales team rebuilt inbound with Claude Managed Agents(claude.com)
- Agent security review(Claude Cookbook)