AI 기능의 킬 스위치는 버튼 하나가 아니라 단계별 강등 경로다
AI 기능이 잘못된 답을 내놓기 시작했을 때 운영팀이 할 수 있는 조치가 전체 서비스를 끄는 것뿐이라면 대응 설계가 늦은 것이다. 공급자 장애, 특정 모델 회귀, 프롬프트 배포 실수, 검색 인덱스 오염, 도구 권한 오류는 피해 범위가 다르다. 하나의 전역 on/off 스위치는 너무 거칠고, 모델을 자동으로 계속 재시도하는 정책은 장애를 더 비싸게 만든다.
좋은 킬 스위치는 사용자, 테넌트, 기능, 모델, 도구, 위험 등급별로 트래픽을 줄이고 결정론적 경로로 강등한다. 누가 어떤 근거로 켰는지 기록되고, 오래 켜진 스위치가 자동으로 드러나야 한다. 이 글은 AI 제품의 회로 차단기와 feature flag를 실제 사고 대응 흐름으로 연결한다.
먼저 끌 대상을 기능 단위로 쪼갠다
‘AI 검색’ 하나에도 쿼리 재작성, 벡터 검색, reranking, 답변 생성, 인용 검증이 있다. 답변 생성 모델만 불안정하다면 검색 결과 목록은 계속 제공할 수 있다. ‘에이전트’도 읽기 도구와 쓰기 도구를 나누면 고객 정보 조회는 유지하고 환불·삭제만 막을 수 있다. 제품 UI 이름이 아니라 부작용과 의존성 기준으로 제어면을 만든다.
flag 키는 ai.answer_generation, ai.tool.write.refund, ai.retrieval.reranker처럼 계층적으로 설계할 수 있다. 전역, 환경, 테넌트, 사용자 cohort override의 우선순위를 문서화한다. 긴급 상황에서 어떤 값이 이겼는지 몰라 시간을 쓰지 않도록 평가 결과와 source flag ID를 요청 로그에 남긴다.
킬 스위치와 회로 차단기의 역할은 다르다
킬 스위치는 사람이 의도적으로 기능을 중지하거나 강등하는 제어다. 회로 차단기는 오류율, 타임아웃, 포화도 같은 신호가 임계치를 넘을 때 자동으로 호출을 멈추고 잠시 후 제한적으로 회복을 시험한다. 둘을 같은 boolean으로 구현하면 자동 복구가 사람의 사고 대응 결정을 덮어쓸 수 있다.
상태를 normal, degraded, blocked_manual, blocked_automatic, probe로 분리한다. manual block은 자동 타이머가 해제하지 못하게 하고, automatic block은 cooldown 후 소량 probe를 보낸다. 모델 공급자 5xx와 콘텐츠 정책 위반은 같은 임계치를 쓰지 않는다. 전자는 짧은 창의 오류율, 후자는 단 한 건의 고위험 사건으로도 쓰기 도구를 차단할 수 있다.
강등 경로를 장애 때 처음 만들지 않는다
생성 답변을 끄면 빈 화면이 나오는 제품은 운영자가 스위치를 누르기 어렵다. 각 기능에 deterministic fallback을 준비한다. RAG 답변 생성이 막히면 검색 문서 제목과 검증된 발췌를 보여주고, 자동 분류가 막히면 기본 큐로 보내며, 코딩 에이전트 쓰기 권한이 막히면 diff 제안만 생성한다.
fallback은 정상 경로와 다른 데이터 계약을 가질 수 있으므로 UI와 API가 상태를 표현해야 한다. 응답에 mode: normal|degraded, degradation_reason_code, retryable을 넣고 사용자 문구와 내부 이유를 분리한다. 공급자 이름이나 보안 사고 내용을 그대로 노출하지 않으면서 “자동 답변 대신 관련 문서를 표시합니다”처럼 사용자가 다음 행동을 알 수 있게 한다.
시나리오 1: 새 프롬프트가 환불 정책을 잘못 해석한다
금요일 배포 후 일부 국가에서 30일 환불을 90일로 답하기 시작했다고 하자. 전체 챗봇을 끄기보다 prompt_version과 locale을 기준으로 canary를 즉시 0%로 내리고 이전 버전으로 되돌린다. 이미 잘못된 답이 나간 세션은 response ID로 조회해 상담 검토 큐에 넣는다. 단순 롤백만으로 이미 발생한 피해가 사라지지 않는다.
배포 시스템은 프롬프트와 검색 문서, 모델 설정을 하나의 release manifest로 묶어야 한다. 모델만 이전으로 돌렸는데 새 문서가 남아 있으면 원인이 지속될 수 있다. incident log에는 영향을 받은 locale, policy document version, 응답 수, 사용된 citation을 기록한다. 복구 기준은 오류율이 내려갔다는 것뿐 아니라 고정된 환불 회귀셋과 실제 canary에서 올바른 정책이 확인되는 것이다.
시나리오 2: CRM 쓰기 도구가 중복 레코드를 만든다
에이전트가 CRM 연락처를 중복 생성하면 생성 모델 전체를 차단할 필요는 없다. create_contact만 block하고 search_contact, draft_note는 유지한다. UI는 자동 저장 대신 검토 가능한 초안을 보여준다. 백엔드에서는 차단된 호출을 성공처럼 모델에 돌려주면 안 된다. tool_unavailable_policy라는 기계 판독 가능한 결과를 반환해 모델이 다른 쓰기 도구로 우회하지 못하게 한다.
동일 권한 그룹의 update_contact도 같은 결함 경로를 공유하는지 blast radius를 확인한다. 차단 이벤트 이후 대기 중이던 workflow를 무작정 재개하지 않고 operation ID와 현재 CRM 상태를 재검증한다. 복구 canary는 내부 테스트 tenant에서 시작해 create 성공률뿐 아니라 duplicate constraint violation과 idempotency conflict를 본다.
임계치는 평균이 아니라 피해 속도에 맞춘다
1분에 백만 번 호출되는 추천 기능의 1% 오류와 하루 열 번 실행되는 송금 에이전트의 한 번 오류는 의미가 다르다. 자동 차단 조건에 오류 비율, 최소 표본 수, 절대 사건 수, 위험 가중치를 함께 둔다. latency는 p95가 SLO를 넘는 시간과 큐 깊이를 조합하고, 비용 폭주는 시간당 token spend와 요청당 token 이상치를 본다.
저빈도 고위험 기능은 통계 임계치를 기다리지 않고 정책 위반 한 건에 write_tools를 차단할 수 있다. 반면 자유형 요약의 품질 신호는 자동 판정 오탐이 많으므로 경고와 사람 확인을 거친다. 어떤 지표가 자동 차단 권한을 갖는지 runbook에 적고, metric pipeline 지연이나 결측 시 fail-open인지 fail-closed인지 기능별로 결정한다.
복구는 스위치를 다시 켜는 행위가 아니다
장애가 사라졌다고 바로 100% 트래픽을 복구하면 동일 결함을 재현한다. 차단 상태에서 synthetic probe를 실행하고, 내부 tenant 1%, 외부 1%, 10%, 50%처럼 단계적으로 올린다. 각 단계의 관찰 시간과 rollback threshold를 미리 정한다. 캐시된 잘못된 결과나 오래된 workflow가 남아 있다면 모델 복구와 별개로 무효화한다.
복구 승인자는 차단한 사람과 같을 필요는 없지만, 고위험 쓰기 기능에는 2인 승인을 둘 수 있다. 승인 화면에는 원인, 수정 release ID, 회귀 테스트 결과, canary 지표, 남은 수동 정리 건수를 보여준다. 자동 차단이 반복해서 열리고 닫히는 flapping을 막기 위해 cooldown과 연속 성공 창을 둔다.
도입 전 확인할 제어면과 로그
모든 AI 요청에 feature_id, tenant_id, release_id, model_route, tool_name, risk_class, flag_evaluation, degraded_mode, circuit_state를 연결한다. flag 변경 감사 로그에는 변경자, 이전 값, 새 값, 이유, incident ID, 만료 시각을 남긴다. 긴급 override에는 기본 만료를 두어 임시 차단이 몇 달간 숨지 않게 한다.
분기마다 게임데이로 모델 5xx, latency 급증, 잘못된 prompt release, 쓰기 도구 중복 실행을 주입한다. 목표는 ‘알람이 울렸다’가 아니라 담당자가 어떤 스위치를 몇 분 안에 찾고, 사용자에게 어떤 fallback이 보이며, 어느 지표로 복구를 승인했는지 확인하는 것이다. 버튼의 존재가 아니라 피해 범위를 좁히고 안전한 기능을 유지하는 강등 경로가 AI 킬 스위치의 완성도다.
게임데이에서 반드시 확인할 실패 장면
첫 번째 훈련은 주 공급자 timeout이다. 자동 회로 차단기가 열리고 대체 모델로 이동할 때, 대체 모델이 같은 tool schema와 structured output을 지원하는지 확인한다. 호환되지 않으면 읽기 전용 fallback으로 내려가야지 형식 오류를 재시도하며 비용을 늘려서는 안 된다. 대체 공급자까지 동시에 느릴 때의 최종 정적 응답도 확인한다.
두 번째는 품질 사고다. HTTP 상태는 모두 정상인데 특정 locale에서 금지된 안내가 나온 상황을 주입한다. 네트워크 오류 알람만 있는 팀은 이를 잡지 못한다. 신고 이벤트와 정책 평가 샘플에서 incident를 열고 locale·release 단위 flag를 내린 뒤 영향 응답을 검색할 수 있어야 한다. 로그에 prompt와 개인정보를 과도하게 남기지 않으면서 response ID로 근거를 보존하는 절차도 시험한다.
세 번째는 flag 시스템 자체 장애다. 설정 서비스를 읽지 못할 때 환불 도구가 기본 허용되는지 차단되는지 확인한다. 고위험 쓰기 기능은 last-known-good 설정과 짧은 로컬 캐시를 쓰더라도 만료 후 fail-closed가 적절할 수 있다. 반면 문서 요약은 fail-open 또는 정적 fallback이 낫다. 게임데이 결과에는 탐지 시간, 차단 시간, fallback 성공률, 복구 canary 시간, 수동 정리 건수를 남겨 다음 분기의 구체적인 목표로 사용한다.
팀 회의에서 숫자로 답해야 할 질문
이 주제를 운영 회의에 올릴 때는 ‘좋아졌다’는 표현을 금지하고 circuit_state, degraded_mode 성공률, flag evaluation source의 이전 값, 변경 후 값, 표본 수를 한 화면에 놓는다. 특히 고위험 쓰기 도구만 차단된 canary를 재현한 부하 또는 회귀 샘플을 고정해야 다음 배포와 비교할 수 있다. 정상 요청만 모은 평균은 사고 직전의 위험을 설명하지 못한다. 실패·강등·재시도가 포함된 분모와 제외 규칙도 함께 기록한다.
담당자는 지표 변화에 대응하는 단 하나의 조치를 미리 연결한다. circuit_state가 경계를 넘으면 어떤 배포를 되돌릴지, degraded_mode 성공률가 늘면 어떤 큐나 샘플을 열어볼지, flag evaluation source의 이상을 누가 확인할지를 runbook에 적는다. 알람이 다섯 개 동시에 울리는데 모두 ‘조사 필요’로 끝나면 제어면이 없는 것과 같다. 변경자는 release ID와 예상 효과를 남기고, 관찰 창이 끝난 뒤 실제 효과와 부작용을 기록한다.
마지막 검토에서는 비용과 품질을 같은 요청 ID로 연결한다. 비용이 줄었지만 실패 재시도가 늘었거나, 정확도가 올랐지만 p95가 제품 예산을 넘으면 성공이 아니다. 이 글에서 제시한 메트릭은 보고용 숫자가 아니라 다음 행동을 고르는 분기 조건이다. 임계치, 관찰 시간, rollback 조건까지 적혀 있을 때 비로소 구현 지식이 운영 정책이 된다.