각 요청에 대해 Auto, TokenLab Verified 또는 Official를 선택할 수 있으며, 가격은 사전에 표시됩니다. 새로운 기능 확인하기

AI 모델의 지원 종료(Deprecation) 및 버전 관리: API 통합을 안정적으로 유지하는 방법

·2026년 9월 19일·약 5분 읽기·업데이트 2026년 10월 2일·1819 조회수
#모델 수명 주기#AI API#모델 인프라#TokenLab
AI 모델의 지원 종료(Deprecation) 및 버전 관리: API 통합을 안정적으로 유지하는 방법

모델 문자열은 코드베이스에서 가장 위험한 상수입니다. 팀에서는 이를 단순한 라벨처럼 취급하지만, 실제로는 어떤 체크포인트가 응답할지, 호출 비용이 얼마인지, 요청이 성공할지 여부를 결정합니다. 따라서 AI 모델 지원 중단 및 버전 관리는 일회성 출시 결정이 아니라 릴리스 프로세스의 일부가 되어야 합니다. 이 가이드에서는 2026년 10월 3일 기준으로 관찰된 TokenLab의 공개 모델 API를 사용하여, 자동으로 확인할 수 있는 항목, 다른 곳에서 검증해야 하는 항목, 그리고 ID가 작동을 멈췄을 때 취해야 할 조치를 설명합니다.

핵심 요약

  • 수명 주기 데이터는 모델 객체에 포함되어 있습니다. 블로그 게시물에서 날짜를 복사하는 대신 Get a Model(2026년 10월 3일 관찰됨)에서 tokenlab.lifecycle을 읽으십시오.
  • 2026년 10월 3일에 확인한 5개 모델 모두 active 상태였으며 지원 중단이나 은퇴 날짜는 없었습니다. 저희가 확보한 증거에는 실제로 지원이 중단된 모델이 없으므로, 아래의 실패 경로는 실제로 발생한 사례가 아닌 문서화된 동작을 기반으로 합니다.
  • 모델이 없으면 model_not_found가 반환되지만, 상태 코드는 엔드포인트마다 다릅니다. 상태 코드만 보지 말고 code 값을 기준으로 분기하십시오.
  • 정확한 ID를 고정하고 단일 설정 계층에서 관리하십시오. TokenLab은 사용자가 보낸 모델을 임의로 교체하지 않는다고 명시하고 있습니다.
  • 대체 모델(fallback)은 반드시 사전에 테스트되고 승인된 선택지여야 합니다. 모델마다 기능, 요청 형식, 제한 사항, 가격이 모두 다르기 때문입니다.

API에서 AI 모델 지원 중단 및 버전 관리가 나타나는 곳

Get a Model 참조(2026년 10월 3일 관찰됨)에 따르면 lifecycle 필드는 가용성, 출시일, 지원 중단일, 대체 모델 정보를 포함합니다. List Models 참조(2026년 10월 3일 관찰됨)는 각 목록 항목에 tokenlab.lifecycle, tokenlab.aliases, tokenlab.commercial, tokenlab.badges를 추가합니다. 같은 페이지에 tokenlab.accepted_request_formats와 토큰 제한 사항이 나열되어 있으며, 이는 모델 교체 시 중요한 고려 사항입니다.

다음은 2026년 10월 3일 claude-sonnet-5 실시간 모델 API에서 읽어온 값입니다. 이는 관찰된 값을 요약한 것입니다. 저희 증거는 원시 중첩 키 이름이 아닌 값을 기록했으므로, 정확한 키는 실제 응답을 통해 확인하십시오.

GET https://api.tokenlab.sh/v1/models/claude-sonnet-5
category:             chat
lifecycle stage:      active
released:             2026-06-30
replacement model:    None
deprecated_at:        None
retired_at:           None
max input tokens:     1000000
max output tokens:    128000
accepted formats:     anthropic_messages, openai_chat_completions

5가지 수명 주기 개념을 해당 필드에 다음과 같이 매핑하십시오:

개념 관찰된 응답의 필드 claude-sonnet-5의 값
단계 lifecycle stage active
출시 released 2026-06-30
지원 중단 deprecated_at None
은퇴 retired_at None
대체 replacement model None

값이 비어 있다고 해서 항상 문제가 있는 것은 아닙니다. glm-5.2와 gpt-5.5의 경우, 실시간 API(2026년 10월 3일 관찰)에서 단계는 active이지만 released는 None으로 표시됩니다. 검사는 deprecated_at이 설정되었거나, retired_at이 설정되었거나, 단계가 active가 아닐 때 실패해야 합니다. 출시일이 없다고 해서 실패해서는 안 됩니다.

또한 deepseek-v4-pro와 deepseek-v4-flash(둘 다 2026년 4월 24일 출시, 활성 상태, 대체 모델 없음)도 확인했습니다. 이로써 지원 중단 신호가 없는 모델 5개를 확인했습니다. 지원이 중단된 모델의 대체 모델 필드는 저희가 관찰하지 못한 유일한 값입니다.

의존성이 문제가 생겼을 때 실패하는 스크립트

아래 검사는 문서화된 GET /v1/models/{model} 엔드포인트만 사용하며, 카탈로그가 공개되어 있으므로 API 키가 필요하지 않습니다. ID가 없거나, deprecated_at 또는 retired_at이 설정되었거나, 단계가 active가 아니거나, 모델이 더 이상 허용하지 않는 요청 형식일 경우 실패합니다.

#!/usr/bin/env python3
"""의존 중인 모델 ID가 없거나, 지원이 중단되었거나, 은퇴했을 때 실패 처리."""
import json
import sys
import urllib.error
import urllib.request

BASE = "https://api.tokenlab.sh/v1/models/"

# 모델 ID -> 우리 코드가 실제로 보내는 요청 형식
DEPENDENCIES = {
    "gpt-5.5": "openai_chat_completions",
    "claude-sonnet-5": "anthropic_messages",
    "deepseek-v4-pro": "openai_chat_completions",
}

def fetch(model_id):
    req = urllib.request.Request(BASE + model_id, headers={"Accept": "application/json"})
    try:
        with urllib.request.urlopen(req, timeout=15) as resp:
            return resp.status, json.load(resp)
    except urllib.error.HTTPError as exc:
        try:
            body = json.load(exc)
        except ValueError:
            body = {}
        return exc.code, body

def check(model_id, fmt):
    try:
        status, body = fetch(model_id)
    except urllib.error.URLError as exc:
        return [f"확인 불가: {exc.reason}"], {}, []
    if status in (400, 404):
        return [f"누락됨: HTTP {status}"], {}, []
    if status != 200:
        return [f"확인 불가: HTTP {status}"], {}, []

    info = body.get("tokenlab", {})
    life = info.get("lifecycle") or {}
    problems = []
    if not life:
        problems.append("수명 주기 블록이 반환되지 않음")
    stage = life.get("stage")  # 실제 응답을 통해 정확한 키 확인
    if stage not in (None, "active"):
        problems.append(f"stage={stage}")
    for key in ("deprecated_at", "retired_at"):
        if life.get(key):
            problems.append(f"{key}={life[key]}")
    if fmt not in info.get("accepted_request_formats", []):
        problems.append(f"형식 {fmt} 허용되지 않음")
    return problems, life, info.get("aliases", [])

def main():
    failed = False
    for model_id, fmt in DEPENDENCIES.items():
        problems, life, aliases = check(model_id, fmt)
        if problems:
            failed = True
            print(f"FAIL {model_id}: {'; '.join(problems)}")
            if life:
                print(f"     lifecycle: {json.dumps(life)}")
        else:
            print(f"ok   {model_id} aliases={aliases}")
    sys.exit(1 if failed else 0)

if __name__ == "__main__":
    main()

CI와 야간 스케줄에서 실행하십시오. 모델은 귀하의 커밋 없이도 상태가 변경될 수 있기 때문입니다. 마지막 배포가 일주일 전인데 화요일에 야간 작업이 실패한다고 가정해 보십시오. 이것이 핵심입니다. 실패는 고객의 채팅 창이 아닌 파이프라인에서 나타나야 합니다. 스크립트는 실패 시 전체 수명 주기 블록을 출력하므로, 사람이 키 이름을 추측할 필요 없이 대체 값을 확인할 수 있습니다.

은퇴했거나 알 수 없는 모델의 반환값

증거 자료에는 별도로 "은퇴(retired)"라고 표시된 응답이 아니라, 알 수 없거나 사용할 수 없는 모델에 대한 내용만 있습니다. 따라서 별도의 확인이 있기 전까지는 은퇴를 같은 유형의 오류로 취급합니다. 2026년 10월 3일 기준으로 문서에 명시된 내용은 다음과 같습니다:

위치 응답 출처
GET /v1/models/{model} 404 model_not_found Get a Model
철자가 틀렸거나 사용할 수 없는 모델로 채팅 요청 400 model_not_found, 선택적으로 did_you_mean, suggestions, hint 포함 에이전트가 처리할 수 있는 오류
선택한 Delivery tier에 공급이 없는 경우 503 all_channels_failed 또는 503 delivery_tier_unavailable, retryable: false 에이전트가 처리할 수 있는 오류
키에 모델에 대한 권한이 없는 경우 403 model_not_allowed API 오류 처리

엔드포인트마다 상태 코드가 다르므로 한 가지 수정 사항이 중요합니다. 원본 기사의 대체 코드는 404와 410을 "식별자 사라짐"으로 처리했는데, 이는 채팅 요청에는 잘못된 방식입니다. 문서화된 채팅 응답은 400이며, 오류 가이드에서는 HTTP 상태와 code를 기준으로 오류를 처리하라고 명시합니다. code == "model_not_found"를 기준으로 로직을 작성하십시오.

예를 들어, 문서에는 철자가 틀린 ID가 did_you_mean: "gpt-5.6-terra"를 반환하는 예시가 있습니다. 클라이언트는 다음 순서로 대응해야 합니다:

  1. 요청을 변경 없이 반복하지 마십시오. 오류 가이드에서는 400, 403, 404를 반복 불가능한 오류로 표시합니다.
  2. did_you_mean을 제안으로 취급하십시오. 제품에 이미 모델을 변경할 권한이 있는 경우에만 전환하십시오.
  3. 503 본문에 retryable: false라고 되어 있으면 재시도를 멈추십시오. 문서에 따르면 유사한 이름이 가용성을 보장하지는 않습니다.
  4. 응답 헤더의 Request ID를 모델 및 작업 ID와 함께 저장하십시오.
  5. 사람에게 알림을 보내십시오. 고정된 ID가 사라진 것은 일시적인 오류가 아니라 릴리스 이벤트입니다.

정확한 ID 고정 또는 별칭(alias) 사용

모범 사례 가이드(2026년 10월 3일 관찰)는 각 요청에서 모델 ID를 명시적으로 유지하고 임의로 모델을 전환하지 말라고 권고합니다. 대체 모델이 품질, 가격, 컨텍스트 길이, 도구 또는 미디어 지원을 변경할 수 있다고 경고합니다. 오류 가이드는 TokenLab이 사용자가 보낸 모델을 임의로 교체하지 않는다고 덧붙입니다.

전략 동작 주요 위험
gpt-5.5와 같은 정확한 ID 고정 해당 모델을 얻거나 오류 발생 ID가 제거될 경우 치명적인 실패
별칭(alias) 사용 이름이 시간이 지남에 따라 새로운 곳을 가리킬 수 있음 코드 변경 없이 동작 및 비용이 변경될 수 있음
설정 내 내부 경로 이름 코드는 primary_chat을 요청하고, 설정에서 정확한 ID로 매핑 매핑을 직접 소유하고 테스트해야 함

별칭에 관해서는 간극을 발견했습니다. List Models 참조에는 모든 항목에 tokenlab.aliases가 있다고 되어 있지만, 저희가 확보한 5개의 실시간 발췌본(claude-sonnet-5, deepseek-v4-pro, deepseek-v4-flash, glm-5.2, gpt-5.5) 중 별칭 값이 표시된 것은 없습니다. 현재 어떤 모델이 어떤 별칭을 가지고 있는지 알 수 없습니다. 위의 스크립트는 각 의존성에 대한 aliases를 출력하므로, 실행하여 결과를 확인하십시오.

카탈로그에 관한 두 가지 사실이 더 도움이 됩니다. 2026년 10월 2일 카탈로그는 버전을 claude-sonnet-4-6, claude-sonnet-5, claude-sonnet-5-5와 같이 별도의 정확한 ID로 나열합니다. 나란히 나열되어 있다고 해서 하나가 후속 모델인 것은 아닙니다. replacement 값이 해당 관계를 나타내는 유일한 곳입니다. grok-voice-latest라는 ID는 이름에 "latest"가 포함되어 있습니다. 이것이 무엇을 따르는지에 대한 증거가 없으므로, 신뢰하기 전에 모델 페이지를 확인하십시오. 마켓플레이스 스타일의 접두사가 붙은 ID는 TokenLab 별칭이 아닙니다. 마이그레이션 가이드는 TokenLab ID에 OpenRouter 제공자 접두사가 없다고 명시하며, LiteLLM 별칭을 TokenLab ID와 별도로 유지할 것을 제안합니다.

사라진 고정 모델을 위한 대체(fallback) 패턴

대체 모델을 사전에 테스트한 두 번째 고정 모델로 취급하십시오. 호출 지점마다 선택하고, 어떤 모델이 각 답변을 제공했는지 기록하며, 동일한 야간 스크립트로 검증하십시오. 두 모델을 페어링하기 전에 비교하십시오:

모델 (실시간 API, 2026-10-03 관찰) 1M 토큰당 입력/출력 최대 입력/출력 토큰 요청 형식 나열된 기능
gpt-5.5 $1.50 / $9.00 1,000,000 / 128,000 openai_chat_completions, openai_responses 코딩, json-mode, prompt-cache, 추론, 도구 사용, 비전
claude-sonnet-5 $0.90 / $4.50 1,000,000 / 128,000 anthropic_messages, openai_chat_completions json-mode, prompt-cache, 추론, 도구 사용, 비전
deepseek-v4-pro 비피크 $0.66 / $1.98; 피크 $1.32 / $3.96 1,000,000 / 384,000 anthropic_messages, openai_chat_completions, openai_responses json-mode, prompt-cache, 도구 사용

세 모델 모두 가격은 2026년 10월 2일 16:53:30.068Z에 마지막으로 업데이트되었습니다. 차이점이 중요합니다. claude-sonnet-5는 openai_responses를 허용하지 않으므로 Responses 기반 호출자는 대체 모델로 사용할 수 없습니다. deepseek-v4-pro는 비전이나 추론 기능을 나열하지 않으므로 이미지가 포함된 요청은 여기서 실패합니다. DeepSeek의 피크 시간대는 베이징 시간 기준 09:00-12:00 및 14:00-18:00입니다.

다음은 비용 추정치입니다. 일일 부하를 1,000만 입력 토큰과 200만 출력 토큰으로 가정합니다(측정치가 아닌 예시 수치):

  • gpt-5.5: 10 × $1.50 + 2 × $9.00 = $15 + $18 = 일일 $33.
  • claude-sonnet-5: 10 × $0.90 + 2 × $4.50 = $9 + $9 = 일일 $18.
  • deepseek-v4-pro 비피크: 10 × $0.66 + 2 × $1.98 = $6.60 + $3.96 = 일일 $10.56.
  • deepseek-v4-pro 피크: 10 × $1.32 + 2 × $3.96 = $13.20 + $7.92 = 일일 $21.12.

이는 추정치이며 캐시된 입력은 가격이 다르게 책정됩니다. 아래 코드는 재시도로 해결할 수 없는 오류에 대해서만 대체 모델을 사용합니다. 429 또는 재시도 가능한 5xx 오류는 일반적인 재시도 규칙을 따라야 합니다.

import logging
import os

import openai

log = logging.getLogger("model-routing")

client = openai.OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
    timeout=30.0,
    max_retries=0,  # 반복해도 안전한지 여부를 직접 결정
)

ROUTES = {
    "primary_chat": {"model": "gpt-5.5", "fallback": "claude-sonnet-5"},
    "coding_agent": {"model": "claude-sonnet-5", "fallback": "deepseek-v4-pro"},
}

def _error(exc):
    body = exc.body if isinstance(exc.body, dict) else {}
    err = body.get("error", body)
    return err if isinstance(err, dict) else {}

def _chat(model_id, text):
    resp = client.chat.completions.create(
        model=model_id,
        messages=[{"role": "user", "content": text}],
    )
    return resp.choices[0].message.content

def call_model(route, text):
    """반환 (응답한_모델, 텍스트). 결과를 모델과 함께 기록."""
    cfg = ROUTES[route]
    try:
        return cfg["model"], _chat(cfg["model"], text)
    except openai.APIStatusError as exc:
        err = _error(exc)
        code = err.get("code")
        gone = code == "model_not_found"
        no_supply = (
            code in ("all_channels_failed", "delivery_tier_unavailable")
            and err.get("retryable") is False
        )
        if not (gone or no_supply):
            raise  # 401/402/403/429 등은 다른 수정이 필요함
        log.warning("고정된 모델 %s 사용 불가 (%s); %s 사용 중",
                    cfg["model"], code, cfg["fallback"])
        return cfg["fallback"], _chat(cfg["fallback"], text)

대체 모델은 한 번만 전환하며 연쇄적으로 연결하지 않습니다. 대체 모델도 실패하면 오류를 발생시키고 담당자에게 알림을 보내십시오. 대체 모델의 무분별한 연쇄는 또 다른 형태의 드리프트 문제입니다.

AI 모델 지원 중단 및 버전 관리 릴리스 체크리스트

프로덕션 모델 ID를 변경하기 전에 실행하십시오. 모범 사례 가이드(2026년 10월 3일 관찰)를 반영하고 수명 주기 검사를 추가했습니다.

  1. 프로덕션의 모든 모델 ID를 나열하고 각각을 사용하는 호출 지점의 이름을 지정하십시오. 단일 설정 계층에서 몇 초 안에 답변할 수 있어야 합니다.
  2. 현재 ID와 후보 ID에 대해 수명 주기 스크립트를 실행하십시오. deprecated_at, retired_at, 단계, 대체 모델을 읽으십시오.
  3. Get a Model의 accepted_request_formats를 사용하여 후보 모델이 코드가 보내는 요청 형식을 허용하는지 확인하십시오.
  4. 최대 입력 및 최대 출력 토큰을 가장 긴 실제 요청 및 출력 제한과 비교하십시오.
  5. 기능을 비교하십시오. 제품이 의존하는 비전, 도구 사용, json-mode, 추론 기능을 확인하십시오.
  6. 현재 가격으로 비용을 다시 계산하십시오(위의 계산 방식 참고). DeepSeek의 경우 피크 및 비피크 시간대를 구분하십시오.
  7. 배포할 정확한 후보 ID와 형식으로 대표 요청을 재현하십시오. 알 수 없는 ID와 같은 실패 사례를 하나 포함하십시오.
  8. 오류 경로를 검증하십시오. 클라이언트는 code를 기준으로 분기하고, Request ID를 유지하며, 400, 403, 404를 재시도하지 않아야 합니다.
  9. 이전 ID를 문서화된 롤백 값으로 유지한 채 설정 변경으로 변경 사항을 배포하십시오.
  10. 모든 응답 기록에 실제로 응답한 모델이 저장되는지 확인하십시오.
  11. 릴리스 후 야간 스크립트를 다시 실행하십시오. 대체 모델 ID도 통과하는지 확인하십시오.

문서에 내용이 없는 경우, 이 체크리스트가 안전장치입니다. 지원 중단에 대한 사전 예고나 알림 채널이 없으므로, 제공자의 공지를 별도로 확인하고 모델 자체 페이지에서 수명 주기 관련 메모를 확인하십시오.

FAQ

TokenLab 모델이 지원 중단되었는지 은퇴했는지 어떻게 알 수 있나요?

GET /v1/models/{model}을 호출하여 tokenlab.lifecycle을 읽으십시오. 단계, deprecated_at, retired_at 및 대체 모델을 확인하십시오. 2026년 10월 3일 기준으로 확인한 5개 모델은 모두 active 상태였으며 날짜가 설정되지 않았습니다. 값은 요청한 순간의 상태만 반영하므로 다시 폴링하십시오.

알 수 없는 모델 ID는 어떤 HTTP 상태를 반환하나요?

엔드포인트에 따라 다릅니다. Get a Model은 404 model_not_found를 반환하고, 잘못된 모델로 채팅 요청을 보내면 400 model_not_found를 반환합니다. 선택한 Delivery tier에 공급이 없는 모델은 503을 반환합니다. code 필드를 기준으로 분기하십시오.

model_not_found 오류를 재시도해야 하나요?

아니요. 동일한 요청을 반복해도 결과는 바뀌지 않습니다. did_you_mean과 suggestions가 있으면 확인하되, 제품에 이미 권한이 있는 경우에만 모델을 전환하십시오. 그렇지 않으면 사전에 승인된 대체 모델을 사용하고 팀에 알리십시오.

내 모델이 사라지면 TokenLab이 내 요청을 다른 모델로 전환하나요?

문서에 따르면 사용자가 보낸 모델을 임의로 교체하지 않습니다. 명시적인 ID를 보내고 오류를 직접 처리하십시오. 대체 모델은 플랫폼에 대한 가정이 아니라 테스트된 설정 값이어야 합니다.

다음 모델 변경 전에 모델 디렉토리에서 현재 ID, 제한 사항 및 가격을 비교하십시오.

출처

2026-10-03 기준 가격

관련 모델

최근 출시된 모델

이 가이드의 모델로 바로 구축하기

가격을 비교하고 라우트를 테스트한 뒤, 조사 내용을 실제 API 호출로 이어가세요.