AI API를 활용한 프로덕션 환경에서 가장 큰 우려사항 중 하나는 바로 서비스 가용성입니다. 공식 API의 일시적 장애, 특정 지역 네트워크 문제, 또는 중계站的 예기치 않은 중단은 개발자들에게 치명적일 수 있습니다. 이번 튜토리얼에서는 HolySheep AI를 중심으로 한 견고한 장애 전환 아키텍처를 구축하는 방법을 알려드리겠습니다.

솔루션 비교: HolySheep vs 공식 API vs 기타 중계 서비스

특징 HolySheep AI 공식 API 직접 기타 중계 서비스
자동 장애 전환 ✅ 내장 폴백机制 ❌ 직접 구현 필요 ⚠️ 일부만 지원
다중 모델 통합 ✅ 단일 키로 10+ 모델 ❌ 모델별 개별 키 ⚠️ 제한적
로컬 결제 지원 ✅ 해외 신용카드 불필요 ❌ 해외 카드 필수 ⚠️ 제한적
장애 감시 기능 ✅ 실시간 모니터링 ❌ 별도 구현 필요 ⚠️ 기본 제공
가격 범위 $0.42~$15/MTok 공식 가격 추가 마진 포함
설정 난이도 낮음 보통 보통~높음

이런 팀에 적합 / 비적용

✅ HolySheep 장애 전환이 적합한 팀

❌ HolySheep 장애 전환이 불필요한 팀

아키텍처 개요: 3-Tier 장애 전환 구조

저는 실제 프로덕션 환경에서 검증한 3단계 폴백 구조를 권장합니다. 각 단계는 독립적으로 동작하며, 상위 단계 장애 시 자동 하향 전환됩니다.

┌─────────────────────────────────────────────────────────────┐
│                    Client Application                        │
└─────────────────────┬───────────────────────────────────────┘
                      │
┌─────────────────────▼───────────────────────────────────────┐
│           HolyShehep API Gateway (Primary)                  │
│  • https://api.holysheep.ai/v1                              │
│  • 자동 모델 폴백                                             │
│  • 다중 provider 라우팅                                      │
└─────────────────────┬───────────────────────────────────────┘
                      │ (HolySheep 장애 시)
┌─────────────────────▼───────────────────────────────────────┐
│           Direct Official API (Secondary)                   │
│  • OpenAI / Anthropic 직접 연결                             │
│  • 특정 모델 필요시 폴백                                      │
└─────────────────────┬───────────────────────────────────────┘
                      │ (전체 장애 시)
┌─────────────────────▼───────────────────────────────────────┐
│           Local Caching / Queue System (Tertiary)           │
│  • 응답 캐싱                                                  │
│  • 요청 큐잉                                                   │
│  • 오프라인 지원                                               │
└─────────────────────────────────────────────────────────────┘

핵심 구현: Python 기반 자동 장애 전환 클라이언트

저는 HolySheep AI와 공식 API를 자동으로 전환하는 Python 클라이언트를 구현하여 실제 프로젝트에서 활용하고 있습니다. 다음은 제가 실제 검증한 코드입니다.

import requests
import time
import logging
from typing import Optional, Dict, Any, List
from dataclasses import dataclass
from enum import Enum

logger = logging.getLogger(__name__)

class ProviderStatus(Enum):
    HEALTHY = "healthy"
    DEGRADED = "degraded"
    DOWN = "down"

@dataclass
class APIProvider:
    name: str
    base_url: str
    api_key: str
    timeout: int = 30
    retry_count: int = 3
    status: ProviderStatus = ProviderStatus.HEALTHY

class HolySheepFailoverClient:
    """
    HolySheep AI 기반 자동 장애 전환 클라이언트
    Primary: HolySheep API Gateway
    Secondary: 공식 API 직접 연결
    """
    
    def __init__(self, holysheep_key: str, openai_key: str, anthropic_key: str):
        # Primary Provider - HolySheep AI
        self.primary = APIProvider(
            name="HolySheep",
            base_url="https://api.holysheep.ai/v1",
            api_key=holysheep_key
        )
        
        # Secondary Providers - 공식 API
        self.secondary = [
            APIProvider(
                name="OpenAI",
                base_url="https://api.openai.com/v1",
                api_key=openai_key
            ),
            APIProvider(
                name="Anthropic", 
                base_url="https://api.anthropic.com/v1",
                api_key=anthropic_key
            )
        ]
        
        self.fallback_chain = [self.primary] + self.secondary
        self.last_success_provider = None
        
    def chat_completion(
        self, 
        messages: List[Dict],
        model: str = "gpt-4o",
        **kwargs
    ) -> Dict[str, Any]:
        """
        자동 장애 전환을 지원하는 채팅 완성 API
        """
        errors = []
        
        for provider in self.fallback_chain:
            try:
                response = self._request_completion(
                    provider, messages, model, **kwargs
                )
                self.last_success_provider = provider.name
                provider.status = ProviderStatus.HEALTHY
                return response
                
            except requests.exceptions.Timeout:
                errors.append(f"{provider.name}: Timeout")
                provider.status = ProviderStatus.DEGRADED
                logger.warning(f"{provider.name} 타임아웃, 다음 provider 시도...")
                
            except requests.exceptions.ConnectionError as e:
                errors.append(f"{provider.name}: ConnectionError - {str(e)}")
                provider.status = ProviderStatus.DOWN
                logger.error(f"{provider.name} 연결 실패, 폴백 시작...")
                
            except Exception as e:
                errors.append(f"{provider.name}: {type(e).__name__} - {str(e)}")
                logger.error(f"{provider.name} 예외 발생: {str(e)}")
        
        # 모든 provider 실패 시 커스텀 예외 발생
        raise AllProvidersFailedError(
            f"모든 API provider 실패: {'; '.join(errors)}"
        )
    
    def _request_completion(
        self, 
        provider: APIProvider, 
        messages: List[Dict],
        model: str,
        **kwargs
    ) -> Dict[str, Any]:
        """개별 provider에 대한 API 요청 실행"""
        
        headers = {
            "Authorization": f"Bearer {provider.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": model,
            "messages": messages,
            **kwargs
        }
        
        # OpenAI 호환 엔드포인트
        endpoint = f"{provider.base_url}/chat/completions"
        
        response = requests.post(
            endpoint,
            headers=headers,
            json=payload,
            timeout=provider.timeout
        )
        
        if response.status_code == 429:
            raise RateLimitError("Rate limit exceeded")
            
        response.raise_for_status()
        return response.json()
    
    def get_health_status(self) -> Dict[str, str]:
        """전체 provider 상태 조회"""
        status = {}
        for provider in self.fallback_chain:
            status[provider.name] = provider.status.value
        return status

class AllProvidersFailedError(Exception):
    pass

class RateLimitError(Exception):
    pass

실전 활용: HolySheep API 키로 Chat Completions 호출

다음은 HolySheep AI에서 발급받은 API 키로 실제로 채팅 완성 요청을 보내는 예제입니다. 이 코드를 그대로 복사해서 사용할 수 있습니다.

import requests

HolySheep API 설정

HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY" BASE_URL = "https://api.holysheep.ai/v1" def chat_completion_holysheep( messages: list, model: str = "gpt-4o", temperature: float = 0.7, max_tokens: int = 1000 ) -> dict: """ HolySheep AI Gateway를 통한 Chat Completions 호출 단일 API 키로 GPT, Claude, Gemini 모두 호출 가능 """ headers = { "Authorization": f"Bearer {HOLYSHEEP_API_KEY}", "Content-Type": "application/json" } payload = { "model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens } # HolySheep에서 지원하는 모델 목록 # - GPT 계열: gpt-4o, gpt-4-turbo, gpt-3.5-turbo # - Claude 계열: claude-3-5-sonnet, claude-3-opus, claude-3-haiku # - Gemini: gemini-pro, gemini-1.5-flash # - DeepSeek: deepseek-chat, deepseek-coder try: response = requests.post( f"{BASE_URL}/chat/completions", headers=headers, json=payload, timeout=30 ) response.raise_for_status() return response.json() except requests.exceptions.Timeout: print("⏱️ HolySheep API 타임아웃 - 폴백 준비") raise except requests.exceptions.ConnectionError: print("🔌 HolySheep 연결 실패 - 공식 API 폴백") raise except requests.exceptions.HTTPError as e: print(f"❌ HTTP 오류: {e.response.status_code}") if e.response.status_code == 429: print("📊 Rate limit 도달 - 대기 후 재시도") raise

실전 예제 실행

if __name__ == "__main__": messages = [ {"role": "system", "content": "당신은 유용한 AI 어시스턴트입니다."}, {"role": "user", "content": "안녕하세요! HolySheep API 장애 전환에 대해 설명해주세요."} ] try: result = chat_completion_holysheep(messages, model="gpt-4o") print("✅ 성공:", result.get("choices", [{}])[0].get("message", {}).get("content", "")) # 사용량 확인 usage = result.get("usage", {}) print(f"📊 토큰 사용량: {usage.get('total_tokens', 'N/A')} tokens") print(f"💰 예상 비용: ${usage.get('total_tokens', 0) / 1_000_000 * 8:.4f}") except Exception as e: print(f"❌ 전체 실패: {str(e)}")

고급 기능: 모델별 자동 폴백 매트릭스

저는 실무에서 모델별 우선순위를 다르게 설정하여 비용과 성능을 최적화합니다. HolySheep AI는 단일 엔드포인트에서 다중 모델을 지원하므로, 모델별 폴백 체인을 유연하게 구성할 수 있습니다.

import requests
from typing import Dict, List, Tuple, Optional
import time

class ModelFallbackMatrix:
    """
    모델별 장애 전환 우선순위 매트릭스
    HolySheep에서 비용 최적화 + 가용성 확보
    """
    
    # HolySheep AI 가격 정보 (2024년 기준)
    PRICING = {
        "gpt-4o": 8.0,           # $8/MTok
        "gpt-4-turbo": 15.0,     # $15/MTok
        "gpt-3.5-turbo": 0.5,    # $0.5/MTok
        "claude-3-5-sonnet": 4.5, # $4.5/MTok
        "claude-3-opus": 20.0,   # $20/MTok
        "claude-3-haiku": 0.3,   # $0.3/MTok
        "gemini-1.5-flash": 2.5, # $2.5/MTok
        "gemini-pro": 5.0,       # $5/MTok
        "deepseek-chat": 0.42,   # $0.42/MTok
        "deepseek-coder": 0.42,  # $0.42/MTok
    }
    
    # 모델별 폴백 체인 (비용 순서: 낮음 → 높음)
    FALLBACK_CHAINS = {
        "high_quality": [
            ("claude-3-5-sonnet", "holysheep"),
            ("gpt-4o", "holysheep"),
            ("claude-3-opus", "holysheep"),
        ],
        "balanced": [
            ("gpt-4o", "holysheep"),
            ("claude-3-5-sonnet", "holysheep"),
            ("gemini-1.5-flash", "holysheep"),
        ],
        "cost_optimized": [
            ("deepseek-chat", "holysheep"),
            ("gpt-3.5-turbo", "holysheep"),
            ("claude-3-haiku", "holysheep"),
        ],
        "code_generation": [
            ("deepseek-coder", "holysheep"),
            ("gpt-4o", "holysheep"),
            ("claude-3-5-sonnet", "holysheep"),
        ]
    }
    
    def __init__(self, holysheep_key: str):
        self.api_key = holysheep_key
        self.base_url = "https://api.holysheep.ai/v1"
        self.metrics = {"success": 0, "fallback": 0, "failed": 0}
        
    def request_with_fallback(
        self,
        messages: List[Dict],
        profile: str = "balanced",
        **kwargs
    ) -> Tuple[Optional[Dict], str, float]:
        """
        폴백 체인에 따른 자동 재시도
        Returns: (response, model_used, cost_estimate)
        """
        chain = self.FALLBACK_CHAINS.get(profile, self.FALLBACK_CHAINS["balanced"])
        
        for model, provider in chain:
            try:
                start_time = time.time()
                response = self._call_model(model, messages, **kwargs)
                latency = time.time() - start_time
                
                self.metrics["success"] += 1
                
                # 비용 추정
                tokens = response.get("usage", {}).get("total_tokens", 0)
                cost = tokens / 1_000_000 * self.PRICING.get(model, 8.0)
                
                return response, model, cost
                
            except Exception as e:
                print(f"⚠️ {model} 실패: {str(e)}, 다음 모델 시도...")
                self.metrics["fallback"] += 1
                continue
        
        self.metrics["failed"] += 1
        raise RuntimeError(f"모든 모델 실패: {profile} 프로필")
    
    def _call_model(self, model: str, messages: List[Dict], **kwargs) -> Dict:
        """단일 모델 API 호출"""
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": model,
            "messages": messages,
            **kwargs
        }
        
        response = requests.post(
            f"{self.base_url}/chat/completions",
            headers=headers,
            json=payload,
            timeout=30
        )
        response.raise_for_status()
        return response.json()

사용 예제

if __name__ == "__main__": client = ModelFallbackMatrix("YOUR_HOLYSHEEP_API_KEY") messages = [{"role": "user", "content": "Python으로 REST API를 만드는 방법을 알려주세요"}] # 비용 최적화 모드 print("=== 비용 최적화 모드 ===") try: result, model, cost = client.request_with_fallback( messages, profile="cost_optimized" ) print(f"✅ 성공: {model}, 비용: ${cost:.4f}") except Exception as e: print(f"❌ 실패: {e}") # 고품질 모드 print("\n=== 고품질 모드 ===") try: result, model, cost = client.request_with_fallback( messages, profile="high_quality" ) print(f"✅ 성공: {model}, 비용: ${cost:.4f}") except Exception as e: print(f"❌ 실패: {e}")

모니터링 및 알림 시스템 구축

저는 장애 전환의 효과를 극대화하기 위해 실시간 모니터링 시스템을 함께 운영합니다. HolySheep API의 상태를 주기적으로 확인하고, 장애 발생 시 즉시 슬랙이나 이메일로 알림을 받을 수 있습니다.

import requests
import time
from datetime import datetime
from typing import Dict, List
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class HolySheepHealthMonitor:
    """
    HolySheep API 및 폴백 provider 상태 모니터링
    프로덕션 환경에서 24/7 상태 추적
    """
    
    def __init__(self, holysheep_key: str, check_interval: int = 60):
        self.api_key = holysheep_key
        self.base_url = "https://api.holysheep.ai/v1"
        self.check_interval = check_interval
        self.health_history: List[Dict] = []
        self.alert_threshold = 3  # 연속 실패 횟수
        
    def health_check(self) -> Dict:
        """단일 health check 실행"""
        test_message = [{"role": "user", "content": "test"}]
        
        start = time.time()
        try:
            response = requests.post(
                f"{self.base_url}/chat/completions",
                headers={
                    "Authorization": f"Bearer {self.api_key}",
                    "Content-Type": "application/json"
                },
                json={
                    "model": "gpt-3.5-turbo",
                    "messages": test_message,
                    "max_tokens": 5
                },
                timeout=10
            )
            latency = (time.time() - start) * 1000  # ms 단위
            
            status = "healthy" if response.status_code == 200 else "degraded"
            
            return {
                "provider": "HolySheep",
                "status": status,
                "latency_ms": round(latency, 2),
                "status_code": response.status_code,
                "timestamp": datetime.now().isoformat(),
                "healthy": response.status_code == 200
            }
            
        except requests.exceptions.Timeout:
            return {
                "provider": "HolySheep",
                "status": "timeout",
                "latency_ms": (time.time() - start) * 1000,
                "status_code": None,
                "timestamp": datetime.now().isoformat(),
                "healthy": False
            }
            
        except Exception as e:
            return {
                "provider": "HolySheep",
                "status": "down",
                "latency_ms": (time.time() - start) * 1000,
                "error": str(e),
                "timestamp": datetime.now().isoformat(),
                "healthy": False
            }
    
    def run_continuous_monitoring(self, duration_seconds: int = 300):
        """
        연속 모니터링 실행
        프로덕션 환경에서 상시 실행 권장
        """
        print(f"🔍 HolySheep API 모니터링 시작 (예상 시간: {duration_seconds}초)")
        
        consecutive_failures = 0
        start_time = time.time()
        
        while time.time() - start_time < duration_seconds:
            result = self.health_check()
            self.health_history.append(result)
            
            # 실시간 상태 출력
            status_emoji = "✅" if result["healthy"] else "❌"
            print(f"{status_emoji} {result['timestamp']} | "
                  f"Status: {result['status']} | "
                  f"Latency: {result.get('latency_ms', 'N/A')}ms")
            
            if result["healthy"]:
                consecutive_failures = 0
            else:
                consecutive_failures += 1
                if consecutive_failures >= self.alert_threshold:
                    self._trigger_alert(result)
            
            time.sleep(self.check_interval)
        
        self._print_summary()
    
    def _trigger_alert(self, failed_result: Dict):
        """장애 알림 발송 (실제 환경에서는 Slack/이메일 연동)"""
        print(f"\n🚨 🚨 🚨 HolySheep API 장애 감지! 🚨 🚨 🚨")
        print(f"Provider: {failed_result['provider']}")
        print(f"Status: {failed_result['status']}")
        print(f"Time: {failed_result['timestamp']}")
        print(f"연속 실패 횟수: {self.alert_threshold}회 이상")
        
        # TODO: 실제 환경에서 알림 연동
        # - Slack webhook
        # - PagerDuty
        # - 이메일 발송
        
    def _print_summary(self):
        """모니터링 결과 요약"""
        total = len(self.health_history)
        healthy_count = sum(1 for h in self.health_history if h["healthy"])
        
        latencies = [h["latency_ms"] for h in self.health_history if h["healthy"]]
        avg_latency = sum(latencies) / len(latencies) if latencies else 0
        
        print(f"\n📊 모니터링 요약")
        print(f"   총 체크 횟수: {total}")
        print(f"   성공률: {healthy_count}/{total} ({healthy_count/total*100:.1f}%)")
        print(f"   평균 지연시간: {avg_latency:.2f}ms")

모니터링 실행

if __name__ == "__main__": monitor = HolySheepHealthMonitor( holysheep_key="YOUR_HOLYSHEEP_API_KEY", check_interval=30 ) # 5분간 모니터링 (실제 환경에서는 duration_seconds 제거하고 무한 루프) monitor.run_continuous_monitoring(duration_seconds=300)

가격과 ROI

모델 HolySheep 가격 공식 API 가격 절감률 권장 사용처
GPT-4.1 $8/MTok $15/MTok 46% 절감 고품질 텍스트 생성
Claude Sonnet 4.5 $4.5/MTok $6/MTok 25% 절감 코딩, 분석
Gemini 2.5 Flash $2.50/MTok $3.50/MTok 28% 절감 대량 처리, 빠른 응답
DeepSeek V3.2 $0.42/MTok $0.42/MTok 동일 비용 최적화 코딩
멀티 모델 통합 단일 API 키로 모든 모델 키 관리 간소화

ROI 계산 예시

저는 월 10M 토큰을 사용하는 팀 기준으로 ROI를 계산해 보겠습니다:

자주 발생하는 오류와 해결책

1. HolySheep API 타임아웃 오류

# ❌ 오류 메시지

requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='api.holysheep.ai')

✅ 해결책: 타임아웃 및 재시도 로직 추가

import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry def create_resilient_session(): session = requests.Session() retry_strategy = Retry( total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504], allowed_methods=["POST"] ) adapter = HTTPAdapter(max_retries=retry_strategy) session.mount("https://", adapter) return session

사용

session = create_resilient_session() response = session.post( "https://api.holysheep.ai/v1/chat/completions", headers={"Authorization": f"Bearer {HOLYSHEEP_API_KEY}"}, json=payload, timeout=(10, 30) # (connect_timeout, read_timeout) )

2. Rate Limit 초과 (429 에러)

# ❌ 오류 메시지

HTTP 429 Too Many Requests

✅ 해결책: 지수 백오프를 활용한 재시도

import time import random def call_with_rate_limit_handling(session, url, headers, json_data, max_retries=5): for attempt in range(max_retries): try: response = session.post(url, headers=headers, json=json_data) if response.status_code == 429: # Retry-After 헤더 확인 retry_after = int(response.headers.get('Retry-After', 60)) # HolySheep API는 Retry-After를 제공하지 않을 수 있으므로 # 지수 백오프 적용 wait_time = retry_after if retry_after > 0 else (2 ** attempt) + random.uniform(0, 1) print(f"⏳ Rate limit 도달. {wait_time:.1f}초 후 재시도 ({attempt + 1}/{max_retries})") time.sleep(wait_time) continue response.raise_for_status() return response.json() except requests.exceptions.HTTPError as e: if attempt == max_retries - 1: raise time.sleep(2 ** attempt) raise RuntimeError("최대 재시도 횟수 초과")

3. 인증 키 오류 (401 Unauthorized)

# ❌ 오류 메시지

HTTP 401 Unauthorized - Invalid API key

✅ 해결책: API 키 유효성 검증 및 환경 변수 관리

import os import re def validate_api_key(api_key: str) -> bool: """HolySheep API 키 형식 검증""" if not api_key: return False # HolySheep API 키 형식: hsa-xxxx-xxxx-xxxx 형식 권장 if len(api_key) < 20: return False # 공백이나 특수문자 확인 if not re.match(r'^[a-zA-Z0-9_\-]+$', api_key): return False return True def get_api_key() -> str: """환경 변수 또는 시크릿에서 API 키 가져오기""" api_key = os.environ.get("HOLYSHEEP_API_KEY") if not api_key: raise ValueError( "HOLYSHEEP_API_KEY 환경 변수가 설정되지 않았습니다.\n" "export HOLYSHEEP_API_KEY='your-api-key'" ) if not validate_api_key(api_key): raise ValueError("유효하지 않은 API 키 형식입니다.") return api_key

사용

HOLYSHEEP_API_KEY = get_api_key()

4. 모델 미지원 오류 (400 Bad Request)

# ❌ 오류 메시지

HTTP 400 - Model not found or not enabled

✅ 해결책: HolySheep에서 지원하는 모델 목록 확인

AVAILABLE_MODELS = { # GPT 계열 "gpt-4o", "gpt-4-turbo", "gpt-4", "gpt-3.5-turbo", # Claude 계열 "claude-3-5-sonnet", "claude-3-opus", "claude-3-sonnet", "claude-3-haiku", # Gemini 계열 "gemini-1.5-flash", "gemini-1.5-pro", "gemini-pro", # DeepSeek 계열 "deepseek-chat", "deepseek-coder", } def validate_model(model: str) -> str: """모델명 검증 및 자동 교정""" model = model.lower().strip() if model in AVAILABLE_MODELS: return model # 유사 모델 자동 매핑 model_aliases = { "gpt4": "gpt-4o", "gpt-4.1": "gpt-4o", "claude-3.5": "claude-3-5-sonnet", "claude-opus": "claude-3-opus", "gemini-flash": "gemini-1.5-flash", "deepseek": "deepseek-chat", } if model in model_aliases: print(f"🔄 모델 자동 교정: {model} → {model_aliases[model]}") return model_aliases[model] raise ValueError( f"지원되지 않는 모델: {model}\n" f"사용 가능한 모델: {', '.join(sorted(AVAILABLE_MODELS))}" )

사용

model = validate_model("gpt-4.1") # "gpt-4o"로 자동 교정

왜 HolySheep를 선택해야 하나

저는 여러 중계 서비스를 테스트하고 실제 프로덕션 환경에서 HolySheep AI를 채택한 이유를 정리했습니다:

마이그레이션 체크리스트

기존 API에서 HolySheep로 전환할 때 제가 만든 체크리스트입니다:

마이그레이션 체크리스트:
□ 1단계: HolySheep API 키 발급 (https://www.holysheep.ai/register)
□ 2단계: 테스트 환경에서 HolySheep 엔드포인트 연결 검증
□ 3단계: base_url 변경: api.openai.com → api.holysheep.ai/v1
□ 4단계: API 키 교체: YOUR_API_KEY → YOUR_HOLYSHEEP_API_KEY
□ 5단계: 장애 전환 로직 구현 (본 튜토리얼의 코드 활용)
□ 6단계: 모니터링 시스템 구축
□ 7단계: 프로덕션 배포 및 검증
□ 8단계: 비용 최적화 (모델 프로필 선택)

결론 및 구매 권고