#1. 入口 Worker:接单、查开关、做协调、写库、投递异步任务
import { DurableObject } from "cloudflare:workers";
export interface Env {
FLAGS: KVNamespace;
DB: D1Database;
FILES: R2Bucket;
ORDER_PIPELINE: Queue;
STOCK_ROOM: DurableObjectNamespace<StockRoom>;
}
type OrderPayload = {
orderId: string;
sku: string;
qty: number;
note?: string;
};
export class StockRoom extends DurableObject<Env> {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
this.ctx.storage.sql.exec(`
CREATE TABLE IF NOT EXISTS inventory (
sku TEXT PRIMARY KEY,
stock INTEGER NOT NULL
)
`);
}
async reserve(sku: string, qty: number) {
const row = this.ctx.storage.sql
.exec<{ stock: number }>("SELECT stock FROM inventory WHERE sku = ?", sku)
.one();
const stock = row?.stock ?? 0;
if (stock < qty) {
return { ok: false, reason: "OUT_OF_STOCK" };
}
this.ctx.storage.sql.exec(
"UPDATE inventory SET stock = stock - ? WHERE sku = ?",
qty,
sku,
);
return { ok: true };
}
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
if (url.pathname !== "/orders" || request.method !== "POST") {
return new Response("Not Found", { status: 404 });
}
const body = await request.json<OrderPayload>();
const flashSale = (await env.FLAGS.get("flash-sale")) === "on";
const stock = env.STOCK_ROOM.getByName(`sku:${body.sku}`);
const reserved = await stock.reserve(body.sku, body.qty);
if (!reserved.ok) {
return Response.json(reserved, { status: 409 });
}
await env.DB.prepare(`
INSERT INTO orders (id, sku, qty, note, flash_sale)
VALUES (?, ?, ?, ?, ?)
`)
.bind(body.orderId, body.sku, body.qty, body.note ?? null, flashSale ? 1 : 0)
.run();
ctx.waitUntil(
env.ORDER_PIPELINE.send({
orderId: body.orderId,
note: body.note ?? "",
}),
);
return Response.json({ ok: true, orderId: body.orderId });
},
} satisfies ExportedHandler<Env>;这段代码里每个角色都很清楚:
- Worker 是柜台
- KV 是活动公告栏
- Durable Object 是库存协调室
- D1 是订单账本
- Queue 是后处理传送带
#2. Queue Consumer:把慢活移出主请求
export interface Env {
FILES: R2Bucket;
DB: D1Database;
CF_ACCOUNT_ID: string;
CF_AIG_GATEWAY: string;
CF_AIG_TOKEN: string; // 假设已在 AI Gateway 中配置好上游 BYOK
}
type OrderJob = {
orderId: string;
note: string;
};
export default {
async queue(batch: MessageBatch<OrderJob>, env: Env): Promise<void> {
for (const msg of batch.messages) {
const prompt =
msg.body.note.trim() === ""
? "用户没有备注,请返回“无特殊要求”。"
: `请把这段订单备注压缩成一句客服摘要:${msg.body.note}`;
const aiResp = await fetch(
`https://gateway.ai.cloudflare.com/v1/${env.CF_ACCOUNT_ID}/${env.CF_AIG_GATEWAY}/compat/chat/completions`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${env.CF_AIG_TOKEN}`,
},
body: JSON.stringify({
model: "openai/gpt-5-mini",
messages: [{ role: "user", content: prompt }],
}),
},
);
const aiData = await aiResp.json<any>();
const summary = aiData.choices?.[0]?.message?.content ?? "摘要生成失败";
await env.FILES.put(`orders/${msg.body.orderId}/summary.txt`, summary);
await env.DB.prepare(`
UPDATE orders SET note_summary = ? WHERE id = ?
`)
.bind(summary, msg.body.orderId)
.run();
msg.ack();
}
},
} satisfies ExportedHandler<Env>;这段代码体现的就是一句话:
用户不该在柜台前等 AI 总结跑完。
#3. 一个最小的 AI Gateway SDK 写法
import OpenAI from "openai";
const client = new OpenAI({
apiKey: env.CF_AIG_TOKEN,
baseURL: `https://gateway.ai.cloudflare.com/v1/${env.CF_ACCOUNT_ID}/${env.CF_AIG_GATEWAY}/compat`,
});
const resp = await client.chat.completions.create({
model: "openai/gpt-5-mini",
messages: [{ role: "user", content: "把这段文本压缩成一句标题" }],
});这段的重点不是 SDK,而是心智:
- 你的业务代码对接的是 AI Gateway
- AI Gateway 再帮你治理上游模型流量