每个 Agent 都是一个命名的 Durable Object。路由负责让 Worker 中的请求到达正确对象。routeAgentRequest() 会从 URL 中读取 Durable Object 绑定和对象名称,并将请求转发给该对象。在对象内部,Lifecycle会接管请求,将其交给各项能力处理,然后调用你的 onRequest() 钩子。
routeAgentRequest(request, env) Worker
└─ stub.fetch(request) picks the object from the URL
└─ Lifecycle Durable Object
├─ startup, on a cold object
├─ capabilities, in registration order
└─ host onRequest()routeAgentRequest() 适用于任何安装了 Lifecycle 的 Durable Object。可从 agents/routing 或 agents 导入:
import { DurableObject } from "cloudflare:workers";
import { Lifecycle } from "agents/lifecycle";
import { routeAgentRequest } from "agents/routing";
export class MyAgent extends DurableObject {
lifecycle = Lifecycle.install(this);
onRequest(request) {
return new Response(`Hello from ${this.lifecycle.name}`);
}
}
export default {
async fetch(request, env) {
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
};import { DurableObject } from "cloudflare:workers";
import { Lifecycle } from "agents/lifecycle";
import { routeAgentRequest } from "agents/routing";
export class MyAgent extends DurableObject<Env> {
readonly lifecycle = Lifecycle.install(this);
onRequest(request: Request): Response {
return new Response(`Hello from ${this.lifecycle.name}`);
}
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
} satisfies ExportedHandler<Env>;将此类绑定为基于 SQLite 的 Durable Object:
{
"durable_objects": {
"bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }],
},
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyAgent"] }],
}[[durable_objects.bindings]]
name = "MyAgent"
class_name = "MyAgent"
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "MyAgent" ]routeAgentRequest() 可处理 HTTP 请求和 WebSocket 升级请求。它会返回:
- 如果路径不以此前缀开头,则返回
null,以便 Worker 处理其他路由。 - 如果路径与此前缀匹配,但没有对应的 Durable Object 绑定,则返回
400响应。 - 其他情况下则返回对象的响应。
默认 URL 格式为 /agents/:binding/:name:
https://example.com/agents/my-agent/alice/settings
└──┬───┘ └─┬─┘└───┬──┘
binding name sub-path:binding是env中 Durable Object 绑定的名称,格式为 kebab-case。绑定MyAgent和MY_AGENT都会转换为my-agent。ChatRoom会转换为chat-room。:name是对象名称。路由器使用idFromName(name)寻址对象,对象则通过lifecycle.name读取名称。- 子路径 是名称后面的所有内容。对象会收到完整 URL,因此
onRequest()可以根据/settings进行路由。
如需更改 agents 路径段,请传入 prefix 选项。
导出并绑定每个类。routeAgentRequest() 会根据 URL 查找绑定,因此一次调用即可路由到所有类:
import { routeAgentRequest } from "agents/routing";
export { ChatRoom } from "./chat-room";
export { UserProfile } from "./user-profile";
export default {
async fetch(request, env) {
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
};import { routeAgentRequest } from "agents/routing";
export { ChatRoom } from "./chat-room";
export { UserProfile } from "./user-profile";
export default {
async fetch(request: Request, env: Env): Promise<Response> {
return (
(await routeAgentRequest(request, env)) ??
new Response("Not found", { status: 404 })
);
},
} satisfies ExportedHandler<Env>;{
"durable_objects": {
"bindings": [
{ "name": "ChatRoom", "class_name": "ChatRoom" },
{ "name": "UserProfile", "class_name": "UserProfile" },
],
},
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["ChatRoom", "UserProfile"] },
],
}[[durable_objects.bindings]]
name = "ChatRoom"
class_name = "ChatRoom"
[[durable_objects.bindings]]
name = "UserProfile"
class_name = "UserProfile"
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "ChatRoom", "UserProfile" ]发往 /agents/chat-room/... 的请求会到达 ChatRoom,发往 /agents/user-profile/... 的请求会到达 UserProfile。
名称决定哪个对象处理请求。每个名称对应一个独立对象,有自己的存储、闹钟和连接。请根据数据的共享方式选择合适的名称:
| 模式 | 名称 | 示例 URL |
|---|---|---|
| 每位用户一个对象 | 用户 ID | /agents/user-profile/user-abc123 |
| 每个资源一个对象 | 房间或文档 ID | /agents/chat-room/general |
| 每项任务一个对象 | 生成的 ID | /agents/report/report-2026-10-29 |
| 单例对象 | 固定名称 | /agents/app-config/default |
对象存放私密数据时,请使用客户端无法猜到的名称,并在路由请求前检查调用者身份。更多信息,请参阅身份验证。
Lifecycle 要求对象具有名称。使用 newUniqueId() 或 idFromString() 创建对象,或对象名称超过 1,024 字节时,启动会失败。
对象会收到完整 URL。在 onRequest() 中匹配路径末尾:
import { DurableObject } from "cloudflare:workers";
import { Lifecycle } from "agents/lifecycle";
export class UserProfile extends DurableObject {
lifecycle = Lifecycle.install(this);
async onRequest(request) {
const url = new URL(request.url);
if (request.method === "GET" && url.pathname.endsWith("/settings")) {
return Response.json((await this.ctx.storage.get("settings")) ?? {});
}
if (request.method === "PUT" && url.pathname.endsWith("/settings")) {
await this.ctx.storage.put("settings", await request.json());
return new Response(null, { status: 204 });
}
return new Response("Not found", { status: 404 });
}
}import { DurableObject } from "cloudflare:workers";
import { Lifecycle } from "agents/lifecycle";
export class UserProfile extends DurableObject<Env> {
readonly lifecycle = Lifecycle.install(this);
async onRequest(request: Request): Promise<Response> {
const url = new URL(request.url);
if (request.method === "GET" && url.pathname.endsWith("/settings")) {
return Response.json((await this.ctx.storage.get("settings")) ?? {});
}
if (request.method === "PUT" && url.pathname.endsWith("/settings")) {
await this.ctx.storage.put("settings", await request.json());
return new Response(null, { status: 204 });
}
return new Response("Not found", { status: 404 });
}
}- 路由选项介绍 CORS、位置选择、启动 props 和重试。
- 身份验证会在请求到达对象之前,在 Worker 中检查调用者身份。
- 自定义路由可通过默认 URL 格式之外的方式访问对象,包括通过 RPC 访问。
- HTTP 和 Server-Sent Events介绍如何在
onRequest()中处理请求并流式传输响应。 - 请求分发介绍对象内部如何处理请求。