콘텐츠로 이동

라우터 폴백과 업스트림 라우팅

Backend.AI GO를 거쳐 클라우드 모델로 가는 요청은 서로 독립된 두 계층에서 다시 시도될 수 있습니다. 번들된 Continuum Router는 폴백 체인에 나열한 모델들로 다시 시도합니다. 일부 프로바이더는 라우터에 응답하기 전에 스스로 모델을 고르고 다시 시도하기도 합니다. 두 계층은 서로가 무엇을 했는지 모르기 때문에, 같은 모델에 둘 다 켜져 있으면 시도 횟수가 곱해지고, 어느 계층이 다시 시도했거나 모델을 바꿨는지 알려 주는 응답은 없습니다.

이 문서는 두 계층이 각각 무엇을 하는지, 어떻게 겹치는지, 그리고 한 계층만 폴백을 맡게 하는 방법을 설명합니다.

두 개의 재시도 계층

라우터 폴백

라우터의 폴백 설정은 설정 > API 서버 > 고급에 있습니다. 각 설정은 라우터 구성의 다음 블록에 대응합니다.

설정 라우터 구성 하는 일
폴백 체인 fallback.fallback_chains 주 모델마다, 그 모델로 보낸 요청이 실패했을 때 순서대로 시도할 모델 목록입니다.
트리거 조건, 최대 폴백 시도 횟수, 타임아웃 승수 fallback.fallback_policy 어떤 실패에서 체인의 다음 모델로 넘어갈지(지정한 HTTP 상태 코드, 타임아웃, 연결 오류, 알 수 없는 모델, 열린 서킷 브레이커, 비정상 백엔드), 요청 하나가 몇 번까지 넘어갈 수 있는지, 뒤따르는 시도를 얼마나 더 오래 기다릴지를 정합니다.
스트림 중간 폴백 streaming.mid_stream_fallback 출력이 시작된 뒤 실패한 스트리밍 응답을 체인의 다음 모델에서 이어 가거나 다시 시작할지를 정하며, 별도의 최대 폴백 시도 횟수로 제한됩니다.
응답 품질 검사 fallback.quality_check 오류 없이 도착했지만 쓸 수 없는 비스트리밍 응답도 체인의 다음 모델로 넘길지를 정합니다. 응답 품질 검사를 참고하세요.

라우터 폴백은 모델 단위로 동작합니다. 체인의 각 모델은 일반 백엔드 풀을 통해 결정되므로, 체인 하나가 요청을 한 프로바이더에서 다른 프로바이더로 옮길 수 있습니다. 다음 모델로 넘어갈 때 라우터는 요청의 model 필드를 바꾸고, 본문의 나머지는 클라이언트가 보낸 그대로 전달합니다. 다만 대상 모델이 받아들이지 못하는 추론 강도를 맞추는 것처럼, 대상에 맞춘 몇 가지 조정은 예외입니다.

주 모델에 폴백 시 알림이 켜져 있으면, 비스트리밍 요청이나 아직 시작되지 않은 스트림에 폴백 모델이 응답했을 때 X-Fallback-Used, X-Original-Model, X-Fallback-Model, X-Fallback-Reason, X-Fallback-Attempts 응답 헤더로 알려 줍니다. 스트림이 시작된 뒤의 복구는 헤더를 추가할 수 없습니다. 헤더가 이미 전송되었기 때문입니다.

응답 품질 검사

위의 트리거는 모두 전송 계층이나 프로바이더가 알려 주는 실패입니다. 모델이 거절, 비어 있거나 잘린 답, 다른 질문에 대한 답을 돌려줘도 응답 자체는 성공이므로 라우터는 그 응답을 그대로 전달합니다. 응답 품질 검사는 비스트리밍 /v1/chat/completions 응답에서 이 빈틈을 메웁니다. System One 판정 모델(TypeSafe의 호스팅 Jev 또는 직접 운영하는 laya-serve)이 완료된 응답을 읽고, 쓸 수 없는 응답일 가능성이 높으면 라우터가 요청을 같은 체인의 다음 모델로 넘깁니다.

설정 > API 서버 > 고급의 응답 품질 검사 섹션에 있는 스위치로 켭니다. 이 섹션은 폴백이 켜져 있을 때 나타나며 다음 설정이 있습니다.

설정 라우터 구성 하는 일
판정 엔드포인트 target.endpoint /v1/systemone으로 끝나는 System One 서버의 URL입니다.
API 키 환경 변수 target.api_key_env 서버의 Bearer 키를 담은 환경 변수의 이름입니다. 인증이 없는 서버라면 비워 둡니다.
모드 mode 섀도(기본값)는 응답을 판정하고 넘겼을 경우를 기록하지만 항상 첫 응답을 전달합니다. 적용은 요청을 실제로 넘깁니다.
임계값 threshold 검사가 작동하는 '쓸 수 없는 응답' 확률로, 0보다 크고 1 이하입니다. 기본값은 0.8입니다.
요청당 품질 폴백 횟수 max_extra_hops 검사가 요청 하나를 넘길 수 있는 횟수로, 1~5입니다. 각 이동은 최대 폴백 시도 횟수에도 포함됩니다.
판정 대상 모델 models 응답을 판정할 주 모델입니다. 폴백 체인이 있는 모델만 표시되며, 아무것도 선택하지 않으면 체인이 있는 모든 모델을 판정합니다.

처음에는 섀도로 시작하세요. 기본값 0.8은 출발점일 뿐 실제 트래픽에서 측정한 값이 아니며, 적용 모드에서는 잘못된 판정이 클라이언트가 받는 응답을 바꿉니다. 바꾸기 전에 라우터가 요청을 넘겼을 빈도와 응답이 통과한 빈도를 비교하세요.

판정 모델은 마지막 사용자 메시지와 응답의 텍스트만 읽으며, 각각 앞부분과 끝부분을 남기는 방식으로 정해진 크기까지 줄입니다. 시스템 프롬프트, 이전 대화, 도구 호출과 도구 결과는 보내지 않으므로, 호스팅 서비스를 엔드포인트로 쓸 때도 이 범위만 전달됩니다. 도구를 호출하는 응답과 스트리밍 응답은 판정하지 않습니다.

요청을 넘기면 응답에 x-continuum-quality-fallback: 1이 붙고, 폴백 시 알림이 켜져 있으면 X-Fallback-Reason이 quality_check가 됩니다. 두 응답 모두 실제로 생성된 것이므로 둘 다 사용량에 집계됩니다. 판정 호출이 실패하거나 늦어도 요청을 막지 않으며, 라우터는 이미 받은 응답을 전달합니다.

Backend.AI GO는 API 키를 저장하지 않습니다

API 키 환경 변수에는 키가 아니라 변수의 이름을 넣습니다. Backend.AI GO는 이 키를 저장하거나 전달하지 않으며, 라우터는 앱이 시작된 환경에서 변수를 읽습니다. 헤드리스 서버를 시작하는 셸처럼 Backend.AI GO를 시작하기 전의 환경에 변수를 설정하세요. macOS에서 Finder나 Dock으로 연 데스크톱 앱은 셸 프로필에서 내보낸 변수를 보지 못합니다.

라우터 구성 파일에서는 URL 대신 백엔드 이름(target.backend)으로 판정 대상을 지정할 수도 있습니다. Backend.AI GO는 이런 항목을 유지하고 검사하지만 설정 화면에서는 제공하지 않습니다. 모델이 시작되거나 멈출 때마다 백엔드 목록을 다시 쓰는데, 지정한 백엔드가 없거나 판정 요청을 받을 수 없으면 라우터가 구성 전체를 거부하기 때문입니다. 이때 Backend.AI GO는 대신 품질 검사를 라우터 구성에서 빼고 경고를 기록하며, 재시작하더라도 설정은 그대로 보관합니다. 백엔드가 돌아오면 검사를 바로 다시 씁니다. 검사가 빠져 있는 동안 섹션에 해당 백엔드 이름과 함께 경고가 표시됩니다.

업스트림 라우팅

일부 프로바이더는 많은 모델을 앞단에서 묶어 제공하면서 요청마다 직접 라우팅하는 애그리게이터입니다. Backend.AI GO가 인식하는 것은 OpenRouter입니다. 라우터는 /v1/chat/completions에서 OpenRouter가 읽는 필드를 바꾸지 않고 전달하므로, 클라이언트는 OpenRouter의 라우팅 기능을 모두 쓸 수 있습니다.

  • openrouter/auto 는 요청마다 OpenRouter가 모델을 고르게 합니다.
  • models 배열은 한 모델이 실패했을 때(예: 요청 한도 초과나 장애) OpenRouter가 차례로 시도할 모델 목록입니다.
  • provider.allow_fallbacks 는 선호하는 호스트가 실패했을 때 같은 모델을 제공하는 다른 호스트로 요청을 옮길지를 정합니다. 기본값은 true이며, openai/gpt-5.6-sol처럼 명시적으로 지정한 모델을 포함해 OpenRouter가 제공하는 모든 모델에 적용됩니다.

OpenRouter는 최종적으로 응답한 모델을 응답의 model 필드로 돌려주고, 그 모델의 요금으로 과금합니다. 그 과정에서 몇 번 시도했는지는 알려 주지 않습니다. 각 기능의 자세한 내용은 OpenRouter의 모델 폴백, Auto Router, 프로바이더 선택 가이드를 참고하세요.

두 계층이 곱해지는 방식

라우터는 모델 시도 한 번마다 업스트림 호출 한 번만 봅니다. 그 호출이 OpenRouter로 가면, 그 안에 이미 여러 번의 시도가 들어 있을 수 있습니다. 같은 모델을 제공하는 다른 호스트로 시도하고, 다음으로 models 배열의 다른 모델로 시도합니다. 라우터는 OpenRouter가 포기한 뒤에야 실패를 보고, 그때 자신의 체인에서 다음 모델로 넘어갑니다. 그 모델도 OpenRouter를 거쳐 제공된다면 같은 내부 과정이 다시 반복됩니다.

예를 들어 최대 폴백 시도 횟수가 기본값 3이고, 체인에 세 모델이 있으며 모두 OpenRouter를 거쳐 제공된다고 해 봅시다. 요청 하나가 OpenRouter에 세 번 도달할 수 있습니다. OpenRouter가 오류를 돌려주기 전에 모델마다 호스트 두 곳을 시도한다면 이 요청은 업스트림 시도를 여섯 번 쓴 셈이고, 출력이 시작된 뒤 실패한 스트림이라면 스트림 중간 폴백으로 한 바퀴를 더 돌 수 있습니다. 응답에는 마지막으로 응답한 모델만 나옵니다.

각 계층이 알려 주는 정보를 합쳐도 전체 경로가 되지 않습니다. 라우터의 X-Fallback-* 헤더는 라우터의 이동만 설명하고, OpenRouter의 응답은 최종 선택만 설명합니다. 비용이 몇 배로 늘었거나 아무도 고르지 않은 모델이 응답한 요청이 있어도, 어느 계층 때문인지 직접 알려 주는 단서는 없습니다.

본문이 전달되는 방식에는 또 다른 영향이 있습니다. 라우터의 이동은 OpenRouter의 필드를 제거하지 않기 때문에, OpenRouter를 위해 보낸 models 배열이나 provider 객체는 체인의 다음 모델이 다른 프로바이더에서 제공되더라도 그대로 따라가며, 엄격한 엔드포인트는 알 수 없는 필드를 거부할 수 있습니다.

한 계층에만 폴백 맡기기

업스트림 라우팅을 하는 프로바이더를 거쳐 제공되는 모델이라면, 폴백을 맡을 계층을 하나만 고르세요.

  1. 업스트림에 맡기기. 그 모델을 라우터의 폴백 체인에서 빼 두세요. 주 모델로도, 다른 체인의 폴백으로도 넣지 않습니다. 원하는 폴백은 요청마다 openrouter/auto, models 배열, provider.allow_fallbacks로 지정합니다. OpenRouter의 카탈로그 전체에 걸친 라우팅을 쓰려는 배포에 적합합니다.
  2. 라우터에 맡기기. 체인에는 명시적인 모델을 지정하고, 클라이언트는 OpenRouter가 모델을 대체하지 않도록 요청합니다. models 배열과 openrouter/* 라우터를 쓰지 않고, provider.allow_fallbacks를 false로 설정합니다. OpenRouter와 다른 프로바이더를 오가는 체인이나, 라우터의 헤더와 폴백 메트릭으로 모든 이동을 설명해야 하는 배포에 적합합니다.

두 계층을 함께 쓰는 것도 의도한 선택일 수 있습니다. 예를 들어 OpenRouter가 자체 선택지를 모두 소진한 뒤에만 다른 프로바이더로 넘어가는 라우터 체인이 그렇습니다. 앱은 이를 막지 않고 경고만 표시합니다.

업스트림 라우팅 경고

설정 > API 서버 > 고급의 폴백 체인이 업스트림 라우팅을 하는 프로바이더를 거쳐 제공되는 모델을 지정하면, 해당 체인에 업스트림 라우팅 표시가 붙고 그 아래에 해당 모델과 프로바이더가 나열됩니다. 체인은 계속 편집하고 저장할 수 있습니다.

프로바이더의 base URL 호스트가 openrouter.ai이거나 그 하위 도메인이면 업스트림 라우팅을 하는 프로바이더로 판단합니다. base URL만 보기 때문에 Custom OpenAI-Compatible로 https://openrouter.ai/api/v1을 등록한 OpenRouter 프로바이더도 포함되며, 호스트 단위 폴백은 모든 모델에 적용되므로 openrouter/* 라우터뿐 아니라 그 프로바이더가 제공하는 모든 모델이 대상이 됩니다. openrouter.ai.example.com처럼 비슷해 보이는 호스트는 해당하지 않습니다.

어떤 프로바이더가 어떤 모델을 제공하는지는 라우터가 현재 가진 백엔드에서 가져오므로, 경고는 등록한 프로바이더와 그 프로바이더에서 선택한 모델을 따라갑니다.

슬래시가 포함된 모델 ID

OpenRouter의 모델 ID는 vendor/model 형식입니다. 번들된 라우터는 폴백 체인의 모델 이름에 문자, 숫자, ., _, -와 함께 /와 :도 허용하므로(lablup/continuum-router#1585 이후), 체인에서 openai/gpt-5.6-sol 같은 OpenRouter 모델이나 llama3:8b 같은 Ollama 모델을 직접 지정할 수 있습니다. 이때 이 문서에서 설명한 겹침이 체인에 그대로 적용되며, 위의 경고가 그 경우를 다룹니다. 공백, 제어 문자, 그 밖의 문장 부호는 여전히 거부되며, 이름은 최대 128바이트입니다.