# S4 · 적대 리뷰

> 구조·품질·원문 대조, 세 시선이 서로의 영역을 안 보고 동시에 읽습니다. 판정자 하나가 그 지적을 걸러 수정 계획을 씁니다.

- 수치: 3렌즈
- 사람이 보는 화면: https://aitryed.com/ko/built/tc-team/s4/
- 반대 언어: https://aitryed.com/en/built/tc-team/s4/index.md
- 이 사이트 안내(AI용): https://aitryed.com/ko/llms.txt

---

**S4는 앞 단계가 만든 테스트 케이스를 «흠을 잡으려고» 다시 읽는 단계입니다. 세 시선이 서로의 영역을 안 본 채 동시에 읽고, 판정자 하나가 그 지적을 걸러 «프로그램이 그대로 고칠 수 있는» 수정 계획을 씁니다.**

「적대적 리뷰」라는 이름은 이 태도에서 왔습니다. 잘 됐다고 봐주는 검토가 아니라, **틀린 곳을 찾아내려고 읽는** 검토입니다.

## 코드가 먼저 짚고, 세 시선이 읽고, 판정자가 정리합니다

1. **코드가 먼저** 의심 가는 케이스를 표시해 둡니다 — 완전히 똑같은 케이스, 기획서에 근거가 안 보이는 케이스, 아이템 이름이 빠진 케이스. 표시만 하고, 어떻게 고칠지는 AI가 정합니다
2. **세 시선이 동시에** 읽습니다 — 구조 / 품질 / 원문 대조
3. **판정자 하나가** 셋의 지적을 **서로 반박시켜** 틀린 지적을 떨어내고, 수정 계획을 씁니다
4. 리뷰에서 새로 생긴 질문이 있으면, 사람에게 가기 전에 **사내 위키에서 한 번 더** 찾아봅니다

2번에서 셋이 **서로의 결과를 모릅니다.** 알면 의견이 모이고, 모이면 **같은 걸 같이 놓칩니다.**

## 세 시선은 서로의 영역에 들어가지 않습니다

예전에는 검토를 **두 차례**로 나눴습니다. 1차는 「빠진 게 없나」, 2차는 「문장이 맞나」. 지금은 차례가 없습니다. **세 시선이 한꺼번에** 돌고, 각자 <strong>「다른 시선의 영역에 들어가지 마라」</strong>는 지시를 받습니다.

| 시선 | 묻는 것 | 보는 것 |
|---|---|---|
| **구조** | 짜임이 맞나 | 분류가 맞나, 정상·부정·예외 배분, 똑같은 케이스 |
| **품질** | 문장이 맞나 | 사람이 그대로 따라 할 수 있나, 「적절히」 같은 흐린 말, 한 케이스에 한 가지만 |
| **원문 대조** | 기획서와 맞나 | 숫자·문구가 원문대로인가, 원문에 있는데 빠진 것, 원문에 없는데 지어낸 것 |

나누는 이유는 예전과 같습니다 — **한 번에 다 시키면 쉬운 쪽만 봅니다.**

「빠진 게 없나」는 **기획서 전체를 훑어야** 알 수 있어서 힘듭니다. 「문장이 어색하다」는 **읽다가 바로** 보입니다. 같이 시키면 **자연히 뒤쪽만 잔뜩 나옵니다.** 갈라 놓으면 원문 대조 시선은 문장 얘기를 할 수가 없습니다. 자기 담당이 아니니까요.

지금 구조도 처음엔 세 시선을 **하나씩 차례로** 돌렸습니다. 셋은 서로의 결과가 필요 없으니 2026년 8월부터 동시에 돌리고, 이 구간이 한 번 돌 때마다 9.9분쯤(여러 번 잰 값의 가운데) 짧아졌습니다.

## 지적에는 반드시 「처방」이 붙습니다

이게 중요한 설계입니다.

다음 단계(수정)는 AI가 아니라 **정해진 대로만 움직이는 프로그램**입니다. 판단을 하지 않고, **시킨 대로만** 고칩니다.

그래서 지적이 <strong>「이 문장이 이상하다」</strong>로 끝나면 안 됩니다. <strong>「이 문장을 이렇게 바꿔라」</strong>까지 와야 합니다.

세 시선은 지적마다 고칠 방향을 붙입니다. **판정자**가 그걸 모아 「몇 번 케이스의 어느 칸을, 지금 적힌 이 글에서, 이 글로」라는 모양의 **수정 계획**으로 씁니다. 그러면서 지적끼리 부딪혀 보게 해 **틀린 지적·겹친 지적·값어치 없는 지적은 버립니다.**

| | 결과 |
|---|---|
| 지적만 있음 | **누군가 또 판단해야 함** → 매번 다른 결과 |
| **지적 + 처방** | **그대로 실행** → 재현됨 |

**판단하는 자리를 하나로 몰아 두는 것**이 목적이고, 그 한 자리가 판정자입니다. 여기저기서 판단하면 **어디서 뭐가 바뀌었는지 추적이 안 됩니다.**

판정자가 수정 계획을 약속한 형식대로 못 쓰면 한 번 더 시킵니다. **두 번째도 못 쓰면 그 자리에서 멈춥니다.**

## 값을 치른 것 — 「형식을 안 정하면 다음 단계가 죽습니다」

제외 사유를 **자유 문장으로** 쓰게 뒀습니다. 「이건 이래서 뺍니다」처럼요.

그랬더니 AI마다 다르게 적었습니다. 어떤 건 괄호로 감싸고, 어떤 건 서술형으로 길게 썼습니다.

그리고 **다음 단계가 그걸 읽다가 멈췄습니다.** 예상한 형태가 아니니까요.

**명세를 안 쓴 대가**였습니다. 「알아서 적어」는 **읽는 쪽이 있는 한 성립하지 않습니다.**

## 「같은 지적이 몇 번째인지」 적힌 목록을 들고 읽습니다

검토에서 나오는 지적 중에는 **전에도 나온 것**이 많습니다. 그래서 반복되는 지적을 모아 두는 목록이 따로 있고, 그 목록에 **승격 절차**가 있습니다.

| 같은 지적이 | 그러면 |
|---|---|
| 1~2번 | 그냥 고침 |
| **여러 번 반복** | **규칙으로 승격** — 애초에 그렇게 안 쓰게 만듦 |

왜 이게 필요하냐면 — **매번 잡아서 고치면 매번 비용이 듭니다.** 그리고 **한 번 안 잡히면 그냥 나갑니다.**

<strong>반복되는 지적은 「검토로 잡을 것」이 아니라 「애초에 안 생기게 할 것」</strong>입니다.

그런데 **뭐가 반복되는지는 세어 보기 전에는 모릅니다.** 매번 고치고 나면 기억에 안 남으니까요. 그래서 **세는 장치를 따로** 뒀습니다.

세 시선은 이 목록을 **먼저 읽고** 들어갑니다. 목록에 오른 실수가 이번에도 나왔는지를 자기 영역 안에서 봅니다.

솔직히 적으면, **리뷰가 이 목록에 직접 적지는 않습니다.** 리뷰 규칙서에는 「끝나면 목록에 적어라」가 남아 있지만, 지금 세 시선은 그 규칙서를 받지 않고 <strong>「결과 파일 말고는 아무것도 쓰지 마라」</strong>는 지시를 받습니다. 목록을 채우는 일은 따로 돕니다 — 사람이 테스트하면서 시트를 손으로 고친 흔적을, 파이프라인이 냈던 최종본과 비교해 후보를 뽑습니다. 목록에 올리는 것은 **사람이 시킬 때만** 합니다.

## 여기서 장부도 만듭니다

기획서 규칙과 케이스를 **의미로 이어 붙이는 일**을 여기서 합니다.

「기계적으로 번호를 맞추는 일」이 아니라 **「이 규칙을 저 케이스가 실제로 확인하고 있나」를 판단하는 일**이라, AI가 합니다.

## 리뷰가 새로 만든 질문은 사람에게 가기 전에 한 번 더 찾아봅니다

리뷰를 하다 보면 「기획서만으로는 기대 결과를 못 정하겠다」는 케이스가 새로 생깁니다. 그런 케이스에는 **「기획 확인 필요」** 표시가 붙고, 나중에 기획자에게 가는 질문 목록에 들어갑니다.

그런데 사내 위키에서 답을 찾아보는 일은 **설계 단계에서 한 번만** 했습니다. 그 뒤 리뷰에서 새로 생긴 질문은 **한 번도 찾아보지 않은 채** 사람에게 갔습니다.

2026년 9월부터는 수정을 적용하기 **바로 전에**, 리뷰가 새로 붙인 질문만 골라 사내 위키에서 다시 찾아봅니다. 수정 전이어야 찾은 답이 케이스의 기대 결과까지 채울 수 있습니다. 확신이 없으면 답을 지어내지 않고 **그대로 사람에게 묻습니다.**

한계도 있습니다. 리뷰어가 적은 이유 문장이 **그대로 검색어**가 되어서, 무엇에 대한 질문인지 안 적힌 이유로는 아무것도 못 찾습니다.

## 여기부터는 자세한 기록입니다

코드가 먼저 후보를 뽑는다 — 완전 중복, 원문에 근거 없는 케이스, 아이템 실명 미병기. 그 위에서 세 렌즈가 병렬로 리뷰한다(구조 · 품질 · 원문 대조). 판정자가 셋의 지적을 서로 반박시켜 수정 계획을 낸다. 렌즈 셋과 판정자는 Sonnet 모델로 돌고, 판정자만 깊게 생각하는 설정(effort high)을 쓴다. 판정자 산출이 형식 검증을 두 번 못 넘으면 런이 실패로 멈춘다(2026-09 기준).

## 예전엔 1차와 2차가, 지금은 세 렌즈가 서로를 안 본다

예전(v2)에는 리뷰를 두 차수로 나눠 **담당 항목을 명시적으로 갈랐다.**

| | 묻는 것 | 보는 것 |
|---|---|---|
| **1차** | 빠진 게 없는가 | 커버리지, 분류 정합, 검증 단계 배분 |
| **2차** | 내용이 맞는가 | 문장 품질, 중복, 한 케이스 한 검증점 |

그때도 **상대 영역은 명시적으로 안 봤다.** 2차는 구조를 다시 안 보고, 1차는 문장 품질을 안 봤다. 2차가 하던 구조 관련 일은 1차 지적이 반영됐는지 1:1로 대조하는 것뿐이었다.

지금(2026-09 기준)은 차수가 없다. 구조 · 품질 · 원문 대조 세 렌즈가 한꺼번에 돌고, 렌즈마다 프롬프트에 「타 렌즈 영역 침범 금지」가 박혀 있다. 렌즈 셋은 입출력이 서로 독립이라 2026-08-09 부터 병렬로 돈다 — 순차일 때보다 렌즈 구간이 런당 중앙값 9.9분 짧아졌다. 차수 사이의 「반영 대조」도 없어졌다. 수정 계획은 판정자 하나가 확정하고, 적용은 S5 의 결정론 코드가 한다.

이렇게 나눈 이유는 단순하다. **한 번에 다 보라고 하면 둘 다 대충 본다.** 특히 긴 시트에서는 앞쪽만 꼼꼼하고 뒤로 갈수록 흐려지는데, 축을 좁히면 그게 덜하다.

비율 기준도 걸어 뒀다 — 예전엔 1차가, 지금은 구조 렌즈가 든다. 위험도가 높은 소분류는 부정·예외 케이스가 60% 아래면 지적이 뜬다. 사람이 정상 케이스만 쓰는 쪽으로 쏠리기 때문이다. 이 기준은 리뷰 규칙서에서 뽑은 발췌본에 있다. 규칙서 원본은 체인이 런타임에 읽지 않고, 렌즈 문구는 워크플로 코드에 박혀 있다.

## 지적에는 처방이 따라야 한다

수정 단계는 **판단하지 않는 코더**로 설계돼 있다. 처방을 그대로 실행할 뿐이다. 지금(2026-09 기준)은 그 코더가 LLM 이 아니라 결정론 코드다.

그래서 리뷰어는 이슈마다 **수정자가 그대로 실행할 수 있는 처방**을 반드시 쓴다. "이 부분이 모호합니다"로 끝내면 안 되고, 어느 행의 어느 열을 무엇으로 바꾸라고 적어야 한다. 지금은 렌즈가 지적마다 고칠 방향을 필수로 달고, 판정자가 그걸 「케이스 번호 · 열 · 지금 값 · 바꿀 값」 패치로 확정한다. 지금 값을 같이 적는 건, 적용 때 실제 셀이 그 값과 다르면 코드가 고치지 않고 충돌로 돌려보내게 하려는 것이다.

이 규칙이 없으면 **판단이 두 번 일어난다.** 리뷰어가 "이게 문제다"까지 판단하고, 수정자가 "그럼 어떻게 고치지"를 다시 판단한다. 두 판단이 어긋나면 고친 결과가 지적과 상관없어지고, 그걸 확인하는 건 또 사람이다.

## 작업을 끝내고 죽는 실패

여기서 커버리지 원장도 만든다 — 기획서 규칙과 케이스를 의미로 이어 붙이는 일이다.

규칙 전량을 한 번에 뱉게 했더니 **출력 토큰 상한에 걸렸다.** 매핑은 다 끝내 놓고 **출력만 못 하고 죽는다.** 세 건에서 났고, 재시도까지 겹쳐 한 건은 88.3분이 통째로 날아갔다.

**작업 도중에 죽는 실패보다 작업을 끝내고 죽는 실패가 비싸다.** 앞의 것은 부분 결과라도 남는데, 뒤의 것은 100%가 사라지고 그 사실조차 늦게 안다. 지금은 규칙을 50개씩 끊어 셋씩 병렬로 돌리고, 청크 결과를 코드가 병합한다. 청크끼리 겹치거나 담당 밖 규칙을 건드리는 건 검증기가 막는다. 빠진 규칙은 막지 않는다 — 미커버는 따로 판정하고, S5 가 케이스를 더 만들어 메운다.

## 형식을 안 정하면 다음 단계가 죽는다

제외 사유를 자유 문장으로 쓰게 뒀더니 에이전트마다 래퍼를 씌우거나 서술형으로 적었고, **다음 단계가 타입 오류로 멈췄다.** 명세를 안 쓴 대가다.

지금은 제외 사유가 **정확히 세 값 중 하나**다. 근거 문장은 따로 담는 자리를 뒀다.

그리고 **"추후 구현"은 제외 사유가 될 수 없다.** 그건 케이스로 만들어 두고 판정만 유보하는 것이지, 안 만드는 이유가 아니다. 안 만들면 다음 버전에서 아무도 그게 있었다는 걸 모른다.

## 같은 지적이 몇 번째인지 센다

발견 패턴은 **큐에 쌓인다.** 그리고 그 큐가 승격 절차를 가진다.

1. 한 번 발견되면 관찰 목록에 한 줄
2. 같은 유형이 **두 번 이상 재발**하면 활성 패턴으로 승격
3. 석 달마다 활성 패턴을 규칙서에 정식 반영하고 큐에서 뺀다
4. 규칙에 반영했는데 **또 터지면** 재발 감시로 되돌린다

4번이 핵심이다. 규칙을 고쳤는데도 같은 게 나오면 그건 **규칙이 안 읽히거나 애매하다는 뜻**이고, 다음 조치는 문장을 강화하는 게 아니라 **기계 검사로 격상**하는 것이다.

지금 큐에는 재발 10회, 13회짜리가 앉아 있다. 그 숫자 자체가 정보다 — **열 번 넘게 같은 지적이 나왔으면 그건 쓰는 사람 문제가 아니라 규칙 문제다.**

단, 지금(2026-09 기준) 체인 안의 리뷰는 이 큐를 **읽기만** 한다. 렌즈는 큐 사본을 받아 자기 영역에서 재발을 점검하지만, 산출 파일 외에는 쓰지 말라는 지시를 받는다. 리뷰 규칙서에는 「끝나면 큐에 적어라」가 남아 있는데, 체인이 그 규칙서를 런타임에 읽지 않는다. 큐에 적는 일은 체인 밖의 수집 명령이 한다 — QA 가 테스트하며 시트를 손으로 고친 흔적을 파이프라인 최종본과 비교해 후보를 내고, 등록은 사람이 명시할 때만 한다.
