Cloudflare Agents 从入门到精通
附录

§08 从模板到真实项目:聊天 Agent 拆解

从模板到真实项目,把能力串起来。

08.1 我们要做什么

做一个能聊天、有记忆、会调天气工具、危险操作要你确认的 Agent。这就是 Starter 模板里 ChatAgent 的真身。

08.2 服务端骨架

import { AIChatAgent } from "@cloudflare/ai-chat";
import { createWorkersAI } from "workers-ai-provider";
import { streamText, convertToModelMessages, tool, stepCountIs } from "ai";
import { z } from "zod";

export class ChatAgent extends AIChatAgent {
  async onChatMessage() {
    const workersai = createWorkersAI({ binding: this.env.AI });
    const result = streamText({
      model: workersai("@cf/moonshotai/kimi-k2.7-code"),
      messages: await convertToModelMessages(this.messages),
      tools: {
        getWeather: tool({
          description: "Get weather for a city",
          inputSchema: z.object({ city: z.string() }),
          execute: async ({ city }) => fetchWeather(city),
        }),
        processPayment: tool({
          description: "Process a payment",
          inputSchema: z.object({ amount: z.number(), recipient: z.string() }),
          needsApproval: async ({ amount }) => amount > 100, // 超 100 要批
          execute: async ({ amount, recipient }) => charge(amount, recipient),
        }),
      },
      stopWhen: stepCountIs(5),
    });
    return result.toUIMessageStreamResponse();
  }
}

08.3 wrangler 配置

{
  "ai": { "binding": "AI" },
  "durable_objects": {
    "bindings": [{ "name": "ChatAgent", "class_name": "ChatAgent" }]
  },
  "migrations": [{ "tag": "v1", "new_sqlite_classes": ["ChatAgent"] }]
}
注意
AIChatAgent 用 SQLite 存消息和流式缓冲,new_sqlite_classes 是必选项。漏了,对话历史不落盘。

08.4 客户端连上

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

const { messages, sendMessage, addToolApprovalResponse } = useAgentChat({ agent: "ChatAgent" });

useAgentChat 返回 messagessendMessageclearHistoryaddToolOutputaddToolApprovalResponse 等。一个 hook 管全了。

标叔的经验
我第一次把 needsApproval 加上去,看到前端弹出"是否批准付款"的按钮,才真正觉得这是生产级。安全不是事后补,是内建的。

聊天 Agent 拆完了。下一章讲怎么把它配好、部署到全球。