내 에이전트는 모든 검사를 통과했지만 한 시간 만에 운영 환경을 망가뜨렸다. 현재 내가 실행 중인 CI/CD 프로세스.
요약
에이전트 프롬프트 변경이 운영 환경에서 문제를 일으킨 사례를 통해, 오프라인 평가와 카나리 배포를 결합한 에이전트 전용 CI/CD 프로세스의 중요성을 설명합니다.
핵심 포인트
- 오프라인 평가(Eval)는 데이터 세트의 한계로 인해 실제 트래픽의 모든 케이스를 포착할 수 없음
- 카나리 배포를 통해 실제 트래픽에서 발생하는 퇴보를 조기에 감지하고 자동 롤백 수행 필요
- 빠른 검사, 대규모 평가, 시뮬레이션, 카나리 배포의 4단계 체크포인트 구축 권장
얼마 전 우리 팀은 무해해 보이는 변경 사항을 병합했습니다. 에이전트의 도구 라우팅 (tool-routing) 프롬프트를 약간 리팩토링 (refactor)한 것이었습니다. 린트 (lint)를 통과했고, 단위 테스트 (unit tests)도 통과했습니다. 우리의 평가 게이트 (eval gate)도 통과했습니다. 하지만 한 시간도 채 되지 않아, 운영 환경 (production)에서의 도구 호출 (tool-call) 정확도가 눈에 띄게 퇴보했고, 저는 온콜 (on-call) 상태로 롤백 (rollback)을 진행해야 했습니다.
원인을 파고들어 보니 원인은 거의 지루할 정도였습니다. 우리의 평가 세트 (eval set)는 트래픽 중 디스패치-도구 (dispatch-tool) 영역을 거의 다루지 못했고, 그래서 새로운 프롬프트는 게이트가 잡아낼 사례가 없는 바로 그 지점에서 퇴보를 일으켰습니다. 게이트는 자신이 볼 수 있는 모든 것에 대해 제 역할을 다했습니다. 단지 문제를 일으킨 그 부분을 보지 못했을 뿐입니다.
하루 뒤 우리는 동일한 변경 사항을 다시 배포했습니다. 이번에는 실제 트래픽을 측정하고 스스로 롤백하는 카나리 (canary) 뒤에 배치했습니다. 카나리는 램프업 (ramp) 초기 단계에서 퇴보를 조기에 포착했고, 자동 되돌리기 (automatic revert)가 이루어진 후 온콜 (on-call) 담당자에게 한 번의 페이지 (paged)가 전송되었습니다. 그날 저는 에이전트를 위한 CI/CD의 실제 형태를 이해했습니다. 오프라인 게이트 (offline gate)는 자신이 볼 수 없는 것에 대해 실패를 허용하며 (fails open), 카나리는 오프라인 게이트가 놓친 부분을 보완하여 루프를 닫습니다 (closes the loop). 두 가지 모두가 필요합니다. 하나라도 없으면 희망에 의존하여 배포하게 됩니다.
요즘 저는 이를 "PR 오픈"과 "모두에게 배포" 사이의 네 가지 체크포인트로 생각합니다:
- 모든 PR에 대해 약 90초 이내에 수행하는 빠른 검사 (Fast checks). 프롬프트 템플릿 (Prompt template)이 여전히 파싱되는지, 도구 스키마 (Tool schemas)가 유효한지, 고정된 소규모 케이스 세트가 여전히 통과하는지, 그리고 토큰 수 (Token count)가 폭증하지 않았는지 확인합니다. 이는 비용이 많이 드는 프로세스를 실행하기 전에 오타, 깨진 스키마, 그리고 "새 프롬프트가 세 배나 길어짐"과 같은 문제를 잡아냅니다.
- 머지(Merge) 시점에 수행하는 5~15분 정도의 더 큰 평가 (Eval). 일반적인 트래픽, 엣지 케이스 (Edge cases), 그리고 과거의 실패 사례를 다루는 수백 개의 케이스를 판사 (Judge) 모델로 점수를 매깁니다. 제가 확인하는 것은 절대적인 수치가 아니라, 새 버전이 메인 (Main) 브랜치보다 더 나빠지지는 않았는지 여부입니다. 이것이 왜 중요한지는 아래에서 더 자세히 다룹니다.
- 배포 전, 위험한 변경 사항을 위한 시뮬레이션 단계 (Simulation pass). 몇 가지 페르소나 (Personas)를 활용한 멀티 턴 (Multi-turn) 대화, 탈옥 (Jailbreak) 및 프롬프트 인젝션 (Prompt-injection) 탐지, 그리고 에이전트가 회복할 수 있는지 확인하기 위해 의도적으로 망가뜨린 도구 응답 (Tool responses) 등을 수행합니다. 실제로 사용자에게 도달하는 실패 사례의 대부분은 첫 번째 턴이 아니라 두 번째 또는 세 번째 턴에서 나타나며, 오직 이 단계에서만 이를 잡아낼 수 있습니다.
- 머지 후, 하루에 걸쳐 점진적으로 확대하는 카나리 (Canary) 배포. 트래픽의 1%에서 시작하여 5%, 25%, 100%로 늘려가며, 전 과정에서 라이브 요청 샘플의 점수를 측정합니다. 만약 품질이 떨어지거나, 가드레일 (Guardrails)이 작동하기 시작하거나, 지연 시간 (Latency)이 상승하거나, 요청당 비용 (Cost per request)이 급증하면, 대부분의 사용자가 인지하기 전에 자동으로 롤백 (Rollback)됩니다.
이 모든 과정에 덧붙이고 싶은 단 하나의 게이팅 (Gating) 조언은 다음과 같습니다: 고정된 점수가 아니라, 변경 사항(Change)을 기준으로 게이팅하십시오. 저는 예전에 "충실도 (Faithfulness)가 특정 숫자 이상을 유지해야 한다"라고 말하곤 했습니다. 문제는 그 숫자가 스스로 움직인다는 점입니다. 제공업체가 마이너한 모델 수정 버전을 출시하면 모든 점수가 조금씩 변합니다. 케이스를 추가함에 따라 평가 세트 (Eval set)는 점점 더 어려워집니다. 절대적인 임계값 (Thresholds)은 잘못된 경보를 울리거나, 아무것도 잡아내지 못할 때까지 완화되어 버립니다. 대신 새 버전을 메인과 비교하면, 각 변경 사항이 오직 작고 제한된 범위 내에서만 미끄러질 수 있게 되며, 작은 하락치들이 조용히 쌓이는 것을 방지할 수 있습니다.
제가 느리게 배운 또 다른 사실은 평가 데이터셋 (eval set)은 부패한다는 것입니다. "검사를 통과했는데도 운영 환경이 망가졌다"는 상황의 가장 흔한 버전은, 평가 데이터셋이 몇 달 전부터 이미 운영 환경과 닮지 않게 된 경우입니다. 새로운 유형의 요청이 나타나고, 오래된 요청은 사라지며, 검사 게이트 (gate)는 계속해서 잘못된 것들을 체크하게 됩니다. 그래서 저는 이를 살아있는 것으로 취급합니다. 엣지 케이스 (edge cases)의 일부와 과거 장애 사례의 일부를 포함하여 실제 트래픽에 가깝게 편향시키고, 매달 검토하며, 매 분기마다 일부를 새로 고침하고, 모든 사후 분석 (postmortem)의 마지막에는 최소한 하나 이상의 새로운 사례를 추가하며 마무리합니다. 우리가 이미 경험한 실패가 조용히 다시 반복되어서는 안 됩니다.
그리고 가장 이상한 에이전트 버그는 코드에 아무런 변경 사항이 없는데도 에이전트의 성능이 저하되는 경우입니다. 이는 거의 항상 상류 (upstream)의 문제입니다. 제공업체가 모델을 업데이트했거나, 점수를 매기는 판정기 (judge)가 변질된 것입니다. 그래서 저는 가능한 한 고정 (pin)합니다. 유동적인 이름 대신 날짜가 지정된 모델 스냅샷 (model snapshots)을 사용합니다. 일반적인 이름은 사용자의 발밑에서 계속 변하지만, 날짜가 지정된 이름은 변하지 않기 때문입니다. 또한 판정기를 고정하여 "동일한 평가"가 실제로 동일한 평가를 의미하도록 유지합니다. 그런 다음 매주 점검을 통해 점수가 이유 없이 변했는지 확인하며, 이는 보통 모델이 저도 모르게 변경되었음을 의미합니다.
이 과정에서 제가 빠졌던 몇 가지 함정들은 다음과 같습니다:
- 의미 수준의 퇴보 (meaning-level regressions)를 린트 (lint)와 단위 테스트 (unit tests)가 잡아낼 것이라고 믿는 것. 그들은 잡아내지 못할 것입니다.
- 실제 운영 환경에서 발생하는 기이한 5%의 요청을 전혀 반영하지 못하는, 깨끗하고 쉬운 쿼리들로만 구성된 평가 데이터셋.
- 아무런 모니터링 없이 트래픽의 일부를 새 버전으로 라우팅하면서 그것을 카나리 (canary)라고 부르는 것. 실시간 점수 측정 (live scoring) 없이는 그것은 그저 느린 배포 (slow rollout)일 뿐입니다.
- 수동 롤백 (manual rollback). 이는 사용자에게 직접적인 피해를 주는 시간을 몇 분씩 추가합니다. 스스로 복구되도록 두는 것이 핵심입니다.
이 중 어느 것도 이국적인 인프라가 아닙니다. 이는 대부분 게이트가 모든 것을 볼 수 없다고 가정하고, 첫 번째 그물에 구멍이 있는 곳에 두 번째 그물을 설치하는 규율의 문제입니다. 만약 당신이 에이전트 변경 사항을 배포한다면, 당신은 어디에 선을 긋는지 궁금합니다. 변경 사항이 실제 사용자에게 도달하기 전에 무엇을 통과해야 하며, 스스로 롤백될 것이라고 신뢰하나요?
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기