QA에서 적대적 리뷰를 요청하며 얻은 교훈
요약
QA 엔지니어로서 E2E 테스트 측정 도구를 개발하며, AI에게 적대적 리뷰(adversarial review)를 요청하는 과정에서 겪은 경험을 공유합니다. 초기에는 유효한 오류 사례를 발견했으나, 시간이 지나면서 지적만 늘고 실제 결과는 변하지 않는 한계에 부딪혔습니다. 이 글은 AI 활용 시 '전제'와 '멈출 기준' 설정의 중요성을 강조하며, 효과적인 프롬프팅 전략을 제시합니다.
핵심 포인트
- AI에게 적대적 리뷰를 요청할 때는 명확한 전제가 필수입니다.
- 지속적인 지적이 실제 결과 변화로 이어지지 않는 한계가 있습니다.
- 테스트 도구 개발 시 AI의 오판정 사례를 찾는 것이 중요합니다.
- 리뷰 과정에서 '합격 기준'을 제시하지 못하면 무한 루프에 빠질 수 있습니다.
Codex에게 적대적 리뷰(adversarial review)를 부탁할 때마다 '블로커가 있습니다'라는 답변이 돌아왔습니다.
수정을 다시 요청했을 때는 또다시 '블로커가 있습니다'. 2일 동안 22번의 대화를 나눴지만, 후반부 15번의 상호작용에서 실제 데이터 측정 결과가 움직인 것은 포괄된 요소(網羅できている要素)가 387개에서 388개로 늘어난 단 한 건뿐이었습니다.
적대적 리뷰 자체가 쓸모없었던 것은 아니었습니다.
처음 몇 번은 실제 데이터에서의 오판정 사례를 여러 개 찾아주었습니다. 문제는 어느 시점부터 '지적은 계속 나오지만, 현실적인 결과는 아무것도 변하지 않는' 상태에 빠졌고, 게다가 이를 인지하는 메커니즘이 저희에게 없었다는 것입니다.
본문에서는 그 상호작용 기록을 바탕으로 AI에게 적대적 리뷰를 요청할 때 사전에 제공했어야 할 것, 즉 **전제(前提)**와 **멈출 기준(止める基準)**에 대해 작성합니다.
무엇을 측정하는 도구였는가
저는 TOKIUM의 QA 엔지니어로서, 자사 제품의 E2E 테스트가 '화면에서 조작 가능한 요소를 얼마나 실제로 조작하고 있는가'를 측정하는 도구를 Claude Code와 함께 만들고 있습니다.
프론트엔드 소스 코드(React / TypeScript)에서 버튼이나 입력란 같은 조작 가능한 요소를 추출하여 분모로 삼고, E2E 테스트 실행 기록과 대조하여 실제로 조작된 요소를 계산합니다.
어려운 점은 '이 기록의 조작이 소스의 어떤 요소에 대한 것인가'를 판별하는 것입니다.
테스트용 식별자(data-testid)가 붙어 있으면 쉬워 보이지만, 식별자의 값이 변수나 보조 함수를 거치거나, 번역 라이브러리나 UI 라이브러리의 컴포넌트가 속성을 추가하기 때문에 소스를 읽고 값을 확정하는 정적 분석(static analysis)이 필요합니다.
판단에 오류가 생기면 실제로는 조작하지 않은 요소가 '포괄됨'으로 계산됩니다 (여기서 포괄된 것으로 세는 것을 '가점'이라고 부릅니다). 이는 측정 도구로서 가장 피해야 할 오류이므로, 구현은 Claude Code에게 맡기고 완성된 결과물을 다른 벤더의 AI인 Codex CLI에 생성 시 문맥을 전달하지 않고 적대적으로 리뷰하게 했습니다.
전제 없이 진행한 6라운드
첫 번째 요청은 '이 판별 로직에서 오판정하는 예시를 찾아보고, 찾으면 최소 재현 사례를 보여달라'는 것이었습니다.
첫 번째 리뷰는 기대 이상이었습니다.
실 데이터로 다른 환경의 조작을 착각하여 가점 처리한 오류를 재현하고, 측정 리포트에 대한 리뷰에서는 잘못된 가점 5건을 입증했습니다. 여기까지는 적대적 리뷰를 넣길 정말 잘했다고 생각할 만한 내용입니다.
상황이 바뀐 것은 두 번째 라운드부터였습니다.
지난번의 재현 사례는 수정되었음에도 불구하고, 같은 종류의 다른 방식으로 또다시 오판정이 재현됩니다. 2회차부터 4회차 답변은 모두 '커밋 불가입니다'로 시작했으며, 지난번 반례가 수정된 것을 인정하면서도 다른 반례를 제시했습니다.
지적 내용은 예를 들어 다음과 같습니다 (리뷰에서 제시된 합성 코드를 간략화한 것입니다).
// 예시: rest로 제거했어야 할 속성을 원래 props의 값으로 평가해버리는 경우
const Child = ({ id, ...rest }) =>
<button data-testid={rest.id ??
정적 분석은 어떤 방식으로 작성되더라도 올바르게 답할 수 있는 것이 될 수 없습니다.
전제(前提)를 세우지 않고 '어떤 방식으로 작성되어도 오판하지 않는다'는 기준을 삼으면, 리뷰하는 쪽은 언제든지 새로운 작성 방식을 가져와서 테스트할 수 있습니다. 리뷰가 끝난 것은 상대방의 능력이 문제가 아니라, 우리가 합격의 기준을 제시하지 못했기 때문이었습니다.
그래서 방향을 바꿨습니다.
먼저, 이 측정(計測)이 신뢰할 수 있는 전제를 명문화합니다. 예를 들어 '테스트용 식별자(識別子)를 가질 수 있는 속성 객체에 getter나 setter를 사용하지 않는다'는 전제입니다. React의 props는 일반 값의 객체로 작성하는 것이 통례이므로, 실무적으로는 타당합니다.
전제마다 '왜 타당한지'를 작성하고, 라이브러리의 동작에 의존하는 전제인 경우에는 근거로 라이브러리 구현의 해당 라인까지 작성했습니다.
단순히 전제를 세우기만 해서는, 그 전제가 깨졌을 때 조용히 오판하게 됩니다.
그렇기 때문에, 전제를 위반할 수 있는 작성을 소스 전체에서 구문 트리(構文木)로 찾아내는 탐지기(検知器)도 만들었습니다. 위반이 발견된 컴포넌트는 가점을 받지 못하고, 리포트에 위반 위치를 나열하며 측정 전체를 불합격 처리합니다. 알 수 없는 것은 '포괄하지 못함' 쪽에 기울이는 방식으로 만들었습니다.
다만, 외부 제품의 동작에 의존하는 전제처럼 탐지기를 만들 수 없는 경우도 있습니다. 그럴 경우에는 E2E 테스트가 실제로 조작한 기록을 증거로 삼아, 조건을 충족했을 때만 가점을 주고 있습니다.
첫 번째 전제는 10개였고, 이후의 논의를 거치며 13개로 늘어났습니다.
구현한 탐지기가 실제 제품 소스에서 발견한 위반은 0건이었습니다.

리뷰 요청 문구도 바꿨습니다. 다음과 같은 형태입니다.
(샘플)
대상: 측정 도구의 판정 로직 (커밋 abc1234)
전제: 설계 메모 §0의 전제 (이 시점에서는 P1~P11의 10개. P5는 누락). 각 전제에 근거(구현의 해당 라인)와 탐지 방법을 작성함.
...
분류를 요청한 덕분에, 지적의 성격이 명확하게 구분되어 돌아오게 되었습니다. 실제로 돌아온 것을 하나씩 나열합니다.
- (i) 변수를 거쳐 라이브러리로 전달된 JSX 추적이 끊김
- (ii) React의 API를 별명으로 import하면 탐지기를 빠져나감
- (iii) 번역 라이브러리 컴포넌트에 대한 전제가 자식 요소 대체
멈춘 것은 '고치는 것'이 아니라, '지켜보는 것(감시하는 것)'이 아니었습니다.
이 기준을 바탕으로 남은 블로커들을 정리했고, 측정 도구는 채택되었습니다.
그때의 관련 테스트는 956건 모두 통과했으며, 그 이후의 측정은 평소 운영에 올라탔습니다.
## 적대적 리뷰를 요청할 때 미리 제공하는 것들
돌이켜보면, 적대적 리뷰의 질은 리뷰하는 AI의 지혜보다 제가 제시한 기준에 의해 결정되었습니다.
지금은 요청문에 다음 네 가지를 작성하도록 합니다.
- **전제(前提)**: 이 도구가 믿어도 되는 것. 전제별로 '왜 타당한지'와, 깨졌을 때 어떻게 감지할지 (감지할 수 없다면, 대신 무엇으로 증거를 만들지) -
- **근거의 행**: 라이브러리나 프레임워크의 동작에 의존하는 전제는 구현의 해당 행에 작성합니다. 리뷰하는 측이 대조할 수 있도록 하기 위함입니다 -
- **지적 분류**: 전제를 충족하는 데 오류가 있는 경우 / 전제 위반을 놓치는 경우 / 전제의 근거가 잘못된 경우. 이를 분류하게 하면, 어디를 고쳐야 할지가 지적 시점에서 결정됩니다 -
- **멈출 기준**: 무엇을 블로커(blocker)로 하고, 무엇을 알려진 제약 조건으로 처리할지. 기준이 없으면, 리뷰는 상대방이 반례를 생각해낼 때까지 계속됩니다.
또한, 수정하는 방식에도 신경 쓰게 되었습니다.
반례별 추가가 두 번 연속되면, 그것은 개별적인 구멍(hole)이 아니라 구조적 문제의 징조입니다.
이번에는 중간부터 값의 흐름 추적을 하나의 엔진에 모아 다룰 수 있는 구문을 허용 목록으로 하고, 목록에 없는 형태는 기본적으로 '알 수 없음'으로 처리하는 방식으로 전환했습니다. 이렇게 하면, 새로운 방식을 지적받더라도 잘못 가점을 주는 쪽이 아니라 가점하지 않는 쪽에 기울게 됩니다.
완벽할 수는 없는 도구에 적대적 리뷰를 거는 상황은, 정적 분석에 국한되지 않고, 테스트 설계의 포괄성 체크나 AI 출력을 채점하는 시스템 등 앞으로 더 늘어날 것이라고 생각합니다. 그때 '어디까지를 믿고, 어디부터 미리 지켜볼지'를 먼저 말로 표현해 놓으면, 리뷰는 끝없는 반례 찾기에서 도구를 키워나가는 대화로 바뀔 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기