코딩 에이전트로 에이전트 품질 플라이휠 구동하기
요약
에이전트의 품질을 '대충 확인'이 아닌 체계적으로 개선하기 위해, 코딩 에이전트가 구동하는 품질 플라이휠 스킬을 소개합니다.
인사이트
- 에이전트 개선의 핵심은 '몇 가지 예제에서 잘 보이는 것'과 '프로덕션에서 실제로 잘 동작하는 것' 사이의 간극을 좁히는 평가 방법론이다.
- 최적화 주체와 평가 주체를 분리(decouple)하여 메트릭 게이밍을 방지하고, AutoRater가 독립적으로 평가한다.
- 커스텀 루브릭을 통해 내장 AutoRater가 놓칠 수 있는 특정 실패 패턴(예: 중간 수정사항 무시)을 집중적으로 측정할 수 있다.
왜 중요한가
에이전트가 점점 더 복잡해지고 자율적으로 동작함에 따라, '기분 좋은' 수동 테스트만으로는 품질을 보장할 수 없습니다. 이 스킬은 개발자가 명확한 목표나 심지어 '문제를 찾아줘'라는 느슨한 요청만으로도 체계적인 평가-분석-수정 사이클을 돌릴 수 있게 해줍니다. 특히 드러나지 않는 실패(내부 상태는 옳지만 사용자에게 잘못된 응답)를 찾아내고 수정하는 데 강력합니다.
에이전트 품질을 엔지니어링하세요, 대충 확인하지 말고
에이전트를 출시했습니다. 잘 동작합니다. 사용자가 불평한 한 가지를 고치기 위해 프롬프트를 살짝 수정했고, 테스트한 세 가지 예제에서 더 좋아 보입니다. 당신을 밤새게 하는 질문: 다른 열 가지는 망가뜨리지 않았을까?
"몇 가지 예제에서 더 좋아 보이는 것"과 "프로덕션에서 실제로 더 나은 것" 사이의 그 간극, 이것이 에이전트를 만드는 일상의 현실입니다. 대부분의 팀은 어딘가에 eval 케이스를 가지고 있습니다. 대부분의 팀은 프롬프트를 수정합니다. 하지만 그 둘을 충분한 규율로 연결해서 변경이 메트릭을 움직였는지 아니면 그냥 분위기를 바꿨는지 아는 팀은 거의 없습니다.
가장 무서운 실패는 큰 소리로 드러나는 실패가 아닙니다. 그것들은 마치 잘 동작하는 것처럼 보이는 에이전트들입니다(자신감 있는 답변, 읽히는 계획) — 조용히 사용자의 실제 목표를 놓치면서 말이죠. Cloud Next '26에서 우리는 에이전트 품질을 세 단계 플라이휠로 이야기했습니다 — 빌드 및 테스트 → 출시 및 모니터링 → 학습 및 개선 — 그리고 그 구성 요소를 보여주었습니다. 오늘 우리는 개발자 중심 경로를 추가합니다: 당신의 코딩 에이전트가 설치하고 당신을 대신해 구동하는 스킬입니다.
이 플라이휠 — 방법론과 그 핵심에 있는 AutoRater — 은 우리가 자체 모델과 퍼스트파티 에이전트를 평가하고 개선하는 데 사용하는 것과 동일한 원칙 위에 구축되었으며, AutoRater는 Google DeepMind와의 긴밀한 협력을 통해 개발되었습니다.
플라이휠, 확대해서 보기
이 스킬은 빌드 및 테스트, 즉 빠른 반복 루프에 중점을 두고 있으며, 이를 다섯 가지 구체적인 단계로 확장합니다. 이 단계는 그 단계에만 국한되지 않습니다. 동일한 단계가 프로덕션 트레이스에도 적용되며, 시간이 지남에 따라 플라이휠의 더 많은 부분에 접근할 수 있게 됩니다. 첫 번째 패스에서는 순서대로 실행하고, 그런 다음 2~5단계를 품질 목표가 달성될 때까지 반복하세요:
- 데이터 준비: 기존 OTel 트레이스, 수작업 케이스, 또는 합성 시나리오에서 평가 데이터셋을 구축합니다.
- 추론 실행: 데이터셋에 대해 에이전트를 실행하여 트레이스를 생성합니다; 이미 트레이스가 있으면 이 단계를 건너뜁니다.
- 채점: Google의 적응형 AutoRater(트레이스를 채점하고 이유를 설명하는 모델 기반 평가자) 또는 자체 커스텀 메트릭으로 트레이스를 채점합니다. 이 단계는 항상 실행되는 유일한 단계입니다.
- 실패 분석: 루브릭 평결을 읽어 케이스가 왜 실패했는지 이해합니다; 10개 이상의 실패가 있으면 자동 손실 분석(Automatic Loss Analysis)으로 클러스터링합니다.
- 최적화 및 반복: 대상 수정을 적용하고, 2~4단계를 다시 실행한 후, 이전 기준선과 비교합니다.
대부분의 실패 케이스는 메트릭이 실제로 움직이기까지 여러 번의 반복이 필요하며, 스킬은 그 규율을 인코딩합니다.
최적화 도구는 자신의 작업을 채점하지 않습니다
최적화 도구와 평가 도구는 분리된 상태를 유지합니다: 수정을 제안하는 것(코딩 에이전트, 자동 최적화 도구, 또는 당신)은 절대 그것을 채점하지 않습니다. Gemini Enterprise Agent Platform GenAI 평가 서비스가 독립적으로 채점합니다. 자신의 작업을 스스로 채점하는 최적화 도구는 에이전트를 개선하는 대신 메트릭을 게임하는 법을 배웁니다. 작은 아키텍처 선택이 보이는 것보다 더 중요합니다.
이 스킬의 정체 (그리고 아닌 것)
그것은 당신의 코딩 에이전트 내부에서 실행되는 방법론과 오케스트레이션입니다: 목표에 맞는 올바른 메트릭을 선택하고, GenAI 평가 서비스를 실행하며, 평결을 읽고, 수정을 제안하고, 전후를 비교합니다.
그것은 다음이 아닙니다:
- 자율적. 제안하면; 당신이 승인합니다. 사람이 관여하는 루프(Human-in-the-loop)이지, 손을 떼는 것이 아닙니다.
- 정답의 원천. 내장 AutoRater는 단순히 답변을 채점하는 모델 그 이상입니다. 멀티턴 에이전트의 경우 대화에서 사용자의 의도를 추출하고, 해당 케이스에 특화된 루브릭을 생성하며, 각 기준에 대해 트레이스를 검증하고, 샘플 간 다수결 투표를 합니다. 정교하지만 여전히 모델 기반입니다: 점수를 강력한 방향성 신호로 취급하고, 단일 숫자를 절대적인 등급으로 신뢰하기보다는 실행 간의 _델타_를 신뢰하세요.
- 실제 트래픽의 대체재. 스킬은 User Simulator(GenAI 평가 서비스의 기능)로 합성 시나리오를 생성하지만, 이는 콜드 스타트 부트스트랩입니다. 합성 시나리오는 움직이게 만듭니다; 프로덕션 데이터가 루프를 날카롭게 만듭니다.
두 가지 패키지로 동일한 GenAI 평가 서비스에 대해 제공됩니다. 스택에 맞는 것을 선택하세요:
- google-agents-cli-eval — agents-cli 툴체인으로 ADK 에이전트를 구축하는 경우. skills.sh/google/agents-cli/google-agents-cli-eval에서 설치하세요.
- agent-platform-eval-flywheel — Evaluation SDK를 직접 사용하는 경우(모든 프레임워크). skills.sh/google/skills/agent-platform-eval-flywheel에서 설치하세요.
실제 사이클: 성공처럼 보이는 실패
실제 에이전트에서의 한 사이클입니다. 읽으면서 주목해야 할 점: 개발자는 eval CLI를 전혀 건드리지 않으며, 메트릭 이름을 지정하지 않습니다. 그들은 스킬을 설치하고, 평범한 언어로 걱정을 설명하고, 계획을 승인하고, 결과를 읽습니다. 스킬이 어떻게 할지 결정하며, 가장 흥미로운 결정은 어떤 메트릭이 그 실패를 감지할 수 있는지입니다.
테스트 대상 에이전트는 travel-concierge로, google/adk-samples의 ADK 멀티에이전트 여행 플래너입니다(영감 → 계획 → 예약 → 여행 전/중/후). 그것은 작업 일정을 세션 상태에 유지하며, 이는 특정하고 미묘한 실패를 설정합니다.
코딩 에이전트에게 말하는 것:
"이 레포지토리에 quality-flywheel 스킬을 사용해줘. travel-concierge가 대화 중간에 변경 사항을 잘 반영하는지 걱정이야. 사용자가 여행 중간에 수정할 때(다른 날짜, 다른 호텔, 다른 인원수), 최종 계획이 변경 사항을 반영하는지, 아니면 원래 계획으로 계속 동작하는지? 어떻게 테스트할지 알아내고 실행하기 전에 계획을 제안해줘."
그게 인터페이스의 전부입니다. 플래그도, 메트릭 이름도 없습니다. 스킬의 임무는 그 목표를 올바른 평가로 번역하는 것이며, 여기서 그 가치가 발휘됩니다. 먼저 에이전트의 코드를 읽고, 계획을 가지고 돌아옵니다. 두 개의 내장 멀티턴 AutoRater에 도달한 다음, 고정된 스크립트가 하지 않을 일을 합니다: 그것들 위에 커스텀 루브릭을 추가하여, 전후를 정확히 당신이 물어본 행동에 고정시킵니다:
코딩 에이전트 · quality-flywheel 스킬
"
multi_turn_task_success와multi_turn_trajectory_quality는 적응형입니다: 각 케이스에 대해 루브릭을 생성하고 그 안에 수정 누락을 표면화할 수 있습니다. 하지만 그것은 실행마다 다르게 재생성되는 여러 기준 중 하나로, 혼합 점수에 포함됩니다; 임계값이나 추세를 안정적으로 확인할 수 있는 '수정 준수' 숫자가 없습니다. 그래서 그 한 가지 우려를 자체 메트릭으로 승격시키겠습니다: 커스텀 루브릭,revision_honored, (HONORED / IGNORED / PARTIAL / NO_REVISION) 범주형 평결을 가지며, 이를 집계하고, 게이트할 수 있고(20% 이상이 IGNORED로 나오면 조치), 사이클마다 추적할 수 있습니다. User Simulator로 25개의 시나리오를 다섯 가지 수정 유형으로 분할하여 부트스트랩하겠습니다. 진행할까요?"
승인합니다. 그 문단 뒤에서 스킬은 User Simulator를 실행하여 시나리오를 합성하고, 두 개의 내장 시나리오와 자체 revision_honored 루브릭으로 트레이스를 채점합니다. 소수의 케이스만 실패하여 클러스터링이 효과적인 임계값 아래이므로, 자동 손실 분석에 도달하는 대신 해당 평결을 직접 읽습니다. 실제로 실행한 내용은 다음과 같습니다:
# 수정 유형별 User Simulator 패스 한 번 (×5: 인원수, 목적지, 날짜, 호텔, 중간 정류장 삭제)
agents-cli eval dataset synthesize -n 5 --max-turns 8 --model gemini-3.5-flash \
--instruction "$(cat instr_party_size.txt)" \
--environment-context "$(cat synthesize_env_context.txt)" \
-o traces_party_size.json
# 다섯 개의 트레이스 파일을 병합한 다음, 한 번에 25개 모두 채점
agents-cli eval grade --traces traces_merged.json --config eval_config_revisions.yaml
쉘
복사됨
당신은 하나도 작성하지 않았습니다. 스킬이 메트릭, 시뮬레이터, 분할을 선택했습니다; 당신은 목표를 설명했습니다.
첫 번째 패스. 세 가지 메트릭 모두 발동했습니다. 내장 AutoRater는 이미 명백히 낮은 품질을 보여주었고(평균 0.6대 중반, 엄격한 기준에 대한 낮은 통과율), 커스텀 루브릭은 그 중 얼마나 수정 문제 때문인지 분리했습니다:

이 루브릭에서 IGNORED는 _수정이 무시되었음_을 의미합니다(다른 평결은 HONORED, PARTIAL, NO_REVISION). 21%는 스킬 자체의 조치 임계값을 넘었습니다. 그리고 평결은 실패를 정확히 찾아냈습니다. 당신이 추측하는 것이 아닙니다: 에이전트는 잘못된 일정을 자신있게 확인하지 않습니다. 네 번의 실패 중 세 번에서, 내부 상태는 정확했지만 (올바른 값이 저장되었고, 올바른 도구가 호출되었지만), 사용자에게 보내는 최종 메시지는 여전히 오래된 값을 반영했습니다. 에이전트는 내부적으로 올바르게 수행하고 스스로 모순되는 응답을 내놓았습니다. 한 평결이 이를 구체적으로 보여줍니다:
"에이전트의 내부
memorize호출이 턴 3에서start_date와end_date에 대해 '2027-04-15'와 '2027-04-19'를 올바르게 저장했지만, 명시적인 수정 후 최종 출력에서 사용자에게 올바른 날짜를 제공하지 못했습니다."
이것이 "작동하는 것처럼 보이는" 실패를 작게 축약한 것입니다: 아무것도 충돌하지 않고, 계획은 빠르게 훑어보기에는 괜찮아 보이며, 에이전트는 당신이 요청한 일을 한 것처럼 들리지만, 사용자가 실제로 받는 답변은 틀렸습니다. 케이스들의 공통 원인: 루트 에이전트의 지시사항 중 어느 것도 최종 응답을 보내기 전에 사용자의 가장 최근 메시지와 확인하라고 말하지 않았습니다.
커스텀 루브릭이 정말 필요했는지 궁금할 수 있습니다: 결국 내장 메트릭은 적응형이니까요. 알고 보면 감지는 문제가 아니지만, 실패를 _분리하는 것_이 문제입니다. 내장 task-success가 여전히 0.80으로 편안하게 점수를 매긴 IGNORED 케이스 하나를 보세요: party_size_02, 사용자가 호텔 요청을 특정 호스텔의 도미토리 룸으로 수정한 경우입니다. 아래 주석이 이유를 보여줍니다: 평가자는 그 정확한 요청에 대한 기준을 _생성_했고 충족되지 않았다고 표시했지만(누락을 잡아내고 설명했지만), 그 하나의 기준은 통과한 네 가지 기준 중 하나였기 때문에 혼합 점수는 높게 유지되었습니다. 내장 메트릭이 줄 수 없는 것은 25개 케이스 전체에 걸친 단일 "수정을 준수했는가?" 숫자입니다; 우려 사항을 자체 범주형 메트릭으로 승격시키는 것이 21%→5%의 전후를 계산 가능하게 만든 것입니다.
하나의 케이스, 세 평가자: party_size_02
사용자가 5명을 위한 저렴한 베를린→암스테르담 여행을 요청한 후, 대화 중에 호텔 요청을 "Amsterdam Hostel World의 도미토리 룸"으로 수정했습니다.
revision_honored (커스텀) → IGNORED. "에이전트가 요청을 인정했지만 수정된 기준을 검색하는 대신 이전 결과를 다시 제안했으며, 새 선호도를 저장하지 않았습니다."
multi_turn_task_success (내장) → 0.80. 생성된 다섯 기준 중 네 개 통과: ✓ 5명을 위한 저렴한 여행 · ✓ 항공편 옵션 · ✓ easyJet 선택 확인됨 · ✓ 호텔 옵션 제공됨. 다섯 번째 실패: ✗ "'Amsterdam Hostel World'에서 도미토리 룸 옵션 제공": "에이전트가 요청된 특정 정보를 제공하지 못했습니다... 도구 기능 부족을 이유로 들었기 때문입니다." 수정 누락은 실제로 존재하고 명명되었습니다; 다섯 줄 중 한 줄일 뿐이므로 혼합 점수는 높게 유지됩니다.
multi_turn_trajectory_quality (내장) → 0.67. 여기서의 누락은 평가 구성 아티팩트이지 결함이 아닙니다: 에이전트의 도구 스키마가 평가자에게 제공되지 않아서 합법적인 호출(flight_search_agent, _memorize_impl)을 "허용되지 않은 도구"로 표시했습니다. 그래서 우리는 전후 비교를 위해 커스텀 루브릭과 task-success에 의존하고 trajectory는 사용하지 않습니다.
수정 및 재실행. 대상 변경을 승인합니다: 루트 에이전트 지시사항에 세 문장을 추가하여 최종 응답을 최신 사용자 수정과 조정하도록 지시합니다. 스킬이 동일한 평가를 재실행합니다:

구체적인 목표가 없어도 됩니다
그 사이클은 명확한 목표에서 시작되었습니다. 하지만 스킬은 아직 목표가 없을 때, 무엇이 잘못되었는지 말할 수 없을 때도 잘 작동합니다. 콜드 스타트로 에이전트를 가리키며 "실제 실패를 찾아서 고쳐줘"라고 말하면, 광범위하게 실행됩니다: 다양한 시나리오를 합성하고, 내장 멀티턴 메트릭으로 채점하고, 지배적인 실패 클러스터를 스스로 표면화합니다.
우리는 다른 에이전트에서 정확히 그렇게 시도했습니다: google/adk-samples의 software-bug-assistant, 실제 도구(MCP 도구 상자 뒤의 Postgres 티켓 데이터베이스, 웹 및 StackExchange 검색)에 연결된 버그 분류 도우미입니다. 가설 없이 스킬은 즉시 하나의 클러스터를 표면화했습니다: 15개 케이스 중 14개에서 에이전트는 작업을 올바르게 수행했지만 사용자에게 어떤 도구를 호출했는지 전혀 알려주지 않았습니다. 자체 지시사항이 요구했지만, 모델은 조용히 선택 사항으로 취급했습니다. 모든 응답이 이제 "사용된 도구: search-tickets, get-ticket-by-id" 같은 바닥글로 끝나도록 하는 한 문단 수정으로, 단일 사이클에서 15개 케이스 전체에 걸쳐 0% 에서 96% 로 만들었습니다.
동일한 스킬, 더 느슨한 프롬프트입니다. "여기 내 목표가 있습니다"와 "나에게 문제를 찾아줘" 모두 효과적입니다.
두 사이클 모두 비결은 동일했습니다: 변경한 행동에 대해 하나의 안정적인 측정(커스텀 루브릭 또는 단순 카운트)을 선택하고, 적응형 내장 메트릭을 전반적인 건강 신호로 취급하는 것입니다(루브릭이 실행마다 변경되므로).
내부 루프에서 프로덕션 루프로

위 사이클은 아직 실제 사용이 없었기 때문에 User Simulator를 사용했습니다 — 온디맨드, 개발 측 루프입니다. 에이전트가 성숙해지고 실제 트래픽을 처리함에 따라, 프로덕션 세션이 가장 가치 있는 입력이 됩니다: 각각은 진짜 요청이며 — 사용자, 다른 에이전트, 또는 업스트림 서비스로부터 — 각 실패는 다음 사이클을 위한 준비된 테스트 케이스입니다. 이제 동일한 단계가 시뮬레이션 대신 실제 사용에 의해 공급됩니다.
동일한 스킬이 프로덕션 트래픽에 대해 실행됩니다; 합성된 트레이스 대신 실제 트레이스를 가리키기만 하면 됩니다. 지난주 프로덕션 세션을 채점하라고 말하면, 해당 트레이스는 이미 완료되었으므로 추론 실행을 건너뛰고 동일한 평가자로 그 자리에서 채점합니다. Online Monitors는 실시간 트래픽을 지속적으로 평가하고 품질 점수를 Cloud Monitoring에 기록합니다; 점수가 흔들리면, 동일한 스킬에 실패한 트레이스를 넘깁니다: 방금 본 eval-수정 루프입니다. 동일한 플라이휠, 다른 케이던스: 프로덕션에서는 지속적, 개발에서는 온디맨드이며, 동일한 AutoRater가 둘 다 채점합니다.
오늘날 스킬은 내부 루프를 온디맨드로 실행하고 프로덕션 트레이스를 가리키면 채점합니다. 방향은 스킬이 그 외부 루프를 더 많이 스스로 구동하도록 하는 것입니다: 모니터를 관찰하고, 회귀를 표면화하고, 트래픽이 변화함에 따라 수정을 제안하는 것입니다.
지금 시작하세요
필요한 것: Agent Platform GenAI Evaluation Service가 활성화된 GCP 프로젝트, 평가할 에이전트(ADK 또는 모든 프레임워크), 스킬을 구동할 코딩 에이전트. 프로덕션 트래픽을 채점하려면 에이전트가 OpenTelemetry 트레이스를 내보내야 합니다(ADK는 기본적으로 수행).
코딩 에이전트가 구동할 스킬을 설치하세요:
# CLI 기반 (ADK + agents-cli):
npx skills add https://github.com/google/agents-cli --skill google-agents-cli-eval
# SDK 기반 (모든 프레임워크):
npx skills add https://github.com/google/skills --skill agent-platform-eval-flywheel
쉘
복사됨
그런 다음 사이클을 시작하세요: 에이전트를 가리키고 측정하려는 것을 설명하세요. 코딩 에이전트가 나머지를 처리합니다.
에이전트가 완벽할 필요는 없습니다. 개선 가능하기만 하면 됩니다.
크레딧: Quality Flywheel 스킬과 기본 서비스는 Jason Dai, Ludwik Trammer, Iwo Naglik, Xi Liu, Aleksandra Grzegorczyk, 그리고 더 넓은 Cloud AI Agent Platform 팀이 구축했습니다. 이 글이 기반으로 한 발표는 Cloud Next '26에서 Alex Martin(Google)과 Daniel J. Lewis(Geotab)가 진행했습니다.
더 알아보기: Cloud Next '26 발표 · Agent Evaluation 문서 · GitHub의 agents-cli · GitHub의 google/skills.
다음