AI Agent 托管迁移实战:Anthropic SDK 0.100–0.102 如何精简 Cloudflare 工作流

Anthropic SDK 0.100–0.102 在 8 天内加入 Managed Agents、outcomes、webhooks 与多智能体编排。本文以一套 Cloudflare 六 Durable Objects 架构为例,拆解哪些重试和轮询代码可以删除、哪些成本闸门必须保留,以及为何不宜迁移多智能体编排。

Saturday, September 5, 2026Omid Saffari
AI Agent 托管迁移实战:Anthropic SDK 0.100–0.102 如何精简 Cloudflare 工作流

Anthropic Python SDK 先后于 5 月 6 日、5 月 11 日和 5 月 13 日发布 0.100.0、0.101.0 与 0.102.0——8 天内连更 3 个版本,把 Managed Agents 推进为原生支持 outcomes、webhooks 和多智能体编排的托管式 AI Agent 运行时。我对照检查了自己部署在 Cloudflare 上、由 6 个 Durable Object 组成的技术栈,想看 client.beta.managed_agents.sessions.create() 究竟能替掉什么。结论很直接:两个工作流步骤中约 280 行重试与轮询代码可以删除,其余部分保留。

Anthropic SDK 0.100 到 0.102 为 AI Agent 带来了什么

三个版本、八天,Python SDK 的接口变化幅度超过此前六个月的总和。日期很关键:生产环境如果仍锁定在 anthropic==0.99.x,短短一个迭代周期就会错过整套 Managed Agents 运行时。

**v0.100.0(2026 年 5 月 6 日)**在 beta 命名空间加入了多智能体、outcomes、webhooks 和 vault 验证支持。真正关键的接口形态是:client.beta.managed_agents.sessions.create(thread=..., outcome=..., metadata=...) 会返回 session_id,并在 Anthropic 基础设施上异步运行。编排循环从此不再需要自己维护。

**v0.101.0(2026 年 5 月 11 日)**新增了 Claude Platform on AWS 客户端,并将所有 cookbook 示例更新为 claude-sonnet-4-5-20250929。如果使用 Bedrock,需要的是这个版本:ANTHROPIC_BEDROCK_SERVICE_TIER 环境变量对 default/flex/priority 的支持是在 0.101 才加入的,0.100 并没有。

**v0.102.0(2026 年 5 月 13 日)**加入了 BetaManagedAgentsSearchResultBlock 类型、prompt cache beta 的缓存诊断,以及 Pydantic 迭代器的提前验证。block 类型接口仍在变化,这正是我暂不迁移多智能体代码的最大原因。

最值得关注的功能是 outcomes。先写好 rubric,由独立的 evaluator agent 按标准评分;如果结果不合格,agent 会持续重试,直到通过。Anthropic 的内部评测显示,相比标准 prompting 循环,任务成功率最高可提升 +10 points;docx 生成提升 +8.4%,pptx 提升 +10.1%。这与我在自有 Critic Durable Object 中看到的效果一致:把 judge 的意见带回去重跑一次,质量提升大致相当于模型升一个档位。

另一半能力是 webhooks。在 Claude Console 注册 URL 后,会收到八种 session 事件:session.status_run_startedsession.status_idledsession.status_rescheduledsession.status_terminatedsession.thread_createdsession.thread_idledsession.thread_terminated,以及最重要的 session.outcome_evaluation_ended。签名密钥以 whsec_… 开头,只会在创建时显示一次。验证方式是 client.webhooks.unwrap(payload, signature, secret)

多智能体编排也已推出,但需要单独申请 research-preview 访问权限。下文会解释我为什么还没有打开这个开关。

这对非技术创始人意味着什么

现在,agent 的运行交给 Anthropic。你只需写 rubric(例如“文章是否达到 2,000 词、引用 3 个一手来源,并通过去 AI 痕迹的正则检测?”),Anthropic 的 evaluator agent 就会评分,并在不合格时重新运行 agent,直到通过。工程师不必再手写重试循环。

成本会受到两方面影响。第一,代码库里的手工重试循环减少,资深工程师用于维护它们的时间也随之下降。第二,Anthropic session 内部会发生更多重试;除 token 费用外,每个 session-hour 还要收取 $0.08。最终是否划算,完全取决于 session 的运行时长。

更准确的说法是:团队若正在交付 v1 agent 产品,Managed Agents 能替代资深工程师原本要构建的约 40% 编排代码。如果产品已经上线,它能替代的比例会更小,但 webhook 可以消除系统中几乎必然存在的轮询循环。

本周可以直接问 CTO:“我们还在轮询任务是否完成,还是已经改用 session.outcome_evaluation_ended?” 如果答案是“仍在轮询”,那么只需半天重构,就能同时降低基础设施成本和请求延迟。

我目前运行的 Cloudflare 技术栈

为了说明哪些代码可以删除,先交代现有架构:一个 Cloudflare Workers 上的 Hono worker(ES2021 target,绑定 Static Assets)作为入口,后面连接六个 Durable Objects,每个对应一条发布例程:Editorial、Discovery、Writer、Distribution、Maintenance、Manager;此外还有第七个 ManualIntake,为管理后台提供支持。

每条例程分别通过六个 Cloudflare Workflows 之一触发:PublishWorkflowWriteArticlePublishArticleEnrichIdeaDiscoverIdeasDistributeArticle。工作量最大的是 PublishWorkflow,内部包含八个幂等步骤:validate、ground、generate、clean、persist、index、cover、publish。每个 I/O 步骤都包在下面这段逻辑里:

TypeScript
const result = await step.do(
  "generate-article",
  { retries: { limit: 3, backoff: "exponential" } },
  async () => env.WRITER.generate(brief)
);

D1 保存规范状态(editorial_brief.status 的状态流转为 dispatcheddraftingpublished / failed)。Vectorize 负责按 block 生成 embedding(Gemini-2 768d,非对称检索格式)。所有付费模型调用都经过唯一入口 callAi(env, ctx, runner);该入口把记录写入 ai_call_log,包含 agent_idworkflow_instance_ididea_id,以便汇总成本,同时强制执行每日 $20、单实例 $1 的上限。

这就是我之前记录过的 6-DO 架构。迁移到 Managed Agents 时,关键在于重试逻辑位于何处。共有两个位置:

  1. Workflow 步骤重试(成本低;只要底层调用最终成功,重试本身免费):用于网络瞬断、限流和上游服务临时 5xx。
  2. clean.ts 中手写的“judge-and-retry”循环:运行 Writer,再运行 Critic;若 score < 0.75,就附上 Critic 意见重新 prompting,最多尝试 3 次。

Managed Agents 替代的是第二部分,第一部分仍然保留。

SDK 0.100 能让我删除的 280 行代码

src/worker/workflows/publish/clean.ts 中的 judge-and-retry 循环,与 outcomes 的映射最清晰。目前它包含约 120 行编排代码:调用 Writer;按 editorial_brief.rubric_md 中保存的 rubric 调用 Critic;解析分数;根据阈值分支;把意见作为 system block 附上后重新 prompting;最多重复三次。Critic 本身又占 80 行 Durable Object 代码,包含 hibernation hooks、用于 rubric 历史的单实例 SQLite,以及每次尝试的幂等键。callAi.ts 中按尝试记录并由 dashboard 汇总的 ai_call_log 逻辑再占 40 行。

这三个代码块可以收敛成一次 Managed Agents 调用:

TypeScript
const session = await anthropic.beta.managedAgents.sessions.create({
  thread: { messages: [{ role: "user", content: brief.body_md }] },
  outcome: {
    rubric: brief.rubric_md,
    evaluator: "claude-sonnet-4-5-20250929"
  },
  metadata: { brief_id: brief.id, workflow_instance: ctx.instanceId }
});
return { session_id: session.id, status: "pending" };

就这些。session 会在 Anthropic 一侧异步运行直至完成。outcome 参数接管原先由 Critic DO 完成的工作:独立 evaluator agent 按 rubric 评分,如果未通过,就重新运行主 agent。

需要新增的代码只有一个 /api/admin/webhooks/managed-agents 路由:验证 whsec_… 签名,判断 event.type === "session.outcome_evaluation_ended",然后把结果写回 D1。

TypeScript
app.post("/api/admin/webhooks/managed-agents", async (c) => {
  const raw = await c.req.text();
  const event = await anthropic.webhooks.unwrap(
    raw, c.req.header("anthropic-signature")!, c.env.WEBHOOK_SECRET
  );

  if (event.type !== "session.outcome_evaluation_ended") {
    return c.json({ ok: true });
  }

  await c.env.DB.update(editorial_brief).set({
    status: event.outcome.passed ? "published" : "failed",
    body_md: event.result.body,
    session_cost_usd: event.session.usage.total_cost_usd
  }).where(eq(editorial_brief.id, event.session.metadata.brief_id));

  return c.json({ ok: true });
});

共 40 行,签名已经验证,并以 brief_id 为键实现幂等。

**净变化:**减少 240 行编排代码;从 wrangler.json 中移除一个 Durable Object binding;删除一个 migration 文件;新增 40 行 webhook 处理代码;在 Cloudflare Secrets Store 中增加一个 secret。

GET /api/admin/workflows/:id/status 轮询端点仍可继续使用。现在它从 D1 读取 session 状态(状态由 webhook 写入),不再调用 env.PUBLISH_WORKFLOW.get(id).status()。UI 无需修改,管理 dashboard 也不会感知差异。

需要特别强调:其他所有 I/O 步骤上的 step.do 重试 wrapper 都应保留。封面图生成、Vercel revalidation、Cloudflare cache purge 都无法从 outcome rubric 中获益,却都需要 Workflows 可安全 replay 的步骤缓存。已经可靠运行的部分不要拆。

唯一保留的文件:AI Agent 上规模后,成本账会反转

callAi.ts 必须保留:每日 $20 上限、单实例 $1 上限。无论调用是直接发出、经由 AI Gateway,还是通过 Managed Agents,所有付费模型请求都要从这里经过。

原因在于 Managed Agents 按三个维度计费:token 采用标准价格,另加每个 session-hour $0.08,以及每 1000 次 web search $10。按我目前的规模,六条发布例程每次各产出一篇文章,每个 session 约 3 分钟;除 token 外,每篇文章的 session-hour 成本约为 $0.004,几乎可以忽略。

当 session 变长,账目就会反转。一个运行 4 小时的 Anthropic Skills session,仅运行时就要 $0.32,token 费用另计。若每天运行 50 个这样的 session,那么还没算 token,每月单是 session-hour 就要 $480。多步骤 research session 如果在 web search 队列中空等一小时,会多出原本不需要支付的 $0.08;等待下游服务的空闲时间同样计费(Anthropic 文档称计量精确到毫秒,但计费表一直在走)。

这个统一入口能设置 Managed Agents dashboard 没有的硬上限。dashboard 只能在事后显示 session 成本;如果预估成本会突破每日限额,callAi.ts 会在 session 启动前、工作流运行中抛出 NonRetryableError

预估模型采用保守值:

TypeScript
async function estimateSessionCost(brief: Brief): Promise<number> {
  const tokenEstimate = brief.body_md.length / 3.5;
  const inputCost = (tokenEstimate / 1_000_000) * 3.0;
  const outputCost = (tokenEstimate * 1.5 / 1_000_000) * 15.0;
  const sessionHourEstimate = (brief.expected_minutes / 60) * 0.08;
  const safetyMargin = 1.4;
  return (inputCost + outputCost + sessionHourEstimate) * safetyMargin;
}

单 session-hour 的成本计算最容易让独立工程师的架构失控。如果没有上限,一个失控的 agent——而 rubric 过严时,outcome 重试循环恰恰可能诱发这种行为——会在你发现前吃光当天预算。我已经见过这种情况。

保留统一入口,让 sessions.create() 从这里经过。session 开始前记录预估成本;结束时通过 webhook payload 中的 event.session.usage.total_cost_usd 核对实际费用。

我暂不执行的迁移:多智能体编排

多智能体编排是 Anthropic Dev Day 的主打功能。Lead agent 会拆解任务,把子任务交给各自拥有模型、prompt 与 tools 的 specialist subagents。Subagents 基于共享文件系统并行工作,最后由 Lead 汇总。从概念上看,这与我的 Manager DO 完全相同:通过 DO RPC 并行派发给 WriterDiscoveryDistribution;每个对象都有自己的 SQLite 状态,并以 R2 + D1 充当共享“文件系统”。

我选择观望有三个原因。

**第一,API 仍在快速变化。**多智能体编排仍处于 research preview,需要单独申请权限。BetaManagedAgentsSearchResultBlock 刚在 0.102 加入,多智能体结果的 block 类型接口还没定型。现在迁移,意味着接下来两三个 SDK 版本每次升级都要重写集成代码。Webhook 接口在 0.100 已经稳定,多智能体部分仍在变动。

**第二,共享文件系统仅限当前 session,而且是临时的。**Managed Agents session 一旦终止,内部共享文件系统就会消失。R2 与 D1 则能跨所有例程长期保存,任何 worker 都可以查询,并能从 session 崩溃中存活。在共享文件系统实现跨 session 持久化之前(或 R2 能直接挂载到 session sandbox 之前),这对我的工作负载而言属于功能倒退。

**第三,Anthropic 对 Lead/subagent 的分工有固定取向。**Lead-agent 角色是固定的。有时发布例程触发后,我的 Editorial DO 是 Lead;有时管理后台派发 brief,Editorial 在流水线中途加入,此时它只是 peer。为了适配托管抽象而抹平这种有用的不对称性,并不划算。

什么会让我改变决定?当共享文件系统能持久化并跨 session 使用,或 R2 可以挂载到 sandbox 时,迁移才真正有吸引力。现阶段它只是横向替换,而非升级。

SDK 0.100 到 0.102 的完整迁移清单

  1. 锁定 SDK 版本

    Bash
    uv add anthropic@0.102.0

    如果还没有使用 uv,也可以执行 pip install anthropic==0.102.0。除非有必须停在 0.101 的 Bedrock 特定原因,否则直接跳过 0.100 和 0.101。

  2. 在 Claude Console 注册 webhook

    Claude Console → Settings → Webhooks → New endpoint。端点填写 https://your-worker.example.com/api/admin/webhooks/managed-agents。复制创建时仅显示一次的 whsec_… secret,并保存到 Cloudflare Secrets Store;如果通过 SDK 0.101 使用 Claude Platform on AWS,则保存到 AWS Secrets Manager。

  3. 添加 webhook 路由

    创建 /api/admin/webhooks/managed-agents。使用 client.webhooks.unwrap(payload, signature, secret) 验证签名;这个 helper 在 v0.95.x 加入,并在 0.100 稳定下来。一次 unwrap 调用即可完成 HMAC 验证、时间戳容差检查和事件类型解析。不要自行实现 HMAC 验证,时间戳偏差窗口并没有看起来那么简单。

  4. 改造 evaluator 步骤

    sessions.create() 中使用 outcome={rubric: brief.rubric_md, evaluator: "claude-sonnet-4-5-20250929"},替换原有 judge-and-retry 循环。移除 Critic DO 与重试编排,但继续把 rubric 存在 D1 中;rubric 字段不是变得不重要,而是更重要了。

  5. 从轮询切换到 D1 状态读取

    状态端点现在从 D1 读取,键为 event.session.metadata.brief_id,也可以使用在 sessions.create()metadata 中设置的其他关联键。Webhook 负责写入,状态端点负责读取,不再发生 workflow.status() 往返调用。

  6. 保留成本统一入口

    callAi.ts 继续保留。在 session 启动前预估成本;若预估会突破每日上限,则抛出 NonRetryableError。在 webhook handler 中通过 event.session.usage 记录完成后的实际费用。每周核对预估值与实际值;如果偏差超过 25%,就调整 safety margin。

  7. 先在风险最低的例程上测试

    我选择的是 Discovery,因为迁移出错也不会产生公开内容。新旧路径并行运行 72 小时,对比输出;确认无误后再迁移 Writer

现有 Anthropic Bedrock 环境能否使用 SDK 0.100?

可以,但专用 AWS client 是在 0.101 才加入的。如果使用 Bedrock,应升级到 0.100 以上。SDK 0.101 还新增了 ANTHROPIC_BEDROCK_SERVICE_TIER 环境变量支持(default/flex/priority),0.100 并不支持。

Webhooks 会完全取代 streaming response API 吗?

不会。Webhooks 面向 session 生命周期事件(started、idled、terminated、outcome-evaluation-ended);streaming response 仍通过 messages.create(stream=True) 和常规 delta protocol 传输。Webhooks 解决的是“长时间运行的 session 完成后通知我”,streaming 则解决“生成时逐步显示 token”。

签名密钥的格式是什么,应该如何验证?

密钥以 whsec_… 开头,只在 Console 创建时显示一次。通过 client.webhooks.unwrap(raw_body, signature_header, secret) 验证;一次调用即可处理 HMAC、时间戳容差和事件类型解析。不要记录原始 secret,也不要把它放在 query parameter 中;应使用 Cloudflare Secrets Store 或同类服务。

能否不使用 Managed Agents,只通过 Messages API 运行 outcomes evaluation?

不能。outcome={rubric, evaluator}sessions.create() 上仅供 Managed Agents 使用的参数。可以用 Messages API 自行构建等价方案——我的 Critic DO 目前就是这样做的——但需要自行承担编排延迟并维护相关代码。Managed Agents 的价值正是免去这些工作。

Managed Agents session 内仍能使用 prompt caching 吗?

可以,而且 cache hit 时最多可降低 90% 的 input 成本。Prompt cache beta 的缓存诊断功能是在 0.102 加入的,因此现在可以直接在 response payload 中查看 cache hit rate。

迁移 Discovery 只需一个下午,Writer 再用一个下午,其余部分随后跟进。锁定 0.102.0,注册 webhook,删除 Critic DO,保留成本统一入口。

最近更新

2026年9月5日

分类Build

在 Google 中优先显示本站

将 omidsaffari.com 添加为 Google 搜索的优先来源

把 omidsaffari.com 设为优先来源,Google 会在 Top Stories、AI Overviews 和 AI Mode 中为您优先展示。

更多 Build 文章

查看全部 Build 文章
订阅通讯

每周日,一封信。 写运转中的系统,不写热评。

来自一组 AI 项目组合运营的构建日志、生产系统与一线笔记。

每周一期。无垃圾邮件。随时退订。