资讯详情

Cloudflare边缘运行时实战:用Workers与Durable Objects构建AI Agent

📅 2026/10/28 23:09:14 | 华诺云谱 👁 阅读
Cloudflare边缘运行时实战:用Workers与Durable Objects构建AI Agent
1. 从 cloudflare-os 这个名字说起它到底指什么第一次看到 cloudflare-os 这个词很多人会下意识以为 Cloudflare 出了一款操作系统能装到电脑或者服务器上。我一开始也是这么理解的直到把 Cloudflare 这几年的产品线捋了一遍才反应过来它不是一个传统意义上的 OS而是一套把 Cloudflare 边缘网络当成运行环境来用的思路集合。你可以把它理解成一个没有内核的操作系统——内核是 Cloudflare 遍布全球的边缘节点系统调用是 Workers、Durable Objects、R2、D1、KV、Queues、AI Gateway 这些服务而应用程序就是你部署上去的 Worker 脚本和 Agent。这个理解很关键因为它直接决定了你该怎么用它。如果你抱着装个系统的心态去找 cloudflare-os 的镜像那注定一无所获但如果你把它当成一套把计算、存储、状态、AI 能力全部搬到边缘的运行时那思路一下子就打开了。关键词里出现的 Cloudflare Workers、AI、agent、Gatekeepers其实已经把这条线索交代得很清楚了这是一套围绕边缘计算 AI Agent 构建的运行时体系而 Gatekeepers 则是这套体系里负责守门的那一层——权限、路由、限流、审计都归它管。我写这篇东西的目的不是给你一份官方文档的复述而是把我自己在这套体系上折腾 Agent 时踩过的坑、想明白的原理、以及那些文档里不会写的细节完整地摊开讲一遍。适合谁看如果你正在做 Agent 开发尤其是想让 Agent 跑在离用户更近的地方、又不想自己维护一堆服务器那这套东西值得你花时间。如果你只是想了解边缘计算 AI到底能玩出什么花样也能从里面拿到不少可复用的思路。先说结论cloudflare-os 这套玩法的核心价值在于它把Agent 的运行位置从中心机房挪到了离用户几百毫秒的地方同时用一套统一的绑定Binding机制把状态、存储、AI 推理串了起来。听起来很美但真上手你会发现边缘环境的限制比你想的多得多——没有文件系统、没有长驻进程、CPU 时间有硬上限、冷启动虽然快但不是零。这些限制不是 bug而是这套体系的设计前提理解它们你才能写出真正跑得稳的 Agent。2. 边缘运行时的真实边界Workers 能做什么、不能做什么2.1 为什么 Agent 适合放在边缘而不是中心机房传统 Agent 的部署方式基本是一台服务器 一个常驻进程 一堆依赖。用户发来请求请求先到中心机房Agent 在那边思考、调工具、生成回复再把结果传回去。这套模式在用户和机房同处一个区域时没问题但一旦用户分布在全球延迟就会变得很难看。我实测过一个简单的对话 Agent用户在国内、机房在美西光是网络往返就稳定在 180ms 以上加上模型推理和工具调用一轮对话轻松超过 2 秒。边缘运行时的思路正好相反把 Agent 的外壳——路由、鉴权、状态读写、工具编排——放到离用户最近的节点上只有真正需要大模型推理的那一步才回源。这样一来网络往返被压到了几十毫秒级别用户感知到的响应速度会有质的提升。Cloudflare 在全球有三百多个节点Workers 会在离用户最近的那个节点上执行这就是它最大的卖点。但这里有个容易被忽略的点边缘节点执行的是你的代码不是你的模型。也就是说Agent 的决策逻辑可以放在边缘但思考能力还是得靠回源到模型服务。所以正确的架构不是把 Agent 整个搬到边缘而是把 Agent 的编排层搬到边缘把推理层留在能跑大模型的地方。这个区分想不清楚后面架构一定会拧巴。2.2 CPU 时间、内存和无状态这三道硬约束Workers 的运行环境有几个硬性限制我按踩坑的痛感排序讲。第一是 CPU 时间。Workers 对单次请求的 CPU 执行时间有上限免费版和付费版额度不同但核心逻辑是一样的你的代码不能长时间占着 CPU 不放。这意味着任何同步等待的操作都是灾难——比如你在 Worker 里写一个循环去轮询某个接口CPU 时间会瞬间打满然后被强制中断。正确做法是把所有 I/O 都做成异步用await让出控制权让运行时去调度。第二是内存。Workers 的内存上限相对宽松但也不是让你拿来当缓存用的。我见过有人试图在 Worker 里维护一个全局的 Map 当缓存结果发现不同请求之间根本不共享——因为每个请求可能落在不同的 isolate 里甚至同一个 isolate 也会被回收。想在边缘做缓存得用 KV 或者 Cache API别指望进程内内存。第三是无状态。这是最反直觉的一点。传统后端你可以起一个进程进程里维护各种全局状态边缘环境不行。每个请求都是独立的请求结束你的执行上下文就没了。那 Agent 需要的记忆怎么办答案是 Durable Objects——它给每个 Agent 实例一个唯一的、有状态的锚点所有需要跨请求保持的状态都放在这里。这是 cloudflare-os 这套体系里最关键的一块拼图后面会专门展开。2.3 冷启动到底有多快以及它为什么重要冷启动是边缘计算绕不开的话题。Workers 用的是 V8 isolate 而不是容器启动一个 isolate 的开销远小于启动一个容器官方给的数据是毫秒级。我实测下来一个不带重型依赖的 Worker冷启动基本在 5ms 以内热请求几乎感觉不到额外开销。但这里有个陷阱如果你的 Worker 引入了体积很大的依赖包isolate 的初始化时间会显著上升。我踩过一次坑为了图方便把一个几百 KB 的工具库整个 import 进来结果冷启动从 3ms 涨到了 40ms 以上。后来改成按需引入、把不常用的逻辑拆到单独的 Worker 里才把启动时间压回去。所以给 Agent 写边缘代码依赖管理要像写前端一样抠——能少引一个包就少引一个。提示判断一个依赖该不该引入先看它的体积和初始化开销。纯函数式的工具库通常没问题带全局副作用、需要读配置、需要初始化连接的库尽量别放在边缘。3. Durable Objects给 Agent 一个记得住事的锚点3.1 为什么 Agent 的记忆不能放在普通存储里Agent 和普通 API 最大的区别是它需要记忆。用户上一句说了什么、Agent 之前调过哪些工具、当前任务进行到哪一步这些都得存下来。用 KV 行不行行但很别扭。KV 是最终一致的你写进去的数据不保证立刻能读到而且 KV 没有锁的概念两个请求同时改同一份记忆很容易互相覆盖。用 D1Cloudflare 的 SQLite 服务行不行也行但 D1 是关系型存储适合结构化查询不适合高频的、按会话隔离的状态读写。而且每次读写都要走一次数据库往返延迟上不划算。Durable Objects 解决的正是这个问题。它给每个对象一个全局唯一的 ID所有对这个 ID 的请求都会被路由到同一个对象实例上这个实例是有状态的、单线程的。你可以把它理解成一个永远在线的、只属于某个会话的小服务器。Agent 的对话历史、任务状态、工具调用记录全都可以放在这里读写是强一致的不用担心并发覆盖。3.2 单线程模型带来的免费并发安全Durable Objects 最妙的地方在于它的单线程模型。同一个对象实例上的所有请求是串行处理的这意味着你根本不需要考虑锁的问题——两个请求同时到达运行时会自动排队一个处理完再处理下一个。对于 Agent 这种状态敏感的场景这简直是天赐的礼物。我举个具体例子。假设你的 Agent 支持多轮工具调用用户发来一条消息Agent 可能连续调用三四个工具中间状态需要保持。如果用普通存储你得自己实现一套乐观锁或者事务机制稍不注意就会出现两个请求同时读到旧状态、各自修改、后写的覆盖先写的这种经典并发 bug。用 Durable Object这个问题从根上就不存在——因为同一时刻只有一个请求在处理这个会话。但单线程也有代价如果你的处理逻辑很慢后面的请求就得排队等。所以 Durable Object 里的代码要尽量快耗时的操作比如调大模型应该异步化或者干脆拆到 Worker 里做Durable Object 只负责状态管理。3.3 状态持久化与休眠机制的实际影响Durable Objects 的状态默认是存在内存里的但 Cloudflare 提供了持久化存储 API可以把关键状态写进对象自带的存储里。这里有个细节值得说Durable Object 支持休眠——当一段时间没有请求时对象会被换出内存下次请求来了再唤醒。唤醒时内存状态会丢失但持久化存储里的数据还在。这个机制对 Agent 的影响很直接你不能假设对象一直活着所有需要跨休眠保持的状态都必须写进持久化存储。我一开始没注意这点把对话历史只放在内存里测试时一切正常上线后用户隔了几分钟再发消息历史就没了。后来改成每次更新都写存储问题才解决。注意Durable Object 的存储写入是异步的但为了保证一致性建议在返回响应前await写入完成。否则可能出现响应已返回、状态还没落盘的情况极端场景下会丢状态。4. Gatekeepers 这一层Agent 的权限、路由与审计怎么做4.1 Gatekeeper 在架构里的位置Gatekeepers 这个词在 cloudflare-os 的语境里指的是介于用户请求和 Agent 执行之间的一层守门逻辑。它不参与 Agent 的思考但负责决定这个请求能不能进来、该路由到哪个 Agent、进来之后能干什么、干完留下什么记录。为什么需要单独一层因为 Agent 和普通 API 不一样它能调工具、能访问外部资源、能产生副作用。如果没有一层统一的管控每个 Agent 自己实现鉴权和限流代码会重复得离谱而且很容易漏掉某个安全边界。把 Gatekeeper 抽出来好处是权限策略集中管理Agent 本身只关心业务逻辑。我自己的做法是把 Gatekeeper 实现成一个独立的 Worker所有请求先经过它它做完鉴权、限流、路由决策后再把请求转发给对应的 Agent Worker。这样 Agent Worker 可以假设进来的请求已经是被信任的代码能简化不少。4.2 用 Worker 实现限流与鉴权的具体思路限流这块边缘环境有个天然优势请求在离用户最近的节点就被拦下了不用等到回源。实现上可以用 KV 存计数器key 是用户 ID 加时间窗口每次请求先读计数器、判断是否超限、再写回。但 KV 是最终一致的高并发下计数可能不准。更稳的做法是用 Durable Object 做计数器每个用户一个对象单线程模型保证了计数的准确性。鉴权这块常见做法是校验请求头里的 token。但要注意边缘环境里做 JWT 验签是有 CPU 开销的尤其是非对称加密。如果 QPS 很高验签可能成为瓶颈。我的经验是能用对称加密就用对称加密或者把验签结果缓存一小段时间比如 60 秒同一个 token 在缓存期内不重复验签。路由决策相对简单根据请求里的 Agent ID 或者用户属性决定转发到哪个 Agent Worker。这里可以用 Workers 的 Service Binding直接调用另一个 Worker不用走公网延迟更低。4.3 审计日志Agent 干了什么必须留痕Agent 的审计比普通 API 重要得多因为它会调工具、会产生副作用。一个用户让 Agent 帮我删掉那封邮件如果 Agent 真的删了事后你得能查到是谁、在什么时候、通过哪个 Agent、调了哪个工具、删了哪封邮件。审计日志的写入不能阻塞主流程否则会拖慢响应。我的做法是把审计事件丢进 Queues由消费者异步写入 R2 或者 D1。Queues 的好处是它自带重试和削峰即使写入端短暂不可用事件也不会丢。日志格式上我建议至少包含这几个字段请求 ID、用户 ID、Agent ID、工具名、参数摘要、结果状态、时间戳。参数摘要要注意脱敏别把敏感信息原样记进去。5. 把 AI 推理接进边缘AI Gateway 与模型调用的取舍5.1 为什么不在边缘直接跑模型很多人第一反应是既然边缘节点这么多为什么不把模型也部署到边缘。答案很现实模型太大边缘节点放不下。一个哪怕量化过的小模型动辄几百 MB 到几个 GB而边缘节点的资源是共享的、有限的不可能给每个节点都塞一个模型。所以正确的做法是边缘负责编排推理回源到模型服务。Cloudflare 提供了 AI Gateway它的作用是给你的模型调用加一层代理——统一入口、缓存、限流、可观测。你可以把它理解成模型调用的 Gatekeeper。5.2 AI Gateway 能省下的那些事AI Gateway 最实用的功能是缓存。很多 Agent 的请求其实是重复的——比如用户问同样的问题、或者系统提示词固定不变。把这些请求的响应缓存起来能省下大量推理成本。我实测过一个客服 Agent开启缓存后重复问题的命中率大概在 20% 左右成本直接降了两成。第二个实用功能是可观测。Agent 调模型不像普通 API 调用那么直观你很难知道这次调用花了多少 token、延迟多少、有没有失败。AI Gateway 把这些指标都记下来了排查问题时非常有用。我有一次发现某个 Agent 的响应特别慢查了 Gateway 的日志才发现是某次工具调用的结果太长把上下文撑爆了导致模型处理时间飙升。第三个是限流和重试。模型服务偶尔会抽风直接调用的话失败就失败了。通过 Gateway 配置重试策略能显著提升 Agent 的稳定性。但要注意重试要幂等——如果工具调用有副作用重试可能导致重复执行。5.3 上下文管理与 token 成本控制Agent 的 token 成本是个无底洞。对话历史越攒越长每次调用都把全部历史塞进去成本会指数级上升。我的做法是分层管理上下文最近的几轮对话保留原文更早的对话做摘要再早的直接丢弃。摘要可以用一个便宜的小模型来做成本远低于把原文塞进主模型。另一个技巧是把系统提示词和工具定义做成可缓存的形式。很多模型服务支持 prompt caching固定的前缀部分只计费一次。把不变的部分系统提示、工具 schema放在前面变化的部分用户输入、历史放在后面能最大化缓存命中率。6. 多 Agent 协作在边缘的落地方式6.1 Agent 之间怎么通信多 Agent 协作听起来很高级但落到边缘环境核心问题就一个Agent 之间怎么通信。常见方案有三种。第一种是 Service Binding一个 Worker 直接调用另一个 Worker。这是最快的因为不走公网但要求两个 Agent 部署在同一个账号下耦合度较高。第二种是 Queues一个 Agent 把任务丢进队列另一个 Agent 消费。这是最松耦合的适合异步任务但延迟比直接调用高。第三种是 Durable Objects多个 Agent 共享同一个对象实例通过对象的方法互相调用。这适合需要共享状态的场景比如多个 Agent 协作完成一个任务中间状态需要互相可见。我自己的经验是同步的、需要立即返回的协作用 Service Binding异步的、可以慢慢处理的用 Queues需要共享状态的用 Durable Objects。别一上来就追求全异步架构很多时候同步调用反而更简单可靠。6.2 状态共享与冲突避免多 Agent 协作最容易出问题的地方是状态共享。两个 Agent 同时修改同一份状态谁赢如果都用 Durable Objects单线程模型天然避免了冲突。但如果状态存在 KV 或 D1 里就得自己处理并发。我的建议是把共享状态收敛到少数几个 Durable Object 里让所有 Agent 都通过这个对象来读写。这样虽然牺牲了一点灵活性但换来的是强一致性和简单的心智模型。Agent 之间的协作协议也尽量简单——能用一个消息类型说清楚的事别设计成复杂的多轮握手。6.3 一个可复用的协作模式编排者 执行者我在实际项目里用得最多的模式是编排者 执行者。编排者 Agent 负责理解用户意图、拆解任务、决定调用哪些执行者执行者 Agent 各自负责一类具体能力比如查数据、发邮件、生成内容。编排者和执行者之间通过 Service Binding 通信执行者的状态各自用 Durable Object 管理。这个模式的好处是职责清晰编排者不需要知道执行者的内部实现执行者也不需要理解全局任务。扩展的时候加一个新的执行者就行编排者那边改一下路由逻辑。我试过用这个模式搭一个包含五六个执行者的系统维护起来比一个大 Agent 干所有事轻松太多。7. 部署与调试那些文档里不会写的细节7.1 本地开发与线上行为的差异Workers 有本地开发工具能在本地模拟边缘环境。但本地和线上永远有差异我踩过的几个典型坑本地 KV 是内存模拟的读写瞬间完成线上 KV 有延迟本地 Durable Object 不会休眠线上会本地没有真实的网络延迟线上跨区域调用会慢很多。所以我的习惯是核心逻辑在本地开发但涉及状态、存储、跨服务调用的部分一定要在线上环境验证。别等到上线才发现本地好好的线上全崩了。7.2 日志与可观测性的搭建边缘环境的日志不像传统服务器那么好拿。Workers 有实时日志tail但只能看当前正在发生的请求历史日志得靠 Logpush 推到外部存储。我的做法是开发阶段用 tail 实时看生产环境用 Logpush 推到 R2再用一个查询 Worker 做检索。可观测性方面除了日志还要关注几个指标请求量、错误率、P99 延迟、CPU 时间消耗、Durable Object 的唤醒次数。这些指标能帮你快速定位问题——比如错误率突然上升可能是某个依赖挂了CPU 时间飙升可能是某段代码写成了同步循环。7.3 灰度发布与回滚边缘环境的发布是原子的一次部署所有节点同时生效。这既是优点也是风险——好处是没有部分节点旧版本、部分节点新版本的中间状态坏处是一旦新版本有问题影响面是全局的。我的做法是用 Workers 的版本管理做灰度先部署一个新版本把少量流量导过去观察一段时间没问题再全量。回滚也很简单把流量切回旧版本就行。这里要注意如果新版本改了 Durable Object 的存储结构回滚时旧版本可能读不懂新数据所以存储结构的变更要向前兼容——新版本能读旧数据旧版本也能读新数据至少不崩。8. 我在实际项目里踩过的几个坑第一个坑是把 Durable Object 当数据库用。我一开始把所有状态都往 Durable Object 里塞包括一些需要复杂查询的数据。结果发现查询逻辑写起来极其别扭而且对象体积越来越大唤醒越来越慢。后来把需要查询的数据挪到 D1需要强一致的状态留在 Durable Object才理顺。第二个坑是忽略 CPU 时间限制。我写过一个工具调用逻辑里面有个循环在等外部接口返回结果 CPU 时间直接打满被中断。后来改成异步轮询加退避问题解决。这个坑的教训是边缘环境里任何忙等都是禁忌。第三个坑是审计日志写同步。我一开始在请求处理流程里同步写审计日志结果日志写入的延迟直接叠加到了用户响应上。改成异步写 Queues 后响应时间降了一大截。第四个坑是多 Agent 共享状态没加锁。早期我用 KV 存共享状态两个 Agent 同时写互相覆盖。后来换成 Durable Object问题消失。这个坑让我彻底理解了边缘环境里强一致状态必须用 Durable Object这条铁律。9. 这套体系适合什么样的项目cloudflare-os 这套玩法不是万能的。它最适合的场景是用户分布广、对延迟敏感、Agent 逻辑以编排为主、状态需要强一致。典型的例子是在线客服、实时助手、轻量级任务自动化。它不太适合的场景是需要大量本地计算、需要长驻进程、需要复杂的关系型查询、对成本极度敏感的大规模推理。这些场景用传统服务器或者容器方案可能更合适。我的建议是先用一个小项目试水把 Workers、Durable Objects、AI Gateway 这几个核心组件跑通感受一下边缘环境的限制和优势。跑通之后再决定要不要把核心业务迁过来。别一上来就 all in边缘环境的坑比你想象的多小步快跑才是正道。最后分享一个我自己的判断标准如果一个 Agent 的思考时间远大于编排时间那边缘化的收益有限如果编排和状态管理占了大部分开销那边缘化能带来明显的体验提升。这个标准帮我在多个项目里做了正确的架构决策也希望对你有用。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑