配置
本指南涵盖了为本地开发和生产部署配置 agent 所需的一切,包括 Wrangler 配置文件设置、类型生成、环境变量,以及 Cloudflare 控制台的使用。
项目结构
由 npm create cloudflare@latest agents-starter -- --template cloudflare/agents-starter 创建的 Agent 项目典型文件结构如下:
- Directorysrc/
- index.ts 你的 Agent 定义
- Directorypublic/
- index.html
- Directorytest/
- index.spec.ts 你的测试
- package.json
- tsconfig.json
- vitest.config.mts
- worker-configuration.d.ts
- wrangler.jsonc 你的 Workers 和 Agent 配置
Wrangler 配置文件
wrangler.jsonc 文件用于配置你的 Cloudflare Worker 及其绑定。下面是一个 agent 项目的完整示例:
JSONC
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-agent-app",
"main": "src/server.ts",
// Set this to today's date
"compatibility_date": "2026-04-29",
"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",
},
],
},
// Required: Enable SQLite storage for agents
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["MyAgent", "ChatAgent"],
},
],
// AI binding (optional, for Workers AI)
"ai": {
"binding": "AI",
},
// Observability (recommended)
"observability": {
"enabled": true,
},
}
TOML
"$schema" = "node_modules/wrangler/config-schema.json"
name = "my-agent-app"
main = "src/server.ts"
# Set this to today's date
compatibility_date = "2026-04-29"
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"
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "MyAgent", "ChatAgent" ]
[ai]
binding = "AI"
[observability]
enabled = true
关键字段
compatibility_flags
agent 必须启用 nodejs_compat 标志:
JSONC
{
"compatibility_flags": ["nodejs_compat"],
}
TOML
compatibility_flags = [ "nodejs_compat" ]
这会启用 Node.js 兼容模式,agent 依赖它来使用 crypto、streams 和其他 Node.js API。
durable_objects.bindings
每个 agent 类都需要一个绑定:
JSONC
{
"durable_objects": {
"bindings": [
{
"name": "Counter",
"class_name": "Counter",
},
],
},
}
TOML
[[durable_objects.bindings]]
name = "Counter"
class_name = "Counter"
| 字段 | 描述 |
|---|---|
| name | env 上的属性名。在代码中这样使用:env.Counter |
| class_name | 必须与导出的类名完全一致 |
name 与 class_name 不一致时
当 name 与 class_name 不同时,按下面的写法配置:
JSONC
{
"durable_objects": {
"bindings": [
{
"name": "COUNTER_DO",
"class_name": "CounterAgent",
},
],
},
}
TOML
[[durable_objects.bindings]]
name = "COUNTER_DO"
class_name = "CounterAgent"
当你想要环境变量风格的命名(COUNTER_DO)但又想用更具描述性的类名(CounterAgent)时,这种写法很有用。
migrations
迁移告诉 Cloudflare 如何为你的 Durable Object 设置存储:
JSONC
{
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["MyAgent"],
},
],
}
TOML
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "MyAgent" ]
| 字段 | 描述 |
|---|---|
| tag | 版本标识符(例如 “v1”、“v2”)。必须唯一 |
| new_sqlite_classes | 使用 SQLite 存储(状态持久化)的 agent 类 |
| deleted_classes | 被删除的类 |
| renamed_classes | 被重命名的类 |
assets
用于提供静态文件(HTML、CSS、JS):
JSONC
{
"assets": {
"directory": "public",
"binding": "ASSETS",
},
}
TOML
[assets]
directory = "public"
binding = "ASSETS"
加上绑定后,你可以以编程方式提供资源:
JavaScript
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 });
},
};
TypeScript
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>;
ai
用于 Workers AI 集成:
JSONC
{
"ai": {
"binding": "AI",
},
}
TOML
[ai]
binding = "AI"
在 agent 中访问:
JavaScript
const response = await this.env.AI.run("@cf/meta/llama-3-8b-instruct", {
prompt: "Hello!",
});
TypeScript
const response = await this.env.AI.run("@cf/meta/llama-3-8b-instruct", {
prompt: "Hello!",
});
TypeScript 配置
Agents SDK 提供了一个共享的 tsconfig.json,它设置了 agent 项目所需的所有编译器选项——包括 @callable() 装饰器需要的 ES2021 target、严格模式、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"
}
}
警告
不要设置 "experimentalDecorators": true。Agents SDK 使用 TC39 标准装饰器 ↗,而不是 TypeScript 的旧版装饰器。启用 experimentalDecorators 会应用一个不兼容的转换,在运行时悄悄破坏 @callable()。
Vite 配置
Agents SDK 提供了一个 Vite 插件,处理 TC39 装饰器的转换。Vite 8 使用 Oxc 进行转译,Oxc 目前还不支持 TC39 装饰器——没有这个插件,@callable() 和其他装饰器在运行时会失败。
将插件添加到你的 vite.config.ts:
JavaScript
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()],
});
TypeScript
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() 插件也是安全的。它只会对包含 @ 语法的文件运行转换。
starter 模板和所有示例都默认包含了这个插件。如果你在使用装饰器时遇到 SyntaxError: Invalid or unexpected token,请参考 可调用方法 — 故障排查。
生成类型
Wrangler 可以为你的绑定生成 TypeScript 类型。
自动生成
运行 types 命令:
Terminal window
npx wrangler types
这会创建或更新 worker-configuration.d.ts,包含你的 Env 类型。
自定义输出路径
指定一个自定义路径:
Terminal window
npx wrangler types env.d.ts
不包含运行时类型
为了得到更干净的输出(对 agent 项目推荐):
Terminal window
npx wrangler types env.d.ts --include-runtime false
这只会生成你的绑定,不带 Cloudflare 运行时类型。
生成的输出示例
TypeScript
// env.d.ts (generated)
declare namespace Cloudflare {
interface Env {
OPENAI_API_KEY: string;
Counter: DurableObjectNamespace;
ChatAgent: DurableObjectNamespace;
}
}
interface Env extends Cloudflare.Env {}
手动定义类型
你也可以手动定义类型:
JavaScript
// env.d.ts
TypeScript
// 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;
}
添加到 package.json
加一个脚本以便随时重新生成:
{
"scripts": {
"types": "wrangler types env.d.ts --include-runtime false"
}
}
环境变量与 Secret
本地开发(.env)
创建一个 .env 文件来存放本地 secret(将其加入 .gitignore):
Terminal window
# .env
OPENAI_API_KEY=sk-...
GITHUB_WEBHOOK_SECRET=whsec_...
DATABASE_URL=postgres://...
在 agent 中访问:
JavaScript
class MyAgent extends Agent {
async onStart() {
const apiKey = this.env.OPENAI_API_KEY;
}
}
TypeScript
class MyAgent extends Agent {
async onStart() {
const apiKey = this.env.OPENAI_API_KEY;
}
}
生产环境 secret
生产环境使用 wrangler secret:
Terminal window
# 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
非 secret 变量
对于非敏感配置,在 Wrangler 配置文件中使用 vars:
JSONC
{
"vars": {
"API_BASE_URL": "https://api.example.com",
"MAX_RETRIES": "3",
"DEBUG_MODE": "false",
},
}
TOML
[vars]
API_BASE_URL = "https://api.example.com"
MAX_RETRIES = "3"
DEBUG_MODE = "false"
所有值都必须是字符串。在代码中解析数字和布尔值:
JavaScript
const maxRetries = parseInt(this.env.MAX_RETRIES, 10);
const debugMode = this.env.DEBUG_MODE === "true";
TypeScript
const maxRetries = parseInt(this.env.MAX_RETRIES, 10);
const debugMode = this.env.DEBUG_MODE === "true";
按环境区分变量
使用 env 区块为不同环境(例如 staging、production)配置变量:
JSONC
{
"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",
},
},
},
}
TOML
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"
部署到指定环境:
Terminal window
npx wrangler deploy --env staging
npx wrangler deploy --env production
本地开发
启动开发服务器
使用 Vite(全栈应用推荐):
Terminal window
npx vite dev
不使用 Vite:
Terminal window
npx wrangler dev
本地状态持久化
Durable Object 状态在本地持久化在 .wrangler/state/:
- Directory.wrangler/
- Directorystate/ * Directoryv3/ * Directoryd1/ * Directoryminiflare-D1DatabaseObject/ * … (SQLite files)
清除本地状态
要重置所有本地 Durable Object 状态:
Terminal window
rm -rf .wrangler/state
或者用全新状态重启:
Terminal window
npx wrangler dev --persist-to=""
检查本地 SQLite
你可以直接检查 agent 状态:
Terminal window
# 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 存储 - 附加到每个命名空间
查看 Durable Object
登录 Cloudflare 控制台,然后进入 Durable Objects。
在这里你可以:
- 查看所有 Durable Object 命名空间
- 查看单个对象实例
- 检查存储(键值对)
- 删除对象
实时日志
查看 agent 的实时日志:
Terminal window
npx wrangler tail
或在控制台中:
- 进入你的 Worker。
- 选择 Observability 标签页。
- 启用实时日志。
可按以下条件过滤:
- 状态(成功、错误)
- 搜索文本
- 采样率
生产部署
基础部署
Terminal window
npx wrangler deploy
它会:
- 打包你的代码
- 上传到 Cloudflare
- 应用迁移
- 在
*.workers.dev上线
自定义域名
在 Wrangler 配置文件中添加路由:
JSONC
{
"routes": [
{
"pattern": "agents.example.com/*",
"zone_name": "example.com",
},
],
}
TOML
[[routes]]
pattern = "agents.example.com/*"
zone_name = "example.com"
或者使用自定义域名(更简单):
JSONC
{
"routes": [
{
"pattern": "agents.example.com",
"custom_domain": true,
},
],
}
TOML
[[routes]]
pattern = "agents.example.com"
custom_domain = true
预览部署
不影响生产环境的部署:
Terminal window
npx wrangler deploy --dry-run # See what would be uploaded
npx wrangler versions upload # Upload new version
npx wrangler versions deploy # Gradually roll out
回滚
回滚到上一个版本:
Terminal window
npx wrangler rollback
多环境配置
环境配置
在 Wrangler 配置文件中定义环境:
JSONC
{
"name": "my-agent",
"main": "src/server.ts",
// Base configuration (shared)
// Set this to today's date
"compatibility_date": "2026-04-29",
"compatibility_flags": ["nodejs_compat"],
"durable_objects": {
"bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }],
},
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyAgent"] }],
// Environment overrides
"env": {
"staging": {
"name": "my-agent-staging",
"vars": {
"ENVIRONMENT": "staging",
},
},
"production": {
"name": "my-agent-production",
"vars": {
"ENVIRONMENT": "production",
},
},
},
}
TOML
name = "my-agent"
main = "src/server.ts"
# Set this to today's date
compatibility_date = "2026-04-29"
compatibility_flags = [ "nodejs_compat" ]
[[durable_objects.bindings]]
name = "MyAgent"
class_name = "MyAgent"
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "MyAgent" ]
[env.staging]
name = "my-agent-staging"
[env.staging.vars]
ENVIRONMENT = "staging"
[env.production]
name = "my-agent-production"
[env.production.vars]
ENVIRONMENT = "production"
部署到不同环境
Terminal window
# 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 Object
每个环境有自己的 Durable Object。staging 的 agent 不会与 production 的 agent 共享状态。
如要显式分离:
JSONC
{
"env": {
"staging": {
"durable_objects": {
"bindings": [
{
"name": "MyAgent",
"class_name": "MyAgent",
"script_name": "my-agent-staging",
},
],
},
},
},
}
TOML
[[env.staging.durable_objects.bindings]]
name = "MyAgent"
class_name = "MyAgent"
script_name = "my-agent-staging"
迁移
迁移用于管理 Durable Object 存储的 schema 变更。
添加新的 agent
在新的迁移中加到 new_sqlite_classes:
JSONC
{
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["ExistingAgent"],
},
{
"tag": "v2",
"new_sqlite_classes": ["NewAgent"],
},
],
}
TOML
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "ExistingAgent" ]
[[migrations]]
tag = "v2"
new_sqlite_classes = [ "NewAgent" ]
重命名 agent 类
使用 renamed_classes:
JSONC
{
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["OldName"],
},
{
"tag": "v2",
"renamed_classes": [
{
"from": "OldName",
"to": "NewName",
},
],
},
],
}
TOML
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "OldName" ]
[[migrations]]
tag = "v2"
[[migrations.renamed_classes]]
from = "OldName"
to = "NewName"
同时要更新:
- 代码中的类名
- 绑定中的
class_name - export 语句
删除 agent 类
使用 deleted_classes:
JSONC
{
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["AgentToDelete", "AgentToKeep"],
},
{
"tag": "v2",
"deleted_classes": ["AgentToDelete"],
},
],
}
TOML
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "AgentToDelete", "AgentToKeep" ]
[[migrations]]
tag = "v2"
deleted_classes = [ "AgentToDelete" ]
警告
这会永久删除该类的所有数据。
迁移最佳实践
- 永远不要修改已有迁移 - 总是新增。
- 使用顺序的 tag - v1、v2、v3(或用日期:2025-01-15)。
- 先在本地测试 - 迁移会在部署时执行。
- 备份生产数据 - 在重命名或删除之前。
故障排查
No such Durable Object class
类没有出现在迁移中:
JSONC
{
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["MissingClassName"],
},
],
}
TOML
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "MissingClassName" ]
Cannot find module in types
重新生成类型:
Terminal window
npx wrangler types env.d.ts --include-runtime false
本地无法加载 secret
检查 .env 是否存在并包含该变量:
Terminal window
cat .env
# Should show: MY_SECRET=value
迁移 tag 冲突
迁移的 tag 必须唯一。如果遇到冲突:
JSONC
{
// Wrong - duplicate tags
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["A"] },
{ "tag": "v1", "new_sqlite_classes": ["B"] },
],
}
TOML
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "A" ]
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "B" ]
JSONC
{
// Correct - sequential tags
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["A"] },
{ "tag": "v2", "new_sqlite_classes": ["B"] },
],
}
TOML
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "A" ]
[[migrations]]
tag = "v2"
new_sqlite_classes = [ "B" ]
下一步
Agents API Agents SDK 的完整 API 参考。
路由 将请求路由到你的 agent 实例。
调度任务 通过延迟和 cron 任务进行后台处理。