← Создание агентов на Cloudflare / agents / runtime / communication
HTTP и Server-Sent Events
Agents умеют обрабатывать HTTP-запросы и передавать ответы потоком с помощью Server-Sent Events (SSE). На этой странице рассматривается onRequest метод и паттерны SSE.
Обработка HTTP-запросов
Определите onRequest метод для обработки HTTP-запросов к вашему агенту:
import { Agent } from "agents";
export class APIAgent extends Agent {
async onRequest(request) {
const url = new URL(request.url);
// Route based on path
if (url.pathname.endsWith("/status")) {
return Response.json({ status: "ok", state: this.state });
}
if (url.pathname.endsWith("/action")) {
if (request.method !== "POST") {
return new Response("Method not allowed", { status: 405 });
}
const data = await request.json();
await this.processAction(data.action);
return Response.json({ success: true });
}
return new Response("Not found", { status: 404 });
}
async processAction(action) {
// Handle the action
}
}import { Agent } from "agents";
export class APIAgent extends Agent {
async onRequest(request: Request): Promise<Response> {
const url = new URL(request.url);
// Route based on path
if (url.pathname.endsWith("/status")) {
return Response.json({ status: "ok", state: this.state });
}
if (url.pathname.endsWith("/action")) {
if (request.method !== "POST") {
return new Response("Method not allowed", { status: 405 });
}
const data = await request.json<{ action: string }>();
await this.processAction(data.action);
return Response.json({ success: true });
}
return new Response("Not found", { status: 404 });
}
async processAction(action: string) {
// Handle the action
}
}Server-Sent Events (SSE)
SSE позволяет передавать данные клиентам потоком через долгое HTTP-соединение. Это идеально подходит для ответов моделей ИИ, генерирующих токены постепенно.
Ручной SSE
Создайте SSE-поток вручную с помощью ReadableStream:
export class StreamAgent extends Agent {
async onRequest(request) {
const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
// Send events
controller.enqueue(encoder.encode("data: Starting...\n\n"));
for (let i = 1; i <= 5; i++) {
await new Promise((r) => setTimeout(r, 500));
controller.enqueue(encoder.encode(`data: Step ${i} complete\n\n`));
}
controller.enqueue(encoder.encode("data: Done!\n\n"));
controller.close();
},
});
return new Response(stream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
},
});
}
}export class StreamAgent extends Agent {
async onRequest(request: Request): Promise<Response> {
const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
// Send events
controller.enqueue(encoder.encode("data: Starting...\n\n"));
for (let i = 1; i <= 5; i++) {
await new Promise((r) => setTimeout(r, 500));
controller.enqueue(encoder.encode(`data: Step ${i} complete\n\n`));
}
controller.enqueue(encoder.encode("data: Done!\n\n"));
controller.close();
},
});
return new Response(stream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
},
});
}
}Формат сообщений SSE
Сообщения SSE имеют определённый формат:
data: your message here\n\nВы также можете указать типы событий и идентификаторы:
event: update\n
id: 123\n
data: {"count": 42}\n\nС AI SDK
AI SDK ↗ предоставляет встроенную потоковую передачу SSE:
import { Agent } from "agents";
import { streamText } from "ai";
import { createWorkersAI } from "workers-ai-provider";
export class ChatAgent extends Agent {
async onRequest(request) {
const { prompt } = await request.json();
const workersai = createWorkersAI({ binding: this.env.AI });
const result = streamText({
model: workersai("@cf/zai-org/glm-4.7-flash"),
prompt: prompt,
});
return result.toTextStreamResponse();
}
}import { Agent } from "agents";
import { streamText } from "ai";
import { createWorkersAI } from "workers-ai-provider";
interface Env {
AI: Ai;
}
export class ChatAgent extends Agent<Env> {
async onRequest(request: Request): Promise<Response> {
const { prompt } = await request.json<{ prompt: string }>();
const workersai = createWorkersAI({ binding: this.env.AI });
const result = streamText({
model: workersai("@cf/zai-org/glm-4.7-flash"),
prompt: prompt,
});
return result.toTextStreamResponse();
}
}Обработка подключений
Соединения SSE могут оставаться открытыми надолго. Корректно обрабатывайте отключения клиентов:
- Сохранение прогресса : запись в состояние агента чтобы клиенты могли возобновить работу
- Используйте маршрутизацию агентов : Клиенты могут переподключиться к тому же экземпляру агента без хранилищ сессий
- Отсутствуют ограничения по времени ожидания : Cloudflare Workers не имеют практического ограничения на длительность SSE-ответа
export class ResumeAgent extends Agent {
async onRequest(request) {
const url = new URL(request.url);
const lastEventId = request.headers.get("Last-Event-ID");
if (lastEventId) {
// Client is resuming - send events after lastEventId
return this.resumeStream(lastEventId);
}
return this.startStream();
}
async startStream() {
// Start new stream, saving progress to this.state
}
async resumeStream(fromId) {
// Resume from saved state
}
}export class ResumeAgent extends Agent {
async onRequest(request: Request): Promise<Response> {
const url = new URL(request.url);
const lastEventId = request.headers.get("Last-Event-ID");
if (lastEventId) {
// Client is resuming - send events after lastEventId
return this.resumeStream(lastEventId);
}
return this.startStream();
}
async startStream(): Promise<Response> {
// Start new stream, saving progress to this.state
}
async resumeStream(fromId: string): Promise<Response> {
// Resume from saved state
}
}WebSockets и SSE
| Возможность | WebSockets | SSE |
|---|---|---|
| Направление | Двунаправленный | Только Сервер → Клиент |
| Протокол | ws:// / wss:// |
HTTP |
| Двоичные данные | Да | Нет (только текст) |
| Переподключение | Вручную | Автоматически (браузер) |
| Подходит для | Интерактивные приложения, чат | Потоковые ответы, уведомления |
Рекомендация: Используйте WebSocket для интерактивных приложений. Используйте SSE для потоковой передачи ответов ИИ или push-уведомлений сервера.
См. WebSockets для документации по WebSocket.