내가 Oracle Cloud의 Free Tier에서 프로덕션 AI 에이전트를 실행하는 이유
요약
글쓴이는 Oracle Cloud의 Free Tier라는 제한적인 환경에서도 프로덕션급 AI 에이전트를 성공적으로 운영하는 경험을 공유합니다. 이 과정에서 복잡성을 피하고 간헐적 컴퓨팅(Intermittent Compute) 패턴과 Oracle Autonomous Database의 강력한 기능을 활용하는 아키텍처적 통찰력을 얻었습니다. Oracle Cloud는 GPU나 관리형 Kubernetes 같은 고급 기능을 제공하지 않지만, 이러한 제약이 오히려 에이전트를 가볍고 효율적으로 설계하도록 강제하며, 특히 Autonomous Database가 데이터 영속성 및 자동 확장성을 혁신적으로 개선하는 핵심 역할을 합니다.
핵심 포인트
- Oracle Free Tier의 제한적 자원(Compute VM, Autonomous DB 등)은 복잡한 아키텍처를 단순화하고 가벼운 에이전트 설계를 강제한다.
- 에이전트는 항상 켜져 있을 필요가 없으며, 메시지 배치 처리 및 간헐적 컴퓨팅 패턴을 채택하는 것이 효율적이다.
- Autonomous Database는 자체 인덱싱, 백업, 패칭 기능을 제공하여 AI 에이전트의 데이터 영속성(Persistence) 관리를 단순화한다.
- 내장된 JSON 문서 저장소와 REST API를 통해 복잡한 ORM이나 커넥션 풀 관리 없이도 효율적인 메모리 쿼리가 가능하다.
- 인프라 수준에서 강제되는 mTLS는 보안을 기본값으로 제공하여 개발의 번거로움을 줄여준다.
원래 AIdeazz에 게시되었으며, 정식 링크와 함께 이곳에 교차 게시되었습니다. 제가 다른 빌더들에게 프로덕션 (Production) AI 에이전트를 Oracle Cloud의 Free Tier에서 실행한다고 말할 때마다, 저는 매번 똑같은 표정을 마주합니다. 바로 "왜 스스로에게 그런 일을 하나요?"라고 말하는 듯한 표정입니다. 하지만 파나마에서 수십 개의 자율 에이전트 (Autonomous Agents)를 출시하면서, 저는 직관에 반하는 무언가를 배웠습니다. Oracle의 무료 인프라는 시스템을 덜 신뢰할 수 있게 만드는 것이 아니라, 오히려 더 신뢰할 수 있게 만드는 아키텍처적 결정 (Architectural Decisions)을 강제한다는 점입니다.
Always Free의 현실 점검
Oracle Cloud의 Always Free 티어는 개발자들이 기대하는 방식으로 관대하지 않습니다. 제공되는 것은 다음과 같습니다:
- 2개의 AMD 기반 Compute VM (각각 1/8 OCPU, 1 GB 메모리)
- 2개의 Autonomous Database (각각 20 GB 스토리지)
- 10 GB 오브젝트 스토리지 (Object Storage)
- 월간 10 TB 아웃바운드 데이터 전송 (Outbound Data Transfer)
그게 전부입니다. GPU 액세스도 없고, 화려한 벡터 데이터베이스 (Vector Databases)도 없으며, 관리형 Kubernetes (Managed Kubernetes)도 없습니다. 그저 기본적인 컴퓨팅, 스토리지, 그리고 Oracle의 주력 제품인 Autonomous Database가 있을 뿐입니다. 대부분의 개발자는 이러한 제한을 보고 그냥 지나칩니다. 하지만 저는 더 가벼운 에이전트를 구축하도록 강제하는 제약 사항을 보았습니다. 복잡성으로 치달아버린 한 고객의 "단순한" 챗봇을 위해 AWS 비용으로 3,000달러를 낭비한 후, 저는 다른 접근 방식이 필요했습니다.
깨달음은 파나마시티의 한 레스토랑을 위한 WhatsApp 주문 접수 에이전트를 구축할 때 찾아왔습니다. t3.medium 인스턴스를 띄우고 일을 끝내는 대신, Oracle의 제한 사항은 저로 하여금 컴퓨팅 스케줄링 (Compute Scheduling) 관점에서 생각하도록 강제했습니다. 에이전트는 항상 켜져 있을 필요가 없었습니다. 깨어나서, 메시지를 배치 (Batch) 단위로 처리하고, 데이터베이스를 업데이트한 뒤, 다시 잠들면 되었습니다. 이러한 간헐적 컴퓨팅 (Intermittent Compute) 패턴은 그 이후 제가 구축한 모든 것의 토대가 되었습니다.
Autonomous Database: 간과된 일꾼
Oracle의 Autonomous Database는 에이전트의 영속성 (Persistence)에 대해 생각하는 방식을 바꿔 놓습니다. 이것은 단순한 관리형 데이터베이스가 아닙니다. 자체적으로 인덱싱 (Indexing), 백업 (Backup), 패칭 (Patching), 그리고 성능 튜닝 (Performance Tuning)을 처리하는 데이터베이스입니다. AI 에이전트에게 이는 다음과 같이 적용됩니다:
- 내장된 JSON 문서 저장소 (Built-in JSON document store): 에이전트 메모리, 대화 상태 (Conversation State), 그리고 도구 출력값 (Tool Outputs)이 JSON 문서로서 자연스럽게 존재합니다. ORM (Object-Relational Mapping)의 복잡성이 필요 없습니다.
자동 확장 (Automatic scaling): 프리 티어 (Free Tier)는 워크로드 (Workload)에 따라 0.02에서 0.2 OCPU 사이에서 자동으로 확장됩니다. 에이전트의 새벽 3시 배치 처리 (Batch processing)가 낮 시간의 용량을 소모하지 않습니다.
네이티브 REST API (Native REST APIs): 모든 자율 데이터베이스 (Autonomous Database)는 데이터에 접근할 수 있는 REST 엔드포인트 (Endpoints)를 노출합니다. 에이전트는 커넥션 풀 (Connection pools)을 유지할 필요 없이 자신의 메모리를 쿼리 (Query)할 수 있습니다. 실제 적용 사례는 다음과 같습니다. 저의 문서 처리 에이전트는 추출 결과를 다음과 같이 저장합니다:
프로덕션 코드의 간략화된 버전
async def store_extraction (
self, doc_id: str, extraction: dict
):
await self.odb.insert_json (
collection = 'extractions',
document = {
'_id': doc_id,
'timestamp': datetime.utcnow().isoformat(),
'source': extraction['source'],
'entities': extraction['entities'],
'confidence': extraction['confidence_scores'],
'model_used': self.current_model,
'processing_time_ms': extraction['duration']
}
)
데이터베이스가 _id, timestamp, 그리고 제가 자주 쿼리하는 모든 중첩된 JSON 경로 (Nested JSON paths)에 대한 인덱싱 (Indexing)을 처리합니다. 수동 인덱스 관리도, 마이그레이션 스크립트 (Migration scripts)도 필요 없습니다.
기본 제공되는 mTLS (mTLS by Default): 번거로움 없는 보안
Oracle Cloud 인프라로의 모든 연결은 상호 TLS (mTLS, mutual TLS)를 사용합니다. 이는 선택 사항이 아니라 인프라 수준에서 강제됩니다. 에이전트는 단순한 비밀번호나 API 키가 아닌 클라이언트 인증서 (Client certificates)로 인증합니다. 이전 챗봇이 잘못 설정된 Redis 인스턴스를 통해 해킹당했던 고객을 만나기 전까지는 이것이 과하다고 생각되었습니다. 공격자는 캐시 레이어 (Cache layer)를 통해 프롬프트 지시문 (Prompt instructions)을 주입했습니다. mTLS를 사용하면 누군가 연결 문자열 (Connection string)을 알아내더라도 클라이언트 인증서 없이는 연결할 수 없습니다. 이를 설정하려면 월렛 파일 (Wallet file, 인증서와 연결 문자열이 포함된 zip 파일)을 다운로드하고 데이터베이스 드라이버 (Database drivers)가 이를 가리키도록 설정해야 합니다:
Oracle Autonomous Database 연결
connection = oracledb.connect (user = "agent_user", password = os.
environ['ODB_PASSWORD'], dsn="agentdb_high", config_dir="/opt/oracle/wallet", wallet_location="/opt/oracle/wallet", wallet_password=os.environ['WALLET_PASSWORD']) 대화 기록, 추출된 개인정보(PII), 또는 비즈니스 로직을 저장할 때 인증서 관리의 번거로움은 충분한 가치가 있습니다. 저는 Oracle에서 호스팅되는 에이전트에 대해 보안 사후 분석(security postmortem) 보고서를 작성해야 했던 적이 한 번도 없습니다.
프로세스 감독: 중요하지만 지루한 부분
Free Tier VM은 크기가 작지만, 재활용될 수 있는 컨테이너가 아닌 실제 VM입니다. 이는 실제 프로세스 감독(process supervision)이 필요함을 의미합니다. 제가 고생하며 배운 점들은 다음과 같습니다:
- systemd는 당신의 친구입니다: 모든 에이전트는 자동 재시작 기능이 있는 systemd 서비스로 실행됩니다. 별도의 커스텀 프로세스 매니저를 사용할 필요가 없습니다.
- 메모리 제한은 실재합니다: Python을 실행하는 1GB VM은 OS를 제외하면 에이전트에게 약 600MB의 메모리만을 남깁니다. 메모리 누수(Memory leaks)는 프로세스를 빠르게 종료시킵니다.
- 디스크가 가득 찹니다: 에이전트가 모든 LLM 응답을 로깅하기 시작하기 전까지는 47GB가 충분해 보일 수 있습니다. 초기에 로그 로테이션(log rotation)을 구현하십시오.
다음은 Telegram 에이전트를 위한 프로덕션용 systemd 유닛 파일입니다:
[Unit]
Description = Telegram Support Agent
After = network-online.target
Wants = network-online.target
[Service]
Type = simple
User = agent
WorkingDirectory = /opt/agents/telegram
Environment = "PYTHONPATH=/opt/agents/telegram"
Environment = "OCI_CONFIG_FILE=/home/agent/.oci/config"
ExecStart = /opt/agents/telegram/venv/bin/python -m agent.main
Restart = always
RestartSec = 10
StandardOutput = journal
StandardError = journal
메모리 제한
MemoryMax = 600M
MemorySwapMax = 0
CPU 제한
CPUQuota = 80%
[Install]
WantedBy = multi-user.target
MemoryMax 및 CPUQuota 설정은 하나의 오작동하는 에이전트가 전체 VM을 다운시키는 것을 방지합니다. 에이전트가 메모리 제한에 도달하면, systemd는 이를 깔끔하게 재시작합니다.
최소한의 리소스에서 멀티 모델 라우팅(Multi-Model Routing) 수행하기
1GB RAM에서 Claude, GPT-4, 그리고 Groq 추론(inference)을 실행하는 것은 불가능하게 들리는데, 실제로 불가능하기 때문입니다. Free Tier는 에이전트가 추론 호스트(inference hosts)가 아닌 코디네이터(coordinators) 역할을 수행하는 라우팅 아키텍처를 강제합니다.
나의 프로덕션 설정:
Groq: 대량의 저지연 (low-latency) 작업 (의도 분류 (intent classification), 개체 추출 (entity extraction))
Claude: 복잡한 추론 (complex reasoning), 미묘한 차이가 있는 응답 (nuanced responses), 안전이 중요한 결정 (safety-critical decisions)
GPT-4: 특정 기능 (함수 호출 (function calling), 구조화된 출력 (structured outputs))을 위한 폴백 (Fallback)
라우팅 로직은 기본 에이전트 클래스에 구현됩니다:
class ModelRouter :
def __init__ ( self ):
self . groq_client = Groq ( api_key = os . environ [ ' GROQ_KEY ' ])
self . claude_client = anthropic . Anthropic ( api_key = os . environ [ ' CLAUDE_KEY ' ])
self . openai_client = openai . OpenAI ( api_key = os . environ [ ' OPENAI_KEY ' ])
async def route_completion ( self , task_type : str , prompt : str , ** kwargs ):
if task_type == ' classification ' :
return await self . _groq_complete ( prompt , model = ' mixtral-8x7b-32768 ' )
elif task_type == ' analysis ' :
return await self . _claude_complete ( prompt , model = ' claude-3-opus ' )
elif task_type == ' function_call ' :
return await self . _openai_complete ( prompt , model = ' gpt-4 ' )
else :
# 가장 저렴한 옵션으로 폴백 (Fallback)
return await self . _groq_complete ( prompt )
이 아키텍처는 상태(state)를 로컬에 유지하면서 추론(inference)을 API로 오프로딩(offloading)함으로써, 단일 VM이 수백 개의 동시 대화를 처리할 수 있음을 의미합니다.
제약 조건으로부터 얻은 운영상의 교훈:
Oracle의 프리 티어(free tier)에서 에이전트를 운영한 2년 후, 몇 가지 패턴이 나타났습니다:
모든 것을 배치(Batch)로 처리하기: 메시지가 도착하는 대로 처리하는 대신, 메시지를 축적하여 배치 단위로 처리하세요. 이를 통해 실행 사이에 에이전트를 종료할 수 있어 메모리를 절약할 수 있습니다.
상태는 메모리가 아닌 데이터베이스에 저장하기: 모든 에이전트 상태는 Autonomous Database에 저장됩니다. 에이전트는 컨텍스트(context)를 잃지 않고 재시작할 수 있습니다.
데이터베이스를 통한 모니터링: Autonomous Database에는 성능 인사이트(performance insights)가 포함되어 있으므로, 외부 APM 도구 대신 SQL 쿼리를 통해 에이전트의 동작을 모니터링할 수 있습니다.
지리적 차익 거래 (Geographic arbitrage): Oracle의 프리 티어는 모든 리전(region)에서 사용할 수 있습니다. 저는 라틴 아메리카 고객을 위해 상파울루(São Paulo)에서, 아시아 고객을 위해 뭄바이(Mumbai)에서 에이전트를 실행합니다.
대화형 AI (Conversational AI)에서는 지연 시간 (Latency)이 중요합니다. 가장 놀라운 결과가 무엇인지 아십니까? 이러한 제약 사항들이 오히려 더 신뢰할 수 있는 시스템을 만들었다는 점입니다. 문제에 자원을 무작정 쏟아부을 수 없을 때, 더 나은 아키텍처 (Architecture)를 구축하게 됩니다. 제가 Oracle에서 호스팅하는 에이전트들은 이전에 사용했던, 자원이 과다하게 할당된 AWS 배포 환경보다 더 높은 가동 시간 (Uptime)을 기록하고 있습니다.
주의 사항 및 현실적인 기대치
Oracle Cloud의 프리 티어 (Free Tier)에는 까다로운 점들이 있습니다:
- 계정 정지 (Account suspension): Oracle은 유휴 계정을 정지시킵니다. 계정을 활성 상태로 유지하려면 실제로 실행 중인 워크로드 (Workload)가 필요합니다.
- 지원 없음 (No support): 프리 티어 계정은 지원을 받지 못합니다. 리전 (Region) 전체에 문제가 발생할 경우 (드물지만 발생합니다), 다른 모든 사람과 마찬가지로 기다려야 합니다.
- 업그레이드 압박 (Upgrade pressure): Oracle은 정기적으로 업그레이드에 관한 이메일을 보냅니다. 이메일은 긴급해 보이지만, 프리 티어 제한 범위 내에 있다면 무시해도 됩니다.
- API 가용성 (API availability): 일부 OCI 서비스는 프리 티어에서 모든 리전에 제공되지 않습니다. 아키텍처를 설계하기 전에 리전 가용성을 확인하십시오.
- 학습 곡선 (Learning curve): Oracle의 문서는 엔터프라이즈 (Enterprise) 경험이 있다는 것을 전제로 합니다. OCI 개념을 익히기 위한 시간을 충분히 할애하십시오.
예상치 못한 이점
극단적인 제약 조건 속에서 구축하는 과정은 인프라 (Infrastructure)를 다르게 바라보는 법을 가르쳐 주었습니다. 이제 고객이 AI 에이전트를 요청하면, 저는 "예산이 어떻게 되나요?"라고 묻는 대신 "최소한으로 필요한 컴퓨팅 자원 (Compute)은 무엇인가요?"라고 묻기 시작합니다. 이러한 변화는 매우 중요한데, AI 에이전트의 경제성 (Economics)이 무너져 있기 때문입니다. 인프라 비용을 고려하면 대부분의 에이전트는 상호작용할 때마다 손해를 봅니다. 에이전트가 무료 인프라에서도 수익성 있게 운영될 수 있음을 증명함으로써, 우리는 대화의 주제를 "AI를 감당할 수 있는가?"에서 "AI가 어떤 문제를 해결해야 하는가?"로 바꿀 수 있습니다.
Oracle의 프리 티어가 모두를 위한 것은 아닙니다. GPU, 관리형 벡터 데이터베이스 (Managed vector databases), 또는 항상 켜져 있는 컴퓨팅 자원이 필요하다면 다른 곳을 찾아보십시오. 하지만 문서 추출, 고객 지원, 주문 처리와 같이 실제 문제를 해결하는 실용적인 에이전트를 구축하고 있다면, 이러한 제약 사항들이야말로 당신에게 정확히 필요한 요소일 수 있습니다. 앞서 언급했던 그 레스토랑의 WhatsApp 에이전트요? 18개월이 지난 지금도 여전히 동일한 프리 티어 계정에서 실행 중입니다.
그 에이전트는 50,000건 이상의 주문을 처리했고, 사장님의 시간을 주당 20시간 절약해 주었으며, 인프라 비용은 정확히 0달러입니다. 이것이 진짜 교훈입니다. 때로는 가장 좋은 인프라가 당신으로 하여금 더 나은 소프트웨어를 만들도록 강제하는 인프라라는 점입니다. — Elena Revicheva · AIdeazz · Portfolio
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기