ADR 012: Cloudflare Agents SDK for AI-Powered Educational Services

AcceptedDate: 2026-03-03

Context

A2R Workspaces is a multi-tenant SaaS platform for the educational industry. The platform already uses Cloudflare Durable Objects for real-time WebSocket communication (see ADR-002 and Real-time Communication). There is a growing need for AI-powered educational services — tutoring, content generation, assessment, and an educational assistant — that are:

  • Long-running and persistent: Conversations span multiple sessions. Students return to ongoing tutoring threads, and teachers review AI-generated content iteratively.
  • Multi-user: Multiple students or teachers may interact with the same agent simultaneously (e.g., a classroom tutoring session).
  • Real-time: Responses stream via WebSocket, matching the existing real-time infrastructure patterns.
  • GDPR-compliant: All personal data — including conversation history, student profiles, and assessment results — must be stored and processed exclusively within the European Union.

Building these services on raw Durable Objects would require reimplementing conversation management, WebSocket routing, state persistence, and tool calling from scratch. The Cloudflare Agents SDK provides these capabilities as a first-class abstraction on top of Durable Objects.

Decision

Adopt the Cloudflare Agents SDK (agents package) for all AI-powered educational services. All agent Durable Objects are jurisdiction-pinned to the EU using jurisdiction("eu").

Cloudflare Agents SDK for AI-Powered Educational Services Cloudflare Agents SDK for AI Services Positive Builds on existing DO infrastructure (ADR-002) Persistent state + conversation history (SQLite) Multi-user WebSocket with hibernation ($0 idle) @callable() typed RPC and React hooks MCP server support for tool integration EU jurisdiction pinning for GDPR compliance Negative SDK is relatively new (GA 2025); evolving API surface AI model API costs scale with usage Content moderation required for educational context EU-only processing may limit model provider options Hibernation not fully simulated in local dev

Agent Types

The platform defines four agent types, each extending AIChatAgent:

AgentPurposeUsers
Educational AssistantGeneral Q&A, curriculum navigation, learning path recommendationsStudents, Teachers
Tutoring AgentSubject-specific tutoring with Socratic method, step-by-step explanationsStudents
Content Generation AgentLesson plans, quizzes, rubrics, study materialsTeachers, Administrators
Assessment AgentAutomated grading, feedback generation, learning gap analysisTeachers

Core Implementation Pattern

import { AIChatAgent } from "agents/ai-chat-agent";
import { type Connection, type WSMessage } from "agents";

export class TutoringAgent extends AIChatAgent<Env, AgentState> {
  // Agent-local SQLite stores conversation history automatically
  // Multi-user WebSocket with hibernation support inherited from base

  async onChatMessage(onFinish: StreamTextOnFinishCallback<ToolSet>) {
    const { messages, model } = this;
    const result = streamText({
      model: createOpenAI({ apiKey: this.env.OPENAI_API_KEY })("gpt-4o"),
      system: this.getSystemPrompt(),
      messages,
      tools: this.getTools(),
      onFinish,
    });
    return result;
  }
}

Frontend Integration

import { useAgentChat } from "agents/ai-react";

function TutoringChat({ agentId }: { agentId: string }) {
  const { messages, input, handleInputChange, handleSubmit } = useAgentChat({
    agent: "tutoring-agent",
    name: agentId,
  });

  return (
    <form onSubmit={handleSubmit}>
      {messages.map((m) => <ChatMessage key={m.id} message={m} />)}
      <input value={input} onChange={handleInputChange} />
    </form>
  );
}

GDPR Compliance

All agent Durable Objects are jurisdiction-pinned to the EU:

// workers/agent-service/wrangler.jsonc
{
  "durable_objects": {
    "bindings": [
      {
        "name": "TUTORING_AGENT",
        "class_name": "TutoringAgent",
        "script_name": "agent-service",
        "jurisdiction": "eu"
      }
    ]
  }
}

Consequences

Positive

  • Built on existing infrastructure: The Agents SDK extends Durable Objects, which the platform already uses for real-time communication. The team has operational experience with DO patterns, WebSocket hibernation, and wrangler configuration.
  • Persistent conversation state: Each agent instance stores its conversation history in agent-local SQLite. Students can resume tutoring sessions across days or weeks without external database dependencies.
  • Multi-user WebSocket: Multiple users can connect to the same agent instance simultaneously. This enables classroom scenarios where a teacher and students interact with the same tutoring agent in real time.
  • Typed RPC via @callable(): The @callable() decorator exposes agent methods as typed RPC endpoints over WebSocket, consistent with the platform's existing service binding RPC pattern.
  • React hooks: The useAgentChat hook provides a ready-made integration for the React-based MFE architecture, reducing frontend boilerplate.
  • MCP server support: Agents can expose tools via the Model Context Protocol, enabling integration with external AI-powered tools and IDEs.
  • EU jurisdiction pinning: jurisdiction("eu") ensures all agent state — conversation history, student data, assessment results — is stored and processed exclusively in EU data centers, satisfying GDPR data residency requirements.

Negative

  • SDK maturity: The Cloudflare Agents SDK reached GA in 2025. The API surface is still evolving, and breaking changes are possible in minor versions. Mitigation: pin exact SDK versions and monitor the Cloudflare changelog.
  • AI model costs: Each AI interaction incurs model API costs (token-based pricing). For a platform serving thousands of students, costs can scale significantly. Mitigation: implement token budgets per tenant, cache common responses, and use smaller models for simple tasks.
  • Content moderation: Educational AI must produce age-appropriate, accurate, and unbiased content. The platform must implement content filtering, output validation, and human oversight — especially for assessment agents that influence student grades. Mitigation: define moderation policies, implement output guardrails, and require teacher review for high-stakes assessments.
  • EU-only processing: Restricting all AI processing to EU data centers may limit the choice of model providers or increase latency for models hosted outside the EU. Mitigation: prefer providers with EU endpoints (e.g., Azure OpenAI EU regions, Anthropic EU).
  • Local development limitations: Durable Object hibernation is not fully simulated in Miniflare. Agent WebSocket connections work locally, but hibernation behavior must be tested in staging. Mitigation: document local dev limitations and establish staging test procedures.

Alternatives Considered

Custom Framework on Raw Durable Objects

Build AI agent functionality directly on the existing Durable Object infrastructure without the Agents SDK. This provides full control but requires reimplementing conversation management, WebSocket routing, state persistence, streaming, and tool calling — all of which the Agents SDK provides out of the box. The engineering effort is substantial with no architectural advantage over using the SDK.

External AI Service (e.g., hosted SaaS)

Use a third-party AI platform (e.g., a hosted tutoring API) instead of building agents on Cloudflare. This avoids infrastructure complexity but introduces external dependencies, data residency concerns (GDPR compliance becomes the vendor's responsibility, with limited auditability), higher per-query costs, and reduced flexibility for educational customization. The platform would also lose the tight integration with its existing Cloudflare infrastructure.

Vercel AI SDK (without Agents)

Use the Vercel AI SDK for AI streaming and tool calling, running on Cloudflare Workers without Durable Objects. This works for stateless chat interactions but does not provide persistent conversation history, multi-user sessions, or agent-local storage. Each request would need to reload the full conversation from an external database, adding latency and complexity. The Agents SDK solves these problems natively through Durable Object state.