- Published on
Cloudflare Agents와 Durable Objects로 AI 앱을 만드는 실전 가이드
- Authors

- Name
- Youngju Kim
- @fjvbn20031
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는 그 복잡도를 플랫폼 쪽으로 가져가서, 개발자가 제품 로직에 더 집중하게 만들어 준다.