개념
검토할 산출물이 300건이 되는 순간
앞의 다섯 레슨에서 AI 산출물을 교차검증하는 법을 배웠다. 환각 API를 찾고, 가짜 테스트를 걸러내고, 커버리지 갭을 확인하고, 검증 기준을 세웠다. 그 방법들에는 공통 전제가 하나 있었다 — 사람이 산출물을 본다.
그런데 실무에서 AI를 본격적으로 쓰기 시작하면 이 전제가 곧 깨진다.
레거시 화면 400개를 새 프레임워크로 옮긴다. 에이전트가 하루에 30개씩 변환한다. 사람이 하나씩 열어보면 변환보다 검토가 더 오래 걸린다.
여기서 두 갈래로 갈린다. 대충 보고 넘기거나(사고가 난다), 또는 검증을 사람에서 구조로 옮기거나. 후자를 위한 개념이 하네스 (harness) 다.
최근 국내 대형 테크 컨퍼런스의 세션 제목들이 이 흐름을 그대로 보여준다 — "AI 산출물을 믿어도 되게 만드는 법: QA가 담금질한 하네스와 품질 게이트", "소스코드 보안 분석을 위한 하네스 설계", "에이전트 하네스로 수백 개 JSP 포장이사하기". 세 세션이 전부 하네스라는 같은 단어를 쓴다.
하네스란 무엇인가
하네스는 모델을 감싸는 프로그램 이다. 모델 자체가 아니라, 모델에게 무엇을 주고 무엇을 하게 하고 결과를 어떻게 확인할지를 정하는 바깥 껍데기다.
┌──────────────── 하네스 ─────────────────┐
│ │
작업 지시 →│ ① 컨텍스트 조립 무엇을 보여줄 것인가 │
│ ↓ │
│ ② 도구 인터페이스 무엇을 할 수 있는가 │
│ ↓ │
│ ③ [ 모델 ] ← 여기만 확률적이다 │
│ ↓ │
│ ④ 검증 루프 결과가 기준을 통과하는가 │→ 통과 산출물
│ ↓ (실패) │
│ ⑤ 재시도·에스컬레이션 │→ 사람에게
│ │
│ ⑥ 격리(샌드박스) 실패해도 안전한가 │
└─────────────────────────────────────────┘핵심은 ③만 확률적이고 나머지는 전부 결정적 이라는 점이다. 모델의 지시 준수는 확률적이라 그것만으로는 규모에서 신뢰할 수 없다. 그래서 바깥을 결정적인 장치로 두른다 — 컴파일러, 린터, 타입 체커, 테스트, 정적 분석기. 이것들이 하네스의 센서 다.
이 발상이 QA에게 낯설지 않아야 한다. 모듈 18b(레슨 8)에서 학습데이터 검증 파이프라인을 만들 때 쓴 구조와 같다. 판단이 개입하는 단계를 결정적 게이트로 감싼다.
프롬프트 잘 쓰기에서 하네스 설계하기로
AI를 쓰는 팀의 성숙도는 대체로 이 순서로 올라간다.
| 단계 | 무엇에 집중하나 | 규모 한계 |
|---|---|---|
| 1. 프롬프트 | 지시를 잘 쓴다 | 한 번에 한 건 |
| 2. 프롬프트 + 사람 검토 | 결과를 매번 확인한다 | 하루 몇 건 |
| 3. 하네스 | 검증을 구조에 심는다 | 수백~수천 건 |
1·2단계에서 3단계로 넘어가는 지점이 QA가 개입해야 할 자리다. 프롬프트를 잘 쓰는 것은 개발자도 한다. 그런데 "이 산출물을 믿어도 되는가"를 판정할 기준과 그 기준을 자동으로 적용하는 게이트를 설계하는 것은 QA의 일이다. 앞 레슨(m18c-l05)에서 만든 검증 기준이 여기서 실행되는 코드 가 된다.
품질 게이트를 계층으로 쌓는다
하네스의 검증 루프는 하나의 큰 검사가 아니라 비용 순으로 쌓은 계층 이다. 모듈 14(레슨 4)의 품질 게이트와 모듈 18b(레슨 8)의 4단계 파이프라인이 여기서 합쳐진다.
게이트 0 구문·컴파일 ── 실패하면 나머지는 볼 필요가 없다
↓
게이트 1 린트·타입·정적분석 ── 초 단위, 결정적
↓
게이트 2 기존 테스트 통과 ── 분 단위, 결정적
↓
게이트 3 등가성·차분 검증 ── 원본과 비교 (변환 작업이라면)
↓
게이트 4 판단 검증(LLM) ── 비싸고 확률적
↓
게이트 5 사람 표본 검토 ── 가장 비싸다. 여기까지 온 것만각 게이트의 통과 기준은 성격에 따라 다르게 잡는다. 모듈 18b 레슨 8에서 세운 원칙 그대로다.
| 게이트 | 판정 성격 | 통과 기준 |
|---|---|---|
| 0~2 | 결정적 | 100%(실패 0건) |
| 3 | 대체로 결정적 | 허용 차이 목록에 없는 차이 0건 |
| 4 | 확률적 | 통과율 임계값 + 불일치 시 에스컬레이션 |
| 5 | 사람 | 표본 비율과 선정 기준을 명시 |
게이트 0~2에서 "95%만 통과하면 OK"라고 하면 안 된다. 컴파일이 안 되는 산출물을 5% 허용할 이유가 없다. 반대로 게이트 4에 100%를 요구하면 아무것도 통과하지 못한다.
QA가 하네스에서 맡는 네 가지
하네스를 만드는 것은 개발이지만, 무엇을 검증할지 정하는 것은 QA 다. 구체적으로 네 가지다.
1) 검증기(verifier)를 정의한다
"이 산출물이 맞다"를 무엇으로 판정할 것인가. 변환 작업이라면 원본과의 등가성, 코드 생성이라면 테스트 통과와 정적 분석, 문서 생성이라면 사실 일치. 앞 레슨에서 배운 환각 API 탐지·가짜 테스트 탐지가 그대로 검증기가 된다.
2) 게이트 임계값과 실패 시 행동을 정한다
실패하면 무엇을 하는가? 선택지는 셋이고, 각각 다른 상황에 맞는다.
| 실패 시 행동 | 언제 |
|---|---|
| 자동 재시도(피드백 포함) | 컴파일 오류처럼 기계가 원인을 말해줄 수 있을 때 |
| 사람 큐로 에스컬레이션 | 판단이 필요할 때 |
| 배치 전체 중단 | 실패율이 임계를 넘을 때 — 하네스 자체가 잘못됐다는 신호 |
세 번째를 빠뜨리는 경우가 많다. 개별 실패를 계속 재시도하다 보면 하네스의 전제가 틀렸다는 사실을 놓친다. 실패율이 갑자기 40%가 됐다면 개별 산출물이 아니라 지시나 컨텍스트를 봐야 한다.
3) 사람이 볼 표본을 설계한다
전수를 못 보므로 표본을 본다. 무작위로 뽑으면 안 된다는 것도 모듈 18b 레슨 8에서 배웠다 — 위험 가중 표본 을 쓴다. 변경량이 큰 것, 게이트 4에서 경고가 났던 것, 처음 보는 패턴, 과거에 문제가 많았던 영역.
4) 하네스 자체를 검증한다
여기가 가장 자주 빠지는 항목이고, QA만이 생각하는 지점이다.
검증기에 버그가 있으면 모든 게이트가 거짓말이 된다.
게이트가 통과시킨 것이 정말 맞는지 어떻게 아는가? 두 가지 방법이 있다.
- 골든 세트 — 정답을 아는 입력 묶음을 만들어두고, 하네스를 바꿀 때마다 돌린다. 통과해야 할 것은 통과하고 걸러야 할 것은 걸러지는가.
- 의도적 오류 주입 — 일부러 틀린 산출물을 섞어 게이트가 잡아내는지 본다. 모듈 10에서 배운 뮤테이션 테스트의 발상 을 하네스에 적용하는 것이다.
두 번째가 특히 강력하다. "우리 게이트가 아무것도 못 잡고 있다"는 상황을 발견하는 유일한 방법이기 때문이다. 게이트 통과율이 100%인 것은 좋은 신호일 수도, 게이트가 죽어 있다는 신호일 수도 있다.
대규모 변환에 적용하기 — 등가성이 핵심이다
하네스가 가장 큰 값을 내는 곳이 대규모 코드 변환 이다. 레거시 화면 수백 개를 새 프레임워크로 옮기거나, 언어 버전을 올리거나, 프레임워크를 갈아타는 작업들.
이때 검증의 본질은 하나로 좁혀진다.
"새 코드가 옛 코드와 같은 일을 하는가" — 기능적 등가성 (functional equivalence).
완전한 등가성 증명은 이론적으로 어렵다. 그래서 실무에서는 근사 등가성 을 쓴다. 확인 가능한 지표들의 조합으로 등가성을 추정하는 방식이다.
| 근사 지표 | 무엇을 확인하나 |
|---|---|
| 빌드·컴파일 성공 | 최소 조건 |
| 기존 테스트 통과 | 테스트가 커버하는 범위의 동작 |
| 불변식(invariant) 유지 | API 시그니처, 스키마, 공개 계약 |
| 입출력 대조 | 같은 입력에 같은 출력이 나오는가 |
| 정적 분석 지표 | 복잡도·의존성이 크게 벗어나지 않았는가 |
여기서 테스트가 없는 레거시 라는 현실적 문제를 만난다. 옛 코드에 테스트가 없으면 게이트 2가 비어버린다. 그때의 순서는 이렇다.
① 옛 코드의 동작을 기록한다 (특성화 테스트, characterization test)
실제 입출력을 캡처해 "지금 이렇게 동작한다"를 고정
② 그 테스트를 게이트로 삼아 변환한다
③ 변환 후 같은 테스트를 새 코드에 돌린다①이 변환 작업의 절반이다. 그리고 이건 AI가 잘하는 일이기도 하다 — 기존 코드에서 입출력 조합을 뽑아 테스트를 생성하는 작업. 다만 모듈 18c 레슨 3에서 배운 대로, 생성된 테스트가 가짜가 아닌지 반드시 확인해야 한다. 항상 통과하는 테스트를 게이트로 삼으면 게이트가 없는 것과 같다.
변환 검증의 나머지 기법 — 이중 실행 비교, 리콘실리에이션, 컷오버 — 은 별도 주제라 모듈 4(레슨 6) 에서 따로 다룬다.
보안 분석 하네스 — 오탐이 진짜 비용이다
같은 구조를 보안 분석에 적용하면 성격이 조금 달라진다. AI에게 소스코드 취약점을 찾게 하는 하네스에서는 놓치는 것(FN)보다 오탐(FP)이 먼저 문제가 된다.
이유는 단순하다. 취약점 후보 500건이 쏟아지고 그중 30건만 진짜라면, 보안 담당자는 470건을 걸러내느라 시간을 다 쓰고 결국 도구를 끈다. 모듈 14(레슨 5)에서 배운 false alarm 문제 가 그대로 재현된다.
대응은 게이트를 진단이 아니라 분류 로 쓰는 것이다.
| 등급 | 조건 | 처리 |
|---|---|---|
| 확정 | 재현 가능한 증거가 있음(PoC·실행 경로) | 즉시 티켓 |
| 후보 | 정황은 있으나 확인 필요 | 사람 검토 큐 |
| 기각 | 알려진 패턴의 오탐 | 기록만 남기고 숨김 |
'기각'을 기록으로 남기는 것이 중요하다. 같은 오탐이 다음 실행에서 또 올라오면 하네스를 고쳐야 한다는 신호다.
하네스가 무너지는 방식
1) 게이트가 조용히 죽는다. 스크립트 오류로 검사가 실행되지 않는데 결과는 "실패 0건"으로 보인다. 모듈 18b 레슨 8에서 본 그 문제다 — 0이 "좋음"인지 "고장"인지 구분되지 않는다. 대조 지표를 함께 둔다.
2) 재시도 루프가 돈다. 같은 실패를 반복 재시도하며 비용만 태운다. 재시도 상한과 배치 중단 조건을 반드시 건다.
3) 통과 기준이 슬금슬금 내려간다. 일정이 급하면 임계값을 낮추자는 말이 나온다. 낮추는 것 자체는 결정일 수 있지만, 낮췄다는 사실이 기록되지 않으면 나중에 아무도 그 산출물의 품질 수준을 모른다.
4) 사람 검토가 형식이 된다. 표본 100건을 검토하기로 해놓고 실제로는 훑어본다. 검토에 걸린 시간을 기록해보면 금방 드러난다.
5) 하네스만 남고 목적이 사라진다. 게이트를 통과시키는 것이 목표가 되어, 게이트를 통과하도록 산출물을 다듬는다. 모듈 25 레슨 3에서 본 인증을 목표로 삼으면 최소선으로 수렴한다 는 문제의 AI 버전이다.
그래서 이것이 QA에게 무엇인가
모듈 18a(레슨 10)에서 자동화 엔지니어의 일이 "스크립트를 쓰는 사람"에서 "무엇을 신뢰할 수 있다고 말할지 정의하는 사람"으로 이동한다고 했다. 하네스는 그 이동이 실제 산출물로 나타나는 형태 다.
AI가 코드를 쓰고 문서를 만들고 마이그레이션을 수행하는 조직에서, 그 결과를 믿어도 되는지 판정하는 구조를 설계하는 사람 이 필요하다. 그 일을 할 수 있는 배경은 테스트 설계, 리스크 판단, 게이트 운영 경험이고, 그건 QA가 이미 가진 것이다.
하네스는 산출물 하나를 믿게 만드는 구조 다. 실무 파이프라인에서는 여러 에이전트·로봇·사람이 결과를 차례로 넘겨주고, 신뢰는 그 넘겨주는 순간에 새기 쉽다. 다음 레슨은 노드 계약·결정 테이블·사람 승인 게이트·정책 코드로 과정 전체를 믿게 만드는 오케스트레이션 을 다룬다.
실무에서 왜 필요한가
AI 도입 초기의 조직에서는 대개 "AI가 만든 것을 사람이 검토한다"로 시작한다. 그리고 몇 달 안에 검토가 병목이 된다. 그때 나오는 선택지는 "AI 사용을 줄이자"와 "검토를 구조로 옮기자"인데, 후자를 설계할 수 있는 사람이 없으면 조직은 전자를 고른다.
하네스 설계를 아는 QA는 그 자리에서 다른 제안을 할 수 있다. "검토를 없애자는 게 아니라, 사람이 볼 것을 5%로 줄이고 그 5%를 위험이 큰 것으로 채우자" 는 제안이다. 모듈 18b 레슨 8에서 다룬 그 구조를 코드 산출물에 적용하는 것이다.
그리고 이 능력은 채용 시장에서 변별력이 있다. "AI 도구를 써봤다"는 흔하지만, "AI 산출물의 품질 게이트를 설계하고 그 게이트 자체를 검증해봤다" 는 아직 드물다.