AI 에이전트 평가 루프 구축법: AutoRater와 실패 클러스터링으로 프롬프트 회귀 잡기
요약: 에이전트 품질 관리는 ‘프롬프트를 고친 뒤 몇 개 예시가 좋아 보이면 배포’하는 방식으로는 오래 버티기 어렵다. Google은 최근 coding agent 안에서 평가 flywheel을 돌리는 접근을 설명했다. 핵심은 데이터 준비, 추론 실행, 독립 평가, 실패 분석, 최적화 반복을 하나의 루프로 묶는 것이다. 실무팀은 특정 벤더 기능을 그대로 쓰지 않더라도 이 구조를 가져와야 한다. 특히 optimizer가 자기 결과를 직접 채점하지 않게 분리하는 원칙이 중요하다.
왜 에이전트 평가는 일반 QA와 다른가
전통적인 소프트웨어 QA는 입력과 기대 출력이 비교적 명확하다. 버튼을 누르면 API가 호출되고, DB 값이 바뀌고, 화면에 결과가 나온다. 에이전트는 다르다. 사용자의 목표를 해석하고, 중간 계획을 만들고, 도구를 호출하고, 대화 중 변경된 의도를 반영해야 한다. 같은 최종 답변처럼 보여도 내부 경로가 틀릴 수 있고, 내부 상태는 맞지만 사용자에게 오래된 정보를 말할 수도 있다.
이 때문에 에이전트 평가는 단순 정답 비교보다 trace 평가가 중요하다. 어떤 도구를 언제 호출했는지, 사용자의 최신 요구를 반영했는지, 금지된 작업을 시도하지 않았는지, 실패했을 때 솔직히 말했는지 봐야 한다. Google이 제시한 flywheel도 trace를 중심에 둔다. OpenTelemetry trace, hand-crafted case, synthetic scenario를 평가 데이터로 만들고, 실행 결과를 model-based judge나 custom metric으로 채점한다.
5단계 평가 루프
첫 번째 단계는 Prepare Data다. 여기서 가장 좋은 재료는 실제 운영 trace다. 단, 개인정보와 민감정보는 제거해야 한다. 초기 제품이라 운영 데이터가 부족하면 synthetic scenario를 만들 수 있다. 중요한 것은 ‘성공 예시’보다 ‘깨질 가능성이 높은 예시’를 많이 넣는 것이다. 날짜 변경, 중간 취소, 애매한 지시, 권한 부족, 도구 실패, 긴 대화 후 요구 수정 같은 케이스가 필요하다.
두 번째는 Run Inference다. 같은 dataset에 대해 현재 agent를 실행해 trace를 만든다. 이미 운영 trace가 있다면 이 단계를 건너뛸 수 있다. 세 번째는 Grade다. Google 문서에서 강조하듯 grading은 항상 실행돼야 하는 단계다. 여기서 adaptive AutoRater나 custom rubric이 trace를 평가한다. 네 번째는 Analyze Failures다. 실패가 적으면 사람이 verdict를 직접 읽고, 실패가 많으면 clustering으로 반복 패턴을 찾는다. 다섯 번째는 Optimize & Iterate다. prompt, tool description, state update, planner logic, guardrail 중 하나를 고치고 다시 2~4단계를 돈다.
독립 평가자가 필요한 이유
가장 중요한 원칙은 optimizer가 자기 작업을 직접 채점하지 않는 것이다. 프롬프트를 고친 같은 모델이나 같은 agent가 개선 여부를 판단하면 metric gaming이 생긴다. 모델은 실제 품질을 올리기보다 평가 문구에 맞는 답을 만드는 방향으로 최적화될 수 있다. 사람 개발자도 비슷한 함정에 빠진다. 방금 고친 케이스만 다시 보면서 좋아졌다고 느끼기 쉽다.
실무에서는 최소한 세 가지를 분리한다. 수정 제안자, 실행 환경, 평가자다. 수정 제안자는 coding agent일 수 있고, 개발자일 수도 있다. 실행 환경은 고정된 dataset과 동일한 tool mock 또는 sandbox를 사용한다. 평가자는 별도 모델, 별도 rubric, 또는 사람 리뷰어가 맡는다. 절대 점수보다 중요한 것은 before/after delta다. model-based judge의 단일 점수는 흔들릴 수 있지만, 같은 기준으로 반복 측정한 변화는 더 쓸모 있다.
custom rubric을 만들어야 하는 순간
범용 task success 점수만 보면 중요한 실패가 평균에 묻힌다. Google의 예시에서도 사용자가 중간에 여행 조건을 바꿨을 때 agent가 그 변경을 반영했는지 따로 revision_honored라는 rubric을 만들었다. built-in metric은 문제를 감지할 수 있지만, 여러 기준 중 하나로 섞이면 점수가 0.80처럼 괜찮아 보일 수 있다. 제품 위험이 큰 행동은 별도 rubric으로 승격해야 한다.
예를 들어 B2B SaaS 에이전트라면 다음 rubric이 필요할 수 있다. permission_respected: 권한 없는 데이터에 접근하지 않았는가. latest_user_intent_used: 대화 중 최신 요구를 반영했는가. tool_result_grounded: 도구 결과와 다른 말을 하지 않았는가. escalation_needed: 사람에게 넘겨야 할 상황에서 넘겼는가. no_unapproved_side_effect: 승인 없이 외부 변경을 하지 않았는가. 이런 rubric은 평균 만족도보다 장애 예방에 더 직접적이다.
실패 클러스터링을 어떻게 쓰나
실패가 3~5개라면 사람이 직접 읽는 편이 빠르다. 실패가 30개를 넘으면 클러스터링이 필요하다. 실패 설명, trace event, tool error, user intent를 묶어서 공통 원인을 찾는다. 클러스터 예시는 ‘최신 날짜 변경 무시’, ‘도구 오류를 사용자 오류로 설명’, ‘검색 결과 근거 없이 확정 표현’, ‘권한 부족 시 대체 경로 없음’처럼 나와야 한다. 좋은 클러스터 이름은 바로 backlog ticket 제목으로 쓸 수 있어야 한다.
클러스터링의 목적은 모든 실패를 한 번에 고치는 것이 아니다. 가장 높은 빈도와 가장 큰 리스크를 가진 클러스터 하나를 고르고, 한 가지 수정을 적용한 뒤 다시 평가하는 것이다. 여러 프롬프트와 도구 설명을 동시에 바꾸면 무엇이 좋아졌는지 알 수 없다. 에이전트 최적화는 실험 설계에 가깝다.
최소 구현 아키텍처
작게 시작하려면 네 개 파일이면 된다. cases.jsonl에는 사용자 시나리오와 기대 행동을 넣는다. run_eval.py는 agent를 실행해 traces.jsonl을 만든다. grade.yaml은 rubric과 pass 기준을 정의한다. report.md는 점수, 실패 목록, 클러스터, 전회 대비 변화를 기록한다. CI에서는 전체 dataset 대신 smoke set 20개를 돌리고, 배포 전에는 full set을 돌린다. 운영 trace는 매주 샘플링해 dataset에 편입한다.
도구 호출이 있는 agent라면 mock과 live를 분리해야 한다. 결제, 메일, 배포, 고객 데이터 변경은 sandbox에서만 실행한다. 평가 중 외부 부작용이 발생하면 평가 시스템 자체가 위험해진다. trace schema에는 user message, agent message, tool call, tool result, state diff, final answer, error를 넣는 것이 좋다.
실행 체크리스트
- 운영 trace, 수작업 case, synthetic scenario를 섞어 평가 데이터를 만든다.
- 성공 케이스보다 실패 가능성이 큰 케이스를 우선 넣는다. 최신 의도 변경, 권한 부족, 도구 실패, 중간 취소는 필수다.
- 수정 제안자와 평가자를 분리한다. 같은 agent가 고치고 채점하게 두지 않는다.
- 범용 task success 외에 제품 위험별 custom rubric을 만든다.
- 절대 점수보다 before/after delta와 실패 유형 변화를 본다.
- 실패가 많아지면 클러스터링으로 원인 묶음을 만들고, 한 번에 하나의 클러스터만 고친다.
- CI smoke eval과 배포 전 full eval을 분리한다.
- trace에는 도구 호출과 state diff를 반드시 남긴다. 최종 답변만 저장하면 원인을 찾기 어렵다.
에이전트 품질은 감으로 좋아지지 않는다. 프롬프트 한 줄을 바꾸는 일도 작은 배포다. 평가 루프를 갖춘 팀은 회귀를 숫자로 발견하고, 없는 팀은 사용자 불만이 쌓인 뒤에야 알게 된다.