30초 답변
기업용 AI Gateway는 여러 모델의 주소를 숨기는 프록시가 아니라 정책을 집행하는 제어 지점이어야 한다. 요청이 들어오면 업무 유형, 데이터 등급, 필요한 기능, 지연 한도를 먼저 판별하고, 그 조건을 만족하도록 사전에 승인된 후보 중 하나를 선택한다. 호출이 실패하면 오류 종류와 남은 시간에 따라 제한적으로 재시도하거나 계약이 호환되는 모델로 폴백한다. 공급자·모델·리전별 서킷 브레이커는 장애가 난 경로를 잠시 제외하고, 모든 경로에는 같은 인증·예산·보존·출력 검증·감사 정책을 적용한다.
핵심은 “가장 좋은 모델을 자동으로 고른다”가 아니다. 어떤 요청이 왜 어느 모델로 갔고, 실패하면 무엇을 허용하며, 사용자에게 어떤 품질 저하를 알릴지를 재현 가능한 규칙으로 만드는 것이다.
이 글의 핵심
- 라우팅은 모델 순위표가 아니라 업무 계약, 데이터 경계, 기능 지원, SLO를 함께 보는 정책 결정이다.
- 재시도, 폴백, 서킷 브레이커는 서로 다른 문제를 푼다. 한 규칙으로 합치면 재시도 폭주나 조용한 품질 저하가 생긴다.
- 전체 요청 deadline을 먼저 정하고 모델 호출, 재시도, 후처리에 시간 예산을 나눠야 한다.
- 폴백 모델은 같은 출력 스키마·도구·안전 정책을 통과한 후보만 허용한다.
- Gateway를 단일 장애 지점으로 만들지 말고, 결정 이유와 품질·비용·오류를 trace로 남긴다.
AI Gateway가 책임질 것과 책임지지 않을 것
Gateway의 책임은 공통 정책을 한곳에서 일관되게 집행하는 것이다. 인증, 테넌트별 한도, 허용 모델, 데이터 지역, 입력 크기, timeout, 오류 정규화, 출력 스키마 검증, 사용량 계측이 여기에 해당한다. 반면 “계약서 위험 조항을 어떻게 판단하는가” 같은 업무 의미는 도메인 서비스가 소유해야 한다. Gateway에 도메인 프롬프트와 예외를 계속 넣으면 중앙 병목이 된다.
권장 경계는 다음과 같다.
| 계층 | 책임 | 예시 |
|---|---|---|
| 도메인 애플리케이션 | 업무 목표와 정답 기준 | 계약 검토, 상담 요약, 코드 리뷰 |
| AI Gateway 정책 계층 | 허용 범위와 라우팅 결정 | 데이터 등급, 공급자, 모델군, 예산, deadline |
| 공급자 어댑터 | API 차이 정규화 | 메시지·도구·스트리밍·오류 매핑 |
| 검증 계층 | 기계적·업무적 출력 검사 | JSON Schema, 인용 존재, 금지 필드, 범위 검사 |
| 관측 계층 | 결정과 실행 증거 | route reason, provider, model, latency, retry, fallback |
이 분리는 모델을 바꿔도 도메인 코드를 최소한으로 바꾸게 한다. 다만 모든 공급자 기능을 가장 낮은 공통분모로 억지로 통일해서는 안 된다. 도구 호출, 이미지, 긴 컨텍스트, 구조화 출력처럼 기능 차이가 중요한 경우에는 capabilities를 명시하고 지원하지 않는 경로를 후보에서 제거한다.
권장 요청 흐름
사용자 요청
→ 인증·테넌트 확인
→ 데이터 등급·업무 유형·필요 기능 판별
→ 정책 엔진이 허용 후보 집합 생성
→ 라우터가 1차 경로 선택
→ 공급자 어댑터 호출(개별 timeout)
→ 출력 형식·업무 규칙 검증
→ 성공 응답 또는 제한적 재시도·폴백
→ trace·비용·정책 결정 기록
첫 단계에서 후보를 좁히는 것이 중요하다. 기밀 데이터가 외부 전송 금지라면 성능 점수가 높은 외부 모델도 후보가 아니다. 반대로 이미지 입력이 필수라면 텍스트 전용 경로를 넣지 않는다. 이처럼 정책 필터링을 먼저 하고, 품질·지연·비용 최적화는 허용된 후보 안에서만 수행한다.
라우팅 입력은 명시적 계약으로 만든다
애플리케이션이 Gateway에 자유문장만 보내지 말고 다음과 같은 메타데이터를 함께 보내면 결정이 설명 가능해진다.
{
"task_type": "contract_clause_extraction",
"data_class": "confidential",
"required_capabilities": ["structured_output"],
"quality_tier": "high",
"deadline_ms": 8000,
"max_cost_tier": "standard",
"region_policy": "approved-regions-only",
"fallback_policy": "same-contract-only"
}
deadline_ms 같은 값은 예시일 뿐이며 실제 수치는 서비스의 관측 데이터와 사용자 기대를 바탕으로 정한다. 모델명 대신 quality_tier, required_capabilities를 받으면 애플리케이션을 공급자 변경에서 분리할 수 있다. 예외적으로 규제 승인이나 재현성 때문에 특정 스냅샷이 필요한 업무는 모델을 고정하고 자동 라우팅을 끈다.
라우팅 기준: 품질·지연·비용만 보면 부족하다
| 기준 | 라우터가 확인할 질문 | 잘못 설계했을 때 |
|---|---|---|
| 업무 적합성 | 이 업무의 평가셋을 통과했는가? | 일반 벤치마크는 높지만 실제 추출이 틀림 |
| 기능 | 스키마, 도구, 이미지, 스트리밍을 지원하는가? | 폴백 후 응답 계약이 깨짐 |
| 데이터 정책 | 이 데이터 등급·지역·업체 전송이 허용되는가? | 정책 위반 또는 감사 불가 |
| 지연 | 현재 남은 deadline 안에 완료 가능한가? | 재시도 후 사용자 timeout |
| 가용성 | 최근 오류·포화·서킷 상태는 어떤가? | 장애 경로로 요청이 계속 몰림 |
| 예산 | 업무당 허용 비용과 사용량 한도 안인가? | 고비용 모델로 무제한 승격 |
| 재현성 | 고정 스냅샷·버전이 필요한가? | 같은 입력의 동작이 예고 없이 달라짐 |
라우팅 점수는 하나의 전역 수식보다 업무별 정책이 낫다. 예를 들어 “실시간 FAQ”는 지연을 우선하고, “배치 계약 검토”는 평가셋 품질과 출력 검증을 우선할 수 있다. 가중치는 운영 중 직감으로 바꾸지 말고, 오프라인 평가와 shadow traffic 결과를 근거로 버전 관리한다.
재시도와 폴백을 오류 종류별로 나눈다
모든 실패를 다음 모델로 보내면 비용과 지연만 늘고 같은 오류가 반복된다. OpenAI 오류 가이드는 rate limit과 일부 서버 오류에서 응답 헤더를 존중한 지수 백오프를 권고한다. Anthropic 오류 문서도 공식 SDK가 연결 오류·rate limit·5xx 같은 일시 오류를 기본적으로 제한 재시도하며 retry-after가 있으면 이를 따른다고 설명한다. 이는 “모든 오류를 재시도하라”가 아니라 일시 오류만, 제한된 횟수와 시간 안에서 재시도하라는 뜻이다.
| 실패 종류 | 기본 처리 | 이유 |
|---|---|---|
| 연결 단절·일시적 5xx | 같은 경로 제한 재시도, 이후 호환 경로 폴백 | 일시 복구 가능성이 있음 |
| 429·과부하 | retry-after 존중, 지터 백오프, retry budget 적용 | 즉시 반복은 장애를 키움 |
| 인증·권한 오류 | 재시도·자동 폴백 금지, 구성 오류로 처리 | 다른 모델로 보내도 정책 문제가 남음 |
| 잘못된 요청·컨텍스트 초과 | 입력 축소 또는 명시적 대체 경로 | 무변경 재시도는 같은 결과 |
| 안전 거절 | 사용자에게 안전한 안내, 임의 공급자 우회 금지 | 폴백을 정책 우회로 쓰면 안 됨 |
| 스키마 불일치 | 동일 모델 1회 교정 또는 계약 호환 모델 | 형식 실패와 의미 실패를 구분 |
| 업무 검증 실패 | 보류·사람 검토·재질문 | 모델을 바꿔도 정답 보장 안 됨 |
retry budget은 개별 요청의 횟수뿐 아니라 서비스 전체가 일정 시간 동안 수행할 수 있는 재시도 총량을 제한한다. Azure의 일시 장애 처리 가이드는 동시 요청들이 각각 소수 재시도를 해도 합쳐서 하위 서비스를 압박할 수 있으므로 집계 재시도 예산을 둘 것을 권한다.
폴백은 “성공”이 아니라 “계약을 유지한 대체”다
폴백 후보마다 다음을 사전에 검증한다.
- 같은 입력 형태와 필요한 기능을 지원하는가?
- 같은 JSON Schema와 업무 검증을 통과하는가?
- 같은 데이터·지역·보존 정책에서 허용되는가?
- 해당 업무 평가셋에서 최소 품질 기준을 넘는가?
- 품질이 낮아질 경우 UI에서 그 사실을 알릴 것인가?
예컨대 1차 모델이 인용이 포함된 구조화 응답을 만들도록 계약되어 있는데 폴백 모델이 자유문장만 반환한다면 이는 가용성 향상이 아니라 인터페이스 파손이다. “답변은 가능하지만 근거 검증을 완료하지 못했습니다”처럼 기능 축소 상태를 명시하고 사용자가 다시 시도하거나 사람 검토를 선택하게 한다.
timeout은 호출마다가 아니라 전체 deadline에서 역산한다
한 번의 사용자 요청에 10초가 허용된다고 해서 모델 호출마다 10초 timeout을 줄 수는 없다. 인증, 검색, 1차 호출, 검증, 재시도, 응답 전송이 모두 같은 예산을 쓴다.
전체 deadline
- 이미 사용한 시간
- 출력 검증·응답 전송 예약 시간
= 다음 시도에 쓸 수 있는 최대 시간
다음 시도가 남은 예산 안에 끝날 가능성이 낮다면 시작하지 않는다. 클라이언트가 연결을 끊거나 취소하면 가능한 하위 호출도 취소하고, 이미 발생한 외부 부작용은 별도 멱등성·보상 규칙으로 처리한다. 스트리밍은 첫 토큰 체감 시간을 줄일 수 있지만, 최종 완료 deadline과 출력 검증을 없애지는 않는다.
서킷 브레이커는 모델·리전 단위로 격리한다
Azure Circuit Breaker 패턴은 실패 임계치 이후 장애 난 원격 서비스 호출을 일시 차단하고, 회복 확인을 위해 제한된 시험 요청을 보내는 Closed → Open → Half-Open 상태를 설명한다. AI Gateway에서는 공급자 전체 하나보다 provider + model/deployment + region + capability 단위가 실용적이다. 한 리전의 특정 배포만 느린데 공급자 전체를 차단하면 정상 경로까지 잃기 때문이다.
- Closed: 정상 호출하고 오류율·timeout·429를 관찰한다.
- Open: 해당 경로를 후보에서 즉시 제외하고 빠르게 실패 또는 승인된 대체 경로로 보낸다.
- Half-Open: 소수 시험 요청만 허용한다. 성공이 확인되면 점진적으로 복구한다.
서킷을 열 기준은 평균만 보지 않는다. timeout, 연속 실패, 오류 종류, tail latency, rate limit을 분리하고 최소 표본과 관찰 구간을 둔다. 상태 전이는 반드시 알림과 trace 이벤트로 남긴다. 정적 임계치는 출발점일 뿐이며, 변경은 장애 회고와 부하 시험 근거로 관리한다.
인증·데이터·예산 정책을 라우팅과 같은 지점에서 집행한다
Gateway는 다음 정책을 라우팅 전에 적용해야 한다.
- 사용자·서비스·테넌트 인증과 업무 권한
- 데이터 등급별 허용 공급자·리전·기능
- prompt·응답·도구 인자의 마스킹과 로그 보존
- 테넌트·업무별 요청량, token, 비용 한도
- 승인된 모델 스냅샷과 공급자 계약 목록
- 도구 호출과 외부 전송에 대한 별도 승인
- 출력 스키마와 업무 규칙 검증
중요한 것은 route 결과만 기록하지 않고 policy_version, 후보에서 제외된 이유, 최종 선택 이유도 남기는 것이다. 단, prompt 원문과 개인정보를 관측 로그에 그대로 남기지 않는다. OpenTelemetry의 GenAI semantic conventions 공식 저장소처럼 공통 속성 체계를 참고하되, 안정성 상태와 수집 민감도를 확인하고 사내 표준을 버전 관리한다.
사용자 경험과 실패 시나리오
“답변 중” 화면만 오래 보이다가 갑자기 실패한다
1차 호출이 timeout된 뒤 같은 길이의 2차 호출을 시작했을 가능성이 높다. 전체 deadline에서 다음 시도 시간을 계산하고, 긴 작업은 비동기 실행과 상태 조회로 전환한다. UI에는 요청 접수 → 자료 조회 → 답변 검증처럼 실제 단계를 보여주되 내부 모델명이나 보안 정보를 노출하지 않는다.
같은 질문인데 답변 형식이 가끔 달라진다
폴백 경로의 스키마 지원 또는 어댑터가 다를 수 있다. route별 계약 테스트를 실행하고, 정규화 이후 같은 JSON Schema와 업무 검증을 통과한 결과만 반환한다. 어떤 경로가 응답했는지 trace에서 확인할 수 있어야 한다.
장애가 시작되자 호출량과 비용이 함께 증가한다
여러 계층에서 중복 재시도했을 가능성이 있다. SDK, Gateway, 애플리케이션 중 재시도 책임을 하나로 정하고, 총 retry budget과 서킷 브레이커를 적용한다. 멱등하지 않은 도구 호출은 모델 재시도와 분리한다.
폴백은 성공했지만 사용자가 결과를 신뢰하지 못한다
품질 저하를 숨기면 사용자는 결과 차이를 버그로 느낀다. 인용·검증 같은 핵심 기능이 빠졌다면 “간이 답변”, “검토 필요” 상태를 표시하고 원문 근거, 재시도, 사람 검토 경로를 제공한다.
구현 체크리스트
- Gateway와 도메인 서비스의 책임 경계가 문서화돼 있는가?
- 요청에 업무 유형, 데이터 등급, 필요 기능, deadline이 구조화돼 있는가?
- 정책 필터링 후에만 품질·지연·비용 라우팅을 수행하는가?
- 공급자별 기능 차이를 capability registry로 관리하는가?
- 인증·권한·안전 거절을 자동 폴백으로 우회하지 않는가?
- 재시도 가능 오류와 영구 오류가 명시적으로 분류돼 있는가?
- 지수 백오프, 지터,
retry-after, 총 retry budget을 적용하는가? - 전체 deadline에서 다음 호출의 timeout을 역산하는가?
- 서킷 브레이커가 공급자·모델·리전 단위로 격리돼 있는가?
- 폴백 후보가 동일 스키마·정책·업무 평가를 통과했는가?
- route reason, policy version, retry, fallback, breaker 상태를 trace로 남기는가?
- Gateway 자체의 다중 인스턴스, 무상태 처리, 설정 롤백을 검증했는가?
- 품질 축소와 실패 상태를 사용자가 이해하고 복구할 수 있는가?
자주 묻는 질문
Q1. 모델이 하나뿐이어도 AI Gateway가 필요한가?
여러 모델 라우팅은 필요 없지만 인증, 사용량 한도, 데이터 정책, 오류 정규화, 출력 검증을 여러 애플리케이션에서 공통으로 써야 한다면 가치가 있다. 반대로 단일 소규모 서비스가 이미 같은 정책을 안정적으로 집행한다면 별도 Gateway는 운영 복잡성만 늘릴 수 있다. 중앙화할 공통 정책이 실제로 있는지부터 판단한다.
Q2. 가장 저렴한 모델부터 호출하고 실패하면 큰 모델로 올리면 되나?
업무 평가로 작은 모델이 최소 품질을 충족하고, 승격 조건이 관측 가능한 경우에만 유효하다. 모델이 자신 있게 틀린 결과는 기술적 실패로 잡히지 않으므로 단순 “오류 시 승격”으로는 부족하다. 위험도 높은 업무는 처음부터 검증된 경로를 사용하거나 업무 검증 실패·낮은 근거 품질을 승격 신호로 정의한다.
Q3. 폴백 공급자가 있으면 가용성이 자동으로 높아지나?
아니다. 두 공급자가 같은 네트워크, 같은 클라우드 리전, 같은 인증 계층 또는 같은 Gateway에 의존하면 공통 장애가 남는다. 폴백이 실제로 독립적인지, 데이터 정책상 허용되는지, 계약이 호환되는지 부하·장애 주입 시험으로 확인해야 한다. Gateway 자체도 복제와 설정 롤백이 필요하다.
근거 자료
- OpenAI, API Error codes
- Anthropic, Claude API errors
- Microsoft Azure Architecture Center, Circuit Breaker pattern
- Microsoft Azure Architecture Center, Transient Fault Handling
- OpenTelemetry, Generative AI semantic conventions