콘텐츠로 이동

설정 가이드

이 가이드는 Continuum Router 설정에 대한 종합적인 문서를 제공합니다. 라우터는 다양한 배포 시나리오에 최대한의 유연성을 제공하기 위해 명확한 우선순위 시스템과 함께 여러 설정 방법을 지원합니다.

설정 방법

Continuum Router는 세 가지 설정 방법을 지원합니다:

  1. 설정 파일 (YAML) - 프로덕션 환경에 권장
  2. 환경 변수 - 컨테이너화된 배포에 적합
  3. 명령줄 인수 - 테스트 및 오버라이드에 유용

설정 파일 검색

라우터는 다음 위치에서 설정 파일을 자동으로 검색합니다 (순서대로):

  1. --config 플래그로 지정된 경로
  2. ./config.yaml (현재 디렉토리)
  3. ./config.yml
  4. /etc/continuum-router/config.yaml
  5. /etc/continuum-router/config.yml
  6. ~/.config/continuum-router/config.yaml
  7. ~/.config/continuum-router/config.yml

설정 우선순위

설정은 다음 우선순위로 적용됩니다 (높은 것부터 낮은 순):

  1. 명령줄 인수 (최고 우선순위)
  2. 환경 변수
  3. 설정 파일
  4. 기본값 (최저 우선순위)

이를 통해 다음이 가능합니다:

  • 파일에 기본 설정 지정
  • 컨테이너에서 환경 변수로 특정 설정 오버라이드
  • 명령줄 인수로 임시 조정

설정 파일 형식

전체 설정 예제

# Continuum Router 설정
# 이 예제는 모든 사용 가능한 설정 옵션과 기본값을 보여줍니다

# 서버 설정
server:
  # bind_address는 단일 문자열 또는 주소 배열을 허용합니다
  # TCP 형식: "host:port", Unix 소켓 형식: "unix:/path/to/socket"
  bind_address: "0.0.0.0:8080"          # 단일 주소 (하위 호환)
  # bind_address:                        # 또는 다중 주소:
  #   - "0.0.0.0:8080"                   #   모든 인터페이스의 TCP
  #   - "unix:/var/run/router.sock"     #   Unix 소켓 (Unix/Linux/macOS만 해당)
  # socket_mode: 0o660                   # 선택 사항: Unix 소켓 파일 권한
  workers: 4                             # 워커 스레드 수 (0 = 자동 감지)
  connection_pool_size: 100              # 백엔드당 최대 유휴 연결 수

# 모델 메타데이터 설정 (선택 사항)
model_metadata_file: "model-metadata.yaml"  # 외부 모델 메타데이터 파일 경로

# 백엔드 설정
backends:
  # 내장 설정이 있는 네이티브 OpenAI API
  - name: "openai"
    type: openai                         # 네이티브 OpenAI 백엔드 사용
    api_key: "${CONTINUUM_OPENAI_API_KEY}"  # 환경 변수에서 로드
    org_id: "${CONTINUUM_OPENAI_ORG_ID}"    # 선택적 조직 ID
    weight: 3
    models:                              # 사용할 모델 지정
      - gpt-4o
      - gpt-4o-mini
      - o3-mini
      - text-embedding-3-large
    retry_override:                      # 백엔드별 재시도 설정 (선택 사항)
      max_attempts: 5
      base_delay: "200ms"
      max_delay: "30s"
      exponential_backoff: true
      jitter: true

  # 사용자 정의 메타데이터가 있는 일반 OpenAI 호환 백엔드
  - name: "openai-compatible"
    url: "https://custom-llm.example.com"
    weight: 1
    models:
      - "gpt-4"
      - "gpt-3.5-turbo"
    model_configs:                       # 메타데이터가 포함된 향상된 모델 설정
      - id: "gpt-4"
        aliases:                         # 이 메타데이터를 공유하는 대체 ID (선택 사항)
          - "gpt-4-0125-preview"
          - "gpt-4-turbo-preview"
        metadata:
          display_name: "GPT-4"
          summary: "복잡한 작업을 위한 가장 유능한 GPT-4 모델"
          capabilities: ["text", "image", "function_calling"]
          knowledge_cutoff: "2024-04"
          pricing:
            input_tokens: 0.03
            output_tokens: 0.06
          limits:
            context_window: 128000
            max_output: 4096

  # 자동 URL 감지가 있는 Ollama 로컬 서버
  - name: "local-ollama"
    type: ollama                         # 기본값 http://localhost:11434
    weight: 2
    models:
      - "llama2"
      - "mistral"
      - "codellama"

  # vLLM 서버
  - name: "vllm-server"
    type: vllm
    url: "http://localhost:8000"
    weight: 1
    # 지정하지 않으면 모델이 자동으로 검색됩니다
    # 네임스페이스 접두사가 있는 모델 (예: "custom/gpt-4")은
    # 자동으로 기본 이름의 메타데이터와 일치합니다 (예: "gpt-4")

  # Google Gemini API (네이티브 백엔드)
  - name: "gemini"
    type: gemini                           # 네이티브 Gemini 백엔드 사용
    api_key: "${CONTINUUM_GEMINI_API_KEY}" # 환경 변수에서 로드
    weight: 2
    models:
      - gemini-2.5-pro
      - gemini-2.5-flash
      - gemini-2.0-flash

# 헬스 모니터링 설정
health_checks:
  enabled: true                          # 헬스 체크 활성화/비활성화
  interval: "30s"                        # 백엔드 상태 확인 주기
  timeout: "10s"                         # 헬스 체크 요청 타임아웃
  unhealthy_threshold: 3                 # 비정상으로 표시되기 전 실패 횟수
  healthy_threshold: 2                   # 정상으로 표시되기 전 성공 횟수
  endpoint: "/v1/models"                 # 헬스 체크에 사용되는 엔드포인트

# 요청 처리 및 타임아웃 설정
timeouts:
  connection: "10s"                      # TCP 연결 설정 타임아웃
  request:
    standard:                            # 비스트리밍 요청
      first_byte: "30s"                  # 첫 바이트 수신까지의 시간
      total: "180s"                      # 전체 요청 타임아웃 (3분)
    streaming:                           # 스트리밍 (SSE) 요청
      first_byte: "60s"                  # 첫 SSE 청크까지의 시간
      chunk_interval: "30s"              # 청크 간 최대 시간
      total: "600s"                      # 전체 스트리밍 타임아웃 (10분)
    image_generation:                    # 이미지 생성 요청 (DALL-E 등)
      first_byte: "60s"                  # 첫 바이트 수신까지의 시간
      total: "180s"                      # 전체 타임아웃 (기본 3분)
    model_overrides:                     # 모델별 타임아웃 오버라이드
      gpt-5-latest:
        streaming:
          total: "1200s"                 # GPT-5용 20분
      gpt-4o:
        streaming:
          total: "900s"                  # GPT-4o용 15분
  health_check:
    timeout: "5s"                        # 헬스 체크 타임아웃
    interval: "30s"                      # 헬스 체크 간격

request:
  max_retries: 3                         # 요청 최대 재시도 횟수
  retry_delay: "1s"                      # 재시도 간 초기 지연

# 전역 재시도 및 복원력 설정
retry:
  max_attempts: 3                        # 최대 재시도 횟수
  base_delay: "100ms"                    # 재시도 간 기본 지연
  max_delay: "30s"                       # 재시도 간 최대 지연
  exponential_backoff: true              # 지수 백오프 사용
  jitter: true                           # 지연에 무작위 지터 추가

# 캐싱 및 최적화 설정
cache:
  model_cache_ttl: "300s"               # 모델 목록 캐시 5분
  deduplication_ttl: "60s"              # 요청 중복 제거 1분
  enable_deduplication: true            # 요청 중복 제거 활성화

# 로깅 설정
logging:
  level: "info"                         # 로그 레벨: trace, debug, info, warn, error
  format: "json"                        # 로그 형식: json, pretty
  enable_colors: false                  # 컬러 출력 활성화 (pretty 형식용)

# Files API 설정
files:
  enabled: true                         # Files API 엔드포인트 활성화/비활성화
  max_file_size: 536870912              # 최대 파일 크기 (바이트, 기본: 512MB)
  storage_path: "./data/files"          # 업로드된 파일 저장 경로 (~지원)
  retention_days: 0                     # 파일 보존 기간 (일, 0 = 영구 보존)
  metadata_storage: persistent          # 메타데이터 백엔드: "memory" 또는 "persistent" (기본)
  cleanup_orphans_on_startup: false     # 시작 시 고아 파일 자동 정리

  # 인증 및 권한
  auth:
    method: api_key                     # "none" 또는 "api_key" (기본)
    required_scope: files               # 접근에 필요한 API 키 스코프
    enforce_ownership: true             # 사용자가 자신의 파일만 접근 가능
    admin_can_access_all: true          # admin 스코프는 모든 파일 접근 가능

# 로드 밸런싱 설정
load_balancer:
  strategy: "round_robin"               # 전략: round_robin, weighted, random
  health_aware: true                    # 정상 백엔드로만 라우팅

# 분산 추적 설정
tracing:
  enabled: true                         # 분산 추적 활성화/비활성화
  w3c_trace_context: true               # W3C Trace Context 지원 (traceparent 헤더)
  headers:
    trace_id: "X-Trace-ID"              # 추적 ID 헤더 이름
    request_id: "X-Request-ID"          # 요청 ID 헤더 이름
    correlation_id: "X-Correlation-ID"  # 상관 ID 헤더 이름

# 서킷 브레이커 설정
circuit_breaker:
  enabled: false                        # 서킷 브레이커 활성화
  failure_threshold: 5                  # 회로 개방까지의 실패 횟수
  recovery_timeout: "60s"               # 복구 시도까지의 시간
  half_open_retries: 3                  # 반개방 상태에서의 재시도 횟수

# 속도 제한 설정
rate_limiting:
  enabled: false                        # 속도 제한 활성화
  requests_per_second: 100              # 전역 초당 요청 수
  burst_size: 200                       # 버스트 용량

# 메트릭 및 모니터링 설정
metrics:
  enabled: false                        # 메트릭 수집 활성화
  endpoint: "/metrics"                  # 메트릭 엔드포인트 경로
  include_labels: true                  # 상세 레이블 포함

최소 설정

# 최소 설정 - 나머지 설정은 기본값 사용
server:
  bind_address: "0.0.0.0:8080"

backends:
  - name: "ollama"
    url: "http://localhost:11434"
  - name: "lm-studio"
    url: "http://localhost:1234"

환경 변수

모든 설정 옵션은 CONTINUUM_ 접두사가 붙은 환경 변수로 오버라이드할 수 있습니다:

서버 설정

변수 타입 기본값 설명
CONTINUUM_BIND_ADDRESS string "0.0.0.0:8080" 서버 바인드 주소
CONTINUUM_WORKERS integer 4 워커 스레드 수
CONTINUUM_CONNECTION_POOL_SIZE integer 100 HTTP 연결 풀 크기

백엔드 설정

변수 타입 기본값 설명
CONTINUUM_BACKEND_URLS string 쉼표로 구분된 백엔드 URL
CONTINUUM_BACKEND_WEIGHTS string 쉼표로 구분된 가중치 (URL과 일치해야 함)

헬스 체크 설정

변수 타입 기본값 설명
CONTINUUM_HEALTH_CHECKS_ENABLED boolean true 헬스 체크 활성화
CONTINUUM_HEALTH_CHECK_INTERVAL string "30s" 헬스 체크 간격
CONTINUUM_HEALTH_CHECK_TIMEOUT string "10s" 헬스 체크 타임아웃
CONTINUUM_UNHEALTHY_THRESHOLD integer 3 비정상 판정까지의 실패 횟수
CONTINUUM_HEALTHY_THRESHOLD integer 2 정상 판정까지의 성공 횟수

요청 설정

변수 타입 기본값 설명
CONTINUUM_REQUEST_TIMEOUT string "300s" 최대 요청 타임아웃
CONTINUUM_MAX_RETRIES integer 3 최대 재시도 횟수
CONTINUUM_RETRY_DELAY string "1s" 초기 재시도 지연

로깅 설정

변수 타입 기본값 설명
CONTINUUM_LOG_LEVEL string "info" 로그 레벨
CONTINUUM_LOG_FORMAT string "json" 로그 형식
CONTINUUM_LOG_COLORS boolean false 컬러 출력 활성화
RUST_LOG string Rust 전용 로깅 설정

캐시 설정

변수 타입 기본값 설명
CONTINUUM_MODEL_CACHE_TTL string "300s" 모델 캐시 TTL
CONTINUUM_DEDUPLICATION_TTL string "60s" 중복 제거 TTL
CONTINUUM_ENABLE_DEDUPLICATION boolean true 중복 제거 활성화

Files API 설정

변수 타입 기본값 설명
CONTINUUM_FILES_ENABLED boolean true Files API 활성화/비활성화
CONTINUUM_FILES_MAX_SIZE integer 536870912 최대 파일 크기 (바이트, 512MB)
CONTINUUM_FILES_STORAGE_PATH string "./data/files" 업로드 파일 저장 경로
CONTINUUM_FILES_RETENTION_DAYS integer 0 파일 보존 기간 (일, 0 = 영구)
CONTINUUM_FILES_METADATA_STORAGE string "persistent" 메타데이터 백엔드: "memory" 또는 "persistent"
CONTINUUM_FILES_CLEANUP_ORPHANS boolean false 시작 시 고아 파일 자동 정리
CONTINUUM_FILES_AUTH_METHOD string "api_key" 인증 방법: "none" 또는 "api_key"
CONTINUUM_FILES_AUTH_SCOPE string "files" Files API 접근에 필요한 API 키 스코프
CONTINUUM_FILES_ENFORCE_OWNERSHIP boolean true 사용자가 자신의 파일만 접근 가능
CONTINUUM_FILES_ADMIN_ACCESS_ALL boolean true admin 스코프는 모든 파일 접근 가능
CONTINUUM_DEV_MODE boolean false 개발용 API 키 활성화 (프로덕션에서 사용 금지)

API 키 관리 설정

변수 타입 기본값 설명
CONTINUUM_API_KEY string - 간단한 배포용 단일 API 키
CONTINUUM_API_KEY_SCOPES string "read,write" API 키의 쉼표로 구분된 스코프
CONTINUUM_API_KEY_USER_ID string "admin" API 키와 연결된 사용자 ID
CONTINUUM_API_KEY_ORG_ID string "default" API 키와 연결된 조직 ID
CONTINUUM_DEV_MODE boolean false 개발용 API 키 활성화 (프로덕션에서 사용 금지)

환경 설정 예제

# 기본 설정
export CONTINUUM_BIND_ADDRESS="0.0.0.0:9000"
export CONTINUUM_BACKEND_URLS="http://localhost:11434,http://localhost:1234"
export CONTINUUM_LOG_LEVEL="debug"

# 고급 설정
export CONTINUUM_CONNECTION_POOL_SIZE="200"
export CONTINUUM_HEALTH_CHECK_INTERVAL="60s"
export CONTINUUM_MODEL_CACHE_TTL="600s"
export CONTINUUM_ENABLE_DEDUPLICATION="true"

# 라우터 시작
continuum-router

명령줄 인수

명령줄 인수는 최고 우선순위의 설정 방법으로 테스트와 임시 오버라이드에 유용합니다.

핵심 옵션

continuum-router --help
인수 타입 설명
-c, --config <FILE> path 설정 파일 경로
--generate-config flag 샘플 설정을 생성하고 종료

백엔드 설정

인수 타입 설명
--backends <URLs> string 쉼표로 구분된 백엔드 URL
--backend-url <URL> string 단일 백엔드 URL (지원 중단)

서버 설정

인수 타입 설명
--bind <ADDRESS> string 서버 바인드 주소
--connection-pool-size <SIZE> integer HTTP 연결 풀 크기

헬스 체크 설정

인수 타입 설명
--disable-health-checks flag 헬스 모니터링 비활성화
--health-check-interval <SECONDS> integer 헬스 체크 간격
--health-check-timeout <SECONDS> integer 헬스 체크 타임아웃
--unhealthy-threshold <COUNT> integer 비정상 판정까지의 실패 횟수
--healthy-threshold <COUNT> integer 정상 판정까지의 성공 횟수

CLI 사용 예제

# 설정 파일과 오버라이드 사용
continuum-router --config config.yaml --bind "0.0.0.0:9000"

# 백엔드 임시 오버라이드
continuum-router --config config.yaml --backends "http://localhost:11434"

# 테스트용 헬스 체크 설정 조정
continuum-router --config config.yaml --health-check-interval 10

# 샘플 설정 생성
continuum-router --generate-config > my-config.yaml

설정 섹션

서버 섹션

HTTP 서버 동작을 제어합니다:

server:
  bind_address: "0.0.0.0:8080"    # 바인드할 호스트와 포트
  workers: 4                       # 워커 스레드 (0 = 자동)
  connection_pool_size: 100        # HTTP 연결 풀 크기

다중 바인드 주소 및 Unix 소켓

서버는 Unix 도메인 소켓(Unix 계열 시스템)을 포함하여 여러 주소에 동시에 바인딩하는 것을 지원합니다. 이를 통해 다음과 같은 유연한 배포 시나리오가 가능합니다:

  • IPv4와 IPv6 주소 모두에서 수신
  • 외부 클라이언트용 TCP 포트 노출과 로컬 서비스용 Unix 소켓 동시 사용
  • 보안 강화를 위한 Unix 소켓을 통한 리버스 프록시 운영

단일 주소 (하위 호환):

server:
  bind_address: "0.0.0.0:8080"

다중 주소:

server:
  bind_address:
    - "127.0.0.1:8080"           # IPv4 localhost
    - "[::1]:8080"               # IPv6 localhost
    - "0.0.0.0:9090"             # 포트 9090의 모든 인터페이스

Unix 소켓 바인딩 (Unix/Linux/macOS만 해당):

server:
  bind_address:
    - "0.0.0.0:8080"             # 외부 액세스용 TCP
    - "unix:/var/run/continuum-router.sock"  # 로컬 서비스용 Unix 소켓
  socket_mode: 0o660              # 선택 사항: Unix 소켓의 파일 권한 (8진수)

설정 옵션:

옵션 타입 기본값 설명
bind_address 문자열 또는 배열 "0.0.0.0:8080" 바인드할 주소. TCP 형식: host:port. Unix 소켓 형식: unix:/path/to/socket
socket_mode 정수 (8진수) null Unix 소켓의 파일 권한 (예: 0o660은 소유자/그룹 읽기-쓰기)

Unix 소켓 참고사항:

  • Unix 소켓 주소는 unix: 접두사로 시작해야 합니다
  • 기존 소켓 파일은 바인딩 전에 자동으로 삭제됩니다
  • 소켓 파일은 정상적인 종료 시 정리됩니다
  • Unix가 아닌 플랫폼에서는 unix: 주소가 경고를 기록하고 건너뜁니다
  • Unix 소켓 연결은 IP 기반 인증 검사를 우회합니다 (클라이언트 IP는 "unix"로 보고됨)

Nginx 리버스 프록시 예제:

upstream continuum {
    server unix:/var/run/continuum-router.sock;
}

server {
    listen 443 ssl;
    location /v1/ {
        proxy_pass http://continuum;
    }
}

성능 튜닝:

  • workers: 자동 감지를 위해 0으로 설정하거나 CPU 코어 수와 일치
  • connection_pool_size: 고부하 시나리오에서는 증가 (200-500)

CORS 설정

CORS (Cross-Origin Resource Sharing)는 라우터가 다른 출처에서 실행되는 웹 브라우저의 요청을 수락할 수 있게 합니다. 다음 환경에 continuum-router를 임베딩할 때 필수적입니다:

  • Tauri 앱: tauri://localhost와 같은 출처를 사용하는 WebView
  • Electron 앱: 사용자 정의 프로토콜
  • 별도의 웹 프론트엔드: 다른 포트의 개발 서버
server:
  bind_address: "0.0.0.0:8080"
  cors:
    enabled: true
    allow_origins:
      - "tauri://localhost"
      - "http://localhost:*"        # 와일드카드 포트 매칭
      - "https://example.com"
    allow_methods:
      - "GET"
      - "POST"
      - "PUT"
      - "DELETE"
      - "OPTIONS"
      - "PATCH"
    allow_headers:
      - "Content-Type"
      - "Authorization"
      - "X-Request-ID"
      - "X-Trace-ID"
    expose_headers:
      - "X-Request-ID"
      - "X-Fallback-Used"
    allow_credentials: false
    max_age: 3600                   # 프리플라이트 캐시 기간 (초)

CORS 설정 옵션:

옵션 유형 기본값 설명
enabled boolean false CORS 미들웨어 활성화/비활성화
allow_origins array [] 허용된 출처 (*로 모든 출처 허용, http://localhost:*와 같은 포트 와일드카드 지원)
allow_methods array ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"] 허용된 HTTP 메서드
allow_headers array ["Content-Type", "Authorization", "X-Request-ID", "X-Trace-ID"] 허용된 요청 헤더
expose_headers array [] 클라이언트 JavaScript에 노출되는 헤더
allow_credentials boolean false 쿠키와 인증 헤더 허용
max_age integer 3600 프리플라이트 응답 캐시 기간 (초)

출처 패턴 매칭:

패턴 예시 설명
* * 모든 출처 매칭 (allow_credentials: true와 호환되지 않음)
정확한 URL https://example.com 정확히 일치
사용자 정의 스킴 tauri://localhost 사용자 정의 프로토콜 (Tauri, Electron)
포트 와일드카드 http://localhost:* localhost의 모든 포트 매칭

보안 고려사항:

  • 출처에 *를 사용하면 모든 웹사이트에서 요청할 수 있습니다 - 공개 API에만 사용하세요
  • allow_credentialstrue일 때 출처에 *를 사용할 수 없습니다 - 정확한 출처를 지정하세요
  • 개발 시에는 유연성을 위해 http://localhost:*와 같은 포트 와일드카드를 사용하세요
  • 프로덕션에서는 보안을 위해 항상 정확한 출처를 지정하세요

핫 리로드: CORS 설정은 즉시 핫 리로드를 지원합니다 - 서버 재시작 없이 새 요청에 변경 사항이 즉시 적용됩니다.

백엔드 섹션

요청을 라우팅할 LLM 백엔드를 정의합니다:

backends:
  - name: "unique-identifier"        # 모든 백엔드에서 고유해야 함
    type: "generic"                  # 백엔드 유형 (선택 사항, 기본값 "generic")
    url: "http://backend:port"       # 백엔드 기본 URL
    weight: 1                        # 로드 밸런싱 가중치 (1-100)
    api_key: "${API_KEY}"            # API 키 (선택 사항, 환경 변수 참조 지원)
    org_id: "${ORG_ID}"              # 조직 ID (선택 사항, OpenAI용)
    models: ["model1", "model2"]     # 선택 사항: 명시적 모델 목록
    retry_override:                  # 선택 사항: 백엔드별 재시도 설정
      max_attempts: 5
      base_delay: "200ms"

백엔드 없이 시작하기

라우터는 빈 백엔드 목록(backends: [])으로 시작할 수 있으며, 다음과 같은 경우에 유용합니다:

  • 인프라 부트스트래핑: 라우터를 먼저 시작한 다음 Admin API를 통해 동적으로 백엔드 추가
  • 컨테이너 오케스트레이션: 백엔드 서비스보다 라우터 컨테이너가 먼저 준비될 수 있음
  • 개발 워크플로우: 백엔드가 프로비저닝되기 전에 관리자 엔드포인트 테스트
  • 점진적 롤아웃: 백엔드 없이 시작하여 점진적으로 추가

백엔드 없이 실행할 때:

  • /v1/models{"object": "list", "data": []}를 반환
  • /v1/chat/completions 및 기타 라우팅 엔드포인트는 503 "No backends available" 반환
  • /health는 정상 상태 반환 (라우터 자체는 작동 중)
  • POST /admin/backends를 통해 백엔드 추가 가능

동적 백엔드 관리를 위한 최소 구성 예제:

server:
  bind_address: "0.0.0.0:8080"

backends: []  # 백엔드 없이 시작 - 나중에 Admin API로 추가

admin:
  auth:
    method: bearer
    token: "${ADMIN_TOKEN}"

지원되는 백엔드 유형:

유형 설명 기본 URL
generic OpenAI 호환 API (기본) 지정 필수
openai 내장 설정이 있는 네이티브 OpenAI API https://api.openai.com/v1
gemini Google Gemini API (OpenAI 호환 엔드포인트) https://generativelanguage.googleapis.com/v1beta/openai
azure Azure OpenAI Service 지정 필수
vllm vLLM 서버 지정 필수
ollama Ollama 로컬 서버 http://localhost:11434
llamacpp llama.cpp llama-server (GGUF 모델) http://localhost:8080
anthropic Anthropic Claude API (요청/응답 변환 포함 네이티브) https://api.anthropic.com

네이티브 OpenAI 백엔드

type: openai를 사용하면 라우터는 다음을 제공합니다:

  • 기본 URL: https://api.openai.com/v1 (프록시용으로 오버라이드 가능)
  • 내장 모델 메타데이터: 자동 가격, 컨텍스트 윈도우, 기능
  • 환경 변수 지원: CONTINUUM_OPENAI_API_KEYCONTINUUM_OPENAI_ORG_ID에서 자동 로드

최소 OpenAI 설정:

backends:
  - name: "openai"
    type: openai
    models:
      - gpt-4o
      - gpt-4o-mini
      - o3-mini

명시적 API 키가 있는 전체 OpenAI 설정:

backends:
  - name: "openai-primary"
    type: openai
    api_key: "${CONTINUUM_OPENAI_API_KEY}"
    org_id: "${CONTINUUM_OPENAI_ORG_ID}"     # 선택 사항
    models:
      - gpt-4o
      - gpt-4o-mini
      - o1
      - o1-mini
      - o3-mini
      - text-embedding-3-large

프록시와 함께 OpenAI 사용:

backends:
  - name: "openai-proxy"
    type: openai
    url: "https://my-proxy.example.com/v1"   # 기본 URL 오버라이드
    api_key: "${PROXY_API_KEY}"
    models:
      - gpt-4o

OpenAI 환경 변수

변수 설명
CONTINUUM_OPENAI_API_KEY OpenAI API 키 (type: openai 백엔드용으로 자동 로드)
CONTINUUM_OPENAI_ORG_ID OpenAI 조직 ID (선택 사항)

모델 자동 검색:

models가 지정되지 않았거나 비어 있으면, 백엔드는 초기화 중에 /v1/models API 엔드포인트에서 사용 가능한 모델을 자동으로 검색합니다. 이 기능은 설정 유지보수를 줄이고 백엔드에서 보고된 모든 모델이 라우팅 가능하도록 보장합니다.

백엔드 유형 자동 검색 지원 폴백 모델
openai ✅ 예 gpt-4o, gpt-4o-mini, o3-mini
gemini ✅ 예 gemini-2.5-pro, gemini-2.5-flash, gemini-2.0-flash
vllm ✅ 예 vicuna-7b-v1.5, llama-2-7b-chat, mistral-7b-instruct
ollama ✅ 예 vLLM 검색 메커니즘 사용
llamacpp ✅ 예 /v1/models 엔드포인트에서 자동 검색
anthropic ❌ 아니오 (API 없음) 하드코딩된 Claude 모델
generic ❌ 아니오 모든 모델 지원 (supports_model()true 반환)

검색 동작:

  • 타임아웃: 10초 타임아웃으로 시작 차단 방지
  • 폴백: 검색 실패 시 (타임아웃, 네트워크 오류, 잘못된 응답) 폴백 모델 사용
  • 로깅: 검색된 모델은 INFO 레벨로 로깅; 폴백 사용은 WARN 레벨로 로깅

모델 해석 우선순위:

  1. 설정의 명시적 models 목록 (최고 우선순위)
  2. model_configs 필드의 모델
  3. 백엔드 API에서 자동 검색된 모델
  4. 하드코딩된 폴백 모델 (최저 우선순위)

  5. 명시적 모델 목록은 시작 시간을 개선하고 백엔드 쿼리를 줄입니다

네이티브 Gemini 백엔드

type: gemini를 사용하면 라우터는 다음을 제공합니다:

  • 기본 URL: https://generativelanguage.googleapis.com/v1beta/openai (OpenAI 호환 엔드포인트)
  • 내장 모델 메타데이터: Gemini 모델에 대한 자동 컨텍스트 윈도우 및 기능
  • 환경 변수 지원: CONTINUUM_GEMINI_API_KEY에서 자동 로드
  • 확장 스트리밍 타임아웃: 사고 모델용 300초 타임아웃 (gemini-2.5-pro, gemini-3-pro)
  • 자동 max_tokens 조정: 사고 모델용, 아래 참조

최소 Gemini 설정:

backends:
  - name: "gemini"
    type: gemini
    models:
      - gemini-2.5-pro
      - gemini-2.5-flash
      - gemini-2.0-flash

API 키를 사용한 전체 Gemini 설정:

backends:
  - name: "gemini"
    type: gemini
    api_key: "${CONTINUUM_GEMINI_API_KEY}"
    weight: 2
    models:
      - gemini-2.5-pro
      - gemini-2.5-flash
      - gemini-2.0-flash

Gemini 인증 방법

Gemini 백엔드는 두 가지 인증 방법을 지원합니다:

API 키 인증 (기본)

Google AI Studio API 키를 사용하는 가장 간단한 인증 방법:

backends:
  - name: "gemini"
    type: gemini
    api_key: "${CONTINUUM_GEMINI_API_KEY}"
    models:
      - gemini-2.5-pro
서비스 계정 인증

엔터프라이즈 환경 및 Google Cloud Platform (GCP) 배포의 경우, 자동 OAuth2 토큰 관리와 함께 서비스 계정 인증을 사용할 수 있습니다:

backends:
  - name: "gemini"
    type: gemini
    auth:
      type: service_account
      key_file: "/path/to/service-account.json"
    models:
      - gemini-2.5-pro
      - gemini-2.5-flash

키 파일 경로에 환경 변수 사용:

backends:
  - name: "gemini"
    type: gemini
    auth:
      type: service_account
      key_file: "${GOOGLE_APPLICATION_CREDENTIALS}"
    models:
      - gemini-2.5-pro

서비스 계정 인증 기능:

기능 설명
자동 토큰 갱신 OAuth2 토큰이 만료 5분 전에 자동으로 갱신됩니다
토큰 캐싱 인증 오버헤드를 최소화하기 위해 토큰이 메모리에 캐시됩니다
스레드 안전 동시 요청이 토큰 갱신 작업을 안전하게 공유합니다
환경 변수 확장 키 파일 경로가 ${VAR}~ 확장을 지원합니다

서비스 계정 키 생성:

  1. Google Cloud Console로 이동
  2. IAM & Admin > Service Accounts로 이동
  3. 새 서비스 계정을 만들거나 기존 계정 선택
  4. Keys > Add Key > Create new key 클릭
  5. JSON 형식을 선택하고 키 파일 다운로드
  6. 키 파일을 안전하게 저장하고 설정에서 참조

필요한 권한:

Gemini API 접근을 위해 서비스 계정에 다음 역할이 필요합니다:

  • roles/aiplatform.user - Vertex AI Gemini 엔드포인트용
  • 또는 generativelanguage.googleapis.com용 적절한 Google AI Studio 권한
인증 우선순위

여러 인증 방법이 설정된 경우:

우선순위 방법 조건
1 (최고) auth 블록 auth.type이 지정된 경우
2 api_key 필드 auth 블록이 없는 경우
3 환경 변수 CONTINUUM_GEMINI_API_KEY로 폴백

api_keyauth가 모두 지정된 경우, auth 블록이 우선되며 경고가 기록됩니다.

Gemini 사고 모델: 자동 max_tokens 조정

Gemini "사고" 모델 (gemini-2.5-pro, gemini-3-pro, -pro-preview 접미사가 있는 모델)은 응답 생성 전에 확장된 추론을 수행합니다. 응답 잘림을 방지하기 위해 라우터가 자동으로 max_tokens를 조정합니다:

조건 동작
max_tokens 미지정 자동으로 16384로 설정
max_tokens < 4096 자동으로 16384로 증가
max_tokens >= 4096 클라이언트 값 유지

이렇게 하면 클라이언트 라이브러리의 낮은 기본값으로 인한 잘림 없이 사고 모델이 완전한 응답을 생성할 수 있습니다.

Gemini 환경 변수

변수 설명
CONTINUUM_GEMINI_API_KEY Google Gemini API 키 (type: gemini 백엔드용으로 자동 로드)
GOOGLE_APPLICATION_CREDENTIALS 서비스 계정 JSON 키 파일 경로 (표준 GCP 환경 변수)

네이티브 Anthropic 백엔드

type: anthropic을 사용하면 라우터는 다음을 제공합니다:

  • 기본 URL: https://api.anthropic.com (프록시용으로 오버라이드 가능)
  • 네이티브 API 변환: OpenAI 형식 요청을 Anthropic Messages API 형식으로 자동 변환 및 역변환
  • Anthropic 전용 헤더: x-api-keyanthropic-version 헤더 자동 추가
  • 환경 변수 지원: CONTINUUM_ANTHROPIC_API_KEY에서 자동 로드
  • 확장 스트리밍 타임아웃: 확장 사고 모델용 600초 타임아웃 (Claude Opus, Sonnet 4)

최소 Anthropic 설정:

backends:
  - name: "anthropic"
    type: anthropic
    models:
      - claude-sonnet-4-20250514
      - claude-haiku-3-5-20241022

전체 Anthropic 설정:

backends:
  - name: "anthropic"
    type: anthropic
    api_key: "${CONTINUUM_ANTHROPIC_API_KEY}"
    weight: 2
    models:
      - claude-opus-4-5-20250514
      - claude-sonnet-4-20250514
      - claude-haiku-3-5-20241022

Anthropic API 변환

라우터는 OpenAI와 Anthropic API 형식 간의 변환을 자동으로 처리합니다:

OpenAI 형식 Anthropic 형식
role: "system"이 있는 messages 배열 별도의 system 매개변수
Authorization: Bearer <key> x-api-key: <key> 헤더
선택적 max_tokens 필수 max_tokens (누락 시 자동 채움)
choices[0].message.content content[0].text
finish_reason: "stop" stop_reason: "end_turn"
usage.prompt_tokens usage.input_tokens

요청 변환 예제:

OpenAI 형식 (클라이언트에서 들어오는):

{
  "model": "claude-sonnet-4-20250514",
  "messages": [
    {"role": "system", "content": "당신은 도움이 됩니다."},
    {"role": "user", "content": "안녕하세요"}
  ],
  "max_tokens": 1024
}

Anthropic 형식 (API로 전송되는):

{
  "model": "claude-sonnet-4-20250514",
  "system": "당신은 도움이 됩니다.",
  "messages": [
    {"role": "user", "content": "안녕하세요"}
  ],
  "max_tokens": 1024
}

Anthropic 네이티브 API 엔드포인트

OpenAI 형식 요청을 Anthropic 백엔드로 라우팅하는 것 외에도, 라우터는 네이티브 Anthropic API 엔드포인트도 제공합니다:

엔드포인트 설명
POST /anthropic/v1/messages 네이티브 Anthropic Messages API
POST /anthropic/v1/messages/count_tokens 계층적 백엔드 지원을 통한 토큰 카운팅
GET /anthropic/v1/models Anthropic 형식의 모델 목록

이 엔드포인트를 통해 Anthropic의 네이티브 API 형식을 사용하는 클라이언트(예: Claude Code)가 요청/응답 변환 오버헤드 없이 직접 연결할 수 있습니다.

Claude Code 호환성

Anthropic 네이티브 API 엔드포인트는 Claude Code 및 기타 고급 Anthropic API 클라이언트와의 완전한 호환성을 포함합니다:

프롬프트 캐싱 지원:

라우터는 요청/응답 파이프라인 전체에서 cache_control 필드를 유지합니다:

  • 시스템 프롬프트 텍스트 블록
  • 사용자 메시지 콘텐츠 블록 (텍스트, 이미지, 문서)
  • 도구 정의
  • 도구 사용 및 도구 결과 블록

헤더 전달:

헤더 동작
anthropic-version 네이티브 Anthropic 백엔드로 전달됨
anthropic-beta 베타 기능 활성화를 위해 전달됨 (예: prompt-caching-2024-07-31, interleaved-thinking-2025-05-14)
x-request-id 요청 추적을 위해 전달됨

캐시 사용량 보고:

네이티브 Anthropic 백엔드의 스트리밍 응답에는 캐시 사용량 정보가 포함됩니다:

{
  "usage": {
    "input_tokens": 2159,
    "cache_creation_input_tokens": 2048,
    "cache_read_input_tokens": 0
  }
}

Anthropic 확장 사고 모델

확장 사고를 지원하는 모델 (Claude Opus, Sonnet 4)은 더 긴 응답 시간이 필요할 수 있습니다. 라우터는 자동으로: - 사고 모델에 대해 더 높은 기본 max_tokens (16384) 설정 - 이 모델에 대해 확장 스트리밍 타임아웃 (600초) 사용

OpenAI ↔ Claude 추론 매개변수 변환

라우터는 OpenAI의 추론 매개변수와 Claude의 thinking 매개변수 간을 자동으로 변환하여 원활한 크로스 프로바이더 추론 요청을 가능하게 합니다.

지원되는 OpenAI 형식:

형식 API 예제
reasoning_effort (플랫) Chat Completions API "reasoning_effort": "high"
reasoning.effort (중첩) Responses API "reasoning": {"effort": "high"}

두 형식이 모두 있으면 reasoning_effort (플랫)가 우선합니다.

Effort 레벨에서 Budget 토큰 매핑:

Effort 레벨 Claude thinking.budget_tokens
none (사고 비활성화)
minimal 1,024
low 4,096
medium 10,240
high 32,768

요청 예제 - Chat Completions API (플랫 형식):

// 클라이언트가 OpenAI Chat Completions API 요청을 보냄
{
  "model": "claude-sonnet-4-5-20250929",
  "reasoning_effort": "high",
  "messages": [{"role": "user", "content": "이 복잡한 문제를 풀어주세요"}]
}

// 라우터가 Claude 형식으로 변환
{
  "model": "claude-sonnet-4-5-20250929",
  "thinking": {"type": "enabled", "budget_tokens": 32768},
  "messages": [{"role": "user", "content": "이 복잡한 문제를 풀어주세요"}]
}

요청 예제 - Responses API (중첩 형식):

// 클라이언트가 OpenAI Responses API 요청을 보냄
{
  "model": "claude-sonnet-4-5-20250929",
  "reasoning": {"effort": "medium"},
  "messages": [{"role": "user", "content": "이 데이터를 분석해주세요"}]
}

// 라우터가 Claude 형식으로 변환
{
  "model": "claude-sonnet-4-5-20250929",
  "thinking": {"type": "enabled", "budget_tokens": 10240},
  "messages": [{"role": "user", "content": "이 데이터를 분석해주세요"}]
}

추론 콘텐츠가 있는 응답:

{
  "choices": [{
    "message": {
      "role": "assistant",
      "content": "최종 답변은...",
      "reasoning_content": "단계별로 분석해 보겠습니다..."
    }
  }]
}

중요 사항: - thinking 매개변수가 명시적으로 제공되면 reasoning_effortreasoning.effort보다 우선합니다 - reasoning_effort (플랫)가 두 형식이 모두 있을 때 reasoning.effort (중첩)보다 우선합니다 - 확장 사고를 지원하는 모델 (Opus 4.x, Sonnet 4.x)만 추론이 활성화됩니다 - 추론이 활성화되면 temperature 매개변수가 자동으로 제거됩니다 (Claude API 요구 사항) - 스트리밍 응답의 경우 사고 콘텐츠가 reasoning_content delta 이벤트로 반환됩니다

Anthropic 환경 변수

변수 설명
CONTINUUM_ANTHROPIC_API_KEY Anthropic API 키 (type: anthropic 백엔드용으로 자동 로드)

네이티브 llama.cpp 백엔드

type: llamacpp를 사용하면 라우터는 llama.cpp llama-server에 대한 네이티브 지원을 제공합니다:

  • 기본 URL: http://localhost:8080 (llama-server 기본 포트)
  • 헬스 체크: /health 엔드포인트 사용 (/v1/models로 폴백)
  • 모델 검색: llama-server의 하이브리드 /v1/models 응답 형식 파싱
  • 풍부한 메타데이터: 응답에서 컨텍스트 윈도우, 파라미터 수, 모델 크기 추출

최소 llama.cpp 설정:

backends:
  - name: "local-llama"
    type: llamacpp
    # 기본 http://localhost:8080 사용 시 URL 불필요
    # 로컬 서버에는 API 키 불필요

전체 llama.cpp 설정:

backends:
  - name: "local-llama"
    type: llamacpp
    url: "http://192.168.1.100:8080"  # 필요시 커스텀 URL
    weight: 2
    # 모델은 /v1/models 엔드포인트에서 자동 검색

llama.cpp 기능

기능 설명
GGUF 모델 GGUF 양자화 모델 네이티브 지원
로컬 추론 클라우드 API 의존성 없음
하드웨어 지원 CPU, NVIDIA, AMD, Apple Silicon
스트리밍 완전한 SSE 스트리밍 지원
임베딩 /v1/embeddings 엔드포인트 지원
도구 호출 감지 /props 엔드포인트를 통한 도구 호출 지원 자동 감지

도구 호출 자동 감지

라우터는 모델 검색 중 /props 엔드포인트를 쿼리하여 llama.cpp 백엔드의 도구 호출 기능을 자동으로 감지합니다. 이를 통해 수동 설정 없이 자동으로 함수 호출 지원이 가능해집니다.

작동 방식:

  1. llama.cpp 백엔드가 검색되면 라우터가 /props 엔드포인트를 조회합니다
  2. chat_template 필드를 정밀한 Jinja2 패턴 매칭으로 분석하여 도구 관련 구문을 감지합니다
  3. 도구 호출 패턴이 감지되면 모델의 function_calling 기능이 자동으로 활성화됩니다
  4. 감지 결과가 참조용으로 저장됩니다 (채팅 템플릿의 해시 포함)

감지 패턴:

라우터는 오탐을 줄이기 위해 정밀한 패턴 매칭을 사용합니다:

  • 역할 기반 패턴: message['role'] == 'tool', message.role == "tool"
  • 도구 반복: for tool in tools, for function in functions
  • 도구 호출 접근: .tool_calls, ['tool_calls'], message.tool_call
  • 도구 키워드가 포함된 Jinja2 블록: {% if tools %}, {% for tool_call in ... %}

분석되는 /props 응답 예제:

{
  "chat_template": "{% for message in messages %}{% if message['role'] == 'tool' %}...",
  "default_generation_settings": { ... },
  "total_slots": 1
}

폴백 동작:

  • /props를 사용할 수 없는 경우: 도구 호출이 지원되는 것으로 가정 (최신 llama.cpp 버전에 대한 낙관적 폴백)
  • /props가 오류를 반환하는 경우: 도구 호출이 지원되는 것으로 가정 (새로운 모델과의 호환성 보장)
  • 채팅 템플릿이 64KB를 초과하는 경우: 감지가 건너뛰어지고 지원되는 것으로 기본 설정
  • 최대 호환성을 위해 대소문자 구분 없음
  • 결과는 model-metadata.yaml의 기존 모델 메타데이터와 병합됩니다
  • 감지된 기능은 /v1/models/{model_id} 응답의 features 필드에 나타납니다

모델 메타데이터 추출

라우터는 llama-server 응답에서 풍부한 메타데이터를 추출합니다:

필드 소스 설명
컨텍스트 윈도우 meta.n_ctx_train 학습 컨텍스트 윈도우 크기
파라미터 수 meta.n_params 모델 파라미터 (예: "4B")
모델 크기 meta.size 파일 크기 (바이트)
기능 models[].capabilities 모델 기능 배열

llama-server 시작하기

# 기본 시작
./llama-server -m model.gguf --port 8080

# GPU 레이어 사용
./llama-server -m model.gguf --port 8080 -ngl 35

# 커스텀 컨텍스트 크기 사용
./llama-server -m model.gguf --port 8080 --ctx-size 8192

llama.cpp 백엔드 자동 감지

타입이 지정되지 않은 백엔드가 추가되면 (기본값 generic), 라우터는 자동으로 /v1/models 엔드포인트를 탐색하여 백엔드 타입을 감지합니다. llama.cpp 백엔드는 다음으로 식별됩니다:

  1. 응답의 owned_by: "llamacpp"
  2. llama.cpp 전용 메타데이터 필드 존재 (n_ctx_train, n_params, vocab_type)
  3. models[]data[] 배열이 모두 있는 하이브리드 응답 형식

이 자동 감지는 다음에 적용됩니다:

  • 핫 리로드 설정 변경
  • 명시적 타입 없이 Admin API를 통해 추가된 백엔드
  • type: generic 또는 타입이 지정되지 않은 설정 파일

예제: Admin API를 통한 자동 감지 백엔드:

# 타입 지정 없이 백엔드 추가 - llama.cpp 자동 감지
curl -X POST http://localhost:8080/admin/backends \
  -H "Content-Type: application/json" \
  -d '{
    "name": "local-llm",
    "url": "http://localhost:8080"
  }'

Unix Domain Socket 백엔드

Continuum Router는 로컬 LLM 백엔드를 위해 TCP 대신 Unix Domain Socket(UDS)을 전송 수단으로 지원합니다. Unix 소켓은 다음을 제공합니다:

  • 향상된 보안: TCP 포트 노출 없음 - 파일 시스템을 통한 통신
  • 낮은 레이턴시: 로컬 통신에서 네트워크 스택 오버헤드 없음
  • 더 나은 성능: 컨텍스트 스위칭 및 메모리 복사 감소
  • 간단한 접근 제어: 표준 Unix 파일 권한 사용

URL 형식:

unix:///path/to/socket.sock

플랫폼 지원:

플랫폼 지원
Linux AF_UNIX를 통한 완전 지원
macOS AF_UNIX를 통한 완전 지원
Windows 현재 미지원 (향후 릴리스에서 지원 예정)

설정 예제:

backends:
  # Unix 소켓을 사용하는 llama-server
  - name: "llama-socket"
    type: llamacpp
    url: "unix:///var/run/llama-server.sock"
    weight: 2
    models:
      - llama-3.2-3b
      - qwen3-4b

  # Unix 소켓을 사용하는 Ollama
  - name: "ollama-socket"
    type: ollama
    url: "unix:///var/run/ollama.sock"
    weight: 1
    models:
      - llama3.2
      - mistral

  # Unix 소켓을 사용하는 vLLM
  - name: "vllm-socket"
    type: vllm
    url: "unix:///tmp/vllm.sock"
    weight: 3
    models:
      - meta-llama/Llama-3.1-8B-Instruct

Unix 소켓으로 백엔드 시작하기:

# llama-server
./llama-server -m model.gguf --unix /var/run/llama.sock

# Ollama
OLLAMA_HOST="unix:///var/run/ollama.sock" ollama serve

# vLLM
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Llama-3.1-8B \
  --unix-socket /tmp/vllm.sock

소켓 경로 규칙:

경로 사용 사례
/var/run/*.sock 시스템 서비스 (root 권한 필요)
/tmp/*.sock 임시, 사용자 접근 가능
~/.local/share/continuum/*.sock 사용자별 영구 소켓

헬스 체크: 라우터는 TCP 백엔드와 동일한 엔드포인트(/health, /v1/models)를 사용하여 Unix 소켓 백엔드에 대해 자동으로 헬스 체크를 수행합니다.

현재 제한 사항:

  • 스트리밍(SSE) 미지원: Unix 소켓 백엔드는 현재 Server-Sent Events(SSE) 스트리밍을 지원하지 않습니다. 스트리밍 채팅 완성에는 TCP 백엔드를 사용하세요.
  • Windows 플랫폼: Unix 소켓은 현재 Windows에서 지원되지 않습니다 (향후 릴리스에서 지원 예정).
  • 최대 응답 크기: 메모리 고갈을 방지하기 위해 응답 본문은 기본적으로 100MB로 제한됩니다.

문제 해결:

오류 원인 해결 방법
"Socket file not found" 서버가 실행되지 않음 백엔드 서버 시작
"Permission denied" 파일 권한 chmod 660 socket.sock
"Connection timeout" 서버가 연결을 수락하지 않음 서버가 리스닝 중인지 확인
"Response body exceeds maximum size" 응답이 너무 큼 maxresponsesize 증가 또는 TCP 백엔드로 스트리밍 사용

헬스 체크 섹션

백엔드 헬스 모니터링을 설정합니다:

health_checks:
  enabled: true                    # 헬스 모니터링 활성화/비활성화
  interval: "30s"                  # 확인 주기
  timeout: "10s"                   # 요청 타임아웃
  unhealthy_threshold: 3           # 비정상 표시까지의 실패 횟수
  healthy_threshold: 2             # 정상 표시까지의 성공 횟수
  endpoint: "/v1/models"           # 확인할 엔드포인트
  warmup_check_interval: "1s"      # 워밍업 중 가속화된 확인 주기
  max_warmup_duration: "300s"      # 최대 워밍업 감지 시간

헬스 체크 프로세스:

  1. 라우터가 각 백엔드의 헬스 엔드포인트를 쿼리
  2. 성공적인 응답은 성공 카운터 증가
  3. 실패한 응답은 실패 카운터 증가
  4. 실패 임계값에 도달하면 백엔드를 비정상으로 표시
  5. 성공 임계값에 도달하면 백엔드를 정상으로 표시
  6. 정상 백엔드만 트래픽 수신

가속화된 워밍업 헬스 체크

라우터는 백엔드 워밍업 중 가속화된 헬스 체크를 지원합니다. 이는 모델 로딩 중 HTTP 503을 반환하는 llama.cpp와 같은 백엔드에 특히 유용합니다.

백엔드 상태:

상태 HTTP 응답 동작
ready 200 OK 일반 간격으로 체크
warming_up 503 Service Unavailable 가속화된 간격으로 체크
down 연결 실패 일반 간격으로 체크
unknown 초기 상태 첫 번째 체크로 상태 결정

워밍업 설정:

옵션 기본값 설명
warmup_check_interval 1s 워밍업 중 가속화된 체크 간격
max_warmup_duration 300s 가속화 모드 유지 최대 시간

동작 방식:

  1. 백엔드가 HTTP 503을 반환하면 warming_up 상태로 진입
  2. 헬스 체크가 가속화된 간격(기본값: 1초)으로 전환
  3. 백엔드가 HTTP 200을 반환하면 ready 상태가 되어 일반 간격으로 복귀
  4. 워밍업이 max_warmup_duration을 초과하면 백엔드를 비정상으로 표시

이 기능으로 모델 가용성 감지 지연 시간이 최대 30초(최악의 경우)에서 약 1초로 단축됩니다.

백엔드별 헬스 체크 설정

각 백엔드 타입에는 합리적인 기본 헬스 체크 엔드포인트가 있습니다. 백엔드별로 커스텀 health_check 설정으로 이러한 기본값을 재정의할 수 있습니다.

백엔드 타입별 기본 헬스 체크 엔드포인트:

백엔드 타입 기본 엔드포인트 폴백 엔드포인트 메서드 참고
openai /v1/models - GET 표준 OpenAI 엔드포인트
vllm /health /v1/models GET /health는 모델 로드 후 사용 가능
ollama /api/tags / GET Ollama 전용 엔드포인트
llamacpp /health /v1/models GET llama-server 엔드포인트
anthropic /v1/messages - POST 200, 400, 401, 429를 정상으로 허용
gemini /models /v1beta/models GET 네이티브 Gemini 엔드포인트
azure /health /v1/models GET Azure OpenAI 엔드포인트
generic /health /v1/models GET 범용 폴백

폴백 동작:

기본 헬스 체크 엔드포인트가 HTTP 404를 반환하면 라우터는 자동으로 폴백 엔드포인트를 순서대로 시도합니다. 이를 통해 모든 표준 엔드포인트를 구현하지 않는 백엔드와의 호환성을 보장합니다.

커스텀 헬스 체크 설정:

backends:
    - name: vllm-custom
    type: vllm
    url: http://localhost:8000
    models:
        - my-model
    health_check:
        endpoint: /custom-health          # 기본 엔드포인트
        fallback_endpoints:               # 기본 엔드포인트가 404 반환 시 시도
            - /health
            - /v1/models
        method: GET                       # HTTP 메서드: GET, POST 또는 HEAD
        timeout: 10s                      # 전역 헬스 체크 타임아웃 재정의
        accept_status:                    # 정상을 나타내는 상태 코드
            - 200
            - 204
        warmup_status:                    # 모델 로딩 중을 나타내는 상태 코드
            - 503

헬스 체크 설정 옵션:

옵션 타입 기본값 설명
endpoint string 백엔드 타입별 상이 기본 헬스 체크 엔드포인트 경로
fallback_endpoints array 백엔드 타입별 상이 기본 엔드포인트가 404 반환 시 시도할 엔드포인트
method string GET HTTP 메서드: GET, POST 또는 HEAD
body object null POST 요청용 JSON 본문
accept_status array [200] 백엔드가 정상임을 나타내는 상태 코드
warmup_status array [503] 백엔드가 워밍업 중임을 나타내는 상태 코드
timeout string 전역 타임아웃 전역 헬스 체크 타임아웃 재정의

예시: Anthropic 스타일 헬스 체크:

POST 요청을 사용하거나 오류 코드를 정상 지표로 허용하는 백엔드의 경우:

backends:
    - name: custom-api
    type: generic
    url: http://localhost:9000
    models:
        - custom-model
    health_check:
        endpoint: /api/v1/health
        method: POST
        body:
            check: true
        accept_status:
            - 200
            - 400    # Bad request는 서버가 동작 중임을 의미
            - 401    # Unauthorized는 서버가 동작 중임을 의미
            - 429    # Rate limited는 서버가 동작 중임을 의미

요청 섹션

요청 처리 동작을 제어합니다:

request:
  timeout: "300s"                  # 최대 요청 지속 시간
  max_retries: 3                   # 실패한 요청의 재시도 횟수
  retry_delay: "1s"                # 재시도 간 초기 지연

타임아웃 고려 사항:

  • 긴 타임아웃 (300s)은 느린 모델 추론 수용
  • 스트리밍 요청은 비스트리밍보다 오래 걸릴 수 있음
  • 사용자 경험과 리소스 사용 간 균형

재시도 섹션

복원력을 위한 전역 재시도 설정:

retry:
  max_attempts: 3                  # 최대 재시도 횟수
  base_delay: "100ms"              # 재시도 간 기본 지연
  max_delay: "30s"                 # 재시도 지연 상한
  exponential_backoff: true        # 지수 백오프 사용
  jitter: true                     # 무작위 지터 추가

재시도 전략:

  • 지수 백오프: 지연이 지수적으로 증가 (100ms, 200ms, 400ms...)
  • 지터: 썬더링 허드 방지를 위한 무작위성 추가
  • 최대 지연: 극도로 긴 대기 방지

캐시 섹션

캐싱 및 최적화를 제어합니다:

cache:
  model_cache_ttl: "300s"         # 모델 목록 캐시 기간
  deduplication_ttl: "60s"        # 동일 요청 캐시 기간
  enable_deduplication: true      # 요청 중복 제거 활성화

캐시 스탬피드 방지

라우터는 캐시 스탬피드(썬더링 허드 문제)를 방지하기 위해 세 가지 전략을 구현합니다:

  1. 싱글플라이트 패턴: 한 번에 하나의 집계 요청만 실행
  2. Stale-While-Revalidate: 백그라운드에서 갱신하면서 오래된 데이터 반환
  3. 백그라운드 갱신: 만료 전 사전 캐시 업데이트

고급 캐시 설정:

model_aggregation:
  cache_ttl: 60                     # 캐시 TTL (초, 기본값: 60)
  soft_ttl_ratio: 0.8               # 백그라운드 갱신 트리거 시점 (기본값: 0.8 = 80%)
  empty_response_base_ttl_seconds: 5   # 빈 응답의 기본 TTL
  empty_response_max_ttl_seconds: 60   # 지수 백오프 최대 TTL
  max_cache_entries: 100            # 최대 캐시 항목 수
  background_refresh:
    enabled: true                   # 백그라운드 갱신 활성화
    check_interval: 10s             # 검사 간격
옵션 기본값 설명
cache_ttl 60초 하드 TTL - 이 시간 후 캐시 만료
soft_ttl_ratio 0.8 소프트 TTL = cachettl * softttl_ratio. 소프트와 하드 TTL 사이에서 캐시가 오래되었지만 사용 가능
empty_response_base_ttl_seconds 5 빈 응답의 기본 TTL (DoS 방지)
empty_response_max_ttl_seconds 60 지수 백오프 최대 TTL (base * 2^n)
max_cache_entries 100 최대 캐시 항목 수
background_refresh.enabled true 사전 캐시 갱신 활성화
background_refresh.check_interval 10초 캐시 신선도 검사 주기

캐시 이점:

  • 모델 캐싱은 백엔드 쿼리 감소
  • 중복 제거는 중복 처리 방지
  • TTL은 오래된 데이터 문제 방지
  • 스탬피드 방지로 썬더링 허드 회피
  • 백그라운드 갱신으로 캐시가 항상 신선하게 유지

로깅 섹션

로깅 출력을 설정합니다:

logging:
  level: "info"                   # trace, debug, info, warn, error
  format: "json"                  # json, pretty
  enable_colors: false            # 컬러 출력 (pretty 형식만)

로그 레벨:

  • trace: 매우 상세, 모든 세부 정보 포함
  • debug: 상세한 디버깅 정보
  • info: 일반적인 운영 정보
  • warn: 경고 메시지 및 잠재적 문제
  • error: 오류 조건만

로그 형식:

  • json: 구조화된 JSON 로깅 (프로덕션 권장)
  • pretty: 사람이 읽기 쉬운 형식 (개발에 적합)

API 키 섹션

API 키는 라우터 엔드포인트에 대한 클라이언트 접근을 제어합니다. 키는 여러 소스를 통해 설정할 수 있습니다.

인증 모드

mode 설정은 API 엔드포인트에 API 인증이 필요한지 제어합니다:

모드 동작
permissive (기본) API 키 없이 요청 허용. 유효한 API 키가 있는 요청은 인증됨.
blocking API 키 인증을 통과한 요청만 처리. 인증되지 않은 요청은 401 수신.

대상 엔드포인트 (mode가 blocking일 때):

  • /v1/chat/completions
  • /v1/completions
  • /v1/responses
  • /v1/images/generations
  • /v1/images/edits
  • /v1/images/variations
  • /v1/models

참고: Admin, Files, Metrics 엔드포인트는 별도의 인증 메커니즘이 있으며 이 설정의 영향을 받지 않습니다.

섹션 설정 속성:

속성 타입 필수 기본값 설명
mode string 아니오 permissive 인증 모드: permissive 또는 blocking
api_keys array 아니오 [] 인라인 API 키 정의
api_keys_file string 아니오 - 외부 API 키 파일 경로
api_keys:
  # 인증 모드: "permissive" (기본) 또는 "blocking"
  mode: permissive

  # 인라인 API 키 정의
  api_keys:
    - key: "${API_KEY_1}"              # 환경 변수 치환
      id: "key-production-1"           # 고유 식별자
      user_id: "user-admin"            # 연결된 사용자
      organization_id: "org-main"      # 연결된 조직
      name: "Production Admin Key"     # 사람이 읽을 수 있는 이름
      scopes:                          # 권한
        - read
        - write
        - files
        - admin
      rate_limit: 1000                 # 분당 요청 수 (선택 사항)
      enabled: true                    # 활성 상태
      expires_at: "2025-12-31T23:59:59Z"  # 선택적 만료 (ISO 8601)

    - key: "${API_KEY_2}"
      id: "key-service-1"
      user_id: "service-bot"
      organization_id: "org-main"
      name: "Service Account"
      scopes: [read, write, files]
      rate_limit: 500
      enabled: true

  # 보안 향상을 위한 외부 키 파일
  api_keys_file: "/etc/continuum-router/api-keys.yaml"

키 속성:

속성 타입 필수 설명
key string API 키 값 (${ENV_VAR} 치환 지원)
id string admin 작업을 위한 고유 식별자
user_id string 이 키와 연결된 사용자
organization_id string 사용자가 속한 조직
name string 아니오 사람이 읽을 수 있는 이름
description string 아니오 키에 대한 메모
scopes array 권한: read, write, files, admin
rate_limit integer 아니오 분당 최대 요청 수
enabled boolean 아니오 활성 상태 (기본값: true)
expires_at string 아니오 ISO 8601 만료 타임스탬프

외부 키 파일 형식:

# /etc/continuum-router/api-keys.yaml
keys:
  - key: "sk-prod-xxxxxxxxxxxxxxxxxxxxx"
    id: "key-external-1"
    user_id: "external-user"
    organization_id: "external-org"
    scopes: [read, write, files]
    enabled: true

보안 기능:

  • 키 마스킹: 전체 키는 로깅되지 않음 (sk-***last4로 표시)
  • 만료 적용: 만료된 키는 자동으로 거부
  • 핫 리로드: 서버 재시작 없이 키 업데이트
  • 감사 로깅: 모든 키 관리 작업 로깅
  • 상수 시간 검증: 타이밍 공격 방지
  • 최대 키 제한: DoS 방지를 위해 최대 10,000개 키

Admin API 엔드포인트 (admin 인증 필요):

엔드포인트 메서드 설명
/admin/api-keys GET 모든 키 목록 (마스킹됨)
/admin/api-keys/:id GET 키 세부 정보 가져오기
/admin/api-keys POST 새 키 생성
/admin/api-keys/:id PUT 키 속성 업데이트
/admin/api-keys/:id DELETE 키 삭제
/admin/api-keys/:id/rotate POST 새 키 값 생성
/admin/api-keys/:id/enable POST 키 활성화
/admin/api-keys/:id/disable POST 키 비활성화

고급 설정

전역 프롬프트

전역 프롬프트를 사용하면 모든 요청에 시스템 프롬프트를 주입하여 보안, 규정 준수 및 동작 가이드라인에 대한 중앙 집중식 정책 관리를 제공할 수 있습니다. 프롬프트는 인라인으로 정의하거나 외부 Markdown 파일에서 로드할 수 있습니다.

기본 설정

global_prompts:
  # 인라인 기본 프롬프트
  default: |
    회사 보안 정책을 따라야 합니다.
    내부 시스템 세부 정보를 공개하지 마십시오.
    도움이 되고 전문적이어야 합니다.

  # 병합 전략: prepend (기본), append, 또는 replace
  merge_strategy: prepend

  # 전역 프롬프트와 사용자 프롬프트 사이의 사용자 정의 구분자
  separator: "\n\n---\n\n"

외부 프롬프트 파일

복잡한 프롬프트의 경우 외부 Markdown 파일에서 콘텐츠를 로드할 수 있습니다. 이를 통해:

  • 구문 강조가 있는 더 나은 편집 경험
  • 설정 파일 노이즈 없는 버전 관리
  • 프롬프트 업데이트에 대한 핫 리로드 지원
global_prompts:
  # 프롬프트 파일이 있는 디렉토리 (설정 디렉토리 기준 상대 경로)
  prompts_dir: "./prompts"

  # 파일에서 기본 프롬프트 로드
  default_file: "system.md"

  # 파일에서 백엔드별 프롬프트
  backends:
    anthropic:
      prompt_file: "anthropic-system.md"
    openai:
      prompt_file: "openai-system.md"

  # 파일에서 모델별 프롬프트
  models:
    gpt-4o:
      prompt_file: "gpt4o-system.md"
    claude-3-opus:
      prompt_file: "claude-opus-system.md"

  merge_strategy: prepend

프롬프트 해석 우선순위

요청에 사용할 프롬프트 결정 시:

  1. 모델별 프롬프트 (최고 우선순위) - global_prompts.models.<model-id>
  2. 백엔드별 프롬프트 - global_prompts.backends.<backend-name>
  3. 기본 프롬프트 - global_prompts.default 또는 global_prompts.default_file

각 레벨에서 prompt (인라인)와 prompt_file이 모두 지정되면 prompt_file이 우선합니다.

병합 전략

전략 동작
prepend 전역 프롬프트가 사용자 시스템 프롬프트 앞에 추가 (기본)
append 전역 프롬프트가 사용자 시스템 프롬프트 뒤에 추가
replace 전역 프롬프트가 사용자 시스템 프롬프트를 완전히 대체

REST API 관리

프롬프트 파일은 Admin API를 통해 런타임에 관리할 수 있습니다:

# 모든 프롬프트 목록
curl http://localhost:8080/admin/config/prompts

# 특정 프롬프트 파일 가져오기
curl http://localhost:8080/admin/config/prompts/prompts/system.md

# 프롬프트 파일 업데이트
curl -X PUT http://localhost:8080/admin/config/prompts/prompts/system.md \
  -H "Content-Type: application/json" \
  -d '{"content": "# 업데이트된 시스템 프롬프트\n\n새 콘텐츠."}'

# 디스크에서 모든 프롬프트 파일 리로드
curl -X POST http://localhost:8080/admin/config/prompts/reload

전체 API 문서는 Admin REST API 참조를 참조하세요.

보안 고려 사항

  • 경로 탐색 보호: 디렉토리 탐색 공격 방지를 위한 모든 파일 경로 검증
  • 파일 크기 제한: 개별 파일 1MB, 전체 캐시 50MB 제한
  • 상대 경로만: 프롬프트 파일은 설정된 prompts_dir 또는 설정 디렉토리 내에 있어야 함
  • 샌드박스 접근: 허용된 디렉토리 외부 파일은 거부

핫 리로드

전역 프롬프트는 즉시 핫 리로드를 지원합니다. 프롬프트 설정 또는 파일 변경 사항은 서버 재시작 없이 다음 요청에 적용됩니다.

모델 메타데이터

Continuum Router는 모델 기능, 가격, 한도에 대한 상세 정보를 제공하는 풍부한 모델 메타데이터를 지원합니다. 이 메타데이터는 /v1/models API 응답에 반환되며 클라이언트가 정보에 입각한 모델 선택 결정을 내리는 데 사용할 수 있습니다.

메타데이터 소스

모델 메타데이터는 세 가지 방법으로 설정할 수 있습니다 (우선순위 순):

  1. 백엔드별 model_configs (최고 우선순위)
  2. 외부 메타데이터 파일 (model-metadata.yaml)
  3. 메타데이터 없음 (모델은 메타데이터 없이도 작동)

외부 메타데이터 파일

model-metadata.yaml 파일을 만드세요:

models:
  - id: "gpt-4"
    aliases:                    # 이 메타데이터를 공유하는 대체 ID
      - "gpt-4-0125-preview"
      - "gpt-4-turbo-preview"
      - "gpt-4-vision-preview"
    metadata:
      display_name: "GPT-4"
      summary: "복잡한 작업을 위한 가장 유능한 GPT-4 모델"
      capabilities: ["text", "image", "function_calling"]
      knowledge_cutoff: "2024-04"
      pricing:
        input_tokens: 0.03   # 1000 토큰당
        output_tokens: 0.06  # 1000 토큰당
      limits:
        context_window: 128000
        max_output: 4096

  - id: "llama-3-70b"
    aliases:                    # 동일 모델의 다른 양자화
      - "llama-3-70b-instruct"
      - "llama-3-70b-chat"
      - "llama-3-70b-q4"
      - "llama-3-70b-q8"
    metadata:
      display_name: "Llama 3 70B"
      summary: "강력한 성능의 오픈 소스 모델"
      capabilities: ["text", "code"]
      knowledge_cutoff: "2023-12"
      pricing:
        input_tokens: 0.001
        output_tokens: 0.002
      limits:
        context_window: 8192
        max_output: 2048

설정에서 참조하세요:

model_metadata_file: "model-metadata.yaml"

Thinking 패턴 설정

일부 모델은 추론/사고 콘텐츠를 비표준 방식으로 출력합니다. 라우터는 스트리밍 응답을 적절히 변환하기 위해 모델별 thinking 패턴 설정을 지원합니다.

패턴 유형:

패턴 설명 예시 모델
none thinking 패턴 없음 (기본값) 대부분의 모델
standard 명시적 시작/종료 태그 (<think>...</think>) 커스텀 추론 모델
unterminated_start 시작 태그 없이 종료 태그만 있음 nemotron-3-nano

설정 예시:

models:
    - id: nemotron-3-nano
      metadata:
        display_name: "Nemotron 3 Nano"
        capabilities: ["chat", "reasoning"]
        # Thinking 패턴 설정
        thinking:
          pattern: unterminated_start
          end_marker: "</think>"
          assume_reasoning_first: true

Thinking 패턴 필드:

필드 타입 설명
pattern string 패턴 유형: none, standard, 또는 unterminated_start
start_marker string standard 패턴용 시작 마커 (예: <think>)
end_marker string 종료 마커 (예: </think>)
assume_reasoning_first boolean true인 경우, 종료 마커까지 첫 토큰들을 추론으로 처리

작동 방식:

모델에 thinking 패턴이 설정되면:

  1. 스트리밍 응답이 가로채져 변환됨
  2. end_marker 이전 콘텐츠는 reasoning_content 필드로 전송
  3. end_marker 이후 콘텐츠는 content 필드로 전송
  4. 출력은 호환성을 위해 OpenAI의 reasoning_content 형식을 따름

출력 예시:

// 추론 콘텐츠 (종료 마커 이전)
{"choices": [{"delta": {"reasoning_content": "분석해 보겠습니다..."}}]}

// 일반 콘텐츠 (종료 마커 이후)
{"choices": [{"delta": {"content": "답은 42입니다."}}]}

네임스페이스 인식 매칭

라우터는 네임스페이스 접두사가 있는 모델 ID를 지능적으로 처리합니다. 예:

  • 백엔드 반환: "custom/gpt-4", "openai/gpt-4", "optimized/gpt-4"
  • 메타데이터 정의: "gpt-4"
  • 결과: 모든 변형이 일치하고 동일한 메타데이터 수신

이를 통해 다른 백엔드가 공통 메타데이터 정의를 공유하면서 자체 명명 규칙을 사용할 수 있습니다.

메타데이터 우선순위 및 별칭 해석

모델의 메타데이터를 조회할 때, 라우터는 다음 우선순위 체인을 사용합니다:

  1. 정확한 모델 ID 매칭
  2. 정확한 별칭 매칭
  3. 날짜 접미사 정규화 (자동, 설정 불필요)
  4. 와일드카드 패턴 별칭 매칭
  5. 기본 모델 이름 폴백 (네임스페이스 제거)

각 소스 (백엔드 설정, 메타데이터 파일, 내장) 내에서 동일한 우선순위가 적용됩니다:

  1. 백엔드별 model_configs (최고 우선순위)

    backends:
      - name: "my-backend"
        model_configs:
          - id: "gpt-4"
            aliases: ["gpt-4-turbo", "gpt-4-vision"]
            metadata: {...}  # 이것이 우선
    

  2. 외부 메타데이터 파일 (두 번째 우선순위)

    model_metadata_file: "model-metadata.yaml"
    

  3. 내장 메타데이터 (OpenAI 및 Gemini 백엔드용)

자동 날짜 접미사 처리

LLM 프로바이더는 날짜 접미사가 있는 모델 버전을 자주 릴리스합니다. 라우터는 설정 없이 자동으로 날짜 접미사를 감지하고 정규화합니다:

지원되는 날짜 패턴:

  • -YYYYMMDD (예: claude-opus-4-5-20251130)
  • -YYYY-MM-DD (예: gpt-4o-2024-08-06)
  • -YYMM (예: o1-mini-2409)
  • @YYYYMMDD (예: model@20251130)

작동 방식:

요청: claude-opus-4-5-20251215
      ↓ (날짜 접미사 감지됨)
조회: claude-opus-4-5-20251101  (기존 메타데이터 항목)
      ↓ (기본 이름 일치)
결과: claude-opus-4-5-20251101 메타데이터 사용

이는 모델 패밀리당 메타데이터를 한 번만 설정하면 되고, 새로운 날짜 버전이 자동으로 메타데이터를 상속한다는 것을 의미합니다.

와일드카드 패턴 매칭

별칭은 * 문자를 사용한 glob 스타일 와일드카드 패턴을 지원합니다:

  • 접두사 매칭: claude-*claude-opus, claude-sonnet 등과 매칭
  • 접미사 매칭: *-previewgpt-4o-preview, o1-preview 등과 매칭
  • 중위 매칭: gpt-*-turbogpt-4-turbo, gpt-3.5-turbo 등과 매칭

와일드카드 패턴이 있는 설정 예:

models:
    - id: "claude-opus-4-5-20251101"
    aliases:
        - "claude-opus-4-5"     # 기본 이름의 정확한 매칭
        - "claude-opus-*"       # 모든 claude-opus 변형에 대한 와일드카드
    metadata:
        display_name: "Claude Opus 4.5"
        # 자동 매칭: claude-opus-4-5-20251130, claude-opus-test 등

    - id: "gpt-4o"
    aliases:
        - "gpt-4o-*-preview"    # 프리뷰 버전 매칭
        - "*-4o-turbo"          # 접미사 매칭
    metadata:
        display_name: "GPT-4o"

우선순위 참고: 정확한 별칭은 항상 와일드카드 패턴보다 먼저 매칭되어 둘 다 매칭될 수 있는 경우에도 예측 가능한 동작을 보장합니다.

모델 변형에 별칭 사용

별칭은 특히 다음에 유용합니다:

  • 다른 양자화: qwen3-32b-i1, qwen3-23b-i4 → 모두 qwen3 메타데이터 사용
  • 버전 변형: gpt-4-0125-preview, gpt-4-turbogpt-4 메타데이터 공유
  • 배포 변형: llama-3-70b-instruct, llama-3-70b-chat → 동일 기본 모델
  • 날짜 버전: claude-3-5-sonnet-20241022, claude-3-5-sonnet-20241201 → 메타데이터 공유 (날짜 접미사 처리로 자동)

별칭이 있는 설정 예:

model_configs:
  - id: "qwen3"
    aliases:
      - "qwen3-32b-i1"     # 1비트 양자화된 32B
      - "qwen3-23b-i4"     # 4비트 양자화된 23B
      - "qwen3-16b-q8"     # 8비트 양자화된 16B
      - "qwen3-*"          # 다른 모든 qwen3 변형에 대한 와일드카드
    metadata:
      display_name: "Qwen 3"
      summary: "Alibaba의 Qwen 모델 계열"
      # ... 나머지 메타데이터

API 응답

/v1/models 엔드포인트는 풍부한 모델 정보를 반환합니다:

{
  "object": "list",
  "data": [
    {
      "id": "gpt-4",
      "object": "model",
      "created": 1234567890,
      "owned_by": "openai",
      "backends": ["openai-proxy"],
      "metadata": {
        "display_name": "GPT-4",
        "summary": "복잡한 작업을 위한 가장 유능한 GPT-4 모델",
        "capabilities": ["text", "image", "function_calling"],
        "knowledge_cutoff": "2024-04",
        "pricing": {
          "input_tokens": 0.03,
          "output_tokens": 0.06
        },
        "limits": {
          "context_window": 128000,
          "max_output": 4096
        }
      }
    }
  ]
}

핫 리로드

Continuum Router는 서버 재시작 없이 런타임 설정 업데이트를 위한 핫 리로드를 지원합니다. 설정 변경은 자동으로 감지되어 분류에 따라 적용됩니다.

설정 항목 분류

설정 항목은 핫 리로드 기능에 따라 세 가지 범주로 분류됩니다:

즉시 업데이트 (서비스 중단 없음)

이 설정들은 서비스 중단 없이 즉시 업데이트됩니다:

# 로깅 설정
logging:
  level: "info"                  # ✅ 즉시: 로그 레벨 변경이 즉시 적용
  format: "json"                 # ✅ 즉시: 로그 형식 변경이 즉시 적용

# 속도 제한 설정
rate_limiting:
  enabled: true                  # ✅ 즉시: 속도 제한 활성화/비활성화
  limits:
    per_client:
      requests_per_second: 10    # ✅ 즉시: 새 제한이 즉시 적용
      burst_capacity: 20         # ✅ 즉시: 버스트 설정이 즉시 업데이트

# 서킷 브레이커 설정
circuit_breaker:
  enabled: true                  # ✅ 즉시: 서킷 브레이커 활성화/비활성화
  failure_threshold: 5           # ✅ 즉시: 임계값 업데이트가 즉시 적용
  timeout_seconds: 60            # ✅ 즉시: 타임아웃 변경이 즉시

# 재시도 설정
retry:
  max_attempts: 3                # ✅ 즉시: 재시도 정책이 즉시 업데이트
  base_delay: "100ms"            # ✅ 즉시: 백오프 설정이 즉시 적용
  exponential_backoff: true      # ✅ 즉시: 전략 변경이 즉시

# 전역 프롬프트
global_prompts:
  default: "당신은 도움이 됩니다"     # ✅ 즉시: 프롬프트 변경이 새 요청에 적용
  default_file: "prompts/system.md"  # ✅ 즉시: 파일 기반 프롬프트도 핫 리로드
점진적 업데이트 (기존 연결 유지)

이 설정들은 기존 연결을 유지하면서 새 연결에 적용됩니다:

# 백엔드 설정
backends:
  - name: "ollama"               # ✅ 점진적: 새 요청이 업데이트된 백엔드 풀 사용
    url: "http://localhost:11434"
    weight: 2                    # ✅ 점진적: 새 요청에 로드 밸런싱 업데이트
    models: ["llama3.2"]         # ✅ 점진적: 모델 라우팅이 점진적으로 업데이트

# 헬스 체크 설정
health_checks:
  interval: "30s"                # ✅ 점진적: 다음 헬스 체크 주기가 새 간격 사용
  timeout: "10s"                 # ✅ 점진적: 새 체크가 업데이트된 타임아웃 사용
  unhealthy_threshold: 3         # ✅ 점진적: 임계값이 새 평가에 적용
  healthy_threshold: 2           # ✅ 점진적: 복구 임계값이 점진적으로 업데이트

# 타임아웃 설정
timeouts:
  connection: "10s"              # ✅ 점진적: 새 요청이 업데이트된 타임아웃 사용
  request:
    standard:
      first_byte: "30s"          # ✅ 점진적: 새 요청에 적용
      total: "180s"              # ✅ 점진적: 새 요청이 새 타임아웃 사용
    streaming:
      chunk_interval: "30s"      # ✅ 점진적: 새 스트림이 업데이트된 설정 사용
재시작 필요 (핫 리로드 불가)

이 설정들은 적용을 위해 서버 재시작이 필요합니다. 변경 사항은 경고로 기록됩니다:

server:
  bind_address: "0.0.0.0:8080"   # ❌ 재시작 필요: TCP/Unix 소켓 바인딩
  #   - "0.0.0.0:8080"
  #   - "unix:/var/run/router.sock"
  socket_mode: 0o660              # ❌ 재시작 필요: 소켓 권한
  workers: 4                      # ❌ 재시작 필요: 워커 스레드 풀 크기

이 설정들이 변경되면 라우터는 다음과 같은 경고를 기록합니다:

WARN server.bind_address가 '0.0.0.0:8080'에서 '0.0.0.0:9000'으로 변경됨 - 적용하려면 재시작 필요

핫 리로드 프로세스

  1. 파일 시스템 감시자 - 설정 파일 변경 자동 감지
  2. 설정 로딩 - 새 설정 로드 및 파싱
  3. 유효성 검사 - 스키마에 대해 새 설정 검증
  4. 변경 감지 - ConfigDiff 계산으로 변경 사항 식별
  5. 분류 - 변경 사항 분류 (즉시/점진적/재시작)
  6. 원자적 업데이트 - 유효한 설정이 원자적으로 적용
  7. 컴포넌트 전파 - 영향받는 컴포넌트에 업데이트 전파:
  8. HealthChecker가 체크 간격 및 임계값 업데이트
  9. RateLimitStore가 속도 제한 규칙 업데이트
  10. CircuitBreaker가 실패 임계값 및 타임아웃 업데이트
  11. BackendPool이 백엔드 설정 업데이트
  12. 즉시 헬스 체크 - 백엔드가 추가되면 즉시 헬스 체크가 실행되어 새 백엔드가 다음 주기적 체크를 기다리지 않고 1-2초 내에 사용 가능해짐
  13. 오류 처리 - 잘못된 경우 오류 기록 및 이전 설정 유지

핫 리로드 상태 확인

admin API를 사용하여 핫 리로드 상태 및 기능을 확인하세요:

# 핫 리로드가 활성화되었는지 확인
curl http://localhost:8080/admin/config/hot-reload-status

# 현재 설정 보기
curl http://localhost:8080/admin/config

핫 리로드 동작 예제

예제 1: 로그 레벨 변경 (즉시)

# 이전
logging:
  level: "info"

# 이후
logging:
  level: "debug"
결과: 로그 레벨이 즉시 변경됩니다. 재시작 불필요. 진행 중인 요청은 계속되고 새 로그는 debug 레벨 사용.

예제 2: 백엔드 추가 (즉시 헬스 체크와 함께 점진적)

# 이전
backends:
  - name: "ollama"
    url: "http://localhost:11434"

# 이후
backends:
  - name: "ollama"
    url: "http://localhost:11434"
  - name: "lmstudio"
    url: "http://localhost:1234"
결과: 새 백엔드가 풀에 추가되고 즉시 헬스 체크가 실행됩니다. 새 백엔드는 1-2초 내에 사용 가능해집니다(다음 주기적 헬스 체크까지 최대 30초를 기다리는 대신). 기존 요청은 현재 백엔드로 계속됩니다. 헬스 체크 통과 후 새 요청은 lmstudio로 라우팅 가능.

예제 2b: 백엔드 제거 (우아한 드레이닝)

# 이전
backends:
  - name: "ollama"
    url: "http://localhost:11434"
  - name: "lmstudio"
    url: "http://localhost:1234"

# 이후
backends:
  - name: "ollama"
    url: "http://localhost:11434"
결과: "lmstudio" 백엔드가 드레이닝 상태로 전환됩니다. 새 요청은 해당 백엔드로 라우팅되지 않지만, 기존 진행 중인 요청(스트리밍 포함)은 완료될 때까지 계속됩니다. 모든 참조가 해제되거나 5분 타임아웃 후에 백엔드가 메모리에서 완전히 제거됩니다.

백엔드 상태 생명주기

백엔드가 설정에서 제거되면 우아한 종료 프로세스를 거칩니다:

  1. Active → Draining: 백엔드가 드레이닝으로 표시됩니다. 새 요청은 이 백엔드를 건너뜁니다.
  2. 진행 중인 요청 완료: 기존 요청/스트림은 중단 없이 계속됩니다.
  3. 정리: 모든 참조가 해제되거나 5분 타임아웃 후에 백엔드가 제거됩니다.

이를 통해 설정 변경 중에도 진행 중인 연결에 영향을 주지 않습니다.

예제 3: 바인드 주소 변경 (재시작 필요)

# 이전
server:
  bind_address: "0.0.0.0:8080"

# 이후
server:
  bind_address: "0.0.0.0:9000"
결과: 경고 기록됨. 변경이 적용되지 않음. 새 포트에 바인드하려면 재시작 필요.

분산 추적

Continuum Router는 백엔드 서비스 간 요청 상관관계를 위한 분산 추적을 지원합니다. 이 기능은 여러 서비스를 통과하는 요청의 디버깅 및 모니터링에 도움을 줍니다.

설정

tracing:
  enabled: true                         # 분산 추적 활성화/비활성화 (기본값: true)
  w3c_trace_context: true               # W3C Trace Context 헤더 지원 (기본값: true)
  headers:
    trace_id: "X-Trace-ID"              # 추적 ID 헤더 이름 (기본값)
    request_id: "X-Request-ID"          # 요청 ID 헤더 이름 (기본값)
    correlation_id: "X-Correlation-ID"  # 상관 ID 헤더 이름 (기본값)

동작 방식

  1. 추적 ID 추출: 요청이 도착하면 라우터는 다음 우선순위로 헤더에서 추적 ID를 추출합니다:

    • W3C traceparent 헤더 (W3C 지원 활성화 시)
    • 설정된 trace_id 헤더 (X-Trace-ID)
    • 설정된 request_id 헤더 (X-Request-ID)
    • 설정된 correlation_id 헤더 (X-Correlation-ID)
  2. 추적 ID 생성: 헤더에서 추적 ID가 발견되지 않으면 새 UUID가 생성됩니다.

  3. 헤더 전파: 추적 ID는 여러 헤더를 통해 백엔드 서비스로 전파됩니다:

    • X-Request-ID: 광범위한 호환성을 위함
    • X-Trace-ID: 주요 추적 식별자
    • X-Correlation-ID: 상관관계 추적용
    • traceparent: W3C Trace Context (활성화 시)
    • tracestate: W3C Trace State (원본 요청에 존재 시)
  4. 재시도 시 보존: 동일한 추적 ID가 모든 재시도 시도에서 보존되어, 단일 클라이언트 요청에 대한 여러 백엔드 요청의 상관관계를 쉽게 파악할 수 있습니다.

구조화된 로깅

추적이 활성화되면 모든 로그 메시지에 trace_id 필드가 포함됩니다:

{
  "timestamp": "2024-01-15T10:30:00Z",
  "level": "info",
  "trace_id": "0af7651916cd43dd8448eb211c80319c",
  "message": "Processing chat completions request",
  "backend": "openai",
  "model": "gpt-4o"
}

W3C Trace Context

w3c_trace_context가 활성화되면 라우터는 W3C Trace Context 표준을 지원합니다:

  • 수신: traceparent 헤더 파싱 (형식: 00-{trace_id}-{span_id}-{flags})
  • 송신: 보존된 추적 ID와 새 span ID로 traceparent 헤더 생성
  • 상태: 원본 요청에 있는 경우 tracestate 헤더 전달

traceparent 예시: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01

추적 비활성화

분산 추적을 비활성화하려면:

tracing:
  enabled: false

로드 밸런싱 전략

load_balancer:
  strategy: "round_robin"         # round_robin, weighted, random
  health_aware: true              # 정상 백엔드만 사용

전략:

  • round_robin: 백엔드 간 균등 분배
  • weighted: 백엔드 가중치에 기반한 분배
  • random: 무작위 선택 (패턴 방지에 좋음)

백엔드별 재시도 설정

backends:
  - name: "slow-backend"
    url: "http://slow.example.com"
    retry_override:               # 전역 재시도 설정 오버라이드
      max_attempts: 5             # 느린 백엔드에 더 많은 시도
      base_delay: "500ms"         # 더 긴 지연
      max_delay: "60s"

모델 폴백

Continuum Router는 기본 모델을 사용할 수 없을 때 자동 모델 폴백을 지원합니다. 이 기능은 계층화된 장애 조치 보호를 위해 서킷 브레이커와 통합됩니다.

설정

fallback:
  enabled: true

  # 각 기본 모델에 대한 폴백 체인 정의
  fallback_chains:
    # 동일 프로바이더 폴백
    "gpt-4o":
      - "gpt-4-turbo"
      - "gpt-3.5-turbo"

    "claude-opus-4-5-20251101":
      - "claude-sonnet-4-5"
      - "claude-haiku-4-5"

    # 크로스 프로바이더 폴백
    "gemini-2.5-pro":
      - "gemini-2.5-flash"
      - "gpt-4o"  # Gemini를 사용할 수 없으면 OpenAI로 폴백

  fallback_policy:
    trigger_conditions:
      error_codes: [429, 500, 502, 503, 504]
      timeout: true
      connection_error: true
      model_not_found: true
      circuit_breaker_open: true

    max_fallback_attempts: 3
    fallback_timeout_multiplier: 1.5
    preserve_parameters: true

  model_settings:
    "gpt-4o":
      fallback_enabled: true
      notify_on_fallback: true

트리거 조건

조건 설명
error_codes 폴백을 트리거하는 HTTP 상태 코드 (예: 429, 500, 502, 503, 504)
timeout 요청 타임아웃
connection_error TCP 연결 실패
model_not_found 백엔드에서 모델을 사용할 수 없음
circuit_breaker_open 백엔드 서킷 브레이커가 열림

응답 헤더

폴백이 사용되면 다음 헤더가 응답에 추가됩니다:

헤더 설명 예제
X-Fallback-Used 폴백이 사용되었음을 나타냄 true
X-Original-Model 원래 요청된 모델 gpt-4o
X-Fallback-Model 요청을 처리한 모델 gpt-4-turbo
X-Fallback-Reason 폴백이 트리거된 이유 error_code_429
X-Fallback-Attempts 폴백 시도 횟수 2

크로스 프로바이더 매개변수 변환

프로바이더 간 폴백 시 (예: OpenAI → Anthropic) 라우터가 요청 매개변수를 자동으로 변환합니다:

OpenAI 매개변수 Anthropic 매개변수 비고
max_tokens max_tokens 누락 시 자동 채움 (Anthropic 필수)
temperature temperature 직접 매핑
top_p top_p 직접 매핑
stop stop_sequences 배열 변환

프로바이더별 매개변수는 크로스 프로바이더 폴백 중에 자동으로 제거되거나 변환됩니다.

서킷 브레이커와의 통합

폴백 시스템은 서킷 브레이커와 함께 작동합니다:

  1. 서킷 브레이커가 실패 감지하고 임계값 초과 시 열림
  2. 폴백 체인 활성화 서킷 브레이커가 열렸을 때
  3. 요청이 폴백 모델로 라우팅 설정된 체인에 따라
  4. 서킷 브레이커가 복구 테스트하고 백엔드 복구 시 닫힘
# 예제: 서킷 브레이커와 폴백 결합 설정
circuit_breaker:
  enabled: true
  failure_threshold: 5
  timeout: 60s

fallback:
  enabled: true
  fallback_policy:
    trigger_conditions:
      circuit_breaker_open: true  # 서킷 브레이커에 연결

속도 제한

Continuum Router는 남용을 방지하고 공정한 리소스 할당을 보장하기 위해 /v1/models 엔드포인트에 대한 내장 속도 제한을 포함합니다.

현재 설정

속도 제한은 현재 다음 기본값으로 설정되어 있습니다:

# 참고: 이 값들은 현재 하드코딩되어 있지만 향후 버전에서 설정 가능해질 수 있습니다
rate_limiting:
  models_endpoint:
    # 클라이언트별 제한 (API 키 또는 IP 주소로 식별)
    sustained_limit: 100          # 분당 최대 요청 수
    burst_limit: 20               # 5초 윈도우에서 최대 요청 수

    # 시간 윈도우
    window_duration: 60s          # 지속 제한을 위한 슬라이딩 윈도우
    burst_window: 5s              # 버스트 감지를 위한 윈도우

    # 클라이언트 식별 우선순위
    identification:
      - api_key                   # Bearer 토큰 (처음 16자가 ID로 사용)
      - x_forwarded_for           # 프록시/로드 밸런서 헤더
      - x_real_ip                 # 대체 IP 헤더
      - fallback: "unknown"       # 식별자가 없을 때

작동 방식

  1. 클라이언트 식별: 각 요청은 다음을 사용하여 클라이언트와 연결:
  2. Authorization: Bearer <token> 헤더의 API 키 (선호)
  3. 프록시 헤더의 IP 주소 (폴백)

  4. 이중 윈도우 접근 방식:

  5. 지속 제한: 시간 경과에 따른 과도한 사용 방지
  6. 버스트 보호: 연속적인 빠른 요청 포착

  7. 독립적인 할당량: 각 클라이언트는 별도의 속도 제한:

  8. API 키 abc123...을 가진 클라이언트 A: 100 req/min
  9. API 키 def456...을 가진 클라이언트 B: 100 req/min
  10. IP 192.168.1.1의 클라이언트 C: 100 req/min

응답 헤더

속도 제한 시 응답 포함:

  • 상태 코드: 429 Too Many Requests
  • 오류 메시지: 버스트 또는 지속 제한 초과 여부 표시

캐시 TTL 최적화

캐시 오염 공격 방지를 위해:

  • 빈 모델 목록: 5초만 캐시
  • 일반 응답: 60초 캐시

이를 통해 공격자가 백엔드 장애 중에 빈 응답을 캐시하도록 강제하는 것을 방지합니다.

모니터링

속도 제한 위반은 메트릭에서 추적:

  • rate_limit_violations: 거부된 총 요청
  • empty_responses_returned: 제공된 빈 모델 목록
  • 문제가 있는 클라이언트 식별을 위한 클라이언트별 위반 추적

향후 개선 사항

향후 버전에서 지원될 수 있는 기능:

  • YAML/환경 변수를 통한 설정 가능한 속도 제한
  • 엔드포인트별 속도 제한
  • API 키별 사용자 정의 속도 제한
  • Redis 기반 분산 속도 제한

환경별 설정

개발 설정

# config/development.yaml
server:
  bind_address: "127.0.0.1:8080"

backends:
  - name: "local-ollama"
    url: "http://localhost:11434"

health_checks:
  interval: "10s"                 # 더 빈번한 확인
  timeout: "5s"

logging:
  level: "debug"                  # 상세 로깅
  format: "pretty"                # 사람이 읽기 쉬운
  enable_colors: true

프로덕션 설정

# config/production.yaml
server:
  bind_address: "0.0.0.0:8080"
  workers: 8                      # 프로덕션용 더 많은 워커
  connection_pool_size: 300       # 더 큰 연결 풀

backends:
  - name: "primary-openai"
    url: "https://api.openai.com"
    weight: 3
  - name: "secondary-azure"
    url: "https://azure-openai.example.com"
    weight: 2
  - name: "fallback-local"
    url: "http://internal-llm:11434"
    weight: 1

health_checks:
  interval: "60s"                 # 덜 빈번한 확인
  timeout: "15s"                  # 네트워크 지연을 위한 더 긴 타임아웃
  unhealthy_threshold: 5          # 더 많은 허용
  healthy_threshold: 3

request:
  timeout: "120s"                 # 프로덕션용 짧은 타임아웃
  max_retries: 5                  # 더 많은 재시도

logging:
  level: "warn"                   # 덜 상세한 로깅
  format: "json"                  # 구조화된 로깅

컨테이너 설정

# config/container.yaml - 컨테이너에 최적화
server:
  bind_address: "0.0.0.0:8080"
  workers: 0                      # 컨테이너 제한에 따라 자동 감지

backends:
  - name: "backend-1"
    url: "${BACKEND_1_URL}"       # 환경 변수 치환
  - name: "backend-2"
    url: "${BACKEND_2_URL}"

logging:
  level: "${LOG_LEVEL}"           # 환경을 통해 설정 가능
  format: "json"                  # 컨테이너에서 항상 JSON

예제

다중 백엔드 설정

# 엔터프라이즈 다중 백엔드 설정
server:
  bind_address: "0.0.0.0:8080"
  workers: 8
  connection_pool_size: 400

backends:
  # 기본 OpenAI GPT 모델
  - name: "openai-primary"
    url: "https://api.openai.com"
    weight: 5
    models: ["gpt-4", "gpt-3.5-turbo"]
    retry_override:
      max_attempts: 3
      base_delay: "500ms"

  # 보조 Azure OpenAI
  - name: "azure-openai"
    url: "https://your-resource.openai.azure.com"
    weight: 3
    models: ["gpt-4", "gpt-35-turbo"]

  # 오픈 모델을 위한 로컬 Ollama
  - name: "local-ollama"
    url: "http://ollama:11434"
    weight: 2
    models: ["llama2", "mistral", "codellama"]

  # vLLM 배포
  - name: "vllm-cluster"
    url: "http://vllm-service:8000"
    weight: 4
    models: ["meta-llama/Llama-2-7b-chat-hf"]

health_checks:
  enabled: true
  interval: "45s"
  timeout: "15s"
  unhealthy_threshold: 3
  healthy_threshold: 2

request:
  timeout: "180s"
  max_retries: 4

cache:
  model_cache_ttl: "600s"        # 10분 캐시
  deduplication_ttl: "120s"      # 2분 중복 제거
  enable_deduplication: true

logging:
  level: "info"
  format: "json"

고성능 설정

# 높은 처리량 시나리오에 최적화
server:
  bind_address: "0.0.0.0:8080"
  workers: 16                     # 높은 워커 수
  connection_pool_size: 1000      # 큰 연결 풀

backends:
  - name: "fast-backend-1"
    url: "http://backend1:8000"
    weight: 1
  - name: "fast-backend-2"
    url: "http://backend2:8000"
    weight: 1
  - name: "fast-backend-3"
    url: "http://backend3:8000"
    weight: 1

health_checks:
  enabled: true
  interval: "30s"
  timeout: "5s"                   # 빠른 타임아웃
  unhealthy_threshold: 2          # 빠른 실패
  healthy_threshold: 1            # 빠른 복구

request:
  timeout: "60s"                  # 높은 처리량을 위한 짧은 타임아웃
  max_retries: 2                  # 적은 재시도

retry:
  max_attempts: 2
  base_delay: "50ms"              # 빠른 재시도
  max_delay: "5s"
  exponential_backoff: true
  jitter: true

cache:
  model_cache_ttl: "300s"
  deduplication_ttl: "30s"        # 짧은 중복 제거 윈도우
  enable_deduplication: true

logging:
  level: "warn"                   # 성능을 위한 최소 로깅
  format: "json"

개발 설정

# 개발자 친화적 설정
server:
  bind_address: "127.0.0.1:8080"  # localhost만
  workers: 2                      # 개발용 적은 워커
  connection_pool_size: 20        # 작은 풀

backends:
  - name: "local-ollama"
    url: "http://localhost:11434"
    weight: 1

health_checks:
  enabled: true
  interval: "10s"                 # 빠른 피드백을 위한 잦은 확인
  timeout: "3s"
  unhealthy_threshold: 2
  healthy_threshold: 1

request:
  timeout: "300s"                 # 디버깅을 위한 긴 타임아웃
  max_retries: 1                  # 디버깅을 위한 최소 재시도

logging:
  level: "debug"                  # 상세 로깅
  format: "pretty"                # 사람이 읽기 쉬운 형식
  enable_colors: true             # 컬러 출력

cache:
  model_cache_ttl: "60s"          # 빠른 테스트를 위한 짧은 캐시
  deduplication_ttl: "10s"        # 짧은 중복 제거
  enable_deduplication: false     # 테스트를 위해 비활성화

마이그레이션 가이드

명령줄 인수에서 마이그레이션

현재 명령줄 인수를 사용하고 있다면 설정 파일로 마이그레이션하세요:

이전:

continuum-router --backends "http://localhost:11434,http://localhost:1234" --bind "0.0.0.0:9000"

이후: 1. 설정 파일 생성:

continuum-router --generate-config > config.yaml

  1. 설정 편집:

    server:
      bind_address: "0.0.0.0:9000"
    
    backends:
      - name: "ollama"
        url: "http://localhost:11434"
      - name: "lm-studio"
        url: "http://localhost:1234"
    

  2. 설정 파일 사용:

    continuum-router --config config.yaml
    

환경 변수에서 마이그레이션

설정 파일과 함께 환경 변수를 오버라이드로 계속 사용할 수 있습니다:

설정 파일 (config.yaml):

server:
  bind_address: "0.0.0.0:8080"

backends:
  - name: "default"
    url: "http://localhost:11434"

환경 오버라이드:

export CONTINUUM_BIND_ADDRESS="0.0.0.0:9000"
export CONTINUUM_BACKEND_URLS="http://localhost:11434,http://localhost:1234"
continuum-router --config config.yaml

설정 유효성 검사

서버를 시작하지 않고 설정을 검증하려면:

# 설정 로딩 테스트
continuum-router --config config.yaml --help

# dry-run으로 설정 확인 (향후 기능)
continuum-router --config config.yaml --dry-run

이 설정 가이드는 Continuum Router에서 사용할 수 있는 모든 설정 옵션에 대한 포괄적인 내용을 제공합니다. 유연한 설정 시스템을 통해 명확한 우선순위 규칙과 유효성 검사를 유지하면서 모든 배포 시나리오에 라우터를 적용할 수 있습니다.