개발 slecs

한도 초과할 때도 서비스 지속할 수 있게 상위 모델로 자동 전환

목차

주간 API 호출 한도 제한이 있는 환경에서 기본 모델의 할당량이 떨어지면 상위 모델로 자동 폴백하는 기능을 A레이어에 추가했다. 이렇게 하면 사용자가 명시적으로 모델을 바꾸지 않아도 한도 초과 상황에서 서비스가 중단되지 않는다.

왜 이 작업이 필요했는가

보통 API 서비스를 여러 모델(Sonnet, Opus 같은)로 지원할 때, 각 모델마다 독립적인 주간 호출 한도를 갖는다. CLI 도구라면 사용자가 자주 상호작용하고, 그 과정에서 모델 선택 요청이 반복된다. 만약 기본 모델(Sonnet)로 설정된 요청들이 한 주 동안 많이 들어오면 할당량이 빨리 소진된다.

여기서 흔히 마주치는 딜레마가 있다. 첫 번째 선택지는 "한도 초과 에러를 사용자에게 반환하기"인데, 이건 사용자 입장에선 답답하다. 명시적으로 모델을 바꾸지 않는 한 더 이상 진행할 수 없기 때문이다. 두 번째 선택지는 "모든 요청을 한 가지 모델로 강제하기"인데, 이것도 문제가 있다. 기본 모델로 충분한 작업도 있지만 간단하게는 안 되는 작업도 있기 때문이다.

그래서 세 번째 방법, 즉 자동 폴백 전략을 택했다. Sonnet 한도가 떨어지면 Opus로 자동 전환하는 식이다. 사용자는 모델 선택을 신경 쓰지 않고 계속 사용할 수 있고, 우린 서비스 가용성을 지킬 수 있다.

구현 방향과 고민한 점

변경 대상이 claude_cli.mjs, claude_cli.py 두 개 파일이었다. JavaScript와 Python 모두에서 같은 로직을 구현해야 한다는 뜻이다. 이 두 언어로 동일한 의도를 표현하면서도 각각의 관례를 지키는 건 생각보다 신경 쓸 일이 많다.

측면 고려사항
한도 추적 어느 시점에 남은 한도를 확인할 것인가 (요청 전/후, 응답 헤더)
폴백 로직 Sonnet 실패 → Opus 재시도 인가, 아니면 선제적으로 판단 인가
에러 처리 Opus도 한도 초과면 어떻게 할 것인가 (최종 실패, 더 상위 모델 등)
레이어 배치 A레이어(아마 API 호출 계층)에만 넣을 건가, 다른 곳에도 영향이 있나

API 응답 헤더나 상태코드에서 "한도 초과" 신호를 읽고, 그 시점에 다음 요청부터는 상위 모델을 쓰도록 전환하는 방식이 일반적이다. 현재 요청이 Sonnet으로 이미 실패했다면, 같은 일을 Opus로 재시도하는 것도 고려할 수 있지만, 비용과 지연 시간 문제가 있으니 신중해야 한다.

비슷한 상황에서의 일반 패턴

이런 우아한 성능 저하(graceful degradation) 패턴은 API 설계에서 자주 나타난다:

  • 데이터베이스 복제본 장애: 주 복제본이 느리면 읽기 전용 복제본 사용
  • 이미지 최적화: WebP 미지원 환경에서 PNG 폴백
  • 캐시 계층 실패: Redis 못 쓰면 인메모리 캐시 사용
  • 결제 게이트웨이: A PG 실패 → B PG로 자동 재시도

핵심은 사용자는 느끼지 못하되, 우리는 정책을 유지할 수 있다는 점이다. 대신 로깅이 중요하다. 언제 얼마나 폴백이 발생했는지 추적하지 않으면 나중에 한도 계획을 다시 세울 때 데이터가 없다.

다시 생각해 본 것

이 작업을 진행하면서 느낀 건, 폴백 경로를 설계할 때 단계별 비용을 생각해야 한다는 점이다. Sonnet → Opus 폴백은 실행하지만, 그 다음에는 어떻게 할지 미리 정해야 한다. 혹시 Opus 한도도 떨어지면? 에러를 반환할 것인가, 아니면 또 다른 모델을 시도할 것인가? 이런 결정이 없으면 나중에 급할 때 패치를 반복하게 된다.

또 한 가지는 투명성이다. 폴백이 발생했다면 사용자에게 알려주는 게 좋을 수 있다. "현재 Opus 모델로 처리 중입니다"라는 식의 응답 메타데이터를 포함하면, 사용자가 왜 응답이 다를 수 있는지(처리 속도, 능력) 이해할 수 있다.

마지막으로, 이 기능이 두 언어(JavaScript, Python)로 나뉘어 있다는 점이 앞으로 관리 포인트가 될 것 같다. 로직 변경이 생기면 두 곳 다 신경 써야 하니까.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.