15명 동시 접속에 무너진 코드 생성 파이프라인
Amazon Bedrock에서 Claude Code를 도입한 15명의 개발자가 동시에 접속하자 ThrottlingException(요청 제한 초과 오류)이 발생하며 서비스가 중단됐다. 2명의 개발자가 참여한 파일럿 단계에서는 모든 기능이 정상 작동했으나, 전체 인원이 세션을 시작한 지 몇 분 만에 코드 생성이 중간에 멈추는 현상이 나타났다. 개발자들의 불만이 슬랙(Slack) 채널을 통해 실시간으로 보고될 만큼 서비스 장애의 체감이 컸으며, 코드 완성이 중간에 멈추는 현상이 반복되며 개발 흐름이 끊겼다. 이는 코드 생성 워크플로우의 특성을 고려하지 않은 가드레일 설정이 API 요청 폭증으로 이어진 결과다.
함수 하나를 생성할 때 발생하는 평균 5,000자의 코드 분량이 요청 폭증의 직접적인 원인이다. 기본 스트리밍 설정은 50자마다 가드레일 평가를 수행하며, 이로 인해 개발자 1명이 함수 하나를 완성할 때 100회의 API 호출이 발생한다. 15명이 동시에 세션을 유지하며 코드를 생성할 경우, 시스템은 초당 1,500건의 평가 요청을 처리해야 한다. 1인당 100회라는 호출 횟수가 15명의 동시 세션과 곱해지며 기하급수적인 요청 수치가 발생한 것이다. 단순한 기본 설정값이 동시 접속자 수와 결합해 인프라가 감당할 수 없는 수준의 부하를 만들며 API 응답 지연을 초래했다.
활성화된 가드레일의 개수는 부하를 더욱 가중시켰다. 해당 환경에서는 프롬프트 공격 탐지(입력값 조작을 통한 시스템 제어 시도 방지), 민감 정보 필터(유출된 인증 정보 가리기 또는 차단), 안전하지 않은 코드 패턴 필터 등 3개의 보안 장치를 동시에 적용했다. 이 설정으로 인해 매 평가마다 1개가 아닌 3개의 텍스트 유닛이 소비되며 전체 처리량 소모가 3배로 늘어났다. 텍스트 유닛 소비량이 가드레일 수에 비례해 증가하는 구조 때문에, 3개의 보안 장치를 모두 켠 상태에서의 평가 비용은 단일 필터 적용 시보다 훨씬 무거웠다. 보안 강화를 위해 추가한 필터들이 서로 곱해지며 서비스 가용성을 떨어뜨리는 병목 지점이 됐다.
이러한 실시간 스캔 방식은 실제 개발자의 작업 습관과 정반대로 작동한다. 개발자는 코드를 한 줄 쓸 때마다 린터(Linter, 코드 문법 및 스타일 검사 도구)나 포맷터(Formatter, 코드 형식 자동 정리 도구), 보안 스캐너를 실행하지 않는다. 이들은 보통 커밋(Commit, 변경 사항 저장) 시점에 한 번에 검증을 수행한다. 중간 수정 과정이나 삭제된 줄, 미완성된 함수를 매번 검사하지 않고 최종 결과물이 완성된 시점에만 확인하는 방식이다. 개발자가 실제로 중요하게 생각하는 검증 시점은 코드가 완성되어 저장되는 순간이지, 타이핑하는 매 순간이 아니다. 50자 단위의 인라인 스캔은 개발자의 생산성 방식과 맞지 않는 과도한 검증 주기이며, 이는 보안 가치 대비 불필요한 자원 소모를 일으킨다.
1,000자당 1유닛, 곱절로 늘어나는 가드레일 소비량 계산법
가드레일의 자원 소비량은 1,000자를 1 텍스트 유닛(Text Unit)으로 정의하고 여기에 적용된 보호 장치의 개수를 곱하는 방식으로 산정한다. 텍스트 유닛은 Amazon Bedrock에서 과금과 쿼터 제한의 기준이 되는 최소 단위다. 텍스트의 길이를 1,000으로 나눈 값에 활성화된 가드레일의 수를 곱하면 최종 소비량이 도출되는 구조다. 예를 들어 1,000자의 텍스트를 3개의 서로 다른 보호 장치로 평가하면 총 3 텍스트 유닛이 소비된다. 텍스트 길이가 2,000자로 늘어나면 동일한 조건에서 소비량은 6 텍스트 유닛으로 증가하며 텍스트 양과 보호 장치 수에 정비례하여 자원을 소모한다.
콘텐츠 필터(Content Filters)는 내부의 세부 카테고리 활성화 여부와 상관없이 1,000자당 1 텍스트 유닛으로 처리한다. 이 필터 내부에는 혐오, 모욕, 성적, 폭력, 비행, 프롬프트 공격이라는 6가지 세부 카테고리가 포함되어 있다. 사용자가 이 6가지 카테고리를 모두 활성화하여 검사 범위를 최대화하더라도 소비량은 여전히 1 텍스트 유닛으로 유지된다. 단일 정책 유형 내에서 검사 항목을 추가하는 행위는 자원 소비량에 영향을 주지 않도록 설계되었다.
자원 소비를 배수로 늘리는 승수 관계는 서로 다른 정책 유형 간의 조합에서 발생한다. 정책 유형은 콘텐츠 필터, 거부 주제(Denied Topics), 민감 정보 필터(Sensitive Information Filters) 등으로 구분된다. 거부 주제는 모델이 답변해서는 안 될 특정 주제를 정의하며 민감 정보 필터는 개인 식별 정보(PII)를 찾아내어 마스킹하거나 차단하는 역할을 한다. 만약 이 세 가지 정책 유형을 모두 활성화한 상태에서 텍스트를 평가하면 텍스트 1,000자당 총 3 텍스트 유닛이 소모된다. 정책 유형을 하나씩 추가할 때마다 전체 소비량이 계단식으로 증가하는 방식이다.
이러한 계산 구조는 보안 강도를 높이기 위해 여러 정책을 중첩할수록 쿼터 소모 속도가 빠르게 가속됨을 의미한다. 텍스트 길이가 길어질수록 1,000자 단위의 배수가 커지고 여기에 정책 수라는 승수가 곱해지기 때문이다. 특히 긴 응답을 생성하는 워크플로우에서는 텍스트 양의 단순 증가보다 적용된 정책의 가짓수가 전체 비용과 처리량 제한에 더 결정적인 영향을 미친다. 결과적으로 사용자는 보안 수준과 자원 소비 사이의 균형을 맞추기 위해 활성화할 정책 유형을 전략적으로 선택해야 한다.
기존 방식과 달라진 지점
코드 생성 워크플로우는 짧은 문답이 오가는 일반 대화형 AI와 달리 수천 자에 달하는 긴 텍스트를 실시간으로 출력하는 특성을 가진다. 일반적인 대화형 AI는 사용자가 입력한 짧고 불연속적인 프롬프트에 대해 모델이 응답을 내놓는 구조로 작동하며, 요청과 응답의 단위가 명확히 구분된다. 하지만 코드 생성은 함수 하나를 작성할 때도 수천 자의 결과물이 스트리밍(streaming, 생성되는 즉시 조각 단위로 전송하는 방식) 형태로 출력된다. 출력물의 길이가 길어질수록 가드레일이 검사해야 하는 데이터의 총량은 기하급수적으로 늘어나며, 이는 가드레일 엔진이 처리해야 하는 요청의 성격과 부하 수준을 완전히 다르게 만든다.
실제 개발 환경에서는 다수의 개발자가 동시에 세션을 열어 작업하며 반복적인 컨텍스트 평가(context evaluation, 이전 대화 내용과 현재 출력이 안전 정책에 부합하는지 확인하는 과정)를 수행한다. 코드는 한 번의 생성으로 완성되지 않고, 개발자의 요구에 따라 수정과 보완을 거치며 계속해서 다시 생성되는 반복적 특성을 가진다. 모델이 이전의 코드 맥락을 유지하며 새로운 코드를 덧붙이거나 기존 로직을 수정할 때마다, 시스템은 변경된 부분뿐 아니라 전체적인 문맥을 다시 평가해야 한다. 동시 다발적인 세션에서 이러한 반복 평가가 일어나면 가드레일 서버로 전달되는 요청 밀도는 일반 대화형 서비스보다 훨씬 높게 형성되어 인프라에 가해지는 압박이 커진다.
생성되는 토큰을 즉시 검사하는 인라인 스캔(inline scanning, 텍스트가 완성되기 전 생성 단계에서 실시간으로 필터링하는 방식)을 적용하면 평가 횟수가 비정상적으로 증가한다. 코드 생성처럼 출력량이 많은 작업에서는 텍스트가 조금만 생성되어도 가드레일 평가가 계속해서 호출되는 구조다. 수천 자의 코드가 출력되는 동안 시스템은 아주 짧은 간격으로 끊임없이 보안 검사를 수행하며, 이는 출력 길이와 평가 횟수가 정비례하는 결과를 낳는다. 하지만 코드의 특성상 실제 보안상 위험한 패턴이 발견될 확률은 낮으며, 대부분의 검사는 무의미한 반복 작업에 그친다. 결국 보안 수준의 유의미한 향상을 얻지 못한 채 과도한 평가 횟수만 발생하여 시스템 자원을 낭비하고 API 쿼터 소모를 가속화하는 비효율이 발생한다.
인라인 스캔(Inline Scanning)이 만드는 리소스 낭비의 실체
`guardrailConfig`를 Converse 또는 InvokeModel API(모델 호출 인터페이스)에 직접 연결하면 인라인 스캔(Inline Scanning) 방식으로 동작한다. 이 방식은 모델이 토큰을 생성하는 실시간 시점에 입력 프롬프트 전체와 스트리밍 출력 내용을 활성화된 가드레일로 계속 평가하는 구조다. 짧은 문답이 오가는 일반적인 대화형 AI 환경에서는 프롬프트와 응답이 모두 간결하므로 평가에 드는 오버헤드(추가 비용이나 시간)가 적어 효율적으로 작동한다.
하지만 코드 생성 워크플로우에서는 인라인 스캔이 심각한 리소스 낭비를 초래한다. 코딩 어시스턴트는 단순한 답변을 내놓지 않고 추론 과정과 상세한 주석, 그리고 반복적인 수정 사항이 포함된 수천 자의 텍스트를 스트리밍으로 출력하기 때문이다. 인라인 평가가 활성화되면 모델이 내뱉는 모든 텍스트 조각을 설정된 모든 가드레일로 매번 검사한다. 이 과정에서 이전 평가 이후 전혀 변하지 않은 정적 시스템 프롬프트나 도구 정의, 이전 대화 기록까지 매 턴마다 다시 평가하는 중복 작업이 반복된다.
이러한 중복 평가는 보안 수준의 유의미한 향상 없이 비용만 증가시키고 할당된 쿼터(사용량 제한)를 빠르게 소모하게 만든다. 동일한 보일러플레이트(반복되는 표준 코드) 지침과 컨텍스트를 매번 다시 읽으며 텍스트 유닛(과금 단위)을 소비하기 때문이다. 특히 코드 생성 특성상 출력 길이가 길어질수록 평가 횟수는 기하급수적으로 늘어나며, 이는 실제 제공되는 안전 가치에 비해 과도한 리소스가 투입되는 결과를 낳는다. 변하지 않는 텍스트를 반복해서 스캔하는 행위는 보안상의 이득 없이 비용만 높이는 결과를 초래한다.
결국 이 문제는 짧은 대화형 교환에 최적화된 패턴을 대량의 텍스트가 발생하는 고처리량 코드 생성 파이프라인에 그대로 적용하면서 발생한 구조적 불일치다. 정적인 컨텍스트와 동적인 출력을 구분하지 않고 전체를 매번 스캔하는 방식은 코드 생성 환경에서 성능 저하의 핵심 원인이 된다. 불필요한 반복 평가를 제거하지 않는 한, 가드레일 적용으로 인한 비용 부담과 요청 제한 문제는 지속될 수밖에 없다. 이는 단순한 설정 오류가 아니라 데이터의 흐름과 평가 시점이 맞지 않는 설계상의 한계에서 기인한다.
Git pre-commit hook 방식의 전략적 체크포인트 검증 도입
실시간으로 모든 토큰을 검사하는 인라인 스캔과 특정 시점에만 검증하는 체크포인트 방식은 API 호출 횟수와 지연시간에서 뚜렷한 차이를 만든다. 인라인 스캔은 모델이 글자를 생성할 때마다 가드레일을 작동시키지만, 체크포인트 방식은 리스크 프로필(위험 요소의 특성)이 변하는 경계 지점에서만 검증을 수행한다. 특히 코드 생성 워크플로우는 일반적인 대화와 달리 출력량이 매우 많고 에이전틱 루프(AI가 스스로 계획하고 실행하는 반복 과정)를 포함하는 특성이 있다. 이러한 환경에서 모든 토큰을 감시하는 방식은 보안 가치 대비 과도한 API 호출을 유발하며 시스템 전체의 병목 현상을 일으킨다. 정의된 경계에서만 검증하는 구조로 전환하면 불필요한 호출을 제거하고 응답 속도를 최적화할 수 있다.
이 방식은 개발자가 코드를 작성할 때 모든 타이핑마다 린터(코드 문법 및 스타일 검사 도구)를 돌리지 않고 커밋 시점에만 검증하는 Git pre-commit hook과 작동 원리가 같다. pre-commit hook은 변경 사항을 저장소에 반영하기 직전이라는 명확한 경계에서 자동으로 실행되는 스크립트다. 이는 수정된 코드가 공유 코드베이스라는 공용 영역에 포함되기 전 마지막 관문 역할을 수행하며, 이 시점에 모든 검증과 테스트를 한꺼번에 처리한다. 가드레일 역시 스트리밍되는 모든 토큰을 개별적으로 평가하는 대신, 최종 결과물이 완성되는 시점과 같은 전략적 체크포인트에서 한 번에 검증하는 구조를 취한다. 개별 토큰의 안전성보다는 완성된 코드 블록의 전체적인 안전성을 확인하는 것이 효율적이라는 판단에 근거한다.
전략적 체크포인트(Strategic Checkpoints)를 도입하면 가드레일 평가 횟수가 획기적으로 줄어든다. 코드 생성처럼 출력물이 장황한 경우, 활성화된 가드레일 수와 텍스트 양이 곱해지는 관계가 용량 계획(Capacity Planning, 예상 사용량에 맞춘 자원 할당)의 핵심 변수가 된다. 스트리밍 출력의 모든 단계에서 가드레일을 호출하면 요청 제한 초과 오류가 발생할 가능성이 매우 높지만, 검증 시점을 최종 출력 단계나 논리적 구분점으로 설정하면 API 호출 빈도가 낮아진다. 이는 지연시간을 최적화할 뿐만 아니라, 견고한 안전 범위를 유지하면서도 효율적인 인프라 청사진을 설계하는 기반이 된다. 결과적으로 시스템 부하를 최소화하면서도 보안 요구 사항을 충족하는 실무적인 최적화가 가능하다.
결론적으로 짧은 대화형 응답에는 실시간 인라인 스캔을 적용하고, 수천 자 이상의 긴 코드를 생성하는 워크플로우에는 최종 결과물 시점에 검증하는 체크포인트 방식을 선택하는 것이 리소스 효율을 극대화하는 기준이다.




