mcpField
C
cloudflare-agents

cloudflare-agents

github.com/ovachieverAgent 工作流5649 次安装48 周前更新
代码仓库

关于 cloudflare-agents

Cloudflare Agents SDK 是用于在 Cloudflare Workers 和 Durable Objects 上构建有状态实时 AI Agent 的框架,适合需要持久状态、任务调度或多 Agent 协作的开发者。它提供基础设施,不负责 AI 推理。

主要功能

  1. 01WebSocket 双向通信
  2. 02SQLite 状态持久化
  3. 03定时与 Cron 任务
  4. 04多 Agent 协作
  5. 05人工审核工作流
  6. 06实现 MCP 服务

适用场景

  1. 01在 Agent 会话间保留状态
  2. 02协调多个 Agent
  3. 03运行延迟或周期任务
  4. 04通过人工审批控制操作

MCP 相关

SDK 提供 MCPAgent,可实现 MCP 服务并执行有状态工具。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ovachiever/droid-tings --skill cloudflare-agents

安装后在 Claude Code 中输入/cloudflare-agents确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
.claude-plugin/
plugin.json
templates/
basic-agent.ts
browser-agent.ts
calling-agents-worker.ts
chat-agent-streaming.ts
hitl-agent.ts
mcp-server-basic.ts
rag-agent.ts
react-useagent-client.tsx
scheduled-agent.ts
simple-chat-no-agents-sdk.ts
state-sync-agent.ts
websocket-agent.ts
workflow-agent.ts
wrangler-agents-config.jsonc

详细介绍

Cloudflare Agents SDK

状态:已可用于生产环境 ✅ 最后更新:2025-11-23 依赖项:cloudflare-worker-base(推荐) 最新版本:[email protected](2025 年 11 月 13 日),@modelcontextprotocol/sdk@latest 生产环境测试:Cloudflare 自己的 MCP 服务(https://github.com/cloudflare/mcp-server-cloudflare)

近期更新(2025 年):

  • 2025 年 9 月:兼容 AI SDK v5,自动迁移消息
  • 2025 年 4 月:支持 MCP(MCPAgent 类),从 agents 导入 import { context }
  • 2025 年 3 月:包重命名(agents-sdk → agents)

什么是 Cloudflare Agents?

Cloudflare Agents SDK 支持构建由 AI 驱动的自主 Agent,并在 Cloudflare Workers + Durable Objects 上运行。Agent 可以:

  • 实时通信,通过 WebSocket 和 Server-Sent Events
  • 持久化状态,使用内置 SQLite 数据库(每个 Agent 最多 1GB)
  • 安排任务,使用延迟、指定日期或 cron 表达式
  • 运行工作流,通过触发异步 Cloudflare Workflows
  • 浏览网页,使用 Browser Rendering API + Puppeteer
  • 实现 RAG,使用 Vectorize 向量数据库 + Workers AI 嵌入
  • 构建 MCP 服务,实现 Model Context Protocol
  • 支持人机协作模式,用于审核和批准
  • 扩展至数百万个遍布全球的独立 Agent 实例

每个 Agent 实例都是一个全球唯一、有状态的微型服务,可以运行数秒、数分钟或数小时。


你需要 Agents SDK 吗?

请先停下来:使用 Agents SDK 之前,先问问自己是否真的需要它。

以下情况只用 Vercel AI SDK(更简单):
  • ✅ 构建基本的聊天界面
  • ✅ Server-Sent Events(SSE)流式传输已足够(一种单向通信:服务端 → 客户端)
  • ✅ 不需要持久化 Agent 状态(或者你使用 D1/KV 单独管理状态)
  • ✅ 单用户、单对话场景
  • ✅ 只需要 AI 回复,不需要复杂工作流或任务调度

这涵盖了 80% 的聊天应用。 对于这些情况,直接在 Workers 上使用 Vercel AI SDK——它更简单,所需基础设施更少,并且会自动处理流式传输。

示例(无需 Agents SDK):

// worker.ts - Simple chat with AI SDK only
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';

export default {
  async fetch(request: Request, env: Env) {
    const { messages } = await request.json();

    const result = streamText({
      model: openai('gpt-4o-mini'),
      messages
    });

    return result.toTextStreamResponse(); // Automatic SSE streaming
  }
}

// client.tsx - React with built-in hooks
import { useChat } from 'ai/react';

function ChatPage() {
  const { messages, input, handleSubmit } = useChat({ api: '/api/chat' });
  // Done. No Agents SDK needed.
}

结果:只需 100 行代码,而不是 500 行。无需设置 Durable Objects,无需处理 WebSocket 的复杂性,也无需迁移。


以下情况需要使用 Agents SDK:
  • ✅ WebSocket 连接(真正的双向实时通信)
  • ✅ Durable Objects(全球唯一、有状态的 Agent 实例)
  • ✅ 内置状态持久化(每个 Agent 最多 1GB 的 SQLite 存储)
  • ✅ 多 Agent 协作(Agent 相互调用和通信)
  • ✅ 计划任务(延迟、cron 表达式、重复执行的任务)
  • ✅ 人机协作工作流(审批关卡、审核流程)
  • ✅ 长时间运行的 Agent(后台处理、自主工作流)
  • ✅ 支持有状态工具执行的 MCP 服务

这约占应用的 20%——适用于需要 Agents SDK 所提供基础设施的场景。


关键认知:Agents SDK 的用途与非用途

Agents SDK 是:

  • 🏗️ 用于 WebSocket 连接、Durable Objects 和状态管理的基础设施层
  • 🔧 用于构建有状态自主 Agent 的框架
  • 📦 封装 Durable Objects 并提供生命周期方法的封装层

Agents SDK 不是:

  • ❌ AI 推理服务提供商(由你自行选择:AI SDK、Workers AI、OpenAI 等)
  • ❌ 流式响应处理器(使用 AI SDK 自动解析)
  • ❌ LLM 集成(这是另一个独立的事项)

可以这样理解:

  • Agents SDK = 建筑(WebSocket、状态、房间)
  • AI SDK / Workers AI = AI 大脑(推理、推理过程、回复)

你可以同时使用它们(大多数情况下推荐),也可以直接使用 Workers AI(前提是你愿意手动处理 SSE 解析)。


决策流程图
Building an AI application?
│
├─ Need WebSocket bidirectional communication? ───────┐
│  (Client sends while server streams, agent-initiated messages)
│
├─ Need Durable Objects stateful instances? ──────────┤
│  (Globally unique agents with persistent memory)
│
├─ Need multi-agent coordination? ────────────────────┤
│  (Agents calling/messaging other agents)
│
├─ Need scheduled tasks or cron jobs? ────────────────┤
│  (Delayed execution, recurring tasks)
│
├─ Need human-in-the-loop workflows? ─────────────────┤
│  (Approval gates, review processes)
│
└─ If ALL above are NO ─────────────────────────────→ Use AI SDK directly
                                                       (Much simpler approach)

   If ANY above are YES ────────────────────────────→ Use Agents SDK + AI SDK
                                                       (More infrastructure, more power)

架构对比
特性仅使用 AI SDKAgents SDK + AI SDK
配置复杂度🟢 低(npm install 即可)🔴 较高(Durable Objects、迁移、绑定)
代码量🟢 ~100 行🟡 ~500+ 行
流式传输✅ 自动(SSE)✅ 自动(AI SDK)或手动(Workers AI)
状态管理⚠️ 手动(D1/KV)✅ 内置(SQLite)
WebSockets❌ 需要手动配置✅ 内置
React Hooks✅ useChat、useCompletion⚠️ 需要自定义 hooks
多 Agent❌ 不支持✅ 内置(routeAgentRequest)
调度❌ 外部实现(Queue/Workflow)✅ 内置(this.schedule)
适用场景简单聊天、补全复杂的有状态工作流

还是不确定?

从 AI SDK 开始。 如果之后发现需要 WebSockets 或 Durable Objects,随时可以迁移到 Agents SDK。之后添加基础设施比移除它更容易。

对于大多数开发者:如果你正在构建聊天界面,并且没有 WebSockets、多 Agent 协调或定时任务方面的特定需求,请直接使用 AI SDK。这样可以更快交付,复杂度也更低。

只有在你已确定需要其基础设施能力时,才使用 Agents SDK。


快速入门(10 分钟)

1. 使用模板搭建项目
npm create cloudflare@latest my-agent -- \
  --template=cloudflare/agents-starter \
  --ts \
  --git \
  --deploy false

此操作会创建:

  • 完整的 Agent 项目结构
  • TypeScript 配置
  • 带有 Durable Objects 绑定的 wrangler.jsonc
  • 示例聊天 Agent 实现
  • 带有 useAgent hook 的 React 客户端
2. 或添加到现有 Worker
cd my-existing-worker
npm install agents

然后创建一个 Agent 类:

// src/index.ts
import { Agent, AgentNamespace } from "agents";

export class MyAgent extends Agent {
  async onRequest(request: Request): Promise<Response> {
    return new Response("Hello from Agent!");
  }
}

export default MyAgent;
3. 配置 Durable Objects 绑定

创建或更新 wrangler.jsonc:

{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "my-agent",
  "main": "src/index.ts",
  "compatibility_date": "2025-10-21",
  "compatibility_flags": ["nodejs_compat"],
  "durable_objects": {
    "bindings": [
      {
        "name": "MyAgent",        // MUST match class name
        "class_name": "MyAgent"   // MUST match exported class
      }
    ]
  },
  "migrations": [
    {
      "tag": "v1",
      "new_sqlite_classes": ["MyAgent"]  // CRITICAL: Enables SQLite storage
    }
  ]
}

重要的配置规则:

  • ✅ name 和 class_name 必须完全相同
  • ✅ new_sqlite_classes 必须位于首次迁移中(之后无法添加)
  • ✅ Agent 类 必须导出(否则绑定会失败)
  • ✅ 迁移标签 不能重复使用(每次迁移都需要唯一标签)
4. 部署
npx wrangler@latest deploy

你的 Agent 现在已运行在:https://my-agent.<subdomain>.workers.dev


架构概览:各部分如何协同工作

了解每种工具的用途,可以避免混淆,并帮助你选择合适的组合。

技术栈
┌─────────────────────────────────────────────────────────┐
│                    Your Application                      │
│                                                          │
│  ┌────────────────┐         ┌──────────────────────┐   │
│  │  Agents SDK    │         │   AI Inference       │   │
│  │  (Infra Layer) │   +     │   (Brain Layer)      │   │
│  │                │         │                      │   │
│  │ • WebSockets   │         │  Choose ONE:         │   │
│  │ • Durable Objs │         │  • Vercel AI SDK ✅   │   │
│  │ • State (SQL)  │         │  • Workers AI ⚠️      │   │
│  │ • Scheduling   │         │  • OpenAI Direct     │   │
│  │ • Multi-agent  │         │  • Anthropic Direct  │   │
│  └────────────────┘         └──────────────────────┘   │
│         ↓                             ↓                │
│  Manages connections          Generates responses      │
│  and state                    and handles streaming    │
└─────────────────────────────────────────────────────────┘
                          ↓
              Cloudflare Workers + Durable Objects
每种工具提供的功能
1. Agents SDK(本技能)

用途:为有状态、实时的 Agent 提供基础设施

提供:

  • ✅ WebSocket 连接管理(双向实时通信)
  • ✅ Durable Objects 封装(全局唯一的 Agent 实例)
  • ✅ 内置状态持久化(SQLite,最高 1GB)
  • ✅ 生命周期方法(onStart、onConnect、onMessage、onClose)
  • ✅ 任务调度(使用 cron/延迟调用 this.schedule())
  • ✅ 多 Agent 协调(routeAgentRequest())
  • ✅ 客户端库(useAgent、AgentClient、agentFetch)

不提供:

  • ❌ AI 推理(不调用大模型)
  • ❌ 流式响应解析(需自行实现)
  • ❌ 服务提供商集成(OpenAI、Anthropic 等)

可以把它看作:建筑和基础设施(房间、门、管道),但不包括住户(AI)。


2. Vercel AI SDK(AI 开发推荐)

用途:支持自动流式传输的 AI 推理

提供:

  • ✅ 自动处理流式响应(由 SDK 为你解析 SSE)
  • ✅ 支持多个服务提供商(OpenAI、Anthropic、Google 等)
  • ✅ React hooks(useChat、useCompletion、useAssistant)
  • ✅ 跨服务提供商的统一 API
  • ✅ 工具调用 / 函数调用
  • ✅ 可在 Cloudflare Workers 上运行 ✅

示例:

import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';

const result = streamText({
  model: openai('gpt-4o-mini'),
  messages: [...]
});

// Returns SSE stream - no manual parsing needed
return result.toTextStreamResponse();

与 Agents SDK 配合使用的场景:

  • ✅ 大多数聊天应用
  • ✅ 需要 React hooks 时
  • ✅ 使用多个 AI 服务提供商时
  • ✅ 希望以清晰、抽象化的方式调用 AI 时

与 Agents SDK 组合使用:

import { AIChatAgent } from "agents/ai-chat-agent";
import { streamText } from "ai";

export class MyAgent extends AIChatAgent<Env> {
  async onChatMessage(onFinish) {
    // Agents SDK provides: WebSocket, state, this.messages
    // AI SDK provides: Automatic streaming, provider abstraction

    return streamText({
      model: openai('gpt-4o-mini'),
      messages: this.messages  // Managed by Agents SDK
    }).toTextStreamResponse();
  }
}

3. Workers AI(AI 替代方案)

用途:Cloudflare 平台内的 AI 推理

提供:

  • ✅ 经济高效的推理(包含在 Workers 订阅中)
  • ✅ 无需外部 API 密钥
  • ✅ 模型:LLaMA 3、Qwen、Mistral、嵌入模型等
  • ✅ 在 Cloudflare 网络上运行(延迟低)

不提供:

  • ❌ 自动流式解析(返回原始 SSE 格式)
  • ❌ React hooks
  • ❌ 多提供商抽象

需要手动解析:

const response = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
  messages: [...],
  stream: true
});

// Returns raw SSE format - YOU must parse
for await (const chunk of response) {
  const text = new TextDecoder().decode(chunk);  // Uint8Array → string
  if (text.startsWith('data: ')) {              // Check SSE format
    const data = JSON.parse(text.slice(6));     // Parse JSON
    if (data.response) {                        // Extract .response field
      fullResponse += data.response;
    }
  }
}

适用场景:

  • ✅ 成本至关重要(嵌入、高请求量)
  • ✅ 需要 Cloudflare 专属模型
  • ✅ 愿意手动处理 SSE 解析
  • ✅ 不允许使用外部依赖

权衡:节省成本,花时间手动解析。


推荐组合
选项 A:Agents SDK + Vercel AI SDK(推荐 ⭐)

适用场景:需要 WebSockets/状态管理,并希望简洁地集成 AI

import { AIChatAgent } from "agents/ai-chat-agent";
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";

export class ChatAgent extends AIChatAgent<Env> {
  async onChatMessage(onFinish) {
    return streamText({
      model: openai('gpt-4o-mini'),
      messages: this.messages,  // Agents SDK manages history
      onFinish
    }).toTextStreamResponse();
  }
}

优点:

  • ✅ 最佳开发体验
  • ✅ 自动流式处理
  • ✅ Agents SDK 提供 WebSockets + 状态管理
  • ✅ 代码简洁、易于维护

缺点:

  • ⚠️ 需要外部 API 密钥
  • ⚠️ AI 提供商会产生额外费用

选项 B:Agents SDK + Workers AI

适用场景:需要 WebSockets/状态管理,并且成本至关重要

import { Agent } from "agents";

export class BudgetAgent extends Agent<Env> {
  async onMessage(connection, message) {
    const response = await this.env.AI.run('@cf/meta/llama-3-8b-instruct', {
      messages: [...],
      stream: true
    });

    // Manual SSE parsing required (see Workers AI section above)
    for await (const chunk of response) {
      // ... manual parsing ...
    }
  }
}

优点:

  • ✅ 经济高效
  • ✅ 无需外部依赖
  • ✅ Agents SDK 提供 WebSockets + 状态管理

缺点:

  • ❌ 手动解析 SSE 的复杂性
  • ❌ 可选模型有限
  • ❌ 需要维护更多代码

选项 C:仅使用 Vercel AI SDK(不使用 Agents)

适用场景:不需要 WebSockets 或 Durable Objects

// worker.ts - Simple Workers route
export default {
  async fetch(request: Request, env: Env) {
    const { messages } = await request.json();

    const result = streamText({
      model: openai('gpt-4o-mini'),
      messages
    });

    return result.toTextStreamResponse();
  }
}

// client.tsx - Built-in React hooks
import { useChat } from 'ai/react';

function Chat() {
  const { messages, input, handleSubmit } = useChat({ api: '/api/chat' });
  return <form onSubmit={handleSubmit}>...</form>;
}

优点:

  • ✅ 方案最简单
  • ✅ 代码最少
  • ✅ 实现速度快
  • ✅ 内置 React hooks

缺点:

  • ❌ 不支持 WebSockets(仅支持 SSE)
  • ❌ 不支持 Durable Objects 状态管理
  • ❌ 不支持多 Agent 协同

最适合:80% 的聊天应用


决策矩阵
您的需求推荐技术栈复杂度成本
简单聊天,无状态管理仅使用 AI SDK🟢 低$$(AI 提供商)
聊天 + WebSockets + 状态管理Agents SDK + AI SDK🟡 中$$$(基础设施 + AI)
聊天 + WebSockets + 预算有限Agents SDK + Workers AI🔴 高$(仅基础设施)
多 Agent 工作流Agents SDK + AI SDK🔴 高$$$(基础设施 + AI)
带工具的 MCP 服务Agents SDK(McpAgent)🟡 中$(仅基础设施)

关键要点

Agents SDK 提供的是基础设施,而非 AI。 您需要将它与 AI 推理工具组合使用:

  • 追求最佳开发体验:Agents SDK + Vercel AI SDK ⭐
  • 节省成本:Agents SDK + Workers AI(接受手动解析)
  • 追求简单:仅使用 AI SDK(如果不需要 WebSockets/状态管理)

本技能的其余部分将重点介绍 Agents SDK(基础设施层)。有关 AI 推理模式,请参阅 ai-sdk-core 或 cloudflare-workers-ai 技能。


配置(wrangler.jsonc)

必需的关键配置:

{
  "durable_objects": {
    "bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }]
  },
  "migrations": [
    { "tag": "v1", "new_sqlite_classes": ["MyAgent"] }  // MUST be in first migration
  ]
}

常见的可选绑定:ai、vectorize、browser、workflows、d1_databases、r2_buckets

关键迁移规则:

  • ✅ new_sqlite_classes 必须位于标记 "v1" 中(无法向已部署的类添加 SQLite)
  • ✅ name 和 class_name 必须完全匹配
  • ✅ 迁移是原子操作(所有实例会同时更新)
  • ✅ 每个标记都必须唯一,不能编辑或删除之前的标记

参阅:https://developers.cloudflare.com/agents/api-reference/configuration/


核心 Agent 模式

Agent 类基础知识 — 通过生命周期方法扩展 Agent<Env, State>:

  • onStart() — 初始化 Agent
  • onRequest() — 处理 HTTP 请求
  • onConnect/onMessage/onClose() — 处理 WebSocket
  • onStateUpdate() — 响应状态变更

关键属性:

  • this.env — 环境绑定(AI、DB 等)
  • this.state — 当前 Agent 状态(只读)
  • this.setState() — 更新持久化状态
  • this.sql — 内置 SQLite 数据库
  • this.name — Agent 实例标识符
  • this.schedule() — 安排未来任务

参见:官方 Agent API 文档:https://developers.cloudflare.com/agents/api-reference/agents-api/


WebSocket 与实时通信

Agent 支持通过 WebSocket 进行双向实时通信。适用于以下场景:

  • 客户端可以在服务端推送数据时发送消息
  • Agent 主动发送消息(通知、更新)
  • 需要保持长连接并维护状态

基本模式:

export class ChatAgent extends Agent<Env, State> {
  async onConnect(connection: Connection, ctx: ConnectionContext) {
    // Auth check, add to participants, send welcome
  }

  async onMessage(connection: Connection, message: WSMessage) {
    // Process message, update state, broadcast response
  }
}

SSE 替代方案:对于单向的服务端 → 客户端数据流(更简单,基于 HTTP),请使用 Server-Sent Events,而不是 WebSocket。

参见:https://developers.cloudflare.com/agents/api-reference/websockets/


状态管理

两种状态机制:

  1. this.setState(newState) — 可序列化为 JSON 的状态(最大 1GB)

    • 自动持久化,并同步到 WebSocket 客户端
    • 适用于:用户偏好、会话数据、小型数据集
  2. this.sql — 内置 SQLite 数据库(最大 1GB)

    • 带标签的模板字面量可防止 SQL 注入
    • 适用于:关系型数据、大型数据集、复杂查询

状态规则:

  • ✅ 仅支持可序列化为 JSON 的数据(对象、数组、原始类型、null)
  • ✅ 重启后仍会保留,且立即保持一致
  • ❌ 不支持函数或循环引用
  • ❌ 总容量限制为 1GB(状态与 SQL 合计)

SQL 模式:

await this.sql`CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, email TEXT)`
await this.sql`INSERT INTO users (email) VALUES (${userEmail})`  // ← Prepared statement
const users = await this.sql`SELECT * FROM users WHERE email = ${email}`  // ← Returns array

参见:https://developers.cloudflare.com/agents/api-reference/store-and-sync-state/


安排任务

Agent 可以使用 this.schedule() 安排未来运行的任务。

延迟(秒)
export class MyAgent extends Agent {
  async onRequest(request: Request): Promise<Response> {
    // Schedule task to run in 60 seconds
    const { id } = await this.schedule(60, "checkStatus", { requestId: "123" });

    return Response.json({ scheduledTaskId: id });
  }

  // This method will be called in 60 seconds
  async checkStatus(data: { requestId: string }) {
    console.log('Checking status for request:', data.requestId);
    // Perform check, update state, send notification, etc.
  }
}
指定日期
export class MyAgent extends Agent {
  async scheduleReminder(reminderDate: string) {
    const date = new Date(reminderDate);

    const { id } = await this.schedule(date, "sendReminder", {
      message: "Time for your appointment!"
    });

    return id;
  }

  async sendReminder(data: { message: string }) {
    console.log('Sending reminder:', data.message);
    // Send email, push notification, etc.
  }
}
Cron 表达式
export class MyAgent extends Agent {
  async setupRecurringTasks() {
    // Every 10 minutes
    await this.schedule("*/10 * * * *", "checkUpdates", {});

    // Every day at 8 AM
    await this.schedule("0 8 * * *", "dailyReport", {});

    // Every Monday at 9 AM
    await this.schedule("0 9 * * 1", "weeklyReport", {});

    // Every hour on the hour
    await this.schedule("0 * * * *", "hourlyCheck", {});
  }

  async checkUpdates(data: any) {
    console.log('Checking for updates...');
  }

  async dailyReport(data: any) {
    console.log('Generating daily report...');
  }

  async weeklyReport(data: any) {
    console.log('Generating weekly report...');
  }

  async hourlyCheck(data: any) {
    console.log('Running hourly check...');
  }
}
管理已安排的任务
export class MyAgent extends Agent {
  async manageSchedules() {
    // Get all scheduled tasks
    const allTasks = this.getSchedules();
    console.log('Total tasks:', allTasks.length);

    // Get specific task by ID
    const taskId = "some-task-id";
    const task = await this.getSchedule(taskId);

    if (task) {
      console.log('Task:', task.callback, 'at', new Date(task.time));
      console.log('Payload:', task.payload);
      console.log('Type:', task.type);  // "scheduled" | "delayed" | "cron"

      // Cancel the task
      const cancelled = await this.cancelSchedule(taskId);
      console.log('Cancelled:', cancelled);
    }

    // Get tasks in time range
    const upcomingTasks = this.getSchedules({
      timeRange: {
        start: new Date(),
        end: new Date(Date.now() + 24 * 60 * 60 * 1000)  // Next 24 hours
      }
    });

    console.log('Upcoming tasks:', upcomingTasks.length);

    // Filter by type
    const cronTasks = this.getSchedules({ type: "cron" });
    const delayedTasks = this.getSchedules({ type: "delayed" });
  }
}

安排任务的限制:

  • 每项任务对应 SQL 数据库中的一行(每项任务最大 2 MB)
  • 任务总数受以下条件限制:(task_size * count) + other_state < 1GB
  • Cron 任务会持续运行,直到被明确取消
  • 回调方法必须存在于 Agent 类中(如果缺失,则会抛出错误)

严重错误:如果回调方法不存在:

// ❌ BAD: Method doesn't exist
await this.schedule(60, "nonExistentMethod", {});

// ✅ GOOD: Method exists
await this.schedule(60, "existingMethod", {});

async existingMethod(data: any) {
  // Implementation
}

运行工作流

Agent 可以触发异步 Cloudflare Workflows。

工作流绑定配置

wrangler.jsonc:

{
  "workflows": [
    {
      "name": "MY_WORKFLOW",
      "class_name": "MyWorkflow"
    }
  ]
}

如果 Workflow 位于不同的脚本中:

{
  "workflows": [
    {
      "name": "EMAIL_WORKFLOW",
      "class_name": "EmailWorkflow",
      "script_name": "email-workflows"  // Different project
    }
  ]
}
触发工作流
import { Agent } from "agents";
import { WorkflowEntrypoint, WorkflowEvent, WorkflowStep } from "cloudflare:workers";

interface Env {
  MY_WORKFLOW: Workflow;
  MyAgent: AgentNamespace<MyAgent>;
}

export class MyAgent extends Agent<Env> {
  async onRequest(request: Request): Promise<Response> {
    const userId = new URL(request.url).searchParams.get('userId');

    // Trigger a workflow immediately
    const instance = await this.env.MY_WORKFLOW.create({
      id: `user-${userId}`,
      params: { userId, action: "process" }
    });

    // Or schedule a delayed workflow trigger
    await this.schedule(300, "runWorkflow", { userId });

    return Response.json({ workflowId: instance.id });
  }

  async runWorkflow(data: { userId: string }) {
    const instance = await this.env.MY_WORKFLOW.create({
      id: `delayed-${data.userId}`,
      params: data
    });

    // Monitor workflow status periodically
    await this.schedule("*/5 * * * *", "checkWorkflowStatus", { id: instance.id });
  }

  async checkWorkflowStatus(data: { id: string }) {
    // Check workflow status (see Workflows docs for details)
    console.log('Checking workflow:', data.id);
  }
}

// Workflow definition (can be in same or different file/project)
export class MyWorkflow extends WorkflowEntrypoint<Env> {
  async run(event: WorkflowEvent<{ userId: string }>, step: WorkflowStep) {
    // Workflow implementation
    const result = await step.do('process-data', async () => {
      return { processed: true };
    });

    return result;
  }
}
Agent 与 Workflow 对比
特性AgentWorkflow
用途交互式、面向用户后台处理
持续时间几秒到几小时几分钟到几小时
状态SQLite 数据库基于步骤的检查点
交互方式WebSocket、HTTP无直接交互
重试手动每个步骤自动重试
使用场景聊天、实时 UIETL、批处理

最佳实践:使用 Agent 协调多个 Workflow。Agent 可以触发、监控 Workflow 并响应其结果,同时保持与用户的交互。


浏览网页

Agent 可以使用 Browser Rendering 进行网页抓取和自动化:

绑定:将 "browser": { "binding": "BROWSER" } 添加到 wrangler.jsonc 软件包:@cloudflare/puppeteer 使用场景:网页抓取、截图,以及在 Agent 工作流中自动浏览网页

参见:cloudflare-browser-rendering skill,了解完整的 Puppeteer + Workers 集成指南。


检索增强生成(RAG)

Agent 可以使用 Vectorize(向量数据库)+ Workers AI(嵌入)实现 RAG:

模式:导入文档 → 生成嵌入 → 存储到 Vectorize → 查询 → 检索上下文 → 传递给 AI

绑定:

  • "ai": { "binding": "AI" } - 用于嵌入的 Workers AI
  • "vectorize": { "bindings": [{ "binding": "VECTORIZE", "index_name": "my-vectors" }] } - 向量搜索

典型工作流:

  1. 使用 Workers AI 生成嵌入(@cf/baai/bge-base-en-v1.5)
  2. 将向量写入 Vectorize(this.env.VECTORIZE.upsert(vectors))
  3. 查询相似向量(this.env.VECTORIZE.query(queryVector, { topK: 5 }))
  4. 在 AI 提示词中使用检索到的上下文

参见:cloudflare-vectorize 技能,了解完整的 RAG 实现指南。


使用 AI 模型

Agent 可以通过以下方式调用 AI 模型:

  • Vercel AI SDK(推荐):支持多种提供商、自动流式传输和工具调用
  • Workers AI:Cloudflare 平台内的推理(经济高效,但需手动解析)

架构说明:Agents SDK 提供基础设施(WebSocket、状态、调度)。AI 推理属于独立层——使用 AI SDK 作为“大脑”。

参见:

  • ai-sdk-core 技能,了解完整的 AI SDK 集成模式
  • cloudflare-workers-ai 技能,了解 Workers AI 流式解析

调用 Agent

两种主要模式:

  1. routeAgentRequest(request, env) - 通过 URL 模式 /agents/:agent/:name 自动路由

    • 示例:/agents/my-agent/user-123 路由到 MyAgent 实例“user-123”
  2. getAgentByName<Env, T>(env.AgentBinding, instanceName) - 自定义路由

    • 返回 Agent 存根,用于调用方法或传递请求
    • 示例:const agent = getAgentByName(env.MyAgent, 'user-${userId}')

多 Agent 通信:

export class AgentA extends Agent<Env> {
  async processData(data: any) {
    const agentB = getAgentByName<Env, AgentB>(this.env.AgentB, 'processor-1');
    return await (await agentB).analyze(data);
  }
}

重要安全提示:始终在创建或访问 Agent 之前,在 Worker 中进行身份验证。Agent 应假定调用方已获授权。

参见:https://developers.cloudflare.com/agents/api-reference/calling-agents/


客户端 API

浏览器/React 集成:

  • AgentClient(来自 agents/client)- 用于浏览器的 WebSocket 客户端
  • agentFetch(来自 agents/client)- 向 Agent 发送 HTTP 请求
  • useAgent(来自 agents/react)- 用于 WebSocket 连接和状态同步的 React Hook
  • useAgentChat(来自 agents/ai-react)- 预构建的聊天 UI Hook

所有客户端库都会自动处理:WebSocket 连接、状态同步、重新连接逻辑。

参见:https://developers.cloudflare.com/agents/api-reference/client-apis/


模型上下文协议(MCP)

使用 Agents SDK 构建 MCP 服务。

MCP 服务设置
npm install @modelcontextprotocol/sdk agents
基本 MCP 服务
import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

export class MyMCP extends McpAgent {
  server = new McpServer({ name: "Demo", version: "1.0.0" });

  async init() {
    // Define a tool
    this.server.tool(
      "add",
      "Add two numbers together",
      {
        a: z.number().describe("First number"),
        b: z.number().describe("Second number")
      },
      async ({ a, b }) => ({
        content: [{ type: "text", text: String(a + b) }]
      })
    );
  }
}
有状态 MCP 服务
type State = { counter: number };

export class StatefulMCP extends McpAgent<Env, State> {
  server = new McpServer({ name: "Counter", version: "1.0.0" });

  initialState: State = { counter: 0 };

  async init() {
    // Resource
    this.server.resource(
      "counter",
      "mcp://resource/counter",
      (uri) => ({
        contents: [{ uri: uri.href, text: String(this.state.counter) }]
      })
    );

    // Tool
    this.server.tool(
      "increment",
      "Increment the counter",
      { amount: z.number() },
      async ({ amount }) => {
        this.setState({
          ...this.state,
          counter: this.state.counter + amount
        });

        return {
          content: [{
            type: "text",
            text: `Counter is now ${this.state.counter}`
          }]
        };
      }
    );
  }
}
MCP 传输配置
import { Hono } from 'hono';

const app = new Hono();

// Modern streamable HTTP transport (recommended)
app.mount('/mcp', MyMCP.serve('/mcp').fetch, { replaceRequest: false });

// Legacy SSE transport (deprecated)
app.mount('/sse', MyMCP.serveSSE('/sse').fetch, { replaceRequest: false });

export default app;

传输方式对比:

  • /mcp:可流式传输的 HTTP(现代方式,推荐)
  • /sse:服务器发送事件(旧版,已弃用)
使用 OAuth 的 MCP
import { OAuthProvider } from '@cloudflare/workers-oauth-provider';

export default new OAuthProvider({
  apiHandlers: {
    '/sse': MyMCP.serveSSE('/sse'),
    '/mcp': MyMCP.serve('/mcp')
  },
  // OAuth configuration
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  // ... other OAuth settings
});
测试 MCP 服务
# Run MCP inspector
npx @modelcontextprotocol/inspector@latest

# Connect to: http://localhost:8788/mcp

Cloudflare 的 MCP 服务:请参见参考资料,了解生产环境示例。


关键规则

始终要做 ✅
  1. 导出 Agent 类 - 绑定才能正常工作
  2. 在 v1 迁移中包含 new_sqlite_classes - 之后无法再添加 SQLite
  3. 让绑定名称与类名称一致 - 避免出现“找不到绑定”错误
  4. 在 Worker 中进行身份验证,而非 Agent 中 - 安全最佳实践
  5. 使用带标签的模板字面量编写 SQL - 防止 SQL 注入
  6. 处理 WebSocket 断开连接 - 状态会持久化,但连接不会
  7. 确认存在定时任务回调 - 如果方法缺失,会抛出错误
  8. 使用全局唯一的实例名称 - 名称相同 = 全局同一个 Agent
  9. 检查状态大小限制 - 每个 Agent 总计最多 1 GB
  10. 监控任务负载大小 - 每个定时任务最多 2 MB
  11. 正确使用工作流绑定 - 必须在 wrangler.jsonc 中配置
  12. 在插入数据前创建 Vectorize 索引 - 元数据筛选所必需
  13. 关闭浏览器实例 - 防止资源泄漏
  14. 使用 setState() 实现持久化 - 不要只修改 this.state
  15. 先在本地测试迁移 - 迁移是原子的,无法回滚
绝不要做 ❌
  1. 不要向已部署的类添加 SQLite - 必须在首次迁移中启用
  2. 不要逐步部署迁移 - 迁移只能原子性地部署
  3. 不要跳过 Worker 中的身份验证 - 访问 Agent 前务必先进行身份验证
  4. 不要手动构造 SQL 字符串 - 使用带标签的模板字面量
  5. 不要让每个 Agent 的状态超过 1 GB - 硬性限制
  6. 不要为不存在的回调安排任务 - 会导致运行时错误
  7. 不要认为名称相同就代表不同 Agent - 名称全局唯一
  8. 不要将 SSE 用于 MCP - 已弃用,请使用 /mcp 传输方式
  9. 不要忘记浏览器绑定 - 网页浏览所必需
  10. 不要直接修改 this.state - 请改用 setState()

预防已知问题

此技能可预防 16+ 个已记录的问题:

问题 1:迁移不是原子的

错误:“Cannot gradually deploy migration” 来源:https://developers.cloudflare.com/durable-objects/reference/durable-objects-migrations/ 原因:迁移会同时应用于所有实例 预防措施:独立于代码更改部署迁移,使用 npx wrangler versions deploy

问题 2:缺少 new_sqlite_classes

错误:“Cannot enable SQLite on existing class” 来源:https://developers.cloudflare.com/agents/api-reference/configuration/ 原因:必须在首次迁移中启用 SQLite 预防措施:在标记为 "v1" 的迁移中包含 new_sqlite_classes

问题 3:Agent 类未导出

错误:“Binding not found” 或 “Cannot access undefined” 来源:https://developers.cloudflare.com/agents/api-reference/agents-api/ 原因:Durable Objects 要求类必须导出 预防措施:export class MyAgent extends Agent(包含 export 关键字)

问题 4:绑定名称不匹配

错误:“Binding 'X' not found” 来源:https://developers.cloudflare.com/agents/api-reference/configuration/ 原因:绑定名称必须与类名称完全一致 预防措施:确保 wrangler.jsonc 中的 name 和 class_name 完全相同

问题 5:未理解全局唯一性

错误:Agent 实例出现意外行为 来源:https://developers.cloudflare.com/agents/api-reference/agents-api/ 原因:相同名称始终会在全局范围内返回同一个 Agent 实例 预防措施:使用唯一标识符(userId、sessionId)作为实例名称

问题 6:WebSocket 状态未持久化

错误:断开连接后连接状态丢失 来源:https://developers.cloudflare.com/agents/api-reference/websockets/ 原因:WebSocket 连接不会持久化,但 Agent 状态会 预防措施:通过 setState() 将重要数据存储在 Agent 状态中,而非连接状态中

问题 7:计划任务回调不存在

错误:“Agent 上不存在方法 X” 来源: https://developers.cloudflare.com/agents/api-reference/schedule-tasks/ 原因:this.schedule() 调用了未定义的方法 预防:计划任务前,确保回调方法已存在

问题 8:状态大小超出限制

错误:“超出数据库最大容量” 来源: https://developers.cloudflare.com/agents/api-reference/store-and-sync-state/ 原因:Agent 状态和计划任务总大小超过 1GB 预防:监控状态大小,大型数据使用外部存储(D1、R2)

问题 9:计划任务过大

错误:“任务负载超过 2MB” 来源: https://developers.cloudflare.com/agents/api-reference/schedule-tasks/ 原因:每个任务都对应一个数据库行,大小限制为 2MB 预防:尽量精简任务负载,将大型数据存储在 Agent 状态或 SQL 中

问题 10:缺少工作流绑定

错误:“无法读取 undefined 的属性 'create'” 来源: https://developers.cloudflare.com/agents/api-reference/run-workflows/ 原因:未在 wrangler.jsonc 中配置工作流绑定 预防:使用 this.env.WORKFLOW 前添加工作流绑定

问题 11:需要浏览器绑定

错误:“BROWSER 绑定未定义” 来源: https://developers.cloudflare.com/agents/api-reference/browse-the-web/ 原因:Browser Rendering 需要显式绑定 预防:将 "browser": { "binding": "BROWSER" } 添加到 wrangler.jsonc

问题 12:未找到 Vectorize 索引

错误:“索引不存在” 来源: https://developers.cloudflare.com/agents/api-reference/rag/ 原因:必须先创建 Vectorize 索引才能使用 预防:部署 Agent 前运行 wrangler vectorize create

问题 13:MCP 传输方式混淆

错误:“SSE 传输方式已弃用” 来源: https://developers.cloudflare.com/agents/model-context-protocol/transport/ 原因:SSE 传输方式已过时,建议使用可流式传输的 HTTP 预防:使用 /mcp 端点和 MyMCP.serve('/mcp'),而不是 /sse

问题 14:绕过身份验证

错误:安全漏洞 来源: https://developers.cloudflare.com/agents/api-reference/calling-agents/ 原因:在 Agent 中而不是 Worker 中进行身份验证 预防:调用 getAgentByName() 前,始终在 Worker 中进行身份验证

问题 15:实例命名错误

错误:用户间数据泄露 来源: https://developers.cloudflare.com/agents/api-reference/calling-agents/ 原因:实例命名不当,可能导致访问错误的 Agent 预防:使用命名空间名称,例如 user-${userId},并验证所有权

问题 16:Workers AI 流式传输需要手动解析

错误:“无法读取 undefined 的属性 'response'”,或 AI 响应为空 来源: https://developers.cloudflare.com/workers-ai/platform/streaming/ 原因:Workers AI 以服务器发送事件(SSE)格式返回 Uint8Array 流式响应,而不是普通对象 预防:使用 TextDecoder + SSE 解析模式(参见上文“Workers AI(AI 的替代方案)”部分)

问题——尝试直接访问流块会失败:

const response = await env.AI.run(model, { stream: true });
for await (const chunk of response) {
  console.log(chunk.response);  // ❌ undefined - chunk is Uint8Array, not object
}

解决方案——手动解析 SSE 格式:

const response = await env.AI.run(model, { stream: true });
for await (const chunk of response) {
  const text = new TextDecoder().decode(chunk);  // Step 1: Uint8Array → string
  if (text.startsWith('data: ')) {              // Step 2: Check SSE format
    const jsonStr = text.slice(6).trim();       // Step 3: Extract JSON from "data: {...}"
    if (jsonStr === '[DONE]') break;            // Step 4: Handle termination
    const data = JSON.parse(jsonStr);           // Step 5: Parse JSON
    if (data.response) {                        // Step 6: Extract .response field
      fullResponse += data.response;
    }
  }
}

更好的替代方案:使用 Vercel AI SDK 自动处理:

import { streamText } from 'ai';
import { createCloudflare } from '@ai-sdk/cloudflare';

const cloudflare = createCloudflare();
const result = streamText({
  model: cloudflare('@cf/meta/llama-3-8b-instruct', { binding: env.AI }),
  messages
});
// No manual parsing needed ✅

适合接受手动解析的情况:

  • 成本至关重要(Workers AI 更便宜)
  • 不允许使用外部依赖项
  • 愿意维护 SSE 解析代码

适合改用 AI SDK 的情况:

  • 相较于计算成本,更看重开发者时间
  • 希望自动处理流式传输
  • 需要支持多个提供商

依赖项

必需
  • cloudflare-worker-base - 基础组件(Hono、Vite、Workers 设置)
可选(按功能)
  • cloudflare-workers-ai - 用于调用 Workers AI 模型
  • cloudflare-vectorize - 用于使用 Vectorize 实现 RAG
  • cloudflare-d1 - 用于在 Agent 状态之外提供额外的持久化存储
  • cloudflare-r2 - 用于文件存储
  • cloudflare-queues - 用于消息队列
NPM 包
  • agents - Agents SDK(必需)
  • @modelcontextprotocol/sdk - 用于构建 MCP 服务
  • @cloudflare/puppeteer - 用于网页浏览
  • ai - 用于调用模型的 AI SDK
  • @ai-sdk/openai - OpenAI 模型
  • @ai-sdk/anthropic - Anthropic 模型

官方文档


捆绑资源

模板(templates/)
  • wrangler-agents-config.jsonc - 完整配置示例
  • basic-agent.ts - 最简 HTTP Agent
  • websocket-agent.ts - WebSocket 处理程序
  • state-sync-agent.ts - 状态管理模式
  • scheduled-agent.ts - 任务调度
  • workflow-agent.ts - 工作流集成
  • browser-agent.ts - 网页浏览
  • rag-agent.ts - RAG 实现
  • chat-agent-streaming.ts - 流式聊天
  • calling-agents-worker.ts - Agent 路由
  • react-useagent-client.tsx - React 客户端
  • mcp-server-basic.ts - MCP 服务
  • hitl-agent.ts - 人在回路中
参考文档(references/)
  • agent-class-api.md - 完整的 Agent 类参考
  • client-api-reference.md - 浏览器客户端 API
  • state-management-guide.md - 状态与 SQL 深入指南
  • websockets-sse.md - WebSocket 与 SSE 对比
  • scheduling-api.md - 任务调度详情
  • workflows-integration.md - 工作流指南
  • browser-rendering.md - 网页浏览模式
  • rag-patterns.md - RAG 最佳实践
  • mcp-server-guide.md - MCP 服务开发
  • mcp-tools-reference.md - MCP 工具 API
  • hitl-patterns.md - 人在回路中的工作流
  • best-practices.md - 生产环境模式
示例(examples/)
  • chat-bot-complete.md - 完整聊天 Agent
  • multi-agent-workflow.md - Agent 编排
  • scheduled-reports.md - 定期任务
  • browser-scraper-agent.md - 网页抓取
  • rag-knowledge-base.md - RAG 系统
  • mcp-remote-server.md - 生产环境 MCP 服务

最后验证时间:2025-10-21 包版本:agents@latest 合规性:符合 Cloudflare Agents SDK 官方文档

评论

支持 Markdown