개요

이 가이드에서는 Clova Studio Gov API를 사용하여 완전한 대화형 챗봇 애플리케이션을 만드는 방법을 다룹니다.
사용 가능한 모델 종류와 특징은 언어 모델 종류를 참고하세요.

기본 Chat 구현

Python 예제

import requests
import json

class ClovaChat:
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = "https://api.clovastudio.go.kr/v1"
        self.messages = []
    
    def chat(self, user_message):
        # 메시지 히스토리에 추가
        self.messages.append({
            "role": "user",
            "content": user_message
        })
        
        # API 호출
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        data = {
            "model": "HCX-GOV-THINK",
            "messages": self.messages,
            "temperature": 0.7,
            "max_tokens": 1000,
            "stream": True
        }
        
        response = requests.post(
            f"{self.base_url}/chat/completions",
            headers=headers,
            json=data
        )
        
        if response.status_code == 200:
            result = response.json()
            assistant_message = result['choices'][0]['message']['content']
            
            # 어시스턴트 응답을 히스토리에 추가
            self.messages.append({
                "role": "assistant",
                "content": assistant_message
            })
            
            return assistant_message
        else:
            raise Exception(f"API Error: {response.status_code} - {response.text}")
    
    def reset(self):
        """대화 히스토리 초기화"""
        self.messages = []

# 사용 예제
if __name__ == "__main__":
    chat = ClovaChat("YOUR_API_KEY")
    
    # 첫 번째 메시지
    response = chat.chat("안녕하세요! Python에 대해 알려주세요.")
    print(f"AI: {response}")
    
    # 후속 질문 (컨텍스트 유지)
    response = chat.chat("Python의 주요 특징은 무엇인가요?")
    print(f"AI: {response}")

Node.js/TypeScript 예제

import fetch from 'node-fetch';

interface Message {
  role: 'system' | 'user' | 'assistant';
  content: string;
}

class ClovaChat {
  private apiKey: string;
  private baseUrl: string = 'https://api.clovastudio.go.kr/v1';
  private messages: Message[] = [];

  constructor(apiKey: string) {
    this.apiKey = apiKey;
  }

  async chat(userMessage: string): Promise<string> {
    // 메시지 히스토리에 추가
    this.messages.push({
      role: 'user',
      content: userMessage
    });

    const headers = {
      'Authorization': `Bearer ${this.apiKey}`,
      'Content-Type': 'application/json'
    };

    const data = {
      model: 'HCX-GOV-THINK',
      messages: this.messages,
      temperature: 0.7,
      max_tokens: 1000,
      stream: true
    };

    const response = await fetch(`${this.baseUrl}/chat/completions`, {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(data)
    });

    if (response.ok) {
      const result = await response.json();
      const assistantMessage = result.choices[0].message.content;

      // 어시스턴트 응답을 히스토리에 추가
      this.messages.push({
        role: 'assistant',
        content: assistantMessage
      });

      return assistantMessage;
    } else {
      throw new Error(`API Error: ${response.status} - ${await response.text()}`);
    }
  }

  reset(): void {
    this.messages = [];
  }
}

// 사용 예제
async function main() {
  const chat = new ClovaChat('YOUR_API_KEY');
  
  const response1 = await chat.chat('안녕하세요! TypeScript에 대해 알려주세요.');
  console.log(`AI: ${response1}`);
  
  const response2 = await chat.chat('TypeScript의 주요 특징은 무엇인가요?');
  console.log(`AI: ${response2}`);
}

main();

스트리밍 응답 구현

실시간으로 응답을 받아 사용자 경험을 개선할 수 있습니다.

Python 스트리밍 예제

import requests
import json

def chat_stream(api_key, messages):
    """스트리밍 방식으로 채팅 응답 받기"""
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    
    data = {
        "model": "HCX-GOV-THINK",
        "messages": messages,
        "stream": True
    }
    
    response = requests.post(
        "https://api.clovastudio.go.kr/v1/chat/completions",
        headers=headers,
        json=data,
        stream=True
    )
    
    full_response = ""
    
    for line in response.iter_lines():
        if line:
            line = line.decode('utf-8')
            if line.startswith('data: '):
                data_str = line[6:]  # 'data: ' 제거
                if data_str == '[DONE]':
                    break
                try:
                    data = json.loads(data_str)
                    if 'choices' in data and len(data['choices']) > 0:
                        delta = data['choices'][0].get('delta', {})
                        content = delta.get('content', '')
                        if content:
                            print(content, end='', flush=True)
                            full_response += content
                except json.JSONDecodeError:
                    continue
    
    print()  # 새 줄
    return full_response

# 사용 예제
messages = [{"role": "user", "content": "Python의 역사에 대해 설명해주세요."}]
response = chat_stream("YOUR_API_KEY", messages)

시스템 프롬프트 활용

시스템 프롬프트를 사용하여 챗봇의 페르소나와 행동을 정의할 수 있습니다.
class CustomBot:
    def __init__(self, api_key, system_prompt):
        self.api_key = api_key
        self.base_url = "https://api.clovastudio.go.kr/v1"
        self.messages = [
            {"role": "system", "content": system_prompt}
        ]
    
    def chat(self, user_message):
        self.messages.append({"role": "user", "content": user_message})
        
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        response = requests.post(
            f"{self.base_url}/chat/completions",
            headers=headers,
            json={
                "model": "HCX-GOV-THINK",
                "messages": self.messages,
                "temperature": 0.7,
                "stream": True
            }
        )
        
        assistant_message = response.json()['choices'][0]['message']['content']
        self.messages.append({"role": "assistant", "content": assistant_message})
        
        return assistant_message

# 전문가 봇 예제
expert_bot = CustomBot(
    "YOUR_API_KEY",
    "당신은 Python 프로그래밍 전문가입니다. 사용자의 질문에 명확하고 자세하게 답변하며, 코드 예제를 포함하여 설명합니다."
)

response = expert_bot.chat("함수 데코레이터에 대해 설명해주세요.")
print(response)

에러 처리 및 재시도 로직

import time
from typing import Optional

class RobustClovaChat:
    def __init__(self, api_key, max_retries=3):
        self.api_key = api_key
        self.base_url = "https://api.clovastudio.go.kr/v1"
        self.max_retries = max_retries
        self.messages = []
    
    def chat(self, user_message: str) -> Optional[str]:
        self.messages.append({"role": "user", "content": user_message})
        
        for attempt in range(self.max_retries):
            try:
                response = self._make_request()
                
                if response.status_code == 200:
                    assistant_message = response.json()['choices'][0]['message']['content']
                    self.messages.append({"role": "assistant", "content": assistant_message})
                    return assistant_message
                elif response.status_code == 429:  # Rate limit
                    wait_time = 2 ** attempt  # 지수 백오프
                    print(f"Rate limit reached. Waiting {wait_time} seconds...")
                    time.sleep(wait_time)
                else:
                    print(f"Error {response.status_code}: {response.text}")
                    if attempt == self.max_retries - 1:
                        raise Exception(f"Failed after {self.max_retries} attempts")
            except requests.exceptions.RequestException as e:
                print(f"Request failed: {e}")
                if attempt == self.max_retries - 1:
                    raise
                time.sleep(2 ** attempt)
        
        return None
    
    def _make_request(self):
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        return requests.post(
            f"{self.base_url}/chat/completions",
            headers=headers,
            json={
                "model": "HCX-GOV-THINK",
                "messages": self.messages,
                "stream": True
            },
            timeout=30
        )

다음 단계

실제 프로덕션 환경에서는 API 키를 환경 변수로 관리하고, 적절한 로깅과 모니터링을 추가하는 것이 좋습니다.