Featured Post
작성자:
Iros
- 공유 링크 만들기
- X
- 이메일
- 기타 앱

갑자기 왜 OpenRouter를 쓰게 됐냐면요
요즘 개발자들 사이에서 AI 바이브 코딩 얘기 진짜 많이 하잖아요. 저도 처음엔 “에이, 그래도 개발은 사람이 구조 잡고 차근차근 해야지” 쪽에 가까웠는데요. 막상 바쁜 회사 일 사이사이에 사이드 프로젝트를 만들거나, 주말에 카페 앉아서 작은 도구 하나 뚝딱 만들어보려고 하면 생각이 좀 달라지더라고요.
특히 저처럼 20년 넘게 개발을 해온 사람도 이제는 혼자 모든 걸 다 붙잡고 있기엔 시간이 아깝다는 생각이 들어요. 코드는 내가 책임지고 봐야 하지만, 초안 만들기, 테스트 케이스 뽑기, 로그 분석하기, 문서 정리하기 같은 건 AI한테 잘 맡기면 꽤 든든합니다. 뭐랄까, 야근 많은 후배 한 명이 옆에 앉아 있는 느낌이랄까요. 다만 문제는 AI 모델마다 성격이 너무 다르다는 거였어요.
Claude는 코드 읽고 설명하는 느낌이 좋고, GPT-4o는 아이디어를 넓게 펼칠 때 편하고, Gemini Flash는 빠르게 툭툭 물어볼 때 괜찮고요. 그런데 매번 “이번 요청은 누구한테 보내지?”를 고민하다 보니, 이게 또 은근히 피곤하더라고요. 비용도 봐야 하고, 응답 속도도 봐야 하고, 장애가 나면 대체 모델도 생각해야 하고요.
그러다가 알게 된 게 OpenRouter였습니다. 처음엔 그냥 여러 모델을 하나의 API로 쓸 수 있는 서비스 정도로 봤는데, 실제로 써보니 제가 제일 마음에 들었던 건 모델 라우팅 쪽이었어요. 요청 성격에 따라 모델 우선순위를 정해두고, 첫 번째 모델이 안 되면 다음 모델로 넘기는 식이 가능하니까요. 이게 별거 아닌 것 같아도 실제 개발 흐름에서는 꽤 큰 차이를 만들더라고요.
OpenRouter 모델 라우팅, 제 느낌엔 AI 모델 교환소에 가까웠어요
OpenRouter 모델 라우팅을 너무 어렵게 생각할 필요는 없어요. 저는 그냥 “AI 모델 교환소”처럼 이해하고 있습니다. 요청이 들어오면 먼저 A 모델에 보내보고, A가 느리거나 실패하면 B 모델로 보내고, 그래도 안 되면 C 모델로 넘기는 식이죠.
예전 같았으면 이런 걸 백엔드에서 직접 짰을 거예요. 실제로 저도 처음엔 Python 쪽에 try-except를 잔뜩 넣고, timeout 걸고, 모델별 예외 메시지 따로 보고, 로그 남기고… 그렇게 하려다가 잠깐 멈췄습니다. 이거 내가 지금 하고 싶은 게 제품 개발인지, AI API 장애 대응 프레임워크 만드는 건지 헷갈리더라고요.
그래서 OpenRouter를 붙여봤는데, 생각보다 흐름이 단순해졌습니다. 저는 요즘 아래처럼 용도별로 모델 조합을 나눠두고 있어요.
| 제가 쓰는 용도 | 먼저 시도하는 모델 | 대체 모델 | 이렇게 둔 이유 |
|---|---|---|---|
| 코드 리뷰와 디버깅 | Claude 3.5 Sonnet | GPT-4o | 코드 맥락을 꽤 차분하게 읽고, 설명도 부담스럽지 않아요 |
| 아이디어 브레인스토밍 | GPT-4o | Claude 3 Opus | 처음 생각을 넓게 펼칠 때 편합니다 |
| 빠른 프로토타입 질문 | Gemini Flash 1.5 | Llama 3 70B | 속도가 중요할 때 부담이 덜해요 |
| 한국어 문장 교정 | Claude 3 Haiku | GPT-4o mini | 가볍고 빠른 작업에는 이 정도면 충분한 경우가 많았어요 |
물론 이 조합이 정답은 아닙니다. 모델 가격도 바뀌고, 성능도 조금씩 달라지고, 프로젝트 성격에 따라서도 달라요. 다만 제가 몇 달 써보면서 느낀 건 하나예요. 모델을 하나만 믿고 가는 방식은 생각보다 불안하다는 겁니다. 특히 고객에게 보여주는 기능이라면 더 그렇고요.
혼자 쓰는 개발 도구라면 모델 하나가 잠깐 느려져도 “아, 오늘 좀 버벅이네” 하고 넘길 수 있는데, 서비스 안에 들어간 기능이면 얘기가 달라집니다. 사용자는 그 모델이 지금 장애인지, 토큰이 몰렸는지, provider 쪽 이슈인지 관심 없거든요. 그냥 “왜 안 돼?”가 됩니다. 개발자는 그 한마디가 제일 무섭죠.
제가 실제로 쓰는 Python 호출 예제
아래 코드는 제가 개인 프로젝트에서 거의 비슷한 형태로 쓰는 구조입니다. 실제 운영 코드는 로깅이나 예외 처리, timeout 설정이 더 들어가긴 하지만, 핵심 아이디어는 이 정도면 충분히 보일 거예요.
import os
import requests
OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
def ask_ai(prompt, route_key="code"):
url = "https://openrouter.ai/api/v1/chat/completions"
headers = {
"Authorization": f"Bearer {OPENROUTER_API_KEY}",
"Content-Type": "application/json",
"HTTP-Referer": "https://my-service.example.com",
"X-Title": "my-vibe-coding-tool"
}
if route_key == "code":
models = [
"anthropic/claude-3.5-sonnet",
"openai/gpt-4o"
]
elif route_key == "creative":
models = [
"openai/gpt-4o",
"anthropic/claude-3-opus"
]
elif route_key == "fast":
models = [
"google/gemini-flash-1.5",
"meta-llama/llama-3-70b-chat"
]
else:
models = [
"openai/gpt-4o-mini",
"google/gemini-flash-1.5"
]
payload = {
"model": models,
"messages": [
{
"role": "user",
"content": prompt
}
],
"max_tokens": 1024
}
response = requests.post(
url,
headers=headers,
json=payload,
timeout=30
)
response.raise_for_status()
return response.json()
result = ask_ai(
"이 Python 코드에서 메모리 누수가 생길 만한 부분을 찾아줘",
route_key="code"
)
print(result)
여기서 제가 좋아하는 포인트는 model 값을 하나로 고정하지 않고, 상황에 따라 우선순위를 바꿔준다는 점이에요. 그러면 애플리케이션 코드 입장에서는 “코드 작업인지”, “아이디어 작업인지”, “빠른 응답이 중요한 작업인지”만 알면 됩니다. 나머지 모델 선택은 설정에 맡기는 거죠.
예전에는 이런 식으로 모델 호출 코드를 짜다 보면 서비스 곳곳에 모델명이 흩어졌어요. 컨트롤러에도 있고, 배치 작업에도 있고, 테스트 스크립트에도 있고요. 그러다 모델명을 바꾸려면 grep 돌려서 찾아다니고, 하나 빠뜨리면 운영에서 이상한 모델이 호출되고. 은근히 지저분합니다.
그래서 요즘은 route_key 개념을 일부러 둡니다. code, creative, fast, translate 같은 식으로요. 이렇게 해두면 나중에 모델을 바꿀 때도 비즈니스 로직은 거의 안 건드려도 됩니다. 개발 오래 하다 보면 이런 사소한 분리가 나중에 사람을 살려요. 진짜입니다.
하드코딩은 초반엔 편한데, 금방 발목을 잡더라고요
처음 테스트할 땐 코드 안에 모델명을 바로 박아도 됩니다. 저도 그렇게 시작했어요. 그런데 조금만 지나면 바로 불편해집니다. 모델 가격이 바뀌거나, 특정 모델 응답이 느려지거나, 새 모델이 나왔을 때 코드를 다시 배포해야 하거든요.
그래서 저는 모델 라우팅 설정을 YAML 파일로 빼두는 방식을 좋아합니다. 대충 이런 느낌이에요.
routes:
code:
models:
- anthropic/claude-3.5-sonnet
- openai/gpt-4o
max_tokens: 2048
timeout: 30
creative:
models:
- openai/gpt-4o
- anthropic/claude-3-opus
max_tokens: 1500
timeout: 40
fast:
models:
- google/gemini-flash-1.5
- openai/gpt-4o-mini
max_tokens: 800
timeout: 15
이렇게 빼두면 운영 중에도 판단이 편해져요. 예를 들어 어느 날 GPT-4o 쪽 응답이 좀 무겁다 싶으면 설정만 바꿔서 우선순위를 내릴 수 있습니다. 물론 실제 운영 환경에서는 설정 반영 방식도 신중해야 해요. 그래도 코드 전체를 다시 고치는 것보다는 훨씬 낫습니다.
제가 느끼기에 AI 바이브 코딩이 진짜 편해지는 순간은, 모델을 잘 고르는 순간이 아니라 모델 고르는 일을 덜 신경 쓰게 되는 순간이었어요. 개발자는 흐름이 끊기면 안 되거든요. 머릿속에서 설계가 굴러가고 있는데, 갑자기 “이번엔 어떤 모델 쓰지?” 하고 멈추면 김이 확 빠집니다.
몇 달 써보면서 알게 된 자잘한 꿀팁들
이건 문서만 보고는 잘 안 와닿고, 실제로 이것저것 붙여보면서 느낀 것들이에요. 엄청 대단한 비법은 아닌데, 저한테는 꽤 도움이 됐습니다.
-
fallback은 너무 많이 넣지 않는 게 좋습니다.
처음엔 욕심이 나서 모델을 4개, 5개씩 넣어봤어요. “이러면 절대 실패 안 하겠지?” 싶었거든요. 그런데 현실은 좀 달랐습니다. 앞 모델이 느리게 실패하고, 다음 모델도 애매하게 지연되고, 그다음 모델까지 넘어가면 전체 응답 시간이 너무 길어져요. 사용자는 실패보다 긴 침묵을 더 답답해합니다. 저는 보통 2개, 많아도 3개 정도로 제한합니다. -
비싼 모델과 싼 모델을 무조건 섞는다고 좋은 건 아니었어요.
코드 리뷰용으로 Claude 3.5 Sonnet을 쓰다가 fallback으로 너무 작은 모델을 붙였더니, 응답 품질이 확 달라지는 경우가 있었습니다. 같은 질문인데 어떤 날은 깊게 봐주고, 어떤 날은 겉핥기처럼 답하면 사용자 입장에서는 서비스가 들쑥날쑥하게 느껴져요. 그래서 저는 비슷한 급의 모델끼리 묶고, 저렴한 모델은 별도의fastroute로 빼는 편입니다. -
시스템 프롬프트는 따로 관리하는 게 좋습니다.
프롬프트가 길어질수록 비용도 늘고, 수정도 어려워집니다. 저는 공통 시스템 프롬프트를 코드에 흩뿌리지 않고 파일로 관리해요. 그리고 자주 쓰는 프롬프트 조합은 애플리케이션 레벨에서 캐싱하거나 템플릿화합니다. OpenRouter나 각 provider의 캐싱 정책은 모델마다 차이가 있을 수 있으니, 실제 과금과 동작은 꼭 문서에서 확인하는 게 마음 편합니다. -
스트리밍을 쓸 때는 사용자 안내 문구를 넣어두면 좋습니다.
스트리밍은 UX가 좋아요. 한 글자씩 답이 나오니까 사용자가 기다리는 느낌이 덜하거든요. 그런데 라우팅이나 fallback이 섞이면 첫 응답이 늦어지는 경우가 있습니다. 저는 이런 기능에는 “응답을 준비하는 중입니다” 같은 짧은 안내를 넣어둡니다. 별거 아닌데 체감이 달라요. -
로그는 꼭 남겨야 합니다. 안 남기면 감으로 운영하게 돼요.
어떤 route_key로 요청했는지, 실제 어떤 모델이 응답했는지, latency가 얼마였는지, 에러는 뭐였는지 정도는 남겨두는 게 좋습니다. 나중에 비용이 갑자기 튀거나 응답 품질이 떨어졌을 때, 로그가 없으면 그냥 느낌으로 추측하게 됩니다. 20년 개발하면서 배운 건데요. 느낌은 자주 틀립니다. 로그는 덜 틀려요.
제가 겪은 실패담도 하나 얘기해볼게요
한 번은 개인용 코드 분석 도구를 만들면서 fallback 모델을 다섯 개나 넣어둔 적이 있습니다. 마음은 좋았죠. 어떤 모델이 죽어도 살아남는 튼튼한 구조를 만들고 싶었으니까요. 그런데 테스트하다 보니 이상하게 응답이 너무 늦는 거예요.
로그를 까보니 첫 번째 모델에서 timeout 직전까지 기다리고, 두 번째 모델도 한참 버티고, 세 번째로 넘어가서야 겨우 응답이 나오는 경우가 있었습니다. 최종 응답 시간이 30초 가까이 나왔어요. AI 기능에서 30초면 꽤 긴 시간입니다. 특히 개발 도구에서는 더 그래요. 코딩하다가 30초 멈추면 흐름이 끊깁니다. 커피 한 모금 마시고 와도 찜찜해요.
그때 이후로 저는 원칙을 조금 바꿨습니다.
- fallback 모델은 2개에서 3개까지만 둔다
- route_key별 timeout을 따로 둔다
- 빠른 응답용 route와 고품질 응답용 route를 분리한다
- fallback끼리 품질 차이가 너무 크면 같은 그룹에 넣지 않는다
이렇게 바꾸고 나니 오히려 안정감이 좋아졌습니다. 이상하죠. 더 많이 대비했을 때보다, 적당히 제한했을 때 서비스가 더 건강해졌어요. 개발하다 보면 이런 일이 종종 있습니다. 많이 붙인다고 좋은 게 아니고, 적당한 선을 정하는 게 더 중요할 때가 있어요.
적용 전후로 뭐가 달라졌냐면요
제가 OpenRouter 모델 라우팅을 쓰기 전에는 모델 호출 코드가 꽤 지저분했습니다. 기능별로 모델명이 박혀 있었고, 장애가 나면 어디서 실패했는지 찾아야 했고, 비용 최적화도 감으로 했습니다. 그런데 route_key 중심으로 정리한 뒤에는 생각이 조금 단순해졌어요.
| 구분 | 적용 전 | 적용 후 |
|---|---|---|
| 모델 선택 | 기능 코드마다 모델명을 직접 지정 | route_key로 용도만 지정 |
| 장애 대응 | 직접 예외 처리와 재시도 로직 작성 | fallback 우선순위로 단순화 |
| 비용 관리 | 나중에 청구서 보고 놀람 | 용도별 모델 조합으로 미리 조절 |
| 운영 편의성 | 모델 바꾸려면 코드 수정이 필요 | 설정 파일 중심으로 변경 가능 |
| 개발 흐름 | 요청마다 모델 고민 | 작업에 집중하기 쉬움 |
물론 OpenRouter를 쓴다고 모든 문제가 사라지는 건 아닙니다. 모델마다 응답 스타일도 다르고, 가끔은 예상과 다른 답을 하기도 합니다. 특히 코드 생성은 아직도 사람이 봐야 해요. 저는 AI가 짜준 코드를 그대로 믿지 않습니다. 이건 좀 단호하게 말하고 싶어요. AI는 빠른 조수지, 최종 책임자는 아닙니다.
다만 초안 만들고, 막힌 부분 뚫고, 로그 해석하고, 낡은 코드 리팩토링 방향 잡는 데는 정말 쓸 만합니다. 여기에 OpenRouter 모델 라우팅을 얹으면 모델 선택 스트레스가 줄어듭니다. 이게 생각보다 큽니다.
이런 분들이라면 한 번 써볼 만합니다
제 기준에서 OpenRouter 모델 라우팅은 특히 이런 분들에게 잘 맞을 것 같아요.
- 여러 AI 모델을 번갈아 쓰는데 매번 선택하는 게 귀찮은 개발자
- AI 바이브 코딩으로 빠르게 프로토타입을 만드는 사람
- 코드 리뷰, 번역, 문서화, 아이디어 정리처럼 작업 성격이 자주 바뀌는 사람
- 특정 모델 장애에 대비해 fallback 구조를 갖추고 싶은 사람
- 비용과 응답 품질 사이에서 현실적인 균형을 찾고 싶은 사람
- 모델명을 코드 여기저기에 박아두는 방식이 슬슬 불안해진 사람
반대로 아주 단순한 챗봇 하나 만들고, 특정 모델 하나만 안정적으로 쓰면 되는 상황이라면 굳이 처음부터 복잡하게 라우팅을 넣을 필요는 없다고 봅니다. 저도 뭐든 도입부터 크게 벌리는 걸 좋아하진 않아요. 작게 붙여보고, 불편함이 생기면 그때 구조를 잡는 편이 더 오래 갑니다.
제가 지금 생각하는 OpenRouter 활용 방식
솔직히 말하면, 저는 요즘 AI 도구를 대하는 태도가 조금 바뀌었습니다. 예전엔 “어떤 모델이 제일 똑똑하지?”에 관심이 많았어요. 그런데 실제로 개발에 붙여보면 제일 똑똑한 모델 하나보다, 상황에 맞는 모델을 자연스럽게 고르는 구조가 더 중요할 때가 많더라고요.
코드 분석은 차분하게 잘 보는 모델에게 맡기고, 짧은 질문은 빠른 모델에게 보내고, 글 정리는 한국어가 부드러운 모델에게 넘기고요. 이렇게 역할을 나누면 AI를 쓰는 느낌이 훨씬 편해집니다. 마치 여행 갈 때도 그렇잖아요. 산길 갈 땐 등산화 신고, 도심 산책할 땐 편한 운동화 신고, 비 올 땐 방수되는 신발 챙기는 것처럼요. 하나로 다 해결하려고 하면 꼭 어딘가 불편합니다.
OpenRouter는 그 역할 분담을 조금 덜 귀찮게 만들어주는 도구였습니다. 엄청 화려한 마법은 아니에요. 그런데 개발자의 하루를 조금 덜 피곤하게 해주는 쪽에 가깝습니다. 저는 그런 도구를 좋아합니다. 조용히 옆에서 일을 줄여주는 도구요.
제 총평은 이렇습니다
OpenRouter 모델 라우팅은 AI를 자주 쓰는 개발자라면 한 번쯤 만져볼 가치가 있습니다. 특히 AI 바이브 코딩처럼 빠르게 만들고, 고치고, 다시 물어보고, 또 다듬는 흐름에서는 꽤 잘 맞아요.
제가 가장 추천하는 방식은 처음부터 거창하게 설계하지 않는 겁니다. 우선 code, fast, creative 정도의 route_key만 만들어보세요. 그리고 실제로 며칠 써보면서 어떤 모델이 내 작업 스타일에 맞는지 보면 됩니다. 그다음에 fallback을 조정하고, 설정 파일로 빼고, 로그를 붙이면 충분합니다.
이 글은 여러 AI 모델을 업무나 사이드 프로젝트에 붙여보고 싶은 개발자, 모델 비용과 품질 사이에서 감을 잡고 싶은 분, 그리고 저처럼 퇴근 후나 주말에 조용히 자기 프로젝트를 만지는 분들이 읽으면 특히 도움이 될 것 같아요.
AI가 개발자를 대체한다는 얘기보다, 저는 이런 쪽이 더 현실적이라고 봅니다. 개발자가 AI를 어떻게 배치하고, 어디까지 맡기고, 어디서 직접 판단할지 정하는 능력. 앞으로는 그게 꽤 중요한 실력이 될 거예요. 저도 아직 계속 배우는 중입니다. 그러니 너무 어렵게 생각하지 말고, 작은 route 하나부터 만들어보세요. 생각보다 재미있습니다.
댓글
댓글 쓰기