반응형
모델마다 API 키 따로 관리하는 거 지쳐있죠.
Anthropic API 키 따로
OpenAI API 키 따로
Google API 키 따로
각각 다른 SDK
각각 다른 요금 청구서
OpenRouter가 이걸 하나로 합쳐줘요.
OpenRouter API 키 하나
→ 200개+ 모델 전부
→ OpenAI SDK 그대로 사용
→ 모델명만 바꾸면 끝
1단계 — 가입 및 API 키 발급
1. openrouter.ai 접속
2. 우상단 "Sign In" → Google 또는 GitHub 로그인
3. 좌측 메뉴 "Keys" 클릭
4. "Create Key" 버튼
5. 이름 입력 (예: my-project) → Create
6. API 키 복사 (sk-or-v1-xxxxx 형태)
→ 한 번만 보여줌. 반드시 저장
크레딧 충전:
좌측 메뉴 "Credits" → "Add Credits"
최소 $5부터 충전 가능
카드 등록 없이 크레딧 선충전 방식
무료 모델만 쓸 거면 충전 불필요.
2단계 — 설치
# Python
pip install openai # OpenAI SDK 그대로 사용
# Node.js
npm install openai
별도 SDK 없음. 기존 OpenAI SDK에 base_url만 바꾸면 됩니다.
3단계 — 기본 사용법
Python
from openai import OpenAI
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key="sk-or-v1-xxxxx", # OpenRouter 키
)
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4-6",
messages=[
{"role": "user", "content": "파이썬으로 퀵소트 구현해줘"}
]
)
print(response.choices[0].message.content)
환경변수로 관리 (권장)
# .env 파일
OPENROUTER_API_KEY=sk-or-v1-xxxxx
import os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.getenv("OPENROUTER_API_KEY"),
)
Node.js / TypeScript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY,
});
const response = await client.chat.completions.create({
model: "openai/gpt-5.4",
messages: [{ role: "user", content: "안녕" }],
});
console.log(response.choices[0].message.content);
4단계 — 주요 모델 목록
유료 모델
# Anthropic Claude
"anthropic/claude-opus-4-7" # 가장 강력, 비쌈
"anthropic/claude-sonnet-4-6" # 균형 잡힌 선택 (권장)
"anthropic/claude-haiku-4-5" # 빠르고 저렴
# OpenAI
"openai/gpt-5.4" # 최신 GPT
"openai/gpt-5.4-mini" # 저렴한 버전
"openai/o3" # 추론 특화
# Google
"google/gemini-3.1-pro" # 강력한 추론
"google/gemini-3.1-flash" # 빠르고 저렴
# Mistral
"mistralai/mistral-large"
"mistralai/codestral-2" # 코딩 특화
무료 모델 (:free 붙은 것들)
# 완전 무료 (크레딧 불필요)
"meta-llama/llama-4-scout:free"
"meta-llama/llama-4-maverick:free"
"google/gemma-4-27b:free"
"mistralai/mistral-7b-instruct:free"
"deepseek/deepseek-chat:free"
# 무료 모델 주의사항:
# - 속도 느릴 수 있음
# - 컨텍스트 제한 있을 수 있음
# - 사용량 제한 있음 (일 20회 정도)
전체 모델 목록: openrouter.ai/models
5단계 — 실전 활용 패턴
패턴 1 — 작업별 모델 라우팅
from openai import OpenAI
import os
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.getenv("OPENROUTER_API_KEY"),
)
def get_model_for_task(task_type: str) -> str:
"""작업 유형에 따라 최적 모델 선택"""
routing = {
"coding": "anthropic/claude-sonnet-4-6", # 코딩 최강
"reasoning": "openai/o3", # 추론 특화
"fast": "google/gemini-3.1-flash", # 빠른 응답
"cheap": "meta-llama/llama-4-scout:free", # 무료
"creative": "anthropic/claude-opus-4-7", # 창의적 글쓰기
"translation": "google/gemini-3.1-pro", # 다국어
}
return routing.get(task_type, "anthropic/claude-sonnet-4-6")
def ask(prompt: str, task_type: str = "fast") -> str:
model = get_model_for_task(task_type)
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}]
)
print(f"[사용 모델: {model}]")
return response.choices[0].message.content
# 사용
code = ask("FastAPI JWT 인증 미들웨어 만들어줘", task_type="coding")
summary = ask("이 문서 요약해줘: ...", task_type="fast")
analysis = ask("이 수학 문제 풀어줘: ...", task_type="reasoning")
패턴 2 — 자동 폴백
def ask_with_fallback(
prompt: str,
models: list[str] = None
) -> str:
"""
모델 순서대로 시도. 실패하면 다음 모델로 폴백.
"""
if models is None:
models = [
"anthropic/claude-sonnet-4-6", # 1순위
"openai/gpt-5.4-mini", # 2순위
"meta-llama/llama-4-scout:free", # 3순위 (무료)
]
for model in models:
try:
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
timeout=30,
)
print(f"성공: {model}")
return response.choices[0].message.content
except Exception as e:
print(f"실패: {model} → {e}")
continue
raise RuntimeError("모든 모델 실패")
# Claude 다운되면 GPT로, GPT도 안 되면 Llama로
result = ask_with_fallback("안녕하세요")
패턴 3 — 여러 모델 동시 비교
import asyncio
from openai import AsyncOpenAI
async_client = AsyncOpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.getenv("OPENROUTER_API_KEY"),
)
async def ask_model(model: str, prompt: str) -> dict:
try:
response = await async_client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}]
)
return {
"model": model,
"response": response.choices[0].message.content,
"tokens": response.usage.total_tokens,
}
except Exception as e:
return {"model": model, "error": str(e)}
async def compare_models(prompt: str, models: list[str]) -> list[dict]:
"""여러 모델에 동시에 같은 프롬프트 보내기"""
tasks = [ask_model(m, prompt) for m in models]
return await asyncio.gather(*tasks)
# 실행
models_to_compare = [
"anthropic/claude-sonnet-4-6",
"openai/gpt-5.4-mini",
"google/gemini-3.1-flash",
"meta-llama/llama-4-scout:free",
]
results = asyncio.run(compare_models(
"파이썬 리스트 컴프리헨션 예시 3개 보여줘",
models_to_compare
))
for r in results:
print(f"\n{'='*40}")
print(f"모델: {r['model']}")
if "error" in r:
print(f"에러: {r['error']}")
else:
print(f"응답: {r['response'][:200]}...")
print(f"토큰: {r['tokens']}")
패턴 4 — 스트리밍
def stream_response(prompt: str, model: str = "anthropic/claude-sonnet-4-6"):
"""실시간 스트리밍"""
stream = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
stream_response("파이썬의 GIL을 설명해줘")
패턴 5 — 비용 추적
def ask_with_cost(prompt: str, model: str) -> dict:
"""응답과 함께 비용 계산"""
# 모델별 가격 (1M 토큰당 달러)
pricing = {
"anthropic/claude-opus-4-7": {"in": 5.0, "out": 25.0},
"anthropic/claude-sonnet-4-6": {"in": 3.0, "out": 15.0},
"anthropic/claude-haiku-4-5": {"in": 0.25, "out": 1.25},
"openai/gpt-5.4": {"in": 5.0, "out": 25.0},
"openai/gpt-5.4-mini": {"in": 0.4, "out": 1.6},
"google/gemini-3.1-flash": {"in": 0.15, "out": 0.6},
"meta-llama/llama-4-scout:free":{"in": 0.0, "out": 0.0},
}
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}]
)
usage = response.usage
price = pricing.get(model, {"in": 0, "out": 0})
cost = (
usage.prompt_tokens / 1_000_000 * price["in"] +
usage.completion_tokens / 1_000_000 * price["out"]
)
return {
"response": response.choices[0].message.content,
"model": model,
"input_tokens": usage.prompt_tokens,
"output_tokens": usage.completion_tokens,
"cost_usd": round(cost, 6),
}
result = ask_with_cost("안녕하세요", "anthropic/claude-sonnet-4-6")
print(f"응답: {result['response']}")
print(f"비용: ${result['cost_usd']} (입력 {result['input_tokens']}tok, 출력 {result['output_tokens']}tok)")
6단계 — 요청 헤더 추가 (선택)
OpenRouter가 앱 정보를 요청하면:
import httpx
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.getenv("OPENROUTER_API_KEY"),
http_client=httpx.Client(
headers={
"HTTP-Referer": "https://my-app.com", # 선택
"X-Title": "My App Name", # 선택
}
)
)
OpenRouter vs 직접 API vs LiteLLM
OpenRouter:
✅ 세팅 없음. 가입하고 바로 사용
✅ 200개+ 모델
✅ 무료 모델 있음
✅ 비용 대시보드 제공
❌ 직접 API보다 5~10% 비쌈
❌ 내 데이터가 OpenRouter 통과
직접 API (Anthropic/OpenAI):
✅ 가장 저렴
✅ 데이터 보안
❌ 각각 키/SDK/코드 따로 관리
❌ 모델 전환 시 코드 수정 필요
LiteLLM (자체 서버):
✅ 직접 API 가격
✅ 완전한 데이터 통제
❌ 서버 직접 운영
❌ 세팅 복잡함
추천:
개인 프로젝트, 프로토타입 → OpenRouter
프로덕션, 비용 민감 → 직접 API
기업, 규정 준수 필요 → LiteLLM 자체 서버
이런 상황에 바로 써라
"Claude랑 GPT 중 어느 게 더 잘 하나 비교해보고 싶다"
→ 같은 코드로 둘 다 테스트
"Claude 구독 없이 API로만 쓰고 싶다"
→ OpenRouter로 연결
"무료로 Llama 4 써보고 싶다"
→ :free 모델
"Claude 죽으면 자동으로 GPT로 전환하고 싶다"
→ 폴백 패턴 구현
"여러 모델 비용 한 곳에서 보고 싶다"
→ OpenRouter 대시보드
반응형
'LLM' 카테고리의 다른 글
| GPT-5.5 비싸다 — GPT-5.4 대비 2배 (0) | 2026.04.24 |
|---|---|
| GPT-5.5 출시 완전 분석 — Claude Opus 4.7에 일주일 만에 날린 OpenAI의 반격 (0) | 2026.04.24 |
| Gemma 4 파인튜닝 Unsloth로 30분에 끝내기 — API 비용 0원, 도메인 특화 모델 (0) | 2026.04.21 |
| LLM 사설 평가셋 50개 만들고 모델 비교하기 — 벤치마크를 믿지 마세요 (1) | 2026.04.20 |
| Opus 4.7 에이전트 비용 제어 실전 — effort + Task Budget 완전 가이드 (0) | 2026.04.20 |