고급의사 결정권자 + 플랫폼 엔지니어

클라이언트에는 모델 하나: 게이트웨이가 자동으로 계층화

UI에서 모델 선택을 없애세요 — 클라이언트는 모델 이름 하나만 노출하고, 계획은 강한 모델에서 실행되고 실행은 비용 효율 모델로 떨어지며, 요청이 이미 지나던 홉에서 계층화됩니다.

커뮤니티가 실제로 불평하는 것

"모두가 설정에 다른 모델을 넣어 같은 프롬프트가 사람마다 다르게 나온다", "누군가의 첫 주에 가장 흔한 질문이 어떤 모델을 골라야 하냐는 것이다", "모델을 은퇴시키려면 모든 개발자 머신의 환경 변수를 고쳐야 한다". 모델 선택이 결정할 정보가 가장 적은 사람에게 넘어갔습니다: 자기 지출을 볼 수 없고, 이 특정 요청이 강한 모델을 받을 자격이 있는지 알 방법이 없습니다.

대신 모두를 저렴한 모델로 내리면 작업 품질이 떨어집니다 — 계획과 아키텍처 판단을 작은 모델에 맡기면 재작업 비용이 절감보다 커집니다. 정말 중요한 구분은 이 요청이 무엇을 하는가, 계획인가 실행인가이며, 클라이언트는 게이트웨이에 그걸 알려 준 적이 없습니다.

GateLLM은 이렇게 합니다

클라이언트는 모델 이름 하나를 유지하고, 게이트웨이의 포괄 매핑(from "*")이 클라이언트가 요청한 이름을 정규화하므로 개인 설정을 바꿔도 요청의 도착지가 바뀌지 않습니다. 어떤 모델을 고를지 설명할 것도 남지 않습니다.

계층화 신호는 이미 대화 안에 있습니다: Claude Code의 계획 모드가 진입 시 Plan mode is active, 종료 시 Exited Plan Mode를 주입합니다. before 슬롯 스크립트가 마지막 메시지부터 거꾸로 스캔해 마지막으로 본 마커로 현재 상태를 판단한 뒤 context.useModel()을 호출해 라우팅을 전환합니다. 결정은 문자열 위치 비교입니다 — 별도 분류 호출도, 추가 네트워크 홉도 없습니다.

계층화는 before 슬롯에 있어야 합니다: after 슬롯은 번역된 업스트림 본문을 보므로 클라이언트가 주입한 마커를 읽을 수 없고, after-slot useModel은 같은 프로토콜 안에서만 전환하는 반면 계획에서 실행으로의 전환은 모델 간 경로 변경입니다. request_payload 규칙(prompt_cache_key 등)은 두 모델에 모두 구성해야 합니다: 진입 모델은 계획 중 자기 것을 유지하고, 대상 모델의 것은 전환 후에 적용됩니다.

실제로 효과가 있는 5가지 레버

  • 단일 인그레스 이름: 클라이언트는 모델 이름 하나를 노출하고 from "*" 포괄 매핑이 모든 요청 이름을 하나의 도착 모델로 정규화
  • 자동 계층화: before 슬롯 스크립트가 거꾸로 스캔해 마지막 마커를 취함 — 진입 마커는 기록에 영원히 남으므로 "포함" 검사는 상태를 영구히 계획 모드로 읽습니다
  • 프로토콜 가드: 스크립트가 context.sourceProtocol을 먼저 확인하고 비-Anthropic 트래픽에는 조기 반환하므로, 여러 클라이언트를 서비스하는 진입 모델이 잘못 라우팅되지 않음
  • 관찰 가능: 로그 모델 열의 SW 태그는 스크립트 전환, MM은 아이덴티티 매핑을 표시하며, 통계와 과금이 최종 모델 이름으로 귀속되어 모든 계층화 결정을 감사 가능
  • 클라이언트 배포 제로: 구성 변경에 머신별 편집이 필요 없고 매핑은 핫 리로드(유일한 예외는 재시작이 필요한 스크립트 힙 상한 SCRIPT_MEMORY_LIMIT_MB)
전체 방법: 계획 모드로 모델 전환(문서)

FAQ