안녕하세요, 저는 HolySheep AI의 기술 전문가입니다. 이번 튜토리얼에서는 AI API를 사용할 때 발생하는 행동 데이터를 분석하는 방법을 초보자도 쉽게 이해할 수 있도록 단계별로 설명드리겠습니다. API 경험이 전혀 없어도 걱정 마세요. 이 가이드를 따라오시면 됩니다.
AI API 행동 데이터 분석이란?
AI API 행동 데이터 분석이란 AI 모델에게 요청을 보낼 때 발생하는 모든 정보(응답 시간, 토큰 사용량, 오류 발생 상황 등)를 수집하고 분석하는 것을 말합니다. 이를 통해 다음 항목들을 파악할 수 있습니다:
- 응답 시간: API가 요청에 응답하는 데 걸리는 시간 (밀리초/ms 단위)
- 토큰 사용량: 입력 토큰(input tokens)과 출력 토큰(output tokens)의 양
- 호출 성공률: 요청이 성공적으로 완료된 비율
- 비용 추적: 각 요청에 소비된 금액 (센트 단위로 계산)
- 오류 패턴: 어떤 상황에서 오류가 발생하는지 파악
HolySheep AI에서 행동 데이터 분석하기
HolySheep AI를 사용하면 모든 주요 AI 모델(GPT-4.1, Claude Sonnet, Gemini, DeepSeek)의 행동 데이터를 단일 대시보드에서 확인할 수 있습니다. 먼저 지금 가입하여 무료 크레딧을 받고 시작해보겠습니다.
1단계: API 키 확인하기
HolySheep AI 대시보드에 로그인하면 좌측 메뉴에서 "API Keys"를 클릭하여 API 키를 확인할 수 있습니다. 이 키는后续 코드에서 사용됩니다.
화면 구성 이미지: 대시보드 좌측에 "API Keys" 메뉴가 파란색으로 강조되어 있습니다
2단계: Python으로 API 행동 데이터 수집하기
이제 Python을 사용하여 API 호출 시 발생하는 데이터를 수집하는 코드를 작성해보겠습니다. requests 라이브러리와 time 라이브러리를 사용합니다.
# api_behavior_tracker.py
AI API 행동 데이터 수집을 위한 Python 스크립트
import requests
import time
import json
from datetime import datetime
HolySheep AI API 설정
BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY" # 실제 API 키로 교체하세요
헤더 설정
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
def track_api_behavior(model_name, messages):
"""
API 호출의 행동 데이터를 수집하는 함수
Args:
model_name: 사용할 AI 모델 이름
messages: 대화 메시지 리스트
Returns:
dict: 행동 데이터 (응답 시간, 토큰 사용량, 응답 내용)
"""
# 요청 시작 시간 기록
start_time = time.time()
# HolySheep AI를 통한 API 요청
payload = {
"model": model_name,
"messages": messages,
"max_tokens": 1000
}
try:
# API 호출
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload,
timeout=30
)
# 요청 종료 시간 기록
end_time = time.time()
# 응답 시간 계산 (밀리초 단위)
response_time_ms = (end_time - start_time) * 1000
# 응답 데이터 파싱
response_data = response.json()
# 행동 데이터 구성
behavior_data = {
"timestamp": datetime.now().isoformat(),
"model": model_name,
"status_code": response.status_code,
"response_time_ms": round(response_time_ms, 2),
"success": response.status_code == 200,
"usage": response_data.get("usage", {}),
"response": response_data.get("choices", [{}])[0].get("message", {}).get("content", "")
}
# 토큰 사용량이 있는 경우 비용 계산
if "usage" in response_data:
usage = response_data["usage"]
behavior_data["cost_breakdown"] = calculate_cost(model_name, usage)
return behavior_data
except requests.exceptions.Timeout:
return {
"timestamp": datetime.now().isoformat(),
"model": model_name,
"success": False,
"error": "요청 시간 초과 (30초)"
}
except requests.exceptions.RequestException as e:
return {
"timestamp": datetime.now().isoformat(),
"model": model_name,
"success": False,
"error": str(e)
}
def calculate_cost(model_name, usage):
"""토큰 사용량에 따른 비용 계산 (USD)"""
# HolySheep AI 가격표 (2024년 기준)
prices = {
"gpt-4.1": {"input": 0.008, "output": 0.032}, # $8/MTok 입력, $32/MTok 출력
"claude-sonnet-4-5": {"input": 0.015, "output": 0.075}, # $15/MTok 입력, $75/MTok 출력
"gemini-2.5-flash": {"input": 0.0025, "output": 0.01}, # $2.50/MTok 입력, $10/MTok 출력
"deepseek-v3.2": {"input": 0.00042, "output": 0.00168} # $0.42/MTok 입력, $1.68/MTok 출력
}
if model_name in prices:
price = prices[model_name]
input_cost = (usage.get("prompt_tokens", 0) / 1000000) * price["input"]
output_cost = (usage.get("completion_tokens", 0) / 1000000) * price["output"]
return {
"input_cost_usd": round(input_cost, 6),
"output_cost_usd": round(output_cost, 6),
"total_cost_usd": round(input_cost + output_cost, 6),
"prompt_tokens": usage.get("prompt_tokens", 0),
"completion_tokens": usage.get("completion_tokens", 0),
"total_tokens": usage.get("total_tokens", 0)
}
return None
테스트 실행
if __name__ == "__main__":
# 테스트 메시지
test_messages = [
{"role": "user", "content": "안녕하세요, 간단한 인사말을 알려주세요."}
]
# 여러 모델 테스트
models = ["gpt-4.1", "deepseek-v3.2"]
for model in models:
print(f"\n{'='*50}")
print(f"모델 테스트: {model}")
print('='*50)
result = track_api_behavior(model, test_messages)
print(f"타임스탬프: {result['timestamp']}")
print(f"상태 코드: {result['status_code']}")
print(f"응답 시간: {result['response_time_ms']}ms")
print(f"성공 여부: {result['success']}")
if "usage" in result:
print(f"입력 토큰: {result['usage'].get('prompt_tokens', 'N/A')}")
print(f"출력 토큰: {result['usage'].get('completion_tokens', 'N/A')}")
if "cost_breakdown" in result:
print(f"비용: ${result['cost_breakdown']['total_cost_usd']}")
print(f"\n응답 내용:\n{result.get('response', 'N/A')}")
3단계: 행동 데이터 저장 및 분석하기
수집한 데이터를 파일로 저장하고 분석하는 확장 스크립트를 만들어보겠습니다.
# api_behavior_analysis.py
AI API 행동 데이터 저장 및 분석 스크립트
import json
import csv
from datetime import datetime
from collections import defaultdict
import statistics
class APIBehaviorAnalyzer:
"""API 행동 데이터를 저장하고 분석하는 클래스"""
def __init__(self, save_file="api_behavior_log.json"):
self.save_file = save_file
self.behavior_history = []
self.load_history()
def load_history(self):
"""기존 데이터 로드"""
try:
with open(self.save_file, 'r', encoding='utf-8') as f:
self.behavior_history = json.load(f)
print(f"기존 데이터 {len(self.behavior_history)}개 로드 완료")
except FileNotFoundError:
print("새로운 데이터 파일 생성")
self.behavior_history = []
def save_data(self, data):
"""새 데이터 추가 및 저장"""
self.behavior_history.append(data)
with open(self.save_file, 'w', encoding='utf-8') as f:
json.dump(self.behavior_history, f, ensure_ascii=False, indent=2)
def generate_report(self):
"""행동 데이터 분석 리포트 생성"""
if not self.behavior_history:
return "분석할 데이터가 없습니다."
# 성공/실패 카운트
total_requests = len(self.behavior_history)
successful_requests = sum(1 for d in self.behavior_history if d.get('success', False))
failed_requests = total_requests - successful_requests
# 모델별 통계
model_stats = defaultdict(lambda: {
'count': 0,
'response_times': [],
'total_cost': 0,
'total_tokens': 0
})
for data in self.behavior_history:
model = data.get('model', 'unknown')
model_stats[model]['count'] += 1
if 'response_time_ms' in data:
model_stats[model]['response_times'].append(data['response_time_ms'])
if 'cost_breakdown' in data:
model_stats[model]['total_cost'] += data['cost_breakdown']['total_cost_usd']
if 'usage' in data:
model_stats[model]['total_tokens'] += data['usage'].get('total_tokens', 0)
# 리포트 생성
report = []
report.append("=" * 60)
report.append("AI API 행동 데이터 분석 리포트")
report.append(f"생성 시간: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
report.append("=" * 60)
report.append(f"\n[전체 통계]")
report.append(f"총 요청 수: {total_requests}")
report.append(f"성공 요청: {successful_requests} ({successful_requests/total_requests*100:.1f}%)")
report.append(f"실패 요청: {failed_requests} ({failed_requests/total_requests*100:.1f}%)")
report.append(f"\n[모델별 상세 통계]")
for model, stats in model_stats.items():
report.append(f"\n모델: {model}")
report.append(f" - 요청 횟수: {stats['count']}")
if stats['response_times']:
avg_time = statistics.mean(stats['response_times'])
min_time = min(stats['response_times'])
max_time = max(stats['response_times'])
report.append(f" - 평균 응답 시간: {avg_time:.2f}ms")
report.append(f" - 최소 응답 시간: {min_time:.2f}ms")
report.append(f" - 최대 응답 시간: {max_time:.2f}ms")
report.append(f" - 총 비용: ${stats['total_cost']:.6f}")
report.append(f" - 총 토큰 사용: {stats['total_tokens']:,} tokens")
# 비용 최적화 추천
report.append(f"\n[비용 최적화 추천]")
if model_stats:
cheapest_model = min(model_stats.keys(),
key=lambda m: model_stats[m]['total_cost'] / max(model_stats[m]['count'], 1))
fastest_model = max(model_stats.keys(),
key=lambda m: statistics.mean(model_stats[m]['response_times']) if model_stats[m]['response_times'] else float('inf'))
report.append(f" - 가장 저렴한 모델: {cheapest_model}")
report.append(f" - 가장 빠른 모델: {fastest_model}")
report.append("\n" + "=" * 60)
return "\n".join(report)
def export_to_csv(self, csv_file="api_behavior_export.csv"):
"""CSV 파일로 내보내기"""
if not self.behavior_history:
return "내보낼 데이터가 없습니다."
with open(csv_file, 'w', newline='', encoding='utf-8') as f:
fieldnames = ['timestamp', 'model', 'status_code', 'response_time_ms',
'success', 'prompt_tokens', 'completion_tokens', 'total_cost_usd']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for data in self.behavior_history:
row = {
'timestamp': data.get('timestamp', ''),
'model': data.get('model', ''),
'status_code': data.get('status_code', ''),
'response_time_ms': data.get('response_time_ms', ''),
'success': data.get('success', ''),
'prompt_tokens': data.get('usage', {}).get('prompt_tokens', ''),
'completion_tokens': data.get('usage', {}).get('completion_tokens', ''),
'total_cost_usd': data.get('cost_breakdown', {}).get('total_cost_usd', '')
}
writer.writerow(row)
return f"CSV 파일로 {len(self.behavior_history)}건 내보내기 완료: {csv_file}"
사용 예시
if __name__ == "__main__":
analyzer = APIBehaviorAnalyzer()
# 이전 예제의 데이터 추가 (실제로는 API 호출 결과가 저장됨)
sample_data = [
{
"timestamp": datetime.now().isoformat(),
"model": "gpt-4.1",
"status_code": 200,
"response_time_ms": 1250.45,
"success": True,
"usage": {"prompt_tokens": 50, "completion_tokens": 120, "total_tokens": 170},
"cost_breakdown": {"total_cost_usd": 0.00434}
},
{
"timestamp": datetime.now().isoformat(),
"model": "deepseek-v3.2",
"status_code": 200,
"response_time_ms": 890.32,
"success": True,
"usage": {"prompt_tokens": 50, "completion_tokens": 100, "total_tokens": 150},
"cost_breakdown": {"total_cost_usd": 0.000315}
}
]
for data in sample_data:
analyzer.save_data(data)
# 리포트 생성
print(analyzer.generate_report())
# CSV 내보내기
print(analyzer.export_to_csv())
실전 활용: 실시간 모니터링 대시보드
아래는 Flask를 사용한 실시간 API 모니터링 대시보드 예제입니다. API를 호출할 때마다 자동으로 행동 데이터가 업데이트됩니다.
# api_dashboard.py
Flask 기반 실시간 API 모니터링 대시보드
from flask import Flask, request, jsonify, render_template_string
import requests
import time
from datetime import datetime
import threading
app = Flask(__name__)
HolySheep AI 설정
BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
전역 데이터 저장소
api_metrics = {
"total_requests": 0,
"successful_requests": 0,
"failed_requests": 0,
"total_cost_usd": 0.0,
"total_tokens": 0,
"average_response_time_ms": 0.0,
"recent_requests": [],
"model_usage": {}
}
데이터 잠금 (스레드 안전을 위해)
data_lock = threading.Lock()
@app.route('/')
def dashboard():
"""대시보드 메인 페이지"""
template = '''
HolySheep AI API 모니터링
🐑 HolySheep AI API 모니터링 대시보드
실시간 API 호출 통계 및 성능 분석
총 요청 수
{{ metrics.total_requests }}
성공률
{{ "%.1f"|format(success_rate) }}%
총 비용
${{ "%.4f"|format(metrics.total_cost_usd) }}
평균 응답 시간
{{ "%.0f"|format(metrics.average_response_time_ms) }}ms
🔧 API 테스트
{% if last_result %}
📊 마지막 호출 결과
모델: {{ last_result.model }}
응답 시간: {{ last_result.response_time_ms }}ms
토큰: {{ last_result.prompt_tokens }} 입력 + {{ last_result.completion_tokens }} 출력
비용: ${{ last_result.cost_usd }}
응답:
{{ last_result.response }}
{% endif %}
📝 최근 요청 내역
{% for req in metrics.recent_requests[:10] %}
{{ req.timestamp }} |
{{ req.model }} |
{{ req.response_time_ms }}ms |
${{ "%.6f"|format(req.cost) }}
{% endfor %}
'''
success_rate = 0
if api_metrics["total_requests"] > 0:
success_rate = (api_metrics["successful_requests"] / api_metrics["total_requests"]) * 100
return render_template_string(template,
metrics=api_metrics,
success_rate=success_rate,
last_result=api_metrics.get("last_result"))
@app.route('/test_api', methods=['POST'])
def test_api():
"""API 테스트 실행"""
model = request.form.get('model', 'gpt-4.1')
prompt = request.form.get('prompt', 'Hello')
max_tokens = int(request.form.get('max_tokens', 500))
start_time = time.time()
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": model,
"messages": [{"role": "user", "content": prompt}],
"max_tokens": max_tokens
}
try:
response = requests.post(f"{BASE_URL}/chat/completions", headers=headers, json=payload, timeout=30)
end_time = time.time()
response_time_ms = (end_time - start_time) * 1000
data = response.json()
usage = data.get("usage", {})
prompt_tokens = usage.get("prompt_tokens", 0)
completion_tokens = usage.get("completion_tokens", 0)
# 비용 계산
prices = {"gpt-4.1": (0.008, 0.032), "claude-sonnet-4-5": (0.015, 0.075),
"gemini-2.5-flash": (0.0025, 0.01), "deepseek-v3.2": (0.00042, 0.00168)}
if model in prices:
input_price, output_price = prices[model]
cost_usd = (prompt_tokens / 1000000) * input_price + (completion_tokens / 1000000) * output_price
else:
cost_usd = 0
result = {
"model": model,
"response_time_ms": round(response_time_ms, 2),
"prompt_tokens": prompt_tokens,
"completion_tokens": completion_tokens,
"cost_usd": round(cost_usd, 6),
"response": data.get("choices", [{}])[0].get("message", {}).get("content", "")[:500]
}
# 메트릭 업데이트
with data_lock:
api_metrics["total_requests"] += 1
api_metrics["successful_requests"] += 1
api_metrics["total_cost_usd"] += cost_usd
api_metrics["total_tokens"] += prompt_tokens + completion_tokens
# 평균 응답 시간 계산
if api_metrics["total_requests"] > 0:
api_metrics["average_response_time_ms"] = (
(api_metrics["average_response_time_ms"] * (api_metrics["total_requests"] - 1) + response_time_ms)
/ api_metrics["total_requests"]
)
# 모델 사용량 업데이트
if model not in api_metrics["model_usage"]:
api_metrics["model_usage"][model] = {"count": 0, "cost": 0, "tokens": 0}
api_metrics["model_usage"][model]["count"] += 1
api_metrics["model_usage"][model]["cost"] += cost_usd
api_metrics["model_usage"][model]["tokens"] += prompt_tokens + completion_tokens
# 최근 요청 기록
api_metrics["recent_requests"].insert(0, {
"timestamp": datetime.now().strftime("%H:%M:%S"),
"model": model,
"response_time_ms": round(response_time_ms, 2),
"success": True,
"cost": cost_usd
})
api_metrics["recent_requests"] = api_metrics["recent_requests"][:20]
api_metrics["last_result"] = result
return result
except Exception as e:
with data_lock:
api_metrics["total_requests"] += 1
api_metrics["failed_requests"] += 1
api_metrics["recent_requests"].insert(0, {
"timestamp": datetime.now().strftime("%H:%M:%S"),
"model": model,
"response_time_ms": 0,
"success": False,
"cost": 0
})
return {"error": str(e)}
if __name__ == '__main__':
print("🚀 HolySheep AI 모니터링 대시보드 시작")
print("📊 http://localhost:5000 에서 대시보드 확인")
app.run(debug=True, port=5000)
HolySheep AI 가격 비교 분석
행동 데이터 분석을 통해 모델별 비용 효율성을 비교할 수 있습니다. HolySheep AI에서 제공하는 주요 모델들의 가격을 정리하면:
- DeepSeek V3.2: 입력 $0.42/MTok, 출력 $1.68/MTok — 최고의 비용 효율성
- Gemini 2.5 Flash: 입력 $2.50/MTok, 출력 $10/MTok — 가성비 우수
- GPT-4.1: 입력 $8/MTok, 출력 $32/MTok — 고성능 작업용
- Claude Sonnet 4.5: 입력 $15/MTok, 출력 $75/MTok — 프리미엄 분석용
실제 테스트 결과, 간단한 텍스트 생성 작업에서 DeepSeek V3.2는 GPT-4.1 대비 약 95% 비용 절감 효과를 보여주었습니다. 저는日常적인 쿼리에는 항상 DeepSeek를 사용하고, 복잡한 reasoning이 필요한 경우에만 상위 모델로 전환하는 전략을 사용합니다.
자주 발생하는 오류와 해결책
오류 1: 401 Unauthorized - API 키 인증 실패
# ❌ 오류 메시지
{"error": {"message": "Incorrect API key provided", "type": "invalid_request_error", "code": "invalid_api_key"}}
✅ 해결 방법
1. HolySheep AI 대시보드에서 API 키가 정확한지 확인
2. 키 앞뒤 공백 없이 복사
3. API 키가 활성화 상태인지 확인
API_KEY = "hs_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 정확한 형식으로 입력
유효성 검사 코드 추가
if not API_KEY.startswith("hs_"):
raise ValueError("HolySheep API 키는 'hs_'로 시작해야 합니다")
오류 2: 429 Rate Limit Exceeded - 요청 한도 초과
# ❌ 오류 메시지
{"error": {"message": "Rate limit exceeded", "type": "rate_limit_error", "code": "429"}}
✅ 해결 방법
HolySheep AI는 분당 요청 수 제한이 있습니다
아래 코드로 지수 백오프와 재시도 로직 구현
import time
import random
def make_request_with_retry(url, headers, payload, max_retries=3):
"""재시도 로직이 포함된 API 요청 함수"""
for attempt in range(max_retries):
try:
response = requests.post(url, headers=headers, json=payload, timeout=30)
if response.status_code == 200:
return response.json()
elif response.status_code == 429:
# Rate limit 도달 시 대기
wait_time = (2 ** attempt) + random.uniform(0, 1)
print(f"Rate limit 도달. {wait_time:.1f}초 후 재시도 ({attempt + 1}/{max_retries})")
time.sleep(wait_time)
else:
print(f"오류 발생: {response.status_code}")
return response.json()
except requests.exceptions.Timeout:
print(f"요청 시간 초과. 재시도 ({attempt + 1}/{max_retries})")
time.sleep(2)
return {"error": "최대 재시도 횟수 초과"}
오류 3: 500 Internal Server Error - 서버 내부 오류
# ❌ 오류 메시지
{"error": {"message": "An error occurred during completion", "type": "server_error", "code": "500"}}
✅ 해결 방법
서버 일시적 오류일 수 있으므로 재시도 + 폴백 모델 설정
def smart_api_call(messages, primary_model="gpt-4.1", fallback_model="deepseek-v3.2"):
"""
기본 모델 실패 시 폴백 모델로 자동 전환하는 함수
"""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": primary_model,
"messages": messages,
"max_tokens": 1000
}
# 기본 모델 시도
try:
response = requests.post(f"{BASE_URL}/chat/completions",
headers=headers, json=payload, timeout=30)
if response.status_code == 200:
print(f"✅ {primary_model} 성공")
return response.json()
# 500 에러 시 폴백
if response.status_code >= 500:
print(f"⚠️ {primary_model} 서버 오류. {fallback_model}으로 폴백...")
payload["model"] = fallback_model
response = requests.post(f"{BASE_URL}/chat/completions",
headers=headers, json=payload, timeout=30)
if response.status_code == 200:
print(f"✅ {fallback_model} 성공")
return response.json()
except requests.exceptions.RequestException as e:
print(f"❌ 요청 실패: {e}")
return {"error": "모든 모델 호출 실패"}
오류 4: Timeout - 요청 시간 초과
# ❌ 오류 메시지
requests.exceptions.ReadTimeout: HTTPSConnectionPool
✅ 해결 방법
타임아웃 시간 조정 + 비동기 처리 고려
import concurrent.futures
import asyncio
def async_api_call(messages, model="deepseek-v3.2"):
"""
비동기 API 호출로 타임아웃 해결
"""
def sync_call():
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": model,
"messages": messages,
"max_tokens": 500
}
# 타임아웃을 충분히 설정 (60초)
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload,
timeout=60 # 긴 컨텍스트나 복잡한 요청을 위해 60초
)
return response.json()
# 스레드 풀에서 비동기 실행
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
future = executor.submit(sync_call)
try:
result = future.result(timeout=90) # 전체 타임아웃 90초
return result
except concurrent.futures.TimeoutError:
return {"error": "요청 처리 시간 초과 (90초)"}
오류 5: Invalid Request - 잘못된 요청 형식
# ❌ 오류 메시지
{"error": {"message": "Invalid input", "type": "invalid_request_error"}}
✅ 해결 방법
요청 페이로드 유효성 검사
def validate_request(messages, max_tokens=4000, model=None):
"""
API 요청 전 유효성 검사
"""
errors = []
# 메시지 형식 검사
if not isinstance(messages, list):
errors.append("messages는 리스트여야 합니다")
elif len(messages) == 0:
errors.append("messages가 비어있습니다")
else:
for i, msg in enumerate(messages):
if not isinstance(msg, dict):
errors.append(f"메시지 {i}가 딕셔너리가 아닙니다")
elif "role" not in msg or "content" not in msg:
errors.append(f"메시지 {i}에 role 또는 content가 없습니다")
elif msg["role"] not in ["system", "user", "assistant"]:
errors.append(f"메시지 {i}의 role이 올바르지 않습니다: {msg['role']}")
# 토큰 제한 검사
if max_tokens > 8000:
errors.append(f"max_tokens({max_tokens})가 최대값(8000)을 초과했습니다")
elif max_tokens < 1:
errors.append("max_tokens는 최소 1이어야 합니다")
# 지원 모델 검사
supported