Split View: Cloudflare Agents와 Durable Objects로 AI 앱을 만드는 실전 가이드
Cloudflare Agents와 Durable Objects로 AI 앱을 만드는 실전 가이드
Cloudflare Agents가 AI 제품에 잘 맞는 이유
Cloudflare의 공식 문서에 따르면, Agent는 각 인스턴스가 하나의 Durable Object 위에서 실행된다. Durable Object는 상태를 가진 마이크로 서버이고, 자체 SQL 데이터베이스, WebSocket 연결, 스케줄링을 함께 가진다. 다시 말해, 에이전트가 대화를 기억하고, 도구를 호출하고, 장기 작업을 이어가고, 사용자와 실시간으로 연결된 상태를 유지하는 데 필요한 기본 단위가 이미 플랫폼에 들어 있다.
이 구조가 매력적인 이유는 단순하다. 많은 AI 앱은 여전히 요청 하나를 처리하고 끝나는 stateless 패턴에 머문다. 하지만 실제 에이전트 제품은 메모리, 도구 호출, 승인 흐름, 예약 실행, 세션 연결 같은 요소를 동시에 다뤄야 한다. Cloudflare Agents는 이 문제를 별도 서버 조합으로 억지로 풀지 않고, 에이전트 자체를 상태 단위로 배치하는 쪽에 가깝다.
Cloudflare는 Agents를 전역 네트워크에서 실행하고, 수천만 단위의 인스턴스로 확장할 수 있다고 설명한다. 이건 단순한 규모 자랑이 아니라, 사용자별 에이전트, 티켓별 에이전트, 작업별 에이전트를 제품 설계의 기본 단위로 삼을 수 있다는 뜻이다.
Durable Object 기반 에이전트란 무엇인가
Durable Object 기반 에이전트는 "서버리스 함수"보다 "상태를 가진 개인 서버"에 더 가깝다. 차이는 다음처럼 생각하면 쉽다.
| 항목 | 일반적인 stateless serverless | Cloudflare Agents + Durable Objects |
|---|---|---|
| 상태 | 외부 DB나 캐시에 따로 둬야 함 | 에이전트 자체에 붙어 있음 |
| 연결 | 요청이 끝나면 끊김 | WebSocket과 장기 연결에 적합 |
| 스케줄링 | 별도 크론이나 워커 필요 | 에이전트 수준에서 다루기 쉬움 |
| 메모리 | 매 요청마다 다시 조립 | 인스턴스가 기억을 유지 |
| 규모 | 상태를 맞추는 오케스트레이션이 필요 | Cloudflare가 전역으로 배치 |
이 차이는 UX에서 크게 드러난다. 예를 들어 사용자가 한 번만 승인해도 되는 작업, 진행 중에 여러 번 상태가 바뀌는 작업, 긴 대화 맥락을 보존해야 하는 작업은 stateless 구조보다 상태형 에이전트가 훨씬 자연스럽다.
Cloudflare의 Agents API 문서도 Agents가 Durable Objects를 필요로 하며, 각 Agent가 수많은 인스턴스를 가질 수 있다고 설명한다. 그만큼 멀티테넌트 제품이나 사용자별 보조 에이전트를 만들기에 적합하다.
AI 앱에서 가장 잘 먹히는 패턴
Cloudflare가 제공하는 starter 패턴은 실전성이 높다. 공식 docs 기준으로 대표적인 출발점은 다음 네 가지다.
- 스트리밍 AI 채팅
- 서버사이드와 클라이언트사이드 도구 호출
- human-in-the-loop 승인
- 작업 스케줄링
이 조합은 AI 앱의 전형적인 요구사항과 거의 정확히 맞아떨어진다. 대화형 인터페이스는 스트리밍이 필요하고, 비즈니스 액션은 도구 호출이 필요하며, 위험한 동작은 사람이 승인해야 하고, 백그라운드 정리는 예약 실행이 필요하다.
예를 들어 고객 지원 에이전트를 생각해 보자. 대화는 스트리밍으로 응답하고, 주문 조회나 환불 검토는 도구로 처리하고, 금액이 큰 작업은 승인 대기 상태로 두고, 미처리 항목은 몇 분 뒤 다시 확인한다. 이 전체 흐름이 하나의 Agent 안에서 자연스럽게 이어진다.
import { Agent } from "agents";
export class SupportAgent extends Agent {
async onRequest(request) {
const latestMessage = await request.json();
// 상태를 SQL에 저장하고, 모델 응답과 승인 흐름을 이어붙이는 식으로 운영한다.
return new Response(JSON.stringify({ ok: true, latestMessage }));
}
}
모델 선택은 더 유연하다
Cloudflare Agents는 하나의 모델 공급자에 묶이지 않는다. 공식 문서에 따르면 Workers AI는 기본으로 제공되고, OpenAI, Anthropic, Google Gemini, 그리고 OpenAI 호환 API를 제공하는 다른 서비스들도 사용할 수 있다.
이 점은 제품 설계에서 중요하다. 에이전트의 상태와 실행은 Cloudflare에서 관리하고, 모델은 작업 성격에 따라 바꿀 수 있기 때문이다. 예를 들어 다음처럼 생각하면 된다.
- 짧고 빠른 응답은 경량 모델
- 구조화된 추출은 안정적인 지시 준수 모델
- 장문의 추론이나 고난도 코딩은 더 강한 모델
- 비용이 민감한 경로는 Workers AI 우선
즉, 에이전트 아키텍처와 모델 아키텍처를 분리해서 다룰 수 있다. 이 분리 덕분에 롤아웃과 A/B 테스트도 훨씬 쉬워진다.
메모리와 상태는 어떻게 다루는가
AI 앱에서 가장 자주 무너지는 부분은 "기억"이다. 대화 기록이 커지면 외부 저장소를 따로 설계해야 하고, 세션이 꼬이면 상태 동기화가 어려워진다. Cloudflare Agents는 이 부분을 에이전트 단위의 SQL과 상태 저장으로 단순화한다.
공식 docs는 각 Agent 인스턴스가 자체 SQL 데이터베이스를 가지며, 같은 컨텍스트 안에서 실행된다고 설명한다. 실무적으로는 다음과 같은 설계가 잘 맞는다.
- 사용자 프로필과 선호도 저장
- 최근 대화 요약 저장
- 작업 진행 상태 저장
- 승인 여부와 만료 시간 저장
- 외부 도구 호출 결과의 짧은 캐시 저장
이 방식의 장점은 메모리가 모델 프롬프트에만 있지 않다는 점이다. 앱이 구조화된 상태를 갖고 있으므로, "기억해야 할 것"과 "요약해도 되는 것"을 분리하기 쉽다.
장기 실행 작업과 human-in-the-loop
에이전트 제품은 종종 즉시 끝나지 않는다. 문서 검토, 외부 API 확인, 승인 대기, 예약 재시도 같은 흐름은 시간이 걸린다. Cloudflare Agents는 이런 작업을 자연스럽게 처리하도록 설계되어 있다.
특히 human-in-the-loop 패턴은 중요하다. 예를 들어 다음 경우가 그렇다.
- 환불, 결제, 삭제처럼 되돌리기 어려운 작업
- 외부 시스템에 영향을 주는 변경 작업
- 민감한 데이터가 포함된 액션
- 정책상 사람이 반드시 승인해야 하는 액션
좋은 패턴은 에이전트가 먼저 제안하고, 사람이 확인한 뒤, 승인된 범위만 실행하는 것이다. 이렇게 하면 자동화와 통제를 동시에 얻을 수 있다.
Propose action:
- Summarize the request
- Show the side effects
- Ask for approval
After approval:
- Execute only the approved step
- Persist the decision in agent state
- Schedule a follow-up check if needed
관측 가능성은 기본적으로 조용하다
Cloudflare Agents의 observability는 실무에서 꽤 좋은 균형을 잡는다. 공식 docs에 따르면 Agent는 중요한 작업에 대해 구조화된 이벤트를 내보내며, 아무도 구독하지 않으면 기본적으로 조용하고, hot path에서 사실상 오버헤드가 없다.
이건 운영 관점에서 아주 유용하다. 초기에 로깅을 과하게 심지 않아도 되고, 필요한 순간에만 이벤트를 구독해서 RPC 호출, 상태 변화, 스케줄 실행, 워크플로 전환, MCP 연결 같은 사건을 필터링할 수 있다.
즉, observability는 부가 기능이 아니라 에이전트 제품의 안전장치다. 상태형 시스템은 디버깅이 어려워지기 쉬운데, 구조화된 이벤트가 있으면 문제를 훨씬 빨리 추적할 수 있다.
MCP 배포에도 잘 맞는다
Cloudflare의 MCP 클라이언트 문서는 연결이 Agent의 SQL 저장소에 지속되고, 서버에 연결되면 해당 서버의 모든 도구가 자동으로 사용 가능해진다고 설명한다. 이건 MCP 기반 에이전트를 배포할 때 상당히 중요하다.
왜냐하면 MCP 서버 연결 자체가 상태를 요구하기 때문이다. 연결했던 서버, 인증 토큰, 사용 가능한 도구 목록, 마지막 동기화 시점 같은 것들이 모두 지속되어야 한다. Durable Object의 SQL과 Agent 상태를 함께 쓰면, 이런 연결 정보를 별도 세션 DB 없이도 다루기 쉬워진다.
실무적으로는 "serve path" 하나로 배포 가능한 구조가 가장 편하다. 즉, 에이전트가 HTTP 요청을 받고, 상태를 유지하고, MCP 서버와 연결하고, 필요한 도구를 호출하는 흐름을 한 경로에서 운영하는 것이다. 이 단순함이 나중에 유지보수 비용을 크게 줄여준다.
언제 stateless 패턴보다 이 구조가 나은가
다음 조건에 하나라도 많이 걸리면 Cloudflare Agents 쪽이 더 자연스럽다.
- 사용자가 돌아왔을 때 이전 상태를 기억해야 한다
- WebSocket 같은 실시간 연결이 중요하다
- 승인 절차가 필요하다
- 예약 실행이나 재시도가 필요하다
- 하나의 사용자나 작업 단위에 독립된 상태가 있다
- MCP나 도구 연결이 지속되어야 한다
반대로, 단발성 텍스트 변환이나 외부 상태가 전혀 없는 짧은 작업은 일반 Workers나 다른 stateless 함수로도 충분하다. 핵심은 "항상 Agents를 써야 한다"가 아니라, 상태와 연결이 제품의 본질인지 먼저 보는 것이다.
롤아웃 체크리스트
실제로 배포할 때는 다음 순서가 안전하다.
- 에이전트의 경계를 한 줄로 정의한다. 사용자별인지, 티켓별인지, 작업별인지부터 정한다.
- 상태 항목을 분리한다. 장기 기억, 진행 상태, 승인 상태, 임시 캐시를 섞지 않는다.
- 모델 호출 경로를 결정한다. Workers AI, OpenAI, Anthropic, Gemini 중 무엇을 기본으로 둘지 정한다.
- 승인 흐름이 필요한 액션을 먼저 식별한다.
- 스케줄링이 필요한 백그라운드 작업을 적어 둔다.
- observability 이벤트를 어디서 구독할지 정한다.
- MCP 연결이 있다면 지속 저장과 재연결 방식을 먼저 설계한다.
- 실패했을 때의 재시도와 복구 경로를 정한다.
마무리
Cloudflare Agents와 Durable Objects의 조합은 AI 앱을 "함수의 연속"이 아니라 상태를 가진 제품 단위로 설계하게 해준다. 이것이 이 아키텍처의 가장 큰 장점이다. 메모리, 실시간 연결, 승인, 스케줄링, MCP 연결, 구조화된 관측 가능성을 한쪽으로 몰아넣지 않고 에이전트 자체에 붙일 수 있다.
stateless serverless는 여전히 유용하지만, 에이전트 제품에서는 상태와 연결을 앱 밖으로 계속 밀어내는 순간 복잡도가 커진다. Cloudflare Agents는 그 복잡도를 플랫폼 쪽으로 가져가서, 개발자가 제품 로직에 더 집중하게 만들어 준다.
References
Cloudflare Agents and Durable Objects for AI Apps: A Practical Guide
Why Cloudflare Agents Fit AI Products So Well
According to Cloudflare’s official docs, each Agent runs on a Durable Object. A Durable Object is a stateful micro-server with its own SQL database, WebSocket connections, and scheduling. In practice, that means the basic building blocks an AI agent needs are already part of the platform: memory, realtime connectivity, long-running tasks, and per-agent state.
That is what makes the architecture appealing. Most AI apps still start from a stateless request-response model. But real agent products need more than that. They need to remember context, call tools, pause for approval, resume later, and stay connected while work is in progress. Cloudflare Agents is designed to make those behaviors feel native instead of bolted on.
Cloudflare says Agents run across its global network and can scale to tens of millions of instances. That is not just a scaling claim. It means you can design around one agent per user, one per ticket, or one per workflow without turning the platform into a coordination puzzle.
What a Durable Object-Backed Agent Means
Think of this architecture as "stateful micro-server" instead of "stateless function." The difference shows up immediately.
| Category | Typical stateless serverless | Cloudflare Agents + Durable Objects |
|---|---|---|
| State | Must be externalized | Lives with the agent |
| Connections | Short-lived by default | WebSocket-friendly and persistent |
| Scheduling | Separate cron or worker needed | Built into the agent model |
| Memory | Reconstructed per request | Kept as agent state |
| Scale | Requires state orchestration | Cloudflare handles global placement |
This matters for products where the unit of work is naturally persistent. Support bots, workflow copilots, approval systems, research assistants, and live collaborative tools all benefit from being able to keep context close to execution.
Cloudflare’s Agents API docs also say Agents require Durable Objects and that each Agent can have millions of instances. That makes the model a strong fit for per-user or per-case isolation.
The Patterns That Matter Most
Cloudflare’s starter patterns line up well with real AI product needs. The docs highlight four especially useful starting points.
- Streaming AI chat
- Server-side and client-side tools
- Human-in-the-loop approval
- Task scheduling
That combination covers the most common agent behaviors. Chat needs streaming, actions need tools, risky steps need approval, and cleanup or follow-up work needs scheduling.
Here is the mental model: a user asks a question, the agent streams a response, it calls a tool to verify data, it pauses if human approval is required, and it schedules a follow-up step if the task cannot finish immediately. All of that can live inside one agent boundary.
import { Agent } from "agents";
export class SupportAgent extends Agent {
async onRequest(request) {
const payload = await request.json();
// Persist state, call tools, and resume later if the workflow needs approval.
return new Response(JSON.stringify({ ok: true, payload }));
}
}
Model Choice Is Flexible
Cloudflare Agents is not locked to a single model provider. The docs say Workers AI is built in, and Agents can also call OpenAI, Anthropic, Google Gemini, or any service that exposes an OpenAI-compatible API.
That flexibility is useful for product design. You can keep the agent state and execution on Cloudflare, while choosing the model that best fits each task. For example:
- Fast replies can use a lightweight model
- Structured extraction can use a model with stronger instruction following
- Long reasoning can use a more capable model
- Cost-sensitive paths can start with Workers AI
This separation makes rollout easier. You can swap model providers without redesigning the entire state and execution layer.
Memory and State Are First-Class
A lot of AI products fail when they try to treat memory as an afterthought. Conversation history gets large, session glue gets messy, and the system becomes hard to reason about. Cloudflare Agents makes state a first-class part of the agent.
The docs say each individual Agent instance has its own SQL database that runs in the same context as the Agent itself. That suggests a practical structure like this:
- Store user preferences and profile data
- Store recent conversation summaries
- Store task progress and checkpoints
- Store approval flags and expiration timestamps
- Store short-lived results from external tools
The important design win is that memory does not have to live only in prompts. The application can keep structured state separately, which makes it much easier to decide what should be remembered, summarized, or discarded.
Long-Running Work and Human Approval
Agent products often do not finish in one turn. Document review, external API checks, approval waits, and retry loops all take time. Cloudflare Agents supports that kind of work more naturally than a plain request handler.
Human-in-the-loop is especially important when the action is risky or irreversible.
- Refunds, payments, and deletions
- Changes that affect external systems
- Actions involving sensitive data
- Steps that policy requires a human to approve
A good pattern is simple: the agent proposes the action, the human approves the narrow scope, and only then does the agent execute it. That gives you automation without losing control.
Propose action:
- Summarize the request
- Show side effects
- Ask for approval
After approval:
- Execute only the approved step
- Persist the decision in agent state
- Schedule a follow-up if needed
Observability Comes Built In
Cloudflare’s observability docs say Agents emit structured events for significant operations, and those events are silent by default with zero overhead when nobody is listening.
That is a strong operational default. You do not need to overload the hot path with custom logging just to understand what happened. Instead, you can subscribe to structured events for RPC calls, state changes, schedule execution, workflow transitions, MCP connections, and more.
For agent products, that is a big deal. Stateful systems are much easier to operate when the platform already exposes meaningful events instead of raw log noise.
MCP Deployment Fits the Same Model
Cloudflare’s MCP client docs say connections persist in the agent’s SQL storage, and when an agent connects to an MCP server, all tools from that server become available automatically.
That matters because MCP is not just a tool call. It is a durable relationship. You need to remember which server is connected, what tools are available, and how to reconnect cleanly. Durable Object state and SQL make that much easier than rebuilding everything from scratch on every request.
For deployment, a simple serve path is attractive. One path receives the request, keeps the state, maintains the MCP connection, and calls tools when needed. That simplicity is one of the main reasons this architecture is practical for agent products.
When This Beats Stateless Serverless
This architecture is a better fit when one or more of these are true:
- The agent needs to remember the user when they come back
- Realtime WebSocket connectivity matters
- Approval is part of the workflow
- Scheduling or retries are required
- Each user or case needs isolated state
- MCP or tool connections must persist
If the work is just a one-off text transformation, a normal Worker or other stateless function may still be enough. The key question is whether state and connection are part of the product’s core behavior.
Rollout Checklist
If we were launching this in production, I would check these items first.
- Define the agent boundary in one sentence. Decide whether it is per user, per ticket, or per workflow.
- Split state into clear buckets. Do not mix memory, progress, approval state, and temporary cache.
- Decide the model path. Pick a default provider, then decide where Workers AI, OpenAI, Anthropic, or Gemini fits.
- Identify actions that need approval before execution.
- List the background work that needs scheduling or retrying.
- Decide where observability events will be consumed.
- If MCP is involved, design persistence and reconnect logic up front.
- Define failure and recovery behavior before launch.
Final Takeaway
Cloudflare Agents and Durable Objects turn AI apps from "a chain of functions" into stateful product units. That is the real appeal. Memory, realtime connectivity, human approval, scheduling, MCP persistence, and structured observability all sit close to the agent instead of being scattered across separate services.
Stateless serverless still has a place, but agent products become much easier to build when state and connection are part of the platform rather than something you constantly rebuild around it. Cloudflare’s model gives you that structure without giving up global scale.