本指南涵盖在本地开发与生产部署中配置 Agent 所需的一切,包括 Wrangler 配置文件设置、类型生成、环境变量和 Cloudflare 仪表板。
使用 npm create cloudflare@latest agents-starter -- --template cloudflare/agents-starter 创建的 Agent 项目典型文件结构如下:
- src/
- index.ts Agent 定义
- public/
- index.html
- test/
- index.spec.ts 测试文件
- package.json
- tsconfig.json
- vitest.config.mts
- worker-configuration.d.ts
- wrangler.jsonc Workers 与 Agent 配置
wrangler.jsonc 文件用于配置 Cloudflare Worker 及其绑定。以下是 agents 项目的完整示例:
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-agent-app",
"main": "src/server.ts",
// Set this to today's date
"compatibility_date": "2026-08-17",
"compatibility_flags": ["nodejs_compat"],
// Static assets (optional)
"assets": {
"directory": "public",
"binding": "ASSETS",
},
// Durable Object bindings for agents
"durable_objects": {
"bindings": [
{
"name": "MyAgent",
"class_name": "MyAgent",
},
{
"name": "ChatAgent",
"class_name": "ChatAgent",
},
],
},
// Provision storage for each agent class
"exports": {
"MyAgent": {
"type": "durable-object",
"storage": "sqlite",
},
"ChatAgent": {
"type": "durable-object",
"storage": "sqlite",
},
},
// AI binding (optional, for Workers AI)
"ai": {
"binding": "AI",
},
// Observability (recommended)
"observability": {
"enabled": true,
},
}"$schema" = "node_modules/wrangler/config-schema.json"
name = "my-agent-app"
main = "src/server.ts"
# Set this to today's date
compatibility_date = "2026-08-17"
compatibility_flags = [ "nodejs_compat" ]
[assets]
directory = "public"
binding = "ASSETS"
[[durable_objects.bindings]]
name = "MyAgent"
class_name = "MyAgent"
[[durable_objects.bindings]]
name = "ChatAgent"
class_name = "ChatAgent"
[exports.MyAgent]
type = "durable-object"
storage = "sqlite"
[exports.ChatAgent]
type = "durable-object"
storage = "sqlite"
[ai]
binding = "AI"
[observability]
enabled = trueagents 需要 nodejs_compat 标志:
{
"compatibility_flags": ["nodejs_compat"],
}compatibility_flags = [ "nodejs_compat" ]这会启用 Node.js 兼容模式,agents 依赖该模式来使用 crypto、streams 及其他 Node.js API。
每个 agent 类都需要一个绑定:
{
"durable_objects": {
"bindings": [
{
"name": "Counter",
"class_name": "Counter",
},
],
},
}[[durable_objects.bindings]]
name = "Counter"
class_name = "Counter"| 字段 | 描述 |
|---|---|
name |
env 上的属性名。在代码中使用:env.Counter |
class_name |
必须与导出的类名完全一致 |
exports 字段声明 Worker 导出的每个 Agent 类,以及 Cloudflare 应为其使用的存储后端:
{
"exports": {
"MyAgent": {
"type": "durable-object",
"storage": "sqlite",
},
},
}[exports.MyAgent]
type = "durable-object"
storage = "sqlite"| 字段 | 描述 |
|---|---|
type |
导出类型。Agent 始终为 "durable-object"。 |
storage |
存储后端。新 Agent 请使用 "sqlite"(推荐)。 |
有关重命名、删除或转移 Agent 类的详情,请参阅 Durable Object 类导出。使用旧版 migrations 数组的现有 Workers 仍可正常工作——请参阅 Durable Object 类迁移(旧版)。
用于提供静态文件(HTML、CSS、JS):
{
"assets": {
"directory": "public",
"binding": "ASSETS",
},
}[assets]
directory = "public"
binding = "ASSETS"配置绑定后,你可以以编程方式提供静态资源:
export default {
async fetch(request, env) {
// Static assets are served by the worker automatically by default
// Route the request to the appropriate agent
const agentResponse = await routeAgentRequest(request, env);
if (agentResponse) return agentResponse;
// Add your own routing logic here
return new Response("Not found", { status: 404 });
},
};export default {
async fetch(request: Request, env: Env) {
// Static assets are served by the worker automatically by default
// Route the request to the appropriate agent
const agentResponse = await routeAgentRequest(request, env);
if (agentResponse) return agentResponse;
// Add your own routing logic here
return new Response("Not found", { status: 404 });
},
} satisfies ExportedHandler<Env>;用于 Workers AI 集成:
{
"ai": {
"binding": "AI",
},
}[ai]
binding = "AI"在 agent 中访问:
const response = await this.env.AI.run("@cf/meta/llama-3-8b-instruct", {
prompt: "Hello!",
});const response = await this.env.AI.run("@cf/meta/llama-3-8b-instruct", {
prompt: "Hello!",
});Agents SDK 提供共享的 tsconfig.json,其中包含 agents 项目所需的所有编译器选项——包括 @callable() 装饰器所需的 ES2021 目标、严格模式、bundler 模块解析以及 Workers 类型。
在你的 tsconfig.json 中扩展它:
{
"extends": "agents/tsconfig"
}这等同于:
{
"compilerOptions": {
"target": "ES2021",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"jsx": "react-jsx",
"module": "ES2022",
"moduleResolution": "bundler",
"types": ["node", "@cloudflare/workers-types", "vite/client"],
"allowImportingTsExtensions": true,
"noEmit": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}你可以根据需要覆盖个别选项:
{
"extends": "agents/tsconfig",
"compilerOptions": {
"jsx": "preserve"
}
}Agents SDK 提供 Vite 插件来处理 TC39 装饰器转换。Vite 8 使用 Oxc 进行转译,目前尚不支持 TC39 装饰器——没有此插件,@callable() 及其他装饰器将在运行时失败。
将插件添加到你的 vite.config.ts:
import { cloudflare } from "@cloudflare/vite-plugin";
import react from "@vitejs/plugin-react";
import agents from "agents/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [agents(), react(), cloudflare()],
});import { cloudflare } from "@cloudflare/vite-plugin";
import react from "@vitejs/plugin-react";
import agents from "agents/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [agents(), react(), cloudflare()],
});agents() 插件即使项目不使用装饰器也可以安全包含。它仅对包含 @ 语法的文件运行转换。
入门模板和所有示例默认包含此插件。如果遇到装饰器相关的 SyntaxError: Invalid or unexpected token,请参阅可调用方法 — 故障排除。
Wrangler 可以为你的绑定生成 TypeScript 类型。
运行 types 命令:
npx wrangler types这将创建或更新包含 Env 类型的 worker-configuration.d.ts。
指定自定义路径:
npx wrangler types env.d.ts为获得更简洁的输出(agents 推荐):
npx wrangler types env.d.ts --include-runtime false这仅生成绑定,不包含 Cloudflare 运行时类型。
// env.d.ts (generated)
declare namespace Cloudflare {
interface Env {
OPENAI_API_KEY: string;
Counter: DurableObjectNamespace;
ChatAgent: DurableObjectNamespace;
}
}
interface Env extends Cloudflare.Env {}你也可以手动定义类型:
// env.d.ts// env.d.ts
import type { Counter } from "./src/agents/counter";
import type { ChatAgent } from "./src/agents/chat";
interface Env {
// Secrets
OPENAI_API_KEY: string;
WEBHOOK_SECRET: string;
// Agent bindings
Counter: DurableObjectNamespace<Counter>;
ChatAgent: DurableObjectNamespace<ChatAgent>;
// Other bindings
AI: Ai;
ASSETS: Fetcher;
MY_KV: KVNamespace;
}添加脚本以便轻松重新生成:
{
"scripts": {
"types": "wrangler types env.d.ts --include-runtime false"
}
}创建 .env 文件存放本地密钥(添加到 .gitignore):
# .env
OPENAI_API_KEY=sk-...
GITHUB_WEBHOOK_SECRET=whsec_...
DATABASE_URL=postgres://...在 agent 中访问:
class MyAgent extends Agent {
async onStart() {
const apiKey = this.env.OPENAI_API_KEY;
}
}class MyAgent extends Agent {
async onStart() {
const apiKey = this.env.OPENAI_API_KEY;
}
}生产环境请使用 wrangler secret:
# Add a secret
npx wrangler secret put OPENAI_API_KEY
# Enter value when prompted
# List secrets
npx wrangler secret list
# Delete a secret
npx wrangler secret delete OPENAI_API_KEY对于非敏感配置,在 Wrangler 配置文件中使用 vars:
{
"vars": {
"API_BASE_URL": "https://api.example.com",
"MAX_RETRIES": "3",
"DEBUG_MODE": "false",
},
}[vars]
API_BASE_URL = "https://api.example.com"
MAX_RETRIES = "3"
DEBUG_MODE = "false"所有值必须是字符串。在代码中解析数字和布尔值:
const maxRetries = parseInt(this.env.MAX_RETRIES, 10);
const debugMode = this.env.DEBUG_MODE === "true";const maxRetries = parseInt(this.env.MAX_RETRIES, 10);
const debugMode = this.env.DEBUG_MODE === "true";使用 env 部分为不同环境(例如 staging、production)配置:
{
"name": "my-agent",
"vars": {
"API_URL": "https://api.example.com",
},
"env": {
"staging": {
"vars": {
"API_URL": "https://staging-api.example.com",
},
},
"production": {
"vars": {
"API_URL": "https://api.example.com",
},
},
},
}name = "my-agent"
[vars]
API_URL = "https://api.example.com"
[env.staging.vars]
API_URL = "https://staging-api.example.com"
[env.production.vars]
API_URL = "https://api.example.com"部署到特定环境:
npx wrangler deploy --env staging
npx wrangler deploy --env production使用 Vite(全栈应用推荐):
npx vite dev不使用 Vite:
npx wrangler devDurable Object 状态本地持久化在 .wrangler/state/:
- .wrangler/
- state/
- v3/
- d1/
- miniflare-D1DatabaseObject/
- ... (SQLite files)
- miniflare-D1DatabaseObject/
- d1/
- v3/
- state/
要重置所有本地 Durable Object 状态:
rm -rf .wrangler/state或以全新状态重启:
npx wrangler dev --persist-to=""你可以直接检查 agent 状态:
# Find the SQLite file
ls .wrangler/state/v3/d1/
# Open with sqlite3
sqlite3 .wrangler/state/v3/d1/miniflare-D1DatabaseObject/*.sqlite部署时,Cloudflare 会自动创建:
- Worker - 你部署的代码
- Durable Object 命名空间 - 每个 agent 类一个
- SQLite 存储 - 附加到每个命名空间
登录 Cloudflare 仪表板,然后前往 Durable Objects。
Go to Durable Objects ↗在此你可以:
- 查看所有 Durable Object 命名空间
- 查看单个对象实例
- 检查存储(键和值)
- 删除对象
查看 agent 的实时日志:
npx wrangler tail或在仪表板中:
- 前往你的 Worker。
- 选择 Observability(可观测性) 选项卡。
- 启用实时日志。
按以下条件筛选:
- 状态(success、error)
- 搜索文本
- 采样率
npx wrangler deploy这将:
- 打包你的代码
- 上传到 Cloudflare
- 为 Agent 的 Durable Object 命名空间配置存储
- 在
*.workers.dev上上线
在 Wrangler 配置文件中添加路由:
{
"routes": [
{
"pattern": "agents.example.com/*",
"zone_name": "example.com",
},
],
}[[routes]]
pattern = "agents.example.com/*"
zone_name = "example.com"或使用自定义域名(更简单):
{
"routes": [
{
"pattern": "agents.example.com",
"custom_domain": true,
},
],
}[[routes]]
pattern = "agents.example.com"
custom_domain = true部署而不影响生产环境:
npx wrangler deploy --dry-run # See what would be uploaded
npx wrangler versions upload # Upload new version
npx wrangler versions deploy # Gradually roll out回滚到先前版本:
npx wrangler rollback在 Wrangler 配置文件中定义环境:
{
"name": "my-agent",
"main": "src/server.ts",
// Base configuration (shared)
// Set this to today's date
"compatibility_date": "2026-08-17",
"compatibility_flags": ["nodejs_compat"],
"durable_objects": {
"bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }],
},
"exports": {
"MyAgent": { "type": "durable-object", "storage": "sqlite" },
},
// Environment overrides
"env": {
"staging": {
"name": "my-agent-staging",
"vars": {
"ENVIRONMENT": "staging",
},
},
"production": {
"name": "my-agent-production",
"vars": {
"ENVIRONMENT": "production",
},
},
},
}name = "my-agent"
main = "src/server.ts"
# Set this to today's date
compatibility_date = "2026-08-17"
compatibility_flags = [ "nodejs_compat" ]
[[durable_objects.bindings]]
name = "MyAgent"
class_name = "MyAgent"
[exports.MyAgent]
type = "durable-object"
storage = "sqlite"
[env.staging]
name = "my-agent-staging"
[env.staging.vars]
ENVIRONMENT = "staging"
[env.production]
name = "my-agent-production"
[env.production.vars]
ENVIRONMENT = "production"# Deploy to staging
npx wrangler deploy --env staging
# Deploy to production
npx wrangler deploy --env production
# Set secrets per environment
npx wrangler secret put OPENAI_API_KEY --env staging
npx wrangler secret put OPENAI_API_KEY --env production每个环境拥有独立的 Durable Objects。staging agent 不与 production agent 共享状态。
要显式分离:
{
"env": {
"staging": {
"durable_objects": {
"bindings": [
{
"name": "MyAgent",
"class_name": "MyAgent",
"script_name": "my-agent-staging",
},
],
},
},
},
}[[env.staging.durable_objects.bindings]]
name = "MyAgent"
class_name = "MyAgent"
script_name = "my-agent-staging"每个 Agent 对应一个 Durable Object 类。你通过 Wrangler 配置文件中的 exports 字段管理这些类的生命周期(创建、重命名、删除、转移)。
在 exports 中声明新类:
{
"exports": {
"NewAgent": { "type": "durable-object", "storage": "sqlite" },
},
}[exports.NewAgent]
type = "durable-object"
storage = "sqlite"将旧名称的条目替换为 renamed 墓碑,并为新名称添加活跃条目:
{
"exports": {
"OldName": {
"type": "durable-object",
"state": "renamed",
"renamed_to": "NewName",
},
"NewName": { "type": "durable-object", "storage": "sqlite" },
},
}[exports.OldName]
type = "durable-object"
state = "renamed"
renamed_to = "NewName"
[exports.NewName]
type = "durable-object"
storage = "sqlite"同时更新:
- 代码中的类名。
- 绑定中的
class_name。 - 导出语句。
将条目替换为 deleted 墓碑:
{
"exports": {
"AgentToKeep": { "type": "durable-object", "storage": "sqlite" },
"AgentToDelete": { "type": "durable-object", "state": "deleted" },
},
}[exports.AgentToKeep]
type = "durable-object"
storage = "sqlite"
[exports.AgentToDelete]
type = "durable-object"
state = "deleted"- 保持
exports与代码同步。 Worker 导出的每个 Agent 类都需要一个条目。 - 使用墓碑,而非静默删除。 退役类时,在
exports中保留deleted/renamed/transferred墓碑,以便 Cloudflare 显式协调变更。 - 先在本地测试。 生命周期变更在
wrangler deploy时生效。 - 重命名或删除前备份生产数据。
使用旧版 migrations 数组的现有 Workers 仍可正常工作——请参阅 Durable Object 类迁移(旧版) 了解旧版参考,或参阅从旧版 migrations 流程迁移以迁移到 exports。
该类在 exports 中缺失。声明该类及其存储:
{
"exports": {
"MissingClassName": { "type": "durable-object", "storage": "sqlite" },
},
}[exports.MissingClassName]
type = "durable-object"
storage = "sqlite"重新生成类型:
npx wrangler types env.d.ts --include-runtime false检查 .env 是否存在并包含该变量:
cat .env
# Should show: MY_SECRET=value如果你的 Worker 使用旧版 migrations 数组,每个条目必须有唯一的 tag:
{
// Wrong - duplicate tags
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["A"] },
{ "tag": "v1", "new_sqlite_classes": ["B"] },
],
}[[migrations]]
tag = "v1"
new_sqlite_classes = [ "A" ]
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "B" ]{
// Correct - sequential tags
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["A"] },
{ "tag": "v2", "new_sqlite_classes": ["B"] },
],
}[[migrations]]
tag = "v1"
new_sqlite_classes = [ "A" ]
[[migrations]]
tag = "v2"
new_sqlite_classes = [ "B" ]考虑转换为声明式 exports 字段。