说实话,第一次听说 Cloudflare Agents SDK 的时候,我脑子里全是问号:这玩意儿到底怎么用?官方文档说可以用 AIChatAgent,但我一开始完全理解错了——把它当成普通 Durable Object 来用,从零开始写所有逻辑,结果踩了一堆坑。

后来才明白:AIChatAgent 是一个高级框架,就像 Express.js 一样,你不需要处理底层细节,只需要实现一个方法。

这篇文章记录了我从"错误用法"到"官方标准用法"的过程。

📁 项目地址:https://github.com/YaBoom/cloudflare-agent-zyt


❌ 我一开始的错误用法

刚开始我是这样写的:

import { AIChatAgent } from "@cloudflare/ai-chat";

export class ChatAgent extends AIChatAgent<Env> {
  // ❌ 自己定义 state
  state = { messages: [] };
  
  // ❌ 自己处理 WebSocket
  async onMessage(connection, message) {
    // ❌ 手动解析消息
    const data = JSON.parse(message);
    
    // ❌ 手动管理历史
    this.state.messages.push({ role: "user", content: data.message });
    
    // ❌ 使用旧 API 调用 AI
    const response = await this.env.AI.run("model", {
      messages: this.state.messages
    });
    
    // ❌ 手动发送响应
    connection.send(JSON.stringify({
      type: "message",
      content: response.response
    }));
  }
}

问题在哪?

  • 我把 AIChatAgent 当成普通 Durable Object 来用
  • 自己管理状态、自己处理 WebSocket、自己调用 AI
  • 结果代码复杂还容易出错

✅ 官方标准用法

正确的写法是这样的:

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

export class ChatAgent extends AIChatAgent<Env> {
  // ✅ 只实现 onChatMessage 一个方法
  async onChatMessage(onFinish) {
    // this.messages 自动包含完整对话历史
    // 自动持久化,断线重连后自动恢复

    const workersai = createWorkersAI({ binding: this.env.AI });
    
    const result = streamText({
      model: workersai("@cf/meta/llama-3.3-70b-instruct-fp8-fast"),
      messages: this.messages,
      maxTokens: 1024
    });

    // 返回流式响应
    // AIChatAgent 自动处理:流式传输、断线重连、多客户端同步
    return result.toDataStreamResponse({ onFinish });
  }
}

为什么这么写?

类比一下:就像用 Express.js 写 Web 服务器——

  • ❌ 错误做法:自己处理 TCP 连接、HTTP 协议解析、路由分发
  • ✅ 正确做法:定义路由处理函数,app.get('/', handler)

AIChatAgent 也是同样的思路:

  • ❌ 错误做法:自己管理状态、处理 WebSocket、调用 AI
  • ✅ 正确做法:实现 onChatMessage() 方法,框架帮你处理一切

项目搭建过程

第一步:初始化

mkdir cloudflare-agent-zyt
cd cloudflare-agent-zyt
npm init -y

安装依赖(官方推荐组合):

npm install agents ai workers-ai-provider zod typescript wrangler --save

依赖说明

  • agents - Cloudflare Agents SDK(含 AIChatAgent)
  • ai - Vercel AI SDK(streamText)
  • workers-ai-provider - Workers AI 提供商适配器
  • zod - 类型验证(可选,用于结构化输出)

第二步:核心代码

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

export interface Env {
  AI: Ai;
}

export class ChatAgent extends AIChatAgent<Env> {
  async onChatMessage(onFinish) {
    const workersai = createWorkersAI({ binding: this.env.AI });
    
    const result = streamText({
      model: workersai("@cf/meta/llama-3.3-70b-instruct-fp8-fast"),
      messages: this.messages,
      maxTokens: 1024
    });

    return result.toDataStreamResponse({ onFinish });
  }
}

// Worker 入口
import { routeAgentRequest } from "agents";

export default {
  async fetch(request: Request, env: Env) {
    return (
      routeAgentRequest(request, env) ||
      new Response("Not found", { status: 404 })
    );
  }
} satisfies ExportedHandler<Env>;

第三步:配置 wrangler.toml

name = "cloudflare-agent-zyt"
main = "src/index.ts"
compatibility_date = "2026-02-22"

[[ai]]
binding = "AI"

注意:不需要配置 durable_objects.bindingsmigrationsAIChatAgent 自动处理。

第四步:本地测试

npx wrangler dev

Agent 会自动在 /agents/chat-agent/:instance-name 路径可用。


踩坑实录

坑 1:错误理解 AIChatAgent 的定位

错误想法:AIChatAgent 是一个需要我自己管理一切的基类
正确理解:AIChatAgent 是一个高级框架,我只用实现业务逻辑

关键区别

功能 旧写法(错误) 新写法(正确)
状态管理 自己定义 this.state 使用 this.messages(自动管理)
消息持久化 手动 storage.put() 自动持久化
WebSocket 自己处理 onMessage 框架自动处理
流式输出 自己发送 chunks 返回 toDataStreamResponse
断线重连 自己实现恢复逻辑 框架自动恢复

坑 2:路由配置错误

错误写法

// ❌ 不要自己处理路由
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    if (url.pathname.startsWith("/agent/")) {
      // 自己解析 session ID,自己 get Durable Object
    }
  }
};

正确写法

// ✅ 使用官方路由
import { routeAgentRequest } from "agents";

export default {
  async fetch(request, env) {
    return routeAgentRequest(request, env) || 
           new Response("Not found", { status: 404 });
  }
};

routeAgentRequest 自动处理:

  • URL 解析 (/agents/:agent-name/:instance-name)
  • Agent 实例创建/获取
  • WebSocket 升级
  • HTTP 请求路由

坑 3:依赖包缺失

旧代码缺少必要的依赖:

  • ❌ 只装 agents@cloudflare/ai-chat
  • ✅ 需要 agents + ai + workers-ai-provider + zod

效果怎么样?

使用官方标准写法后:

  1. 代码量减少 70% - 从 150 行减少到 40 行
  2. 功能更强大 - 自动获得持久化、断线重连、多客户端同步
  3. 更可靠 - 框架处理边缘情况(网络抖动、重连等)
  4. 更好的生态 - 兼容 Vercel AI SDK,可切换 OpenAI/Anthropic

还没做完的事

  • 工具调用(Tool Calling)
  • MCP 协议集成
  • 多模型切换(OpenAI/Anthropic)
  • React 客户端(useAgentChat)

一点想法

折腾这个项目最大的收获是:不要和框架对着干。

一开始我想着自己管理所有细节,觉得这样更"灵活"。结果写了一大堆代码,还各种 bug。

后来改用官方标准写法,才发现框架已经帮我想好了 90% 的场景。我只需要关注业务逻辑(怎么处理消息、怎么调用 AI),其他的(状态管理、WebSocket、持久化、重连)都交给框架。

这就像用 React 写前端——你不需要自己操作 DOM,只需要描述 UI 应该长什么样。Agent 框架也是一样的思路。


项目地址

完整代码在这里:

🔗 https://github.com/YaBoom/cloudflare-agent-zyt

README 里有更详细的部署说明。


参考资料


最后

如果你也在折腾 Cloudflare Agents,建议直接去官方仓库看 agents-starter 模板,比我这篇文章更权威。

或者,你觉得 AI Agent 框架这种"傻瓜式"设计是好还是坏?

有人说它限制了灵活性,有人说它让开发更简单。

你怎么看?

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐