← Ascendy EN

backend

한 모델만 404가 났다 — 프리뷰 alias 시한폭탄과 분기 비대칭

· Ascendy Engineering


TL;DR

배경 — 왜 하나만 죽나

여러 LLM 프로바이더를 골라 쓰는 에이전트 채팅이 있었다. 그런데 한 모델만 — 그것만 — 고를 때마다 404가 났다. 나머지 프로바이더는 멀쩡했다.

한 모델만 실패”는 그 자체가 강한 단서다. 공통 경로(인증, 네트워크, 요청 포맷)가 문제면 보통 전부 깨진다. 하나만 깨졌다는 건 그 모델이 다른 분기를 타고 있다는 뜻이다.

원인 1 — 분기 비대칭 (fall-through)

범인은 라우팅에 있었다. 런타임 모델 선택 미들웨어가 일부 프로바이더만 명시적으로 클라이언트에 매핑했고, 문제의 프로바이더엔 매핑이 없었다. None이 반환됐고, override 없이 에이전트의 base 모델로 그대로 fall through했다.

# 분기 비대칭: 일부 프로바이더만 명시 매핑, 나머지는 None → base 모델로 fall through
def _resolve_client(model_name: str):
    if model_name in PROVIDER_A_ALIASES:
        return client_a
    if model_name in PROVIDER_B_ALIASES:
        return client_b
    if model_name in PROVIDER_C_ALIASES:
        return client_c
    return None  # 매핑 없는 프로바이더 → None → 에이전트 base 모델로 fall through

다른 프로바이더들은 명시 매핑이라 자기 클라이언트로 안전하게 갔다. 매핑이 빠진 하나만 base 모델 id에 직접 노출됐다 — 그리고 그 base id가 문제였다.

원인 2 — base가 프리뷰 alias였다

fall-through가 도달한 base 모델 id가 프리뷰 alias로 고정돼 있었다. 프리뷰 alias는 deprecation 공지 후 정해진 일정에 따라 shutdown될 수 있다. shutdown되면 그 id로의 호출은 404 NOT_FOUND(“no longer available”)가 된다.

우리 경우 그 fall-through 경로의 프로바이더가 Gemini였다. 프리뷰 모델이 GA로 승격되면서 기존 프리뷰 alias가 사라졌고(모델 수명주기는 공개 문서로 확인된다), 그 한 경로만 404로 죽은 것이다. 코드에 박아둔 프리뷰 id가 시한폭탄이었던 셈이다.

수정 — GA id + 회귀 가드

즉각 수정은 base를 GA id로 교체하는 한 줄이었다. 거기에 전 코드베이스를 훑어 곧 sunset될 세대의 모델도 같이 교체했다.

핵심은 그다음에 넣은 회귀 가드다. “지금 정답인 모델 id”를 핀하지 않았다 — 그 id 자체도 언젠가 폐기되므로, 정답을 박으면 세대 교체마다 테스트가 깨진다(brittle). 대신 금지 패턴을 검사했다.

# 회귀 가드: 정답 id를 핀하지 말고, 폐기/프리뷰 패턴만 금지
for client in configured_model_clients:
    mid = model_id(client)
    assert "preview" not in mid        # deprecate/shutdown될 수 있는 프리뷰 alias 금지
    assert SUNSET_GENERATION not in mid  # 곧 폐기될 세대 금지

모델 id는 본질적으로 perishable(언젠가 만료된다)하다. 이 가드가 만료될 id 전체를 잡지는 못한다 — 알려진 위험 패턴(프리뷰 alias, 특정 sunset 세대)을 막아 프로바이더의 lifecycle 모니터링을 보완하는 장치다. 다만 “다음 세대로 올릴 때마다 깨지는” brittleness 없이 그 패턴을 막는다는 점이, 정답 id를 핀하는 것보다 낫다.

다음에 같은 함정에 빠지지 않으려면

후속


저작·인용: 이 글은 Ascendy Engineering이 작성했으며 출처 표기 시 재인용 가능합니다. 잘못된 정보를 발견하면 GitHub 이슈로 알려주세요.


Tags: llm, model-lifecycle, regression-testing, incident-prevention, multi-provider