AI 산출물을 믿어도 되게 만드는 법: QA가 담금질한 하네스와 품질 게이트
권성진 - 카카오페이
왜 하네스인가
- QA의 오래된 질문 “이 소프트웨어를 믿을 수 있는가” -> 이제는 “AI가 만든 산출물을 어디까지 믿을 수 있는가”
- 되돌릴 수 있는 곳에서 잘못된 산출물은 버그, 결제 / 금융처럼 되돌리기 어려운 곳에서는 사건
- 전 국민이 쓰는 서비스에서는 그 사건이 한 명에게서 끝나지 않음
- 개발 / 배포는 AI로 빨라지는데 검증 속도는 그대로 -> 만드는 속도와 검증 속도의 간격이 계속 벌어짐
- “위험해도 사람이 승인 단계에서 걸러준다”는 믿음
- 올해 처음으로 외부 연구에서 승인 단계를 대규모로 측정
- 사람이 결함을 놓치는 이유는 두 갈래: 지쳐서, 믿어서 (안 지쳐도 경고를 보고 그대로 승인)
AI 검증이 사럼 검증을 대신한다 X
AI가 사전에 걸러낸다
- 앞으로도 사람이 봐야 할 부분은 남음
- 앞단에서 걸러주면 뒷단 사람 검증이 볼 양이 줄어 속도를 따라갈 수 있음
- QA가 오래 가져온 관점을 개발 단계로 옮기는 것
하네스와 품질 게이트
- 하네스: 모델을 둘러싸고 모델이 실제로 어떻게 행동할지 정하는 층
- 어떤 맥락을 보여줄지, 어떤 도구를 줄지, 무엇을 허용할지, 무엇을 기억하고 검증할지
- 모델은 그 중 하나, 나머지가 전부 하네스
- 3층 구조, 사람의 의도에서 출발해 아래에서 위로
- 가운데 층이 페이 메타 하네스 (도메인 무관, 품질 게이트가 여기 있음)
- 위가 도메인 하네스 - 새 도메인이 와도 위에 얹으면 됨 (발표 자료도 이 하네스로 만듦)
- 하네스를 움직이는 엔진은 넷, 오늘은 품질 게이트와 그 게이트를 만든 방법론만 다룸
- 보통 하네스는 사람 손을 줄이고 마지막 승인만 남김
- 여기서는 밖으로 나가는 지점에서만 사람이 승인하고, 무엇을 하네스에 넣을지는 사람이 정함
- 같은 모델이라도 사람이 책임지는 자리가 결함이 잡히느냐를 가름
게이트
- 게이트 = 통과 조건을 코드로 고정해둔 테스트
- 기존 게이트는 알려주기만 함 -> 경고를 남긴 채 나가고 사고 후에야 돌아옴
- 알려주는 게 아니라 막고 서게 만듦, 내보내기 직전이 아니라 만드는 단계에서 걸리게
- 되돌아가는 거리가 짧을수록 비용과 시간이 덜 듦
- 예: 문서 정리 중 완료 조건 절이 사라지자 커밋이 멈춤
- 건너뛰기에 대한 3중 방어
- 커밋 훅: 개발자 PC에서 바로 막지만 한 줄로 건너뛸 수 있음 (직접 만든 건 이것뿐)
- CI 필수 상태 검사: 건너뛸 수 없지만 되돌아가는 거리가 김
- 브랜치 보호 규칙 (관리자에게도 적용): 앞의 둘을 건너뛰어도 머지 불가
- GitHub은 막을 자리만 주고, 무엇을 검사할지는 게이트가 정함
방법론 (QA 검증 방식을 개발 단계에 적용)
- 적대적 검토
- 자기가 만든 걸 검토하면 자기가 떠올린 질문 안에서만 의심하게 됨 -> 반박 전담 에이전트를 따로 둠
- 결함을 주장하려면 기계가 확인할 수 있는 근거를 대야 함
- 고친 걸 원래대로 되돌려 테스트 -> 실패하면 반박이 맞음, 통과하면 틀림
- 격리하기
- 여러 검토가 같은 맥락을 공유하면 한 사람 의견이 여러 번 반복된 것일 뿐
- 결함을 일부러 심고 측정: 심은 쪽과 검토 쪽이 같으면 매번 “잘 나왔다”, 떼어놓으니 라운드마다 결함 발견
- 같은 도구, 같은 대상, 바뀐 건 떼어놨는지 하나
- 다양성 부여
- 여러 모델 사용
- 한 모델로만 검증하면 그 모델의 맹점까지 같이 떠안음 -> 계열이 다른 모델을 섞음
- 모델이 좋아지면 같이 좋아짐
- 한계: 셋 다 놓치는 자리는 남음, 구조가 비슷해서 생기는 공통 맹점
- 외부 측정: 모델들이 틀릴 때 60%는 같은 답으로 틀림, 개별 정확도가 높을수록 오차가 더 겹침
- 검증자에게 주는 산출물 / 지시 / 맥락이 같으면 맹점이 보완되지 않음
- 여러 입장에서 보기
- 만든 사람 자리에선 자기 맥락 안이라 안 보이던 결함이, 변경을 받는 쪽 자리에서 보면 보임
- 받는 쪽을 격리하고 사전 맥락 없이 변경을 그대로 돌려봄 -> 나온 리뷰는 다시 진위 검증 = “입장 리뷰”
- 모델 다양성과 입장 다양성은 보는 지점이 달라 둘 다 사용
- 사람은 밖으로 나가는 지점 (머지, 릴리즈)에서만 판단, 그 전까지는 기계가 방법론으로 품질을 지킴
- 사람이 책임지는 자리는 하나로 줄고, 게이트를 통과한 것만 올라옴
사례
사내 QA 산출물 생성 프로젝트 (현재 해결됨)
- 기획서 / 버그 리포트를 넣으면 QA 산출물(테스트 케이스)이 나오는 파이프라인
- 해피 케이스만 나오고 네거티브 / 상태 전이 케이스가 0건
- 사용자는 설계 순서대로 쓰지 않음 (이리저리 누르고, 백그라운드 갔다 오고, 뒤로 갔다 다시 들어옴)
- 원인: 프롬프트가 모호했고 모델이 해석의 여지에서 쉬운 경로를 고름
- 적대적 검토를 돌리니 빠진 케이스 4종류가 나옴 -> 코딩 에이전트가 두 군데 수정
- 생성과 병합 사이에 검증 노드 추가, 프롬프트의 해석 여지 축소
- 같은 문서를 다시 넣자 지목된 4종류 모두 나옴
- 프롬프트에만 기대지 않고 파이프라인 구조가 지탱하게 함
외부 오픈소스 (스타 6,000개 프로젝트)
- 설정 파일을 읽지 못하면 (깨짐, 권한 없음) 백업을 만든 뒤 원본을 기본값(빈 값)으로 덮어씀
- “읽지 못했다”가 “설정이 비어 있다”로 바뀜 -> 사용자가 몇 달간 쌓은 설정이 오류창 없이 초기화
- 자기들 판정 코드도 방법론 이전엔 “애매하면 통과”였음, 언어 / 도메인은 달라도 고장 났을 때 통과시키는 같은 결함
- 수정 과정에서 방법론을 한 덩어리로 섞어 돌림
- 적대적 검토로 백업 로직을 뚫어 원본을 빈 값으로 지우는 자리를 찾음
- 격리: 앞선 판단을 알려주지 않고 서로 떼어놓음 -> 결론을 따라가지 않고, 병렬로 돌려 속도도 붙음
- 다양성: 상대 저장소에서 그쪽 규칙으로 직접 돌려 지적과 수정이 실제로 맞는지 확인
- 다시 적대적 검토: 수정을 되돌리면 원본이 다시 빈 값이 되는 것, 즉 테스트가 잡는 것을 확인 후 제출
- 수정: 읽지 못하면 원본을 그대로 둠 -> 수정 요청 없이 그대로 머지 (“초점이 분명하고 기술적으로 타당하고 테스트가 잘 돼 있다”)
성과
- 다른 계열 모델이 심은 결함 8건 측정: 일반 검토 5건 -> 관점 추가 6건 -> 게이트까지 8건 전부
- 모델은 그대로, 방법론만으로 잡는 결함 수가 올라감
- 하루에도 여러 번 도는 검증 루프: 게이트가 막으면 위치 / 이유 / 처방이 나오고 코딩 에이전트가 고쳐 다시 올림, 통과한 것만 사람에게
- 외부 성과
- 스타 13만 개 넘는 프로젝트에 메이저 결함 제보 -> 오너가 직접 고쳐 릴리즈
- 스타 6천 개 넘는 프로젝트에 릴리즈 4번 기여, PR 하나는 피드백 없이 머지
- Awesome Harness Engineering, Awesome Agent Skills 큐레이션 저장소에 심사 거쳐 등재
- 게이트를 공개 레지스트리에 올려 160개 넘는 버전, 누적 다운로드 28,000회 이상
- 저장소 안에서만 놀면 자기 채점 -> 우리를 모르는 코드, 우리를 모르는 판정자에게 한 번이라도 통과하면 더는 자기 채점이 아님
가져갈 것
- 측정하지 않았으면 괜찮다고 하지 않음
- 측정 안 한 걸 정상으로, 안 해봐서 모르는 걸 불가능으로 단정하지 않기
- 고친 걸 되돌려서 테스트가 실패하는지 봄
- 사람이 짤 땐 고치기 전에 실패를 봤지만, AI는 코드와 테스트를 한꺼번에 내놓아 실패를 볼 기회가 없음 -> 되돌려 볼 수밖에 없고 그 습관을 기계가 하게 만듦
- 검증자마다 다른 걸 보게 함
- 가장 쉬운 건 입장 바꾸기 (외부 PR에서 상대 저장소, 상대 규칙으로 돌린 것), 결과는 제3자 입장에서 다시 판정
- 사람은 검증자를 늘리면 보는 범위도 늘었지만, AI는 늘려도 같은 곳을 놓침 -> 검증자에게 무엇을 어떻게 줄지 따로 설계
- 앞의 둘은 새 규율이 아니라 QA가 원래 하던 일 (통과를 그대로 믿지 않기, 고치기 전에 재현 테스트)
- “완벽한 테스팅은 불가능하다”는 AI에도 마찬가지, 그래도 QA는 방법을 만들어 왔고 그걸 AI 쪽으로 옮긴 것
- 답: 믿어도 되게 만드는 장치를 두고, 그 장치가 실제로 작동해 안정적인 결과를 내는지 확인한다
forge-harness
- 오늘 소개한 장치와 게이트의 공개본, 방법론은 논문으로도 공개