Cloudflare Dynamic Workflows 上线前先过哪 5 关?我把官方 basic example 和一个失败路径都跑了一遍
先说结论:如果你只是想把一个固定的长任务搬到 Cloudflare 上,直接用 Cloudflare Workflows 就够了,不必为了 Cloudflare Dynamic Workflows 增加一层调度器。它真正适合的是“每个租户、每个 agent、每个 repo 都可能在运行时生成不同工作流代码”的场景。本文写作时(2026-05-11),我按 Cloudflare 官方 basic-example 在本地跑通了一次成功路径,又补了一次缺少 TenantWorkflow 的失败路径;结论是:先验收调度器绑定、动态 worker 入口和失败回执,再谈多租户 agent 平台上生产。
最小判断
- 你只有一套固定流程:先别上 Cloudflare Dynamic Workflows。
- 你需要让租户或 agent 在运行时提交不同工作流代码:可以继续看这篇。
- 你还没想清楚
Worker Loader、WorkflowEntrypoint和回执日志谁负责:先别急着接生产流量。
Cloudflare 现在文档里把 Dynamic Workflows 放在 Dynamic Workers 的使用章节下,但它底层依然跑在 Cloudflare Workflows 上。也就是说,它不是一个全新的编排产品,而是一层把“运行时加载的租户代码”重新接到 Workflows durable execution 上的胶水层。这个定位,和我们前面写过的 Cloudflare Rust Workers 最小复现 一样,重点不在“能不能跑”,而在“边界是不是清楚”;如果你还在看 Cloudflare 的 agent 体系成熟度,也可以顺手对照 Agent Readiness Score 那篇判断 和 Cloudflare 内部 AI 工程栈拆解 一起看。
Cloudflare Dynamic Workflows 解决的到底是什么问题
官方博客给出的核心限制很直接:传统 Workflows 默认假设 class_name 在部署时就已经固定;但多租户 SaaS、agent 平台、CI/CD 产品里,真正要跑的流程代码往往是按租户、按任务、按 repo 在运行时才出现。Dynamic Workflows 要解决的,不是“让工作流更长”,而是让同一个调度器 Worker 在运行时把不同 create() 请求路由回各自的租户工作流实现。
从 Cloudflare 官方 blog、Dynamic Workers docs 和 cloudflare/dynamic-workflows README 交叉看,它的模型只有三层:
- Worker Loader:你自己部署的调度器,负责按租户或 runId 加载动态 worker。
- wrapped WORKFLOWS binding:把
create()时的 metadata(比如tenantId或runId)封进 payload。 - DynamicWorkflow entrypoint:真正执行
run(event, step)时,再把这层 metadata 解出来,路由回正确的租户代码。
如果你的系统没有“同一个平台承载 N 份不同工作流代码”这件事,那这层复杂度大多是白加的。
我这次怎么做最小验收
本文写作时,我直接按 Cloudflare 官方仓库 cloudflare/dynamic-workflows 的 examples/basic 跑了一轮本地验证,环境是 macOS + Node 22.22.0 + pnpm 10.31.0 + Wrangler 4.83.0。
第一步:先确认官方库能在本地通过自己的测试
我先 clone 官方仓库,然后跑依赖安装和测试:
git clone --depth=1 https://github.com/cloudflare/dynamic-workflows.git
cd dynamic-workflows
pnpm install
pnpm run test
本地结果:
pnpm run test先构建库,再调用wrangler types和vitest- 最终 2 个 test files、22 个 tests 全部通过
- 这一步至少说明官方提供的
wrapWorkflowBinding、createDynamicWorkflowEntrypoint和测试里的 workerd 运行路径在本地是通的
这一步不能证明你的业务代码就能上生产,但能先排除“官方样例自己都没跑通”的低级问题。
第二步:把官方 basic example 在本地启动起来
接着我进入官方 examples/basic,直接用本地 dev server 验证调度器和动态 worker 的配合:
cd examples/basic
pnpm run dev
Wrangler 本地输出里,我拿到的关键信号是:
env.WORKFLOWS (DynamicWorkflow) Workflow localenv.LOADER Worker Loader localReady on http://localhost:8787
如果你连这三项都没有,就先别往后加 agent 或租户逻辑。因为这代表你的本地最小调度骨架还没立住。
第三步:直接打官方 demo 的 API,看成功路径是不是完整闭环
官方 example 暴露了 /api/source、/api/run、/api/status/:runId。我没有只看浏览器页面,而是直接打 HTTP:
curl http://127.0.0.1:8787/api/source
curl -X POST http://127.0.0.1:8787/api/run \
-H 'content-type: application/json' \
-d '{
"source": "<从 /api/source 取回的默认 tenant worker 代码>",
"payload": {"name": "TG Hubs"}
}'
我这次跑到的关键回执是:
runId和id成功返回- 初始
status是running - 轮询
/api/status/:runId后,状态从running变成complete - 最终
output返回:
{
"original": "Hello, TG Hubs!",
"shouted": "HELLO, TG HUBS!!!!",
"length": 18
}
这一步才算真正碰到了 Dynamic Workflows 的核心主张:动态加载的 tenant worker 可以触发 workflow,后续步骤也能沿着同一个 runId 跑完并取回结果。
一个我故意补的失败路径:缺少 TenantWorkflow 会直接报错
只跑成功路径还不够,所以我又故意把 tenant 代码改坏:保留 default.fetch 里对 env.WORKFLOWS.create() 的调用,但去掉 TenantWorkflow 类定义,再重新 POST /api/run。
这次不是模糊失败,而是直接返回了可以拿来写验收 checklist 的错误:
{
"status": "errored",
"error": {
"message": "Worker has no such entrypoint: TenantWorkflow",
"name": "Error"
}
}
这个失败路径很有价值,因为它说明 Dynamic Workflows 最先出问题的地方,往往不是 durable execution 本身,而是调度器和动态 worker 之间的入口契约。你让租户写代码也好,让 agent 生成代码也好,至少要先验这三件事:
- tenant worker 是否真的导出了
TenantWorkflow - 调度器注册的
class_name和租户入口命名是否一致 - workflow 创建和后续
run()是否都沿用了同一份 metadata / runId
什么时候值得上 Cloudflare Dynamic Workflows
你可以考虑继续推进 Cloudflare Dynamic Workflows,前提通常是下面三条至少满足两条:
- 你的平台不是单租户流程:每个租户、repo 或 agent 真的会提交不同工作流逻辑。
- 你需要 durable steps:不是只跑一个短请求,而是明确要用
step.do()、step.sleep()、step.waitForEvent()这类跨重启持续执行能力。 - 你不想自己维护调度和恢复层:如果要自己把 metadata、状态恢复、入口路由、日志回放全补一遍,复杂度通常比直接接这个库更高。
更实际一点说,它更像“多租户 agent 平台的编排胶水层”,而不是“所有 Cloudflare 工作流都该升级的新默认”。
什么时候先别用
下面这些情况,我会建议先别上:
- 你只有一套固定 workflow,部署时就能确定
class_name - 你还没有把动态代码的权限、审计和日志边界想清楚
- 你只是想要一个长任务执行器,但并不需要“按租户动态加载代码”
- 你团队里还没人能独立排查 Worker Loader、Workflow 和动态入口三层之间的报错
这也是为什么它和 Shared Dictionaries 那篇判断 不一样:后者更偏“频繁发版团队是否能拿到收益”,而 Dynamic Workflows 更像“你是不是已经进入了多租户 agent 编排这道门”。
发布前可以直接照抄的最小验收清单
如果你准备把 Cloudflare Dynamic Workflows 接进真实平台,我建议先过这 5 项:
- 官方库自测通过:
pnpm run test至少先跑绿。 - 本地绑定齐全:Wrangler 能明确显示
WORKFLOWS和LOADER两个本地 binding。 - 成功路径闭环:
/api/run到/api/status/:runId能拿到complete和可验证 output。 - 失败路径可读:故意制造一次缺少
TenantWorkflow、错误入口名或错误 metadata,确保错误不是“静默挂起”。 - 边界写清楚:哪些代码允许租户提交、哪些 metadata 只是路由提示、哪些值绝不能塞进 payload,要在接生产前先定下来。
只要前 3 项都还没过,就别急着把它包装成“平台已经支持 agent 工作流”。
FAQ
Cloudflare Dynamic Workflows 和普通 Cloudflare Workflows 有什么区别?
普通 Cloudflare Workflows 默认假设 workflow 类在部署时就固定好了;Cloudflare Dynamic Workflows 解决的是“运行时加载的不同租户代码,怎样继续享受 Workflows 的 durable execution”。如果你的 workflow 类本来就是固定的,通常没必要加这一层。
Cloudflare Dynamic Workflows 能不能直接当 agent orchestration 平台?
不能直接等同。它更像把动态 worker 接到 durable workflow 的基础胶水层。真正要上生产,你还得自己补权限边界、日志、输入校验、回放和租户隔离。
Cloudflare Dynamic Workflows 最容易先踩哪类坑?
从我这次本地验证看,第一类坑不是性能,而是入口契约:TenantWorkflow 没导出、class_name 不匹配、metadata 没沿着 create() 带到 run(),都会让你在第一轮就卡住。
没有多租户需求,只是想跑长任务,还要不要看 Cloudflare Dynamic Workflows?
大概率不用。先看普通 Cloudflare Workflows 就够了。Cloudflare Dynamic Workflows 的额外复杂度,只有在“动态代码 + durable execution”同时出现时才值回票价。
结论
如果你问我 Cloudflare Dynamic Workflows 现在值不值得跟,我的答案是:值得跟,但只适合已经进入多租户 agent / 动态代码编排阶段的团队。 我这次按官方仓库把成功路径和失败路径都跑过之后,更确定它不是一个“更高级的长任务功能”,而是一套要求你先把调度入口、动态代码契约和回执链路讲清楚的基础设施。先把这套最小验收跑通,再谈要不要接进生产。