0:00 — 빌드가 완료됩니다. 에이전트는 완료됐다고 말하지만, 이는 코드를 작성했다는 주장이지 코드가 작동한다는 주장이 아닙니다. AI 빌더를 써본 사람이라면 누구나 이 둘 사이의 간극을 최소 한 번은 느껴봤을 겁니다: 미리보기를 열고 세 번째 버튼을 클릭했는데 아무 일도 일어나지 않는 순간요. 바로 그 순간 데모룸이 조용해지는 걸 본 적이 있습니다. 그래서 사람이 빌드를 보기 전에, 약 6분 동안 체인이 스스로와 논쟁을 벌입니다. 실제로 어떤 모습인지, 잘못됐다가 고쳐진 빌드 하나를 추적해서 보여드리겠습니다.
0:02 — 코드 리뷰가 시작됩니다. 코드를 작성한 에이전트가 자기 숙제를 다시 읽는 게 아니라 — 별도의 에이전트가, 다른 프롬프트로, 빌드 통과 여부에 아무 이해관계 없이 검토합니다. 이 분리는 생각보다 훨씬 중요합니다. 오후 2시 14분에 에러 처리가 없는 fetch 호출이 괜찮다고 판단한 에이전트는, 자기 작업을 스스로 검토하라고 하면 오후 2시 15분에도 여전히 괜찮다고 생각할 겁니다. "무엇이 고장났는지 찾고, 파일을 명시하라"는 지시를 받은 새로운 리뷰어는 여러분이 정말 원하는 까다로운 시니어 엔지니어처럼 행동합니다. 이전 빌드에서는 카트 합계가 조용히 업데이트되지 않는 걸 잡아냈습니다 — `updateTotal`이 `Cart.jsx`에 정의는 되어 있었지만 수량 변경 핸들러에 연결되지 않아서, 함수는 존재하지만 아예 실행되지 않았던 것입니다. 컴파일러는 신경 쓰지 않는 이런 종류의 문제를 잡아내는 게 코드 리뷰의 역할입니다.
0:04 — 보안 감사. 이름처럼 광범위하지 않고, 의도적으로 좁습니다 — 침투 테스트가 아니라, AI가 생성한 코드에서 실제로 나타나는 소수의 실수를 찾아내는 패턴 헌팅입니다. 문자열로 이어붙인 SQL. 클라이언트 측 검증만 있는데 그게 전부인 것처럼 신뢰하는 경우. 그리고 단골 항목: 하드코딩된 API 키인데, 이는 기능을 작성한 에이전트 앞에 환경변수 사용 규칙이 미리 마련되어 있지 않아서 그냥 작동하는 방법을 택했기 때문입니다. 너무 자주 봐서 이제 놀랍지도 않은 수준입니다.
0:07 — 링크 및 SEO. 화려하지 않지만, 고객이 발견하기 전에는 아무도 눈치채지 못하는 것들을 잡아냅니다: 다음을 가리키는 내비게이션 링크 /pricing 인데 실제 페이지는 다음 주소에서 생성된 경우 /price, 404가 뜨는 페이지의 사이트맵 항목, 여전히 템플릿 자리표시자 텍스트가 남아 있는 메타 설명. 이런 것들은 빌드를 깨뜨리지 않습니다. 하지만 우리 사용자 대부분이 사이트를 만든 진짜 목적—발견되고 클릭받는 것—을 조용히 갉아먹습니다.
0:09 — 접근성. 이건 완전한 수동 감사가 아니라 자동화된 axe-core 검사이며, 이 트레이드오프가 무엇을 사주는지 솔직히 말씀드릴 필요가 있습니다. axe-core는 대비율, 누락된 대체 텍스트, 라벨 없는 폼 입력, 탭 순서 함정 등 기계적인 층위 — 완전한 WCAG 검토에서 지적될 사항의 약 30~40% 정도 — 를 잡아냅니다. 기술적으로는 준수하지만 실제로 사용하기 혼란스러운 스크린 리더 경험은 잡아내지 못합니다. 여기서 처리되는 것 대부분이 마케팅 사이트와 소규모 도구이며, 부분 감사가 누군가에게 실질적 위험이 되는 종류의 애플리케이션이 아니기 때문에, 초 단위로 실행되는 자동화 전용 방식을 선택했습니다.
0:11 — 준수 확인. 이 단계는 "이게 좋은가"를 묻는 게 아니라 "약속한 대로인가"를 묻습니다. 계획서에는 네 페이지라고 했는데 빌드는 세 페이지만 배포됐다면 — 준수 확인이 이를 알아챕니다. 작동하는 문의 폼을 약속했는데 실제로 배포된 것이 제출 액션 없는 폼이라면 — 같은 층위, 같은 종류의 발견입니다. 이건 사용자가 명시한 의도를 기준으로 측정하기 때문에, 추상적인 품질 개념이 아니라 사용자에게 가장 직접적으로 책임을 지는 검사입니다.
0:13 — 브라우저 내 검사, 그리고 여기서 실제로 우리 빌드가 망가졌습니다. 이 층위는 코드를 읽는 게 아니라 실제 브라우저를 구동하기 때문에 속이기가 가장 어렵습니다 — 클릭하고, 입력하고, 기다리고, DOM이 예상대로 바뀌었는지 확인합니다. 문제의 빌드는 방치형(idle) 게임이었고, 게임은 여기서 추가 검사를 받습니다. 게임은 픽셀 단위로 완벽하게 렌더링되면서도 플레이가 불가능할 수 있기 때문입니다 — 점수 표시는 완벽해 보이면서도 실제 점수 로직과는 완전히 단절되어 있을 수 있습니다. 검증기가 실제로 플레이해봤습니다. 점수는 잘 업데이트됐습니다. 오디오는 소리를 내지 않았습니다.
세 라운드, 그다음 에스컬레이션
이 발견은 버그 보고서로 우리에게 전달된 게 아니라 곧바로 수정 단계로 넘어갔고, 체인은 빌드 내에서 최대 세 라운드까지 재검증했습니다. 1라운드: 이미 문제없던 믹서 초기화 부분을 수정해서, 오디오는 여전히 소리가 나지 않았습니다. 2라운드: 인접해 보이는 다른 로딩 상태 엣지 케이스를 수정했는데 — 예상보다 자주 일어나는 일이지만 — 원인은 해결하지 못한 채 작은 새 문제를 만들어냈습니다. 3라운드: 여전히 소리가 안 났고, 이 시점이면 보통 정말로 어려운 문제이거나 거짓 경보 둘 중 하나인데, 이번엔 어려운 쪽이었습니다.
그래서 플랫폼이 스스로 에스컬레이션했습니다. 남아 있는 발견 사항만을 대상으로 하는 후속 수정 작업을 예약했는데, 빌드 자체가 아니라 빌드의 복제본에서 작업했습니다 — 즉 에스컬레이션 작업이 실패해도 이미 확보한 정상 작동 버전을 잃을 위험이 없었다는 뜻입니다. 그 작업이 실제 원인을 찾아냈습니다: 이전 디버그 단계에서 설정된 뒤 다시 원상복구되지 않은 음소거 플래그가, 이전 두 번의 수정이 건드렸던 것과는 완전히 다른 파일에 남아 있었습니다. 플래그를 해제하고 재검증했더니 통과했습니다. 이 빌드는 이미 작동하는 상태가 될 때까지 아무도 들여다보지 않았습니다.
| 주문 | 레이어 | 발견 사항 |
|---|---|---|
| 1 | 코드 리뷰 | 고장난 로직, 죽은 핸들러, 상태 버그 |
| 2 | 보안 감사 | 인젝션 취약점, 유출된 시크릿, 안전하지 않은 패턴 |
| 3 | 링크 및 SEO | 깨진 링크, 누락된 메타데이터, sitemap/robots.txt 정확성 |
| 4 | 접근성 | 자동화된 axe-core: 대비, 라벨, 키보드 내비게이션 |
| 5 | 적합성(Conformance) | 빌드가 계획서에서 약속한 내용을 포함하고 있는가 |
| 6 | 브라우저 내 검사 | 빌드를 실제로 실행 — 클릭하고, 입력하고, 반응을 지켜봄 |
다음에는 건너뛸 것
그 방치형 게임이 실행되기 몇 달 전, 우리는 전체 시스템의 더 느슨한 버전을 시도했습니다 — 검증자가 어떤 형태로든 우려 사항을 자유롭게 제기할 수 있도록 한 것입니다. 그 결과 "이걸 헬퍼로 추출하는 걸 고려해보세요", "이 변수 이름이 더 명확할 수 있습니다" 같은 발견이 나왔는데, 성실해 보이지만 아무것도 고치지 못했습니다. 수정 단계는 실제로 고장난 부분을 고치는 대신 문장을 다듬는 데 라운드 전체를 소모했습니다. 우리는 규칙을 다음과 같이 강화했습니다: 파일을 명시하거나, 실패 상황을 설명하거나, 아니면 아무 말도 하지 말 것. 검증자의 출력은 약 절반으로 줄었고, 남은 것은 거의 다 실행 가능한 내용이었습니다. 처음부터 다시 만든다면 느슨한 버전은 건너뛰고 곧바로 근거 규칙으로 갈 것입니다 — 이 교훈을 굳이 비싸게 배울 필요는 없었지만, 결국 그렇게 했습니다.
이 규칙에는 실제 대가가 있고, 이를 숨기지 않겠습니다: "이 API 설계는 6개월 후에 누군가를 곤란하게 만들 것이다"처럼 모호하지만 사실일 수 있는 우려는 이제 그냥 버려집니다. 검증자가 이를 구체적인 실패에 연결할 수 없기 때문입니다. 우리는 이 트레이드오프를 받아들이기로 했습니다. 아키텍처 검토까지 하는 체인은 모든 빌드마다 실행할 만큼 빠르지 않으며, 사람이 직접 검토하는 대신 이걸 자동으로 실행하는 것의 핵심은 바로 속도입니다.
네 번째 라운드를 추가하는 것도 하지 말라고 말씀드리고 싶습니다, 누가 묻는다면요. 실제 빌드를 대상으로 라운드 수를 조정해봤는데, 3라운드를 넘어가면 한계 가치가 급격히 떨어집니다 — 1라운드가 수정 가능한 발견 대부분을 해결하고, 2라운드는 대체로 1라운드가 만든 문제를 정리하며, 3라운드쯤 되면 남은 것은 정말로 어렵거나 애초에 문제가 아니었던 것입니다. 4라운드는 대체로 같은 결과를 위해 대기 시간만 더 늘릴 뿐입니다.
이 중 어느 것도 공짜가 아니고, 완벽하지도 않습니다. 여섯 개의 검증 층위와 필요한 만큼의 수정 라운드는 모든 빌드에 실제 시간을 추가합니다 — 1분 이내에 끝나는 것과 몇 분 걸리는 것의 차이입니다. 우리는 여러분이 자신의 고객 앞에 내놓을 무언가에는 이것이 옳은 트레이드오프라고 생각하지만, "빠름"과 "검증됨"은 서로 반대 방향으로 당기고, 우리는 검증됨을 선택했습니다. 검증자 역시 LLM이기 때문에, 실제로는 고장나지 않은 것을 지적하거나 실제로 고장난 것을 놓치기도 합니다. 근거 규칙과 다중 라운드 루프는 이에 대한 보완책이지, 보장이 아닙니다.
최종적으로 여러분이 받는 것은 하나의 기록입니다: 어떤 층위가 실행됐는지, 무엇을 발견했는지, 무엇이 수정됐는지, 그리고 여러분 스스로 판단할 몫으로 남은 것은 무엇인지. 이 기록은 코드 자체보다 실제 결과물에 더 가깝습니다 — 완성된 것처럼 보여서 신뢰하는 빌드와, 무언가 적대적인 존재가 먼저 깨뜨리려 시도했지만 실패했기 때문에 신뢰하는 빌드의 차이입니다.



