尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于Cloudflare Workers与Agents SDK构建边缘智能体实战指南

基于Cloudflare Workers与Agents SDK构建边缘智能体实战指南 1. 项目概述为什么是Cloudflare边缘智能体最近几年边缘计算的概念越来越火但真正能低成本、快速上手去“玩”起来的平台并不多。Cloudflare Workers 算是一个异类它把全球几百个数据中心变成了一个可以运行代码的“超级计算机”。而“边缘智能体”这个概念就是把一些需要持续状态、能进行复杂逻辑判断的“智能”程序直接部署到离用户最近的地方。这听起来有点像科幻电影里的情节但现在用 Cloudflare 的 Agents SDK 和 Durable Objects我们真的可以动手实现了。简单来说这个项目就是教你如何利用 Cloudflare 这一套工具链开发一个能跑在全球边缘节点上的、有“记忆”和“思考”能力的程序。它可能是一个智能客服机器人、一个实时游戏状态服务器或者一个需要低延迟响应的物联网数据处理中心。传统的云服务器方案用户请求要先绕到中心机房处理完再返回延迟高、单点故障风险大。而边缘智能体你的代码就在用户隔壁的数据中心里毫秒级响应而且天生具备高可用性。对于开发者而言最大的吸引力在于成本和复杂度。你不再需要操心服务器运维、负载均衡、全球网络加速。Cloudflare 把这些都打包好了你只需要专注于业务逻辑。结合最新的 Agents SDK它提供了与AI模型交互、工具调用等框架和 Durable Objects提供强一致性的状态存储一个功能强大的边缘智能应用骨架就搭好了。网络上热议的“hexo cloudflare pages”其实只是静态站点托管而我们这里要搞的是动态的、有状态的、智能的下一代应用。2. 核心架构与工具链深度解析2.1 Workers无服务器函数的边缘化实践Cloudflare Workers 是整个体系的基石。你可以把它理解为一个在全球每个 Cloudflare 数据中心都预置好的 V8 隔离运行时环境。当你部署一段 JavaScript/TypeScript 代码后它会被复制到全球网络。当用户发起请求时请求会被路由到离他最近的、有空闲资源的数据中心并立即执行你的 Worker 代码。与传统 Serverless如 AWS Lambda的关键差异冷启动时间极短Worker 采用 V8 隔离而非虚拟机或容器启动时间在毫秒级几乎无感。全局分布一次部署全球生效。没有“区域”选择困难天生就是全球应用。计费模式主要基于请求次数和 CPU 执行时间免费额度非常慷慨适合个人项目和小型应用初期。在边缘智能体项目中Worker 扮演着“接入层”和“轻量逻辑执行层”的角色。它接收用户请求进行初步验证和路由然后决定是直接处理还是与后端的 Durable Object 或 AI 模型进行交互。注意Worker 的单次执行有 CPU 时间限制通常免费计划为10ms付费计划更高。这意味着耗时的计算、复杂的 AI 模型推理除非是极小模型不适合放在 Worker 主线程中。这时就需要引出 Durable Objects 和 AI Gateway 等组件来分担。2.2 Durable Objects实现有状态服务的核心密钥无服务器函数Worker默认是无状态的这限制了它在需要记忆会话、维护游戏房间、管理设备连接等场景的应用。Durable Objects (DO) 就是为了解决这个问题而生的。它是一个全局唯一的、有状态的、单线程的 JavaScript 对象。你可以把它想象成一个永不关机、全球可寻址的“微服务器”全局唯一ID每个 DO 实例由一个唯一的 ID 标识无论从世界何处都可以通过这个 ID 访问到同一个实例。强一致性同一时刻只有一个请求能进入 DO 执行代码保证了状态修改的绝对安全无需考虑锁的问题。持久化存储DO 内部的状态类属性会自动被持久化。即使这个 DO 实例因为长时间空闲被从内存中卸载当下次被调用时状态也会从持久化存储中恢复。在边缘智能体开发中DO 是“智能体”的大脑和记忆中枢。例如会话管理每个用户会话对应一个 DO存储完整的对话历史、用户偏好。实时协作一个文档或白板对应一个 DO处理所有用户的编辑指令并广播状态。游戏服务器一个游戏房间对应一个 DO管理所有玩家状态和游戏逻辑。设备网关一个物联网设备对应一个 DO维护设备最后状态和指令队列。2.3 AI Gateway 与 Workers AI低成本接入大模型能力智能体的“智能”往往来源于大型语言模型LLM。Cloudflare 提供了两种主要方式AI Gateway这不是一个模型服务而是一个智能代理层。你可以将 OpenAI、AnthropicClaude等第三方 AI 供应商的 API 配置到 AI Gateway。它能帮你实现请求缓存、限流、降级、负载均衡、成本分析和日志聚合。对于使用多个模型或需要稳定性的项目这是必选项。Workers AI这是 Cloudflare 自己托管的、在边缘节点上运行的一系列开源模型如 Llama、Mistral。它的最大优势是低延迟和按次计费。由于模型就在边缘网络无需绕道第三方API速度极快。计费上没有月费只用为每次推理付费非常适合间歇性使用的场景。在 Agents SDK 的框架下你可以轻松配置使用 AI Gateway 或 Workers AI 作为 LLM 提供商从而让智能体拥有理解和生成自然语言的能力。2.4 Agents SDK智能体开发的“脚手架”这是 Cloudflare 为简化智能体开发推出的 SDK。它定义了一套清晰的框架Agent智能体本身包含配置如使用的模型、系统提示词和工具列表。Tool智能体可以调用的函数。例如“查询天气”、“从数据库获取用户信息”、“调用某个外部API”。当用户提问涉及这些功能时智能体会自动决定调用哪个工具并生成调用参数。Runner执行引擎负责接收用户输入组织模型、工具和状态之间的交互流程。Agents SDK 最大的价值是处理了复杂的交互循环模型思考 - 决定是否调用工具 - 执行工具 - 将工具结果返回给模型 - 模型生成最终回答。开发者只需要定义好工具和初始提示剩下的流程交给 SDK。3. 实战构建一个边缘智能客服助手下面我们通过一个具体的例子串联起所有组件构建一个能查询产品信息和记录用户反馈的智能客服助手。3.1 项目初始化与环境配置首先确保你安装了 Node.js 和 npm。然后使用 WranglerCloudflare 的命令行工具来创建项目。# 安装 Wrangler npm install -g wrangler # 登录到你的 Cloudflare 账户 wrangler login # 创建一个新的 Workers 项目选择“Hello World”模板即可 wrangler init edge-customer-support-agent cd edge-customer-support-agent接下来安装必要的依赖。我们将使用 TypeScript、Agents SDK并假设使用 Workers AI 的 Llama 模型。npm install cloudflare/agents npm install -D typescript types/node更新wrangler.toml配置文件声明我们将要使用的绑定Bindings。绑定是 Worker 代码中可用的环境变量或资源句柄。name edge-customer-support-agent main src/index.ts compatibility_date 2024-03-20 # 绑定一个 Durable Object用于存储会话状态 [[durable_objects.bindings]] name SESSION_STORE class_name SessionDurableObject # 声明 Durable Object 的类以便 Wrangler 知道如何部署它 [[migrations]] tag v1 new_classes [SessionDurableObject] # 绑定 Workers AI以便在代码中调用 [[ai.bindings]] binding AI # 在代码中通过 env.AI 访问3.2 实现会话状态 Durable Object在src/目录下创建SessionDO.ts文件。这个 Durable Object 将为每个用户会话保存历史记录。// src/SessionDO.ts export class SessionDurableObject { // 状态存储对话消息历史 state: DurableObjectState; messages: Array{role: string, content: string}; constructor(state: DurableObjectState, env: Env) { this.state state; // 初始化时尝试从持久化存储中加载历史消息 this.state.blockConcurrencyWhile(async () { this.messages (await this.state.storage.get(messages)) || []; }); } // 处理所有 HTTP 请求的方法 async fetch(request: Request) { const url new URL(request.url); switch (url.pathname) { case /append: const { role, content } await request.json(); this.messages.push({ role, content }); // 持久化存储消息历史自动完成 await this.state.storage.put(messages, this.messages); return new Response(JSON.stringify({ success: true }), { headers: { Content-Type: application/json } }); case /get: return new Response(JSON.stringify(this.messages), { headers: { Content-Type: application/json } }); case /clear: this.messages []; await this.state.storage.delete(messages); return new Response(JSON.stringify({ success: true }), { headers: { Content-Type: application/json } }); default: return new Response(Not Found, { status: 404 }); } } } // 导出类型供 Worker 使用 export interface Env { SESSION_STORE: DurableObjectNamespace; }这个 DO 提供了三个端点/append添加消息/get获取历史/clear清空历史。状态this.messages会被自动持久化。3.3 定义智能体的工具Tools智能体的能力通过工具来扩展。我们创建两个工具一个模拟查询产品目录一个用于提交用户反馈。在src/tools.ts中// src/tools.ts import { Tool } from cloudflare/agents; // 工具1查询产品信息这里模拟一个内存中的产品列表 const productCatalogTool: Tool { name: query_product_catalog, description: 根据产品名称或ID查询产品的详细信息包括价格、库存和描述。, parameters: { type: object, properties: { productIdentifier: { type: string, description: 产品的名称或ID例如 iphone-15 或 无线耳机 } }, required: [productIdentifier] }, execute: async ({ productIdentifier }: { productIdentifier: string }) { // 模拟一个产品数据库 const mockProducts [ { id: iphone-15, name: iPhone 15, price: 7999, stock: 50, description: 最新款苹果手机 }, { id: wireless-earbuds, name: 真无线耳机, price: 399, stock: 200, description: 降噪蓝牙耳机 }, { id: laptop-2024, name: 轻薄笔记本, price: 5999, stock: 30, description: 高性能便携笔记本 } ]; const product mockProducts.find(p p.id.includes(productIdentifier.toLowerCase()) || p.name.includes(productIdentifier) ); if (product) { return JSON.stringify(product); } else { return 未找到标识为 ${productIdentifier} 的产品。; } } }; // 工具2提交用户反馈 const submitFeedbackTool: Tool { name: submit_customer_feedback, description: 记录用户的反馈意见并返回一个反馈ID。, parameters: { type: object, properties: { feedbackText: { type: string, description: 用户提供的反馈文本内容 }, category: { type: string, enum: [bug, suggestion, compliment, question], description: 反馈的分类 } }, required: [feedbackText, category] }, execute: async ({ feedbackText, category }: { feedbackText: string; category: string }) { // 在实际应用中这里应该将反馈写入数据库或外部服务 const feedbackId FB-${Date.now()}; console.log([反馈记录] ID: ${feedbackId}, 类别: ${category}, 内容: ${feedbackText}); // 这里我们模拟存储成功并返回一个ID return JSON.stringify({ success: true, feedbackId, message: 您的反馈已记录编号${feedbackId}。我们的团队会尽快处理。 }); } }; export const tools [productCatalogTool, submitFeedbackTool];3.4 编写主 Worker 与智能体集成现在在src/index.ts中编写主逻辑将 Worker、DO、AI 和 Agents SDK 连接起来。// src/index.ts import { Agent, Runner } from cloudflare/agents; import { tools } from ./tools; import { SessionDurableObject } from ./SessionDO; export interface Env { SESSION_STORE: DurableObjectNamespace; AI: any; // Workers AI 绑定 } // 辅助函数获取或创建用户的会话 DO async function getUserSession(env: Env, userId: string): PromiseDurableObjectStub { // 使用一个固定的命名空间和用户ID来派生唯一的 DO ID // 这里简单使用用户ID生产环境建议使用更安全的会话ID const id env.SESSION_STORE.idFromName(userId); return env.SESSION_STORE.get(id); } export default { async fetch(request: Request, env: Env, ctx: ExecutionContext): PromiseResponse { const url new URL(request.url); // 健康检查或前端页面路由可选 if (url.pathname / || url.pathname /health) { return new Response(Edge Customer Support Agent is running.); } // 假设通过请求头或Cookie获取用户标识这里简化处理 // 警告生产环境必须使用安全的身份验证机制 const userId request.headers.get(x-user-id) || anonymous; const userSession await getUserSession(env, userId); // 1. 处理用户消息 if (url.pathname /chat request.method POST) { const { message } await request.json(); if (!message) { return new Response(Missing message, { status: 400 }); } // 1.1 将用户消息保存到会话历史 await userSession.fetch(http://do.internal/append, { method: POST, body: JSON.stringify({ role: user, content: message }) }); // 1.2 从会话DO中获取完整的历史记录 const historyResponse await userSession.fetch(http://do.internal/get); const messageHistory await historyResponse.json(); // 1.3 配置智能体 const agent new Agent({ instructions: 你是一个专业的在线客服助手负责回答关于产品的问题并收集用户反馈。 请保持友好、专业和乐于助人。 当用户询问产品时使用工具查询准确信息。 当用户提出意见或问题时引导他们使用反馈工具进行记录。 对话历史如下请参考历史进行连贯的回复 ${JSON.stringify(messageHistory)} , model: env.AI, // 绑定 Workers AI tools: tools, }); // 1.4 运行智能体获取回复 const runner new Runner(agent); const result await runner.run(message); // 1.5 将智能体的回复也保存到历史 await userSession.fetch(http://do.internal/append, { method: POST, body: JSON.stringify({ role: assistant, content: result.response }) }); // 1.6 返回回复给用户 return new Response(JSON.stringify({ response: result.response }), { headers: { Content-Type: application/json } }); } // 2. 其他API获取历史、清空历史用于调试或前端同步 if (url.pathname /history request.method GET) { const historyResponse await userSession.fetch(http://do.internal/get); return new Response(historyResponse.body, { headers: { Content-Type: application/json } }); } if (url.pathname /clear request.method POST) { await userSession.fetch(http://do.internal/clear, { method: POST }); return new Response(JSON.stringify({ success: true })); } return new Response(Not Found, { status: 404 }); } } satisfies ExportedHandlerEnv; // 必须导出 Durable Object 类 export { SessionDurableObject };3.5 部署与测试代码编写完成后就可以部署了。# 在项目根目录执行部署命令 wrangler deploy部署成功后你会获得一个*.workers.dev的域名。现在可以使用 curl 或 Postman 进行测试。测试对话# 1. 发送用户消息 curl -X POST https://your-worker.you-subdomain.workers.dev/chat \ -H Content-Type: application/json \ -H x-user-id: user123 \ -d {message: 你好我想了解一下iPhone 15的价格。} # 预期会返回一个JSON包含智能体调用工具查询产品后的回复。 # 2. 获取当前会话的历史记录 curl -H x-user-id: user123 https://your-worker.you-subdomain.workers.dev/history # 3. 测试反馈功能 curl -X POST https://your-worker.you-subdomain.workers.dev/chat \ -H Content-Type: application/json \ -H x-user-id: user123 \ -d {message: 我觉得你们的APP启动有点慢希望能优化一下。} # 预期智能体会识别这是反馈并调用 submit_customer_feedback 工具。4. 性能优化与高级配置指南4.1 会话 DO 的生命周期与成本控制Durable Objects 虽然强大但它是按执行时间和存储计费的。一个长期空闲的 DO 会被“休眠”从内存中移除但存储仍然计费。为了控制成本设置会话过期在 DO 的alarm()方法中实现逻辑如果一段时间如30分钟无活动就自动调用storage.deleteAll()清理数据并销毁自身。这需要你在 DO 的fetch()方法中每次请求都重置这个闹钟。使用更细粒度的 ID不要把所有数据都塞进一个 DO。例如将会话历史、用户配置、购物车分别放在不同的 DO 中根据访问频率独立管理生命周期。4.2 利用 KV 存储优化高频读取数据对于产品目录这类更新不频繁但读取频繁的数据放在 DO 中每次查询都通过网络调用 DO 实例是不经济的。更好的选择是使用Cloudflare KV键值存储。KV 是最终一致性的全球缓存读取速度极快亚毫秒级非常适合存储配置、静态数据、缓存结果。你可以在 Worker 中直接查询 KV也可以在工具函数中查询。将上面的mockProducts改为从 KV 读取并在管理后台或通过 Wrangler CLI 更新 KV 数据。4.3 模型选择与提示词工程模型选择Workers AI 提供了不同尺寸的模型。对于客服场景cf/meta/llama-2-7b-chat-int8可能就足够了它速度快、成本低。对于更复杂的逻辑推理可以考虑cf/mistral/mistral-7b-instruct-v0.1。通过 Agents SDK 可以轻松切换模型。提示词优化系统指令instructions是智能体的灵魂。要清晰定义角色、职责和边界。在指令中明确告知智能体“你必须使用工具来查询产品信息”和“当用户表达不满或建议时应引导其提交反馈”可以大大提高工具调用的准确率。将对话历史作为上下文注入是实现多轮对话记忆的关键。4.4 错误处理与弹性设计边缘环境网络情况复杂必须做好错误处理。模型调用重试在Runner.run()外围添加重试逻辑特别是对于网络超时错误。降级策略如果 Workers AI 不可用或超时可以降级到更简单的规则引擎或者返回一个友好的错误信息提示用户稍后再试。输入验证与清理对所有用户输入进行严格的验证和清理防止提示词注入攻击。避免将未经处理的用户输入直接拼接到系统指令中。5. 常见问题与排查技巧实录在实际开发和运维中你肯定会遇到各种问题。下面是一些典型场景和解决思路。5.1 Durable Object “无响应”或状态丢失症状调用 DO API 超时或者之前存储的数据不见了。排查检查 ID 派生确保每次对同一个逻辑实体如用户都使用相同的idFromName()参数。不一致的 ID 会导致访问到不同的 DO 实例。查看日志在 DO 的fetch()方法中使用console.log输出关键信息通过wrangler tail命令实时查看日志流。理解持久化延迟DO 的状态持久化是异步的有极小概率在极端故障下丢失最新数据。对极高一致性要求的场景考虑在state.storage操作后使用state.waitUntil()来确保操作完成。实操心得为每个重要的 DO 设计一个/ping或/status端点用于健康检查。在 Worker 中调用 DO 时设置合理的fetch()超时例如 5 秒并准备好超时后的 fallback 响应。5.2 智能体不调用工具或调用错误症状用户的问题明显符合工具描述但智能体选择自行回答或者调用了错误的工具。排查检查工具描述工具的name和description是模型决定是否调用的关键。description必须清晰、准确说明工具的用途、适用场景和输入参数的意义。用模型能理解的语言写。检查系统指令在instructions中必须明确命令智能体“在适当的时候使用工具”。可以给出具体例子如“当用户询问产品详情时请使用query_product_catalog工具”。启用调试Agents SDK 的Runner可以输出中间步骤。检查模型的“思考过程”看它是否理解了用户意图并正确选择了工具。实操心得这是提示词工程问题。多进行测试根据失败案例反复调整工具描述和系统指令。有时在用户问题不明确时让智能体先通过自然语言追问澄清再调用工具效果更好。5.3 Workers AI 响应慢或超时症状智能体回复延迟很高甚至超时Worker 默认超时时间较长但用户等不及。排查模型尺寸确认你使用的模型是否过大。在边缘运行 70B 参数模型是不现实的。坚持使用 7B 或更小的量化模型带-int8后缀。输入长度传入的对话历史是否过长过长的上下文会显著增加模型推理时间。可以考虑只保留最近 N 轮对话或者对历史进行摘要。网络问题虽然 Workers AI 在边缘但首次冷启动或区域负载均衡可能导致延迟。使用wrangler tail查看 AI 调用的实际耗时。实操心得在 Worker 前端设置一个更短的超时如 10 秒并给用户一个“正在思考”的中间响应。考虑实现一个流式响应Streaming接口让用户看到生成过程提升体验。5.4 部署失败或绑定未找到症状wrangler deploy失败提示Binding not found或Class not defined。排查核对wrangler.toml确保所有[[bindings]]的name和代码中env.XXX的名字完全一致包括大小写。核对 Durable Object 导出确保在src/index.ts的底部使用export { YourDurableObjectClass }正确导出。检查兼容性日期某些功能需要较新的compatibility_date。查看 Cloudflare 文档更新到一个更新的日期。权限问题确认你的账户在 Cloudflare Dashboard 中已经为 Workers 和 Durable Objects 开通了相应服务的权限。实操心得养成先wrangler dev在本地开发环境测试的习惯本地测试通过后再部署。本地开发环境能模拟大部分绑定可以提前发现配置错误。开发边缘智能体是一个将前沿架构与具体业务结合的过程。从我的经验来看最大的挑战不是代码本身而是思维模式的转变——从“中心化处理”转向“状态全球分布计算就近发生”。一旦适应了这种模式你会发现它能优雅地解决很多过去很棘手的问题比如全球用户的延迟问题、状态同步问题。而 Cloudflare 的这一套组合恰好提供了目前可能是最平滑、成本最低的入门路径。
返回列表