news 2026/10/28 13:56:17

cloudflare-os 边缘 Agent 运行时框架:从部署到多 Agent 协作实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
cloudflare-os 边缘 Agent 运行时框架:从部署到多 Agent 协作实战

1. 从标题说起:cloudflare-os 到底是个什么东西

第一次看到cloudflare-os这个名字,我下意识以为 Cloudflare 又出了个操作系统。毕竟这家公司这些年干的事越来越“底层”——从 CDN 起家,一路做到 DNS、零信任、R2 存储、D1 数据库、Workers 计算平台,现在再冒出个“OS”其实也不算意外。但真正去翻了一圈资料、动手跑了一遍之后,我发现它跟传统意义上的操作系统完全是两码事。它更像是一个跑在 Cloudflare Workers 之上的 Agent 运行时框架,把“AI Agent 该住哪儿、怎么调度、怎么记忆、怎么协作”这一整套问题,用边缘计算的方式重新回答了一遍。

说白了,cloudflare-os想解决的核心痛点是:现在大家做 AI Agent,要么本地跑一套 Python 环境,要么租一台云服务器常驻进程,要么用各种 Serverless 拼凑。本地跑的问题是关机就没了、多设备不同步;云服务器的问题是贵、运维烦、冷启动慢;Serverless 拼凑的问题是状态难保持、Agent 之间的通信全靠自己造轮子。而cloudflare-os的思路是——把 Agent 直接部署到全球边缘节点上,用 Workers 做执行引擎,用 Durable Objects 做状态容器,用 KV/R2/D1 做记忆分层,用 pnpm 做依赖管理,让一个 Agent 从“一台机器上的进程”变成“一张网上的常驻实体”。

这套东西适合谁?我觉得三类人最该关注。第一类是独立开发者和小团队,想快速搭一个能 7x24 在线的 Agent,又不想养服务器;第二类是做多 Agent 协作实验的人,需要 Agent 之间能互相发现、互相调用、共享记忆;第三类是对边缘计算 + AI 结合感兴趣的工程师,想看看把推理调度、工具调用、状态管理全放到边缘节点上会是什么体验。如果你只是想让 AI 帮你写个周报,那这东西确实有点杀鸡用牛刀;但如果你在认真考虑“Agent 作为一种基础设施”这件事,那cloudflare-os值得花时间研究。

我下面会从整体设计思路、核心模块拆解、实操部署流程、常见坑与排查四个大块来讲,中间会穿插我自己踩过的坑和一些参数选择的计算逻辑。文章里提到的具体配置和命令,都是基于我实际跑通的版本整理的,你可以直接抄作业,但要注意版本迭代很快,遇到不一致的地方以官方最新文档为准。

2. 整体设计思路:为什么要把 Agent 塞进边缘网络

2.1 从“进程”到“实体”:Agent 的部署范式转移

传统 Agent 的部署模型,本质上是进程模型。你在本地起一个 Python 脚本,它就是一个进程;你把它放到服务器上,它还是一个进程,只不过换了个地方跑。进程模型有几个天然限制:生命周期绑定在宿主上、状态存在内存里、跨进程通信要靠网络、扩容要靠复制。这些限制在单机场景下无所谓,但一旦你想让 Agent 长期在线、多实例协作、按需伸缩,进程模型就开始拖后腿了。

cloudflare-os换了一个思路,把 Agent 当成网络实体来对待。每个 Agent 不是一个进程,而是一个有地址、有状态、有生命周期管理的边缘对象。它跑在 Cloudflare 的全球网络里,你不需要关心它在哪个物理机器上,只需要关心它的逻辑身份和状态。这个转变听起来抽象,但落到具体实现上其实很清晰:Agent 的执行逻辑放在 Worker 里,Agent 的状态放在 Durable Object 里,Agent 的记忆放在 KV 和 R2 里,Agent 之间的通信走内部 RPC。每一层都有明确的职责边界,互不干扰。

我一开始觉得这套设计有点过度工程化,毕竟一个 Agent 而已,至于搞这么复杂吗?但后来想明白了一件事:Agent 的本质不是“一次推理”,而是“持续存在”。一个真正有用的 Agent,需要记住昨天聊过什么、需要在你不在线的时候继续处理任务、需要在多个设备之间保持一致性。这些需求用进程模型做,要么做不了,要么做得很别扭。而用边缘实体模型做,这些能力是天然具备的。这就是设计思路上的根本差异。

2.2 为什么选 Workers 而不是容器

很多人会问,既然要跑 Agent,为什么不直接用容器?Docker 镜像一打,往云上一扔,什么依赖都能装,多省事。这个思路没错,但容器有几个绕不开的问题:冷启动慢、资源粒度粗、全球分布难、按量计费不友好。一个 Agent 可能 90% 的时间都在等消息,只有 10% 的时间在真正计算,用容器跑就是 90% 的资源浪费。

Workers 的优势正好补上这些短板。它的冷启动在毫秒级,资源粒度是请求级的,全球网络天然分布,计费按实际执行时间算。对于 Agent 这种“大部分时间在等待、小部分时间在计算”的负载来说,Workers 的模型匹配度非常高。当然,Workers 也有它的限制:运行时不支持完整的 Node.js API、有 CPU 时间上限、不能跑长时间阻塞任务。但这些限制在 Agent 场景下反而变成了约束条件,逼着你把 Agent 设计成事件驱动、短执行、状态外置的形态,而这恰恰是更健壮的架构。

我实测下来,一个典型的 Agent 请求在 Workers 上的执行时间大概在 50ms 到 300ms 之间,取决于工具调用的复杂度。如果涉及到外部 API 调用,时间会更长,但那是网络延迟,不是计算延迟。这个性能水平对于大多数 Agent 场景是够用的,除非你在做实时性要求极高的东西,比如高频交易或者实时游戏 AI,那 Workers 可能不是最佳选择。

2.3 pnpm 在其中的角色:依赖管理的边缘化

热词里反复出现pnpm,这不是偶然。cloudflare-os的工程体系是围绕 pnpm 构建的,原因很简单:边缘运行时的依赖必须极度精简。Workers 的包体积有硬性限制,免费版 1MB,付费版 10MB,压缩后更小。用 npm 或者 yarn 装一堆冗余依赖,很容易就超了。pnpm 的硬链接和内容寻址存储机制,能在保证依赖完整性的同时把体积压到最小。

但 pnpm 也带来了不少麻烦,热词里那些“pnpm 不是内部或外部命令”“pnpm 下载失败”“pnpm 离线安装”就是典型症状。这些问题我在不同机器上都遇到过,后面会专门讲怎么排查。这里先给一个结论:如果你打算认真玩cloudflare-os,先把 pnpm 环境搞稳,不然后面每一步都会卡。pnpm 的版本建议锁在 8.x 或 9.x,太老的版本和 Workers 的构建工具链不兼容,太新的版本又可能有实验性改动导致构建失败。

3. 核心模块拆解:一个 Agent 在边缘网络里怎么活

3.1 Worker 执行层:Agent 的“身体”

Worker 是 Agent 的执行载体,你可以把它理解成 Agent 的“身体”。它负责接收请求、解析意图、调用工具、生成响应。在cloudflare-os的架构里,每个 Agent 至少对应一个 Worker,复杂一点的 Agent 可能会拆成多个 Worker 分别处理不同职责,比如一个负责对话、一个负责工具调用、一个负责定时任务。

Worker 的入口通常是一个fetch处理器,但cloudflare-os会在此基础上封装一层 Agent 路由。我看到的典型结构是这样的:请求进来先经过一个意图识别层,判断这是对话请求、工具调用请求还是系统管理请求;然后根据意图分发到对应的处理函数;处理函数再调用 LLM、访问状态、执行工具;最后把结果组装成响应返回。这个流程听起来简单,但实际写起来有很多细节要注意,比如错误处理、超时控制、重试策略、日志记录。

注意:Worker 的 CPU 时间上限是 50ms(免费版)或 30 秒(付费版),但这里的 CPU 时间不包括等待网络 IO 的时间。所以如果你的 Agent 主要时间花在等 LLM 响应上,那 CPU 时间其实用不了多少。但如果你在 Worker 里做大量计算,比如向量检索或者文本处理,就要小心超限。

3.2 Durable Objects:Agent 的“记忆中枢”

Durable Objects 是cloudflare-os里最关键的组件,没有之一。它解决的是 Agent 的状态问题。传统 Serverless 函数是无状态的,每次调用都是全新的,这对 Agent 来说是致命的——Agent 需要记住上下文、记住用户偏好、记住任务进度。Durable Objects 提供了一个有状态的、单实例的、全球可寻址的对象,正好补上这个缺口。

每个 Durable Object 有一个唯一的 ID,这个 ID 就是 Agent 的“身份证”。你可以用用户 ID、会话 ID 或者自定义的字符串来生成这个 ID。同一个 ID 的请求永远路由到同一个 Durable Object 实例,这就保证了状态的一致性。Durable Object 内部可以持有内存状态、可以访问存储、可以设置定时器、可以和其他 Durable Object 通信。我实测下来,一个 Durable Object 处理一次状态读写大概在 10ms 到 50ms 之间,取决于存储后端的负载。

这里有个设计上的取舍值得说:Durable Objects 是单实例的,这意味着同一个 ID 的请求是串行处理的。这个特性对于 Agent 来说其实是好事,因为它天然避免了并发写冲突。但如果你有一个高并发的 Agent,比如同时服务几千个用户,那单个 Durable Object 可能成为瓶颈。解决办法是分片——把不同用户路由到不同的 Durable Object,每个 Object 只负责一小部分用户。cloudflare-os里通常会用用户 ID 的哈希来做分片键,这样既能保证同一用户的状态一致,又能把负载分散开。

3.3 KV、R2、D1:Agent 的“三层记忆”

cloudflare-os把 Agent 的记忆分成三层,分别对应不同的存储后端。这个分层设计是我觉得最值得借鉴的地方,因为它把“记忆”这个模糊的概念拆成了可操作的工程结构。

第一层是KV(Key-Value),用来存短期记忆和配置。比如当前会话的上下文、用户的临时偏好、Agent 的运行参数。KV 的读写延迟很低,全球分布,适合存小块的、频繁访问的数据。但 KV 的写入有延迟(最终一致性),所以不适合存需要强一致性的东西。

第二层是R2,用来存长期记忆和文件。比如对话历史归档、用户上传的文档、Agent 生成的报告。R2 是对象存储,容量大、成本低、支持 S3 兼容 API。我通常会把超过一定长度的对话历史定期归档到 R2,然后在 KV 里只保留最近几轮,这样既能控制 KV 的体积,又能保证历史可追溯。

第三层是D1,用来存结构化数据和关系。比如用户表、任务表、工具调用记录。D1 是 SQLite 的边缘版本,支持标准 SQL,适合做查询和聚合。如果你需要做“找出所有上周调用过某个工具的用户”这种查询,D1 是最合适的。

存储层适用场景一致性延迟成本
KV短期记忆、配置最终一致低低
R2长期记忆、文件强一致中极低
D1结构化数据、查询强一致中低

这个分层不是死的,你可以根据实际需求调整。比如有些 Agent 不需要长期记忆,那 R2 就可以省掉;有些 Agent 不需要复杂查询,那 D1 也可以不用。关键是理解每层的特性,然后按需组合。

3.4 Agent 间通信:从“孤岛”到“协作”

热词里有“多 AI 协作”和“agent 架构”,这正好对应cloudflare-os的一个核心能力:Agent 之间的通信。在传统架构里,两个 Agent 要协作,要么通过外部消息队列,要么通过 HTTP 互相调用,要么共享一个数据库。这些方式都有延迟高、耦合重、难管理的问题。

cloudflare-os的做法是利用 Durable Objects 的 RPC 能力,让 Agent 之间可以直接调用。一个 Agent 可以通过 Durable Object 的 ID 直接找到另一个 Agent,然后调用它的方法。这个过程不经过公网,延迟极低,而且天然支持状态传递。我试过让一个“调度 Agent”去调用三个“执行 Agent”分别处理子任务,整个流程跑下来比用 HTTP 调用快了将近一个数量级。

但这里有个坑要注意:Durable Object 之间的调用是同步的,如果被调用的 Agent 处理时间过长,调用方会被阻塞。解决办法是把长任务拆成异步的,调用方只负责发起任务,然后通过回调或者轮询获取结果。cloudflare-os里通常会用一个“任务队列” Durable Object 来管理异步任务,调用方把任务扔进队列就返回,执行方从队列里取任务处理,处理完再通知调用方。

4. 实操部署:从零跑通一个边缘 Agent

4.1 环境准备:pnpm 是第一个拦路虎

在开始之前,先把环境搞干净。你需要的东西不多:Node.js 18 以上、pnpm 8 以上、一个 Cloudflare 账号、wrangler CLI。但就是这几样东西,能卡住不少人。热词里那些“pnpm 不是内部或外部命令”“pnpm 安装”“ubuntu 安装 pnpm”就是典型的环境问题。

Windows 上装 pnpm,最稳的方式是用 npm 全局安装:

npm install -g pnpm

装完之后如果提示“pnpm 不是内部或外部命令”,大概率是 npm 的全局 bin 目录没加到 PATH 里。你可以用npm config get prefix找到全局目录,然后手动加到系统环境变量里。Ubuntu 上更推荐用 corepack,这是 Node.js 自带的包管理器管理工具:

corepack enable corepack prepare pnpm@latest --activate

如果网络环境导致 pnpm 下载失败,可以配置镜像源:

pnpm config set registry https://registry.npmmirror.com

离线安装的场景,可以先用pnpm store path找到存储目录,把离线包放进去,然后用pnpm install --offline安装。这个方式我在没有外网的机器上用过,只要离线包完整,成功率很高。

提示:pnpm 的版本尽量和项目里的packageManager字段保持一致。cloudflare-os的模板项目通常会在package.json里指定 pnpm 版本,用 corepack 会自动切换,省去手动管理的麻烦。

4.2 项目初始化:用模板还是从零搭

cloudflare-os的官方模板可以通过npm create cloudflare拉取,选择对应的 Agent 模板即可。但我建议第一次玩的时候先用模板跑通,再逐步替换成自己的逻辑。从零搭不是不行,但你会花大量时间在配置 wrangler.toml、绑定 Durable Objects、设置 KV 命名空间这些琐事上,而这些模板里都已经配好了。

初始化命令大概是这样:

npm create cloudflare@latest my-agent -- --template=cloudflare-os-agent cd my-agent pnpm install

装完依赖后,你会看到一个典型的目录结构:src/放 Worker 代码,src/agents/放 Agent 定义,wrangler.toml是配置文件,package.json里定义了脚本。先别急着改代码,直接跑pnpm dev看看能不能起来。如果起来了,说明环境没问题;如果报错,大概率是 pnpm 版本或者 Node 版本的问题,按上一节的排查方法处理。

4.3 wrangler.toml 配置:绑定关系是核心

wrangler.toml是cloudflare-os项目的核心配置文件,它定义了 Worker 和各个存储后端的绑定关系。一个典型的配置长这样:

name = "my-agent" main = "src/index.ts" compatibility_date = "2024-01-01" [[durable_objects.bindings]] name = "AGENT_STATE" class_name = "AgentState" [[kv_namespaces]] binding = "AGENT_KV" id = "your-kv-id" [[r2_buckets]] binding = "AGENT_R2" bucket_name = "agent-memory" [[d1_databases]] binding = "AGENT_D1" database_name = "agent-db" database_id = "your-d1-id"

这里每个绑定都对应代码里的一个环境变量。比如AGENT_STATE在代码里通过env.AGENT_STATE访问,AGENT_KV通过env.AGENT_KV访问。绑定的名字可以自定义,但建议保持语义清晰,不然后面代码里容易搞混。

Durable Objects 的绑定有个额外要求:你需要在 Worker 里导出对应的类。比如上面配置了class_name = "AgentState",那你的代码里就必须有一个export class AgentState。这个类需要实现 Durable Object 的标准接口,通常继承DurableObject基类。如果忘了导出,部署的时候会报错,而且错误信息不太直观,我第一次遇到的时候排查了半天。

4.4 部署与验证:第一次上线

配置好之后,用pnpm deploy或者wrangler deploy部署。部署过程大概几十秒,取决于包体积和网络状况。部署成功后,wrangler 会给你一个*.workers.dev的地址,你可以直接用 curl 或者浏览器访问测试。

验证的时候建议分三步走:先测基本连通性,发一个简单请求看能不能返回;再测状态读写,连续发两个请求看状态有没有保持;最后测工具调用,发一个需要调用外部 API 的请求看能不能正常执行。这三步都过了,说明基本链路是通的。

我实测下来,第一次部署最容易出问题的地方是Durable Object 的迁移配置。如果你修改了 Durable Object 的类名或者绑定,需要在wrangler.toml里加迁移声明,否则部署会失败。迁移配置大概长这样:

[[migrations]] tag = "v1" new_classes = ["AgentState"]

每次修改 Durable Object 的结构,都要加一个新的迁移 tag,不能重复使用旧的 tag。这个机制是为了保证已有数据不被破坏,虽然麻烦但很有必要。

5. 常见问题与排查技巧实录

5.1 pnpm 相关问题的速查表

pnpm 的问题在热词里出现频率极高,我整理了一个速查表,覆盖大部分常见症状:

症状可能原因解决方法
pnpm 不是内部或外部命令PATH 未配置把 npm 全局 bin 目录加到 PATH
pnpm 下载失败网络问题配置镜像源或使用离线安装
pnpm install 卡住锁文件冲突删除 pnpm-lock.yaml 重新安装
pnpm 版本不兼容版本过旧或过新用 corepack 锁定项目指定版本
依赖体积超限装了冗余包用 pnpm why 排查依赖树,移除不必要的包

其中“依赖体积超限”是cloudflare-os项目特有的问题。Workers 的包体积限制很严,一个不小心就超了。我通常会用pnpm why <package>来查某个包是被谁引入的,然后决定是替换还是移除。有些包看起来很小,但依赖树很深,拉进来一堆东西。这种情况可以考虑用更轻量的替代品,或者把功能拆到单独的 Worker 里。

5.2 Agent 无响应的排查思路

Agent 部署上去之后没反应,是最让人头疼的问题。我的排查顺序通常是这样的:先看 wrangler 的实时日志,wrangler tail可以实时输出 Worker 的日志,大部分错误都能在这里看到;如果日志里没有明显错误,就检查 Durable Object 的状态,用wrangler d1 execute或者直接访问 Durable Object 的调试接口看状态是否正常;最后检查绑定关系,确认wrangler.toml里的绑定和代码里的访问一致。

有一个坑我踩过好几次:Durable Object 的 ID 生成方式不一致。有时候代码里用用户 ID 生成,有时候用会话 ID 生成,导致同一个用户的不同请求路由到了不同的 Durable Object,状态自然就对不上了。解决办法是统一 ID 生成逻辑,把它封装成一个函数,所有地方都调这个函数。

5.3 多 Agent 协作的常见故障

多 Agent 协作的场景下,最常见的问题是死锁。Agent A 等 Agent B 的响应,Agent B 又等 Agent A 的响应,两边都卡住。这个问题的根源是 Durable Object 的同步调用模型。解决办法是引入超时机制,任何跨 Agent 调用都要设置超时,超时后走降级逻辑。另外,尽量避免循环依赖,Agent 之间的调用关系应该是单向的或者有向无环的。

另一个问题是状态不一致。多个 Agent 同时修改同一个 Durable Object 的状态,可能导致覆盖。虽然 Durable Object 本身是单实例的,但如果你在 Agent 层面做了缓存,就可能出现缓存和实际状态不一致的情况。我的做法是尽量不做 Agent 层缓存,所有状态读写都走 Durable Object,虽然延迟高一点,但一致性有保证。

5.4 性能优化的几个实操技巧

cloudflare-os的性能优化,核心思路是减少跨网络调用。每一次跨网络调用都是几十毫秒的延迟,积少成多就很可观了。具体做法有几个:把频繁访问的数据缓存在 Worker 的内存里,但要注意 Worker 实例可能被回收,缓存不能作为唯一数据源;把多个小请求合并成一个大请求,减少往返次数;用 Durable Object 的 alarm 机制做定时任务,避免轮询。

还有一个容易被忽略的点是冷启动。虽然 Workers 的冷启动很快,但如果你的代码体积很大,冷启动时间也会增加。我实测下来,把包体积从 5MB 压到 1MB,冷启动时间大概能减少一半。压缩包体积的方法包括:移除未使用的依赖、用 tree-shaking、把大文件放到 R2 而不是打包进 Worker。

6. 我对这套东西的真实看法

跑了一段时间cloudflare-os之后,我的感受是:它不是一个拿来就能用的产品,而是一套需要你理解其设计哲学才能用好的框架。如果你只是想快速搭个聊天机器人,用现成的 SaaS 平台可能更省事;但如果你想深入理解 Agent 在边缘网络里怎么运行、怎么协作、怎么管理状态,那这套东西值得投入时间。

我踩过的最大的坑,其实不是技术上的,而是思维上的。一开始我总想用传统后端的思路去套,比如想搞个全局状态、想做个集中式调度、想用长连接保持会话。但这些思路在边缘架构里都不太适用。边缘架构的核心是去中心化、状态外置、事件驱动,你得顺着它的逻辑来,而不是硬掰。想通这一点之后,很多设计上的困惑就迎刃而解了。

最后分享一个小技巧:如果你在本地开发时遇到 Durable Object 的行为和线上不一致,大概率是本地模拟器和真实环境的差异。wrangler dev默认用的是本地模拟的 Durable Object,和线上的实现有细微差别。可以用wrangler dev --remote连到真实的边缘环境调试,虽然慢一点,但行为更准确。这个开关我在排查一个状态同步问题时才发现,之前一直以为是代码 bug,结果是本地模拟器的限制。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 13:53:24

TailwindCSS高效实现响应式网页标题样式

1. 项目概述&#xff1a;TailwindCSS在网页标题样式中的应用最近在重构公司前端项目时&#xff0c;我尝试用TailwindCSS重新设计了整套标题样式系统。这个原子化CSS框架确实让标题开发效率提升了至少3倍&#xff0c;特别是配合Vue3的组合式API使用时。传统CSS写法需要为每个标题…

作者头像 李华
网站建设 2026/10/28 13:51:23

基于YOLOv5/v8的电动车头盔检测实战指南

1. 电动车头盔佩戴检测项目概述电动车头盔佩戴检测是当前智能交通和公共安全领域的重要应用场景。这个基于YOLOv5/v8模型的开源数据集&#xff0c;为开发者提供了快速实现头盔检测功能的解决方案。我在实际交通监控项目中发现&#xff0c;传统人工巡查方式存在效率低、覆盖范围…

作者头像 李华
网站建设 2026/10/28 13:50:24

JSON数据格式详解:从基础语法到实战应用

1. JSON基础概念解析JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;它基于ECMAScript的一个子集&#xff0c;采用完全独立于语言的文本格式来存储和传输数据。我第一次接触JSON是在2012年开发一个电商网站时&#xff0c;当时需…

作者头像 李华
网站建设 2026/10/28 13:49:21

实分析19章习题解答PDF:覆盖附录的可验证证明对照册

简介&#xff1a;《陶哲轩实分析》中文版习题解答以单份PDF整理&#xff0c;面向希望把教材从头到尾精读、逐题做完并厘清每步推导的自学者、本科生和考研复习者。解答覆盖引论、自然数与Peano公理、集合论与基数、整数和比例数、实数构造与Cauchy序列、最小上界性质、序列极限…

作者头像 李华
网站建设 2026/10/28 13:49:06

云安全持续验证:五层自动化、IAM求值与网络边界

简介&#xff1a;这份 PDF 面向云架构师、运维与安全工程师&#xff0c;系统梳理 AWS 云上安全落地的关键实践&#xff0c;可作为企业上云安全建设与合规自查的参考手册。压缩包仅含 1 个 PDF 文件&#xff0c;大小约 15.34MB&#xff0c;便于离线查阅与团队传阅。目前已有 794…

作者头像 李华
网站建设 2026/10/28 13:47:41

AWS云安全架构实战:五层自动化、最小权限与检测响应

简介&#xff1a;面向云计算运维、安全工程师与架构设计人员&#xff0c;PDF《AWS云上安全最佳实践》聚焦企业上云后的身份权限、数据保护、网络隔离、基础设施加固和日志监控&#xff0c;帮助读者搭建可执行的云安全治理框架。内容结合安全架构与分层服务&#xff0c;讲解单独…

作者头像 李华