

AI 프레젠테이션 에이전트 구축하기: 완벽 개발자 가이드
AI 에이전트가 소프트웨어의 콘텐츠 생성 방식을 혁신하고 있습니다. AI 프레젠테이션 에이전트는 CRM 파이프라인부터 내부 보고 도구에 이르기까지, 자동화된 워크플로의 일부로 전문적인 슬라이드 덱을 생성, 맞춤 설정 및 전달할 수 있습니다.
이 가이드에서는 2Slides API를 사용하여 프로덕션 환경에 바로 적용 가능한 프레젠테이션 에이전트를 구축하는 방법을 안내합니다.
아키텍처 개요
프레젠테이션 에이전트는 일반적으로 다음 흐름을 따릅니다:
User Request → Agent Logic → 2Slides API → Poll Job → Deliver Result ↓ Context Gathering (data, templates, brand assets)
핵심 구성 요소
- 입력 핸들러 — 프레젠테이션 요청(텍스트, 데이터, 파일)을 수신합니다.
- 컨텍스트 빌더 — 템플릿, 브랜드 정보, 데이터로 요청을 보강합니다.
- 생성 엔진 — 2Slides API를 호출하여 슬라이드를 생성합니다.
- 상태 모니터 — 작업 완료까지 상태를 폴링합니다.
- 전달 계층 — 다운로드 링크를 반환하고, 이메일로 전송하거나, Slack에 게시합니다.
시작하기
1. API 키 받기
2slides.com에서 가입하고 2slides.com/api에서 API 키를 생성하세요.
2. 종속성 설치
npm install node-fetch dotenv
3. 기본 에이전트 구현
import fetch from 'node-fetch'; class PresentationAgent { constructor(apiKey) { this.apiKey = apiKey; this.baseUrl = 'https://2slides.com/api/v1'; } async generateSlides({ topic, themeId, language = 'en', resolution = '2K' }) { // Step 1: Start generation const response = await fetch(`${this.baseUrl}/slides/generate`, { method: 'POST', headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ userInput: topic, themeId, responseLanguage: language, resolution, mode: 'async' }) }); const job = await response.json(); if (!response.ok) throw new Error(job.error || 'Generation failed'); // Step 2: Poll until complete return await this.waitForCompletion(job.jobId); } async waitForCompletion(jobId, maxWait = 300000) { const start = Date.now(); while (Date.now() - start < maxWait) { const response = await fetch(`${this.baseUrl}/jobs/${jobId}`, { headers: { 'Authorization': `Bearer ${this.apiKey}` } }); const status = await response.json(); if (status.status === 'success') return status; if (status.status === 'failed') throw new Error('Generation failed'); await new Promise(r => setTimeout(r, 3000)); } throw new Error('Generation timed out'); } async generateFromFile({ fileUrl, prompt, themeId }) { const response = await fetch(`${this.baseUrl}/slides/create-pdf-slides`, { method: 'POST', headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ fileUrl, userInput: prompt, themeId, mode: 'async' }) }); const job = await response.json(); return await this.waitForCompletion(job.jobId); } async generateWithDesign({ topic, referenceImageUrl, resolution = '2K' }) { const response = await fetch(`${this.baseUrl}/slides/create-like-this`, { method: 'POST', headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ userInput: topic, designStyle: { global: { referenceImageUrl } }, resolution, mode: 'async' }) }); const job = await response.json(); return await this.waitForCompletion(job.jobId); } async addNarration({ jobId, mode = 'single', voice = 'Charon' }) { const response = await fetch(`${this.baseUrl}/slides/generate-narration`, { method: 'POST', headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ jobId, mode, voice, contentMode: 'concise' }) }); return await response.json(); } } // Usage const agent = new PresentationAgent('sk-2slides-xxx'); const result = await agent.generateSlides({ topic: 'Q1 2026 Business Review', themeId: 'mckinsey-theme-id', resolution: '2K' }); console.log('Download:', result.downloadUrl);
Python 구현
import requests import time class PresentationAgent: def __init__(self, api_key): self.api_key = api_key self.base_url = 'https://2slides.com/api/v1' self.headers = { 'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json' } def generate_slides(self, topic, theme_id=None, language='en', resolution='2K'): response = requests.post( f'{self.base_url}/slides/generate', headers=self.headers, json={ 'userInput': topic, 'themeId': theme_id, 'responseLanguage': language, 'resolution': resolution, 'mode': 'async' } ) response.raise_for_status() job = response.json() return self._wait_for_completion(job['jobId']) def generate_from_file(self, file_url, prompt, theme_id=None): response = requests.post( f'{self.base_url}/slides/create-pdf-slides', headers=self.headers, json={ 'fileUrl': file_url, 'userInput': prompt, 'themeId': theme_id, 'mode': 'async' } ) response.raise_for_status() job = response.json() return self._wait_for_completion(job['jobId']) def _wait_for_completion(self, job_id, max_wait=300): start = time.time() while time.time() - start < max_wait: response = requests.get( f'{self.base_url}/jobs/{job_id}', headers=self.headers ) status = response.json() if status['status'] == 'success': return status if status['status'] == 'failed': raise Exception('Generation failed') time.sleep(3) raise TimeoutError('Generation timed out') # Usage agent = PresentationAgent('sk-2slides-xxx') result = agent.generate_slides('AI Trends 2026', resolution='4K') print(f"Download: {result['downloadUrl']}")
고급 패턴
패턴 1: 템플릿 기반 생성
다양한 사용 사례에 맞게 테마를 미리 구성하세요:
const TEMPLATES = { 'pitch-deck': { themeId: 'apple-id', resolution: '2K' }, 'quarterly-review': { themeId: 'mckinsey-id', resolution: '2K' }, 'training': { themeId: 'corporate-id', resolution: '1K' }, 'social-media': { themeId: 'saul-bass-id', resolution: '4K', aspectRatio: '1:1' }, }; async function generateByType(type, topic) { const config = TEMPLATES[type]; return agent.generateSlides({ topic, ...config }); }
패턴 2: 데이터 파이프라인 통합
데이터 소스에 연결하세요:
async function weeklyReport(dataSource) { // 1. Fetch latest data const data = await dataSource.getWeeklyMetrics(); // 2. Format as presentation input const topic = `Weekly Report: Revenue $${data.revenue}, Users ${data.users}, Churn ${data.churn}%`; // 3. Generate slides const result = await agent.generateSlides({ topic, themeId: 'mckinsey-id' }); // 4. Deliver await slackBot.postMessage('#team-updates', `Weekly report ready: ${result.downloadUrl}`); }
패턴 3: 다중 형식 출력
하나의 파이프라인에서 슬라이드 + 내레이션 + 비디오를 생성하세요:
async function fullPresentation(topic) { // 1. Generate slides const slides = await agent.generateSlides({ topic }); // 2. Add voice narration await agent.addNarration({ jobId: slides.jobId, mode: 'multi', voice: 'Charon' }); // 3. Download with audio const download = await fetch(`${agent.baseUrl}/slides/download-slides-pages-voices`, { method: 'POST', headers: agent.headers, body: JSON.stringify({ jobId: slides.jobId }) }); return download.json(); }
프로덕션 고려 사항
속도 제한 (Rate Limiting)
- 기본값: 분당 60회 요청
- 지수 백오프(exponential backoff)를 사용하여 429 응답을 처리하세요.
- 배치 작업에는 비동기 모드를 사용하세요.
오류 처리
- 모든 API 호출을 try/catch로 감싸세요.
- 일시적인 오류에 대한 재시도 로직을 구현하세요.
- 디버깅을 위해 작업 ID를 기록하세요.
비용 관리
- 생성당 크레딧 사용량을 추적하세요.
- 2Slides 대시보드에서 예산 알림을 설정하세요.
- 내부/초안 콘텐츠에는 낮은 해상도를 사용하세요.
보안
- API 키는 코드에 직접 넣지 말고 환경 변수에 저장하세요.
- 서버 측 API 호출만 사용하고, 클라이언트에 키를 노출하지 마세요.
- 웹훅 콜백에 대한 요청 서명을 구현하세요.
자주 묻는 질문
2Slides API를 기반으로 SaaS 제품을 구축할 수 있나요?
네, API는 프로덕션 사용을 위해 설계되었습니다. 상업적 애플리케이션에 대한 제한은 없습니다.
최대 동시 생성 제한은 얼마인가요?
API는 속도 제한(rate limiting)을 통해 동시 요청을 처리합니다. 대량의 요청이 필요한 경우 2Slides 팀에 문의하여 엔터프라이즈 제한을 확인하세요.
작업 완료를 위한 웹훅이 있나요?
현재는
jobs프레젠테이션 에이전트를 구축하세요 — 2Slides에서 API 키를 받고 프로그래밍 방식으로 슬라이드 생성을 시작하세요.
About 2Slides
Create stunning AI-powered presentations in seconds. Transform your ideas into professional slides with 2slides AI Agent.
Try For Free