AI가 작성한 코드를 멀티 에이전트(multi-agent)로 다각적인 관점에서 다른 AI에게 가차 없이 공격하게 하고,
그것을 여러 번 루프(loop)로 반복하면 품질은 올라갈 것이라고 생각했습니다.
순진했던 저는 오랫동안 그렇게 믿고 있었습니다.
하지만 상당한 토큰을 투입한 PR(Pull Request)에서 쉽게 실제 버그가 발생했고, 다음과 같은 질문에 처음으로 깨달았습니다.
- 질문: AI 간의 적대적 리뷰로 결과물이 정말 신뢰할 수 있는 것이 될까요?
- 결론: 그렇지 않습니다.
그 토큰은 실제로 구동하여 확인하는 '검증(verification)'에 사용되어야 합니다. - 이유: 코드의 차이점만 전달받은 AI는 트집 잡기나 나중에 필요할지도 모른다는 제안에 빠지기 때문입니다.
본 글에서는 저의 실패담과 에이전트 스킬 집합체인 'pstack'의 관점을 바탕으로 이 결론에 도달하게 된 이유를 작성합니다.
적대적 리뷰란 무엇인가
적대적 리뷰(adversarial review)는 특정 AI가 작성한 코드를 다른 AI에게 '결점 찾기'라고 지시하여 검토하게 하는 기법입니다.
예를 들어, Claude에 작성시킨 코드를 Claude의 다른 모델이나 GPT나 Gemini 등에 공격하게 하고, 그 지적 사항을 다시 Claude에게 수정하도록 시키는 방식입니다.
모델이 다르면 놓치는 부분도 다르기 때문에, 서로 부딪치게 하면 각자의 약점을 메울 수 있을 것이라는 발상입니다.
겉보기에는 매우 논리적으로 보이지만 함정이 있습니다.
저 역시 '인간의 코드 리뷰를 AI로 자동화할 수 있다면 최고잖아'라며 뛰어들었습니다. 그 함정이었습니다.
47건에 달하는 방대한 지적과 놓쳐버린 단 하나의 버그
개인적으로 개발하던 애플리케이션에서 집계 로직을 다시 작성했을 때의 일입니다.
에이전트에게 구현시킨 후, 다른 모델 2개에 코드 차이점(diff)을 전달하여 적대적 리뷰를 시켰습니다.
돌아온 지적 사항은 총 47건이었습니다.
내용을 살펴보니 다음과 같았습니다.
- “
total이라는 변수명은 모호합니다. monthlyExpenseTotal로 해야 합니다.” - “장래에 여러 통화에 대응할 가능성을 고려하여, 통화를 추상화하는 레이어(layer)를 두어야 합니다.”
- “이 주석의 표현은 오해를 불러일으킬 우려가 있습니다.”
모두 틀린 것은 아니었습니다.
하지만 47건 중 사용자가 어려움을 겪을 만한 버그를 지적한 것은 단 하나도 없었습니다.
지적 사항을 수정하자, 이번에는 수정한 부분에 새로운 지적이 붙고, 그것을 또 수정하는 과정을 거쳤습니다.
화면 안에서 AI들끼리 끝없이 논쟁을 이어가며 토큰만 점점 줄어들어 갔습니다.
그리고 다음 주, 월말 밤에 등록한 지출이 다음 달에 계상된다는 보고를 받았습니다.
원인은 시간대(Time Zone) 처리 문제였으며, 월말 23시경에 데이터를 한 번 등록해보니 바로 알 수 있는 버그였습니다.
맛보지 않는 '레시피 회의'는 의미가 없으니 그만두세요
이때 상황을 요리에 비유하자면, 한 입도 맛보지 않고, 레시피 종이만 둘러싸고 토론하는 요리사들입니다.
저는 이것을 '맛보기(味見)를 하지 않는 레시피 회의'라고 부릅니다.
레시피 회의에서는 다음과 같은 일들이 벌어집니다.
- ‘소금 약간’이라는 표기는 모호하다고, 표기상의 트집 잡기가 시작됩니다.
- “장래에 100인분을 만들 수도 있으니, 대형 가마솥(寸胴鍋)을 전제로 하자”라며, 이전 논의와 무관한 제안이 나옵니다.
- 그동안 계속 회의실 사용료가 발생합니다.
이 회의의 가장 큰 문제는 '아무도 실제 요리를 먹어본 적이 없다'는 점입니다.
핵심인 “이 요리가 맛있는가?”라는 질문에 아무도 답하지 못하고 있습니다.
왜냐하면 대답할 수 없기 때문입니다. 왜냐하면 먹어보지 않았으니까요.
한 입만 먹으면 10초 만에 알 수 있는 것을, 종이 위에서 몇 시간 동안 논의하는 것입니다.
왜 이런 현상이 발생하는지에 대해서는 두 가지 이유가 있다고 생각합니다.
첫째는 코드의 차이점(diff)만으로는 구동했을 때의 동작을 볼 수 없기 때문에, 코드가 보이는 부분인 명명 규칙이나 구조에 지적이 집중되는 것입니다.
둘째는 '결점을 찾아라'라는 말을 들은 AI는 '문제없습니다'라고 대답하기 어렵다는 점입니다.
리뷰어로서 불려간 이상, 무언가 말하지 않으면 일을 하지 않은 것처럼 보일 수 있기 때문일지도 모릅니다. (필사적으로 유능한 척해버리는 것이죠.)
적대적 리뷰는 대부분 토큰의 낭비다
pstack은 Cursor의 공식 플러그인 리포지토리에서 공개된 에이전트 스킬 집합체입니다.
작성자인 poteto 님은 Meta나 Netflix, Cursor 등에서 대규모 코드베이스를 다루었으며, React Compiler 개발에도 참여했던 분입니다.
pstack에는 차이점(diff)을 여러 모델에 공격시키는 interrogate라는 적대적 리뷰 스킬이 포함되어 있습니다.
그 저자 본인이 최근 X에서 이런 게시물을 올렸습니다.
maybe a hot take but i now consider adversarial reviews mostly a waste of tokens. far better to use those tokens on empirical combined with formal verification. i have updated pstack to use the interrogate skill less, and eventually i think i may remove it altogether
i have found very little value with code review in the abstract, agents tend to just get lost in the nitpicks and yagnis
대략적으로 번역하면, “적대적 리뷰는 대부분 토큰 낭비라고 생각하게 되었다. 그 토큰은 경험적 검증과 형식 검증에 사용하는 것이 훨씬 좋다. pstack도 interrogate를 사용하는 빈도를 줄였고, 결국 완전히 제거할 수도 있을 것 같다.”라는 내용입니다.
poteto 씨는 자신이 만든 스킬을 스스로 축소하고 있는 것입니다.
이것을 읽었을 때, 47건의 지적 사항 더미가 떠올라 “그렇죠”라는 말이 나왔습니다.
pstack이 강제하는 ‘시식(味見)’
그렇다면 pstack은 레시피 회의 대신 무엇을 시키는 것일까요?
답은 시식입니다. (혹은 맛보기 검증)
pstack의 중심에는 principle-prove-it-works라는 원칙이 있습니다.
“실제 본물을 직접 확인하여 검증하라. 대리 지표나 자기 신고, 컴파일 성공 여부로부터 추측하지 마라”는 취지로, “검증되지 않은 작업은 정확성이 불분명하다”라고까지 쓰여 있습니다.
에이전트에게 내리는 지시에도 “인간에게 전달할 확인 사항 중, 스스로 실행할 수 있는 것은 넘기지 말라”는 문구가 있습니다.
시식(味見)은 요리사의 일이지, 손님에게 떠넘기는 것이 아니라는 뜻입니다.
게다가 pstack에는 시식을 위한 도구를 만드는 스킬도 갖추고 있습니다.
create-verification-skill은 프로젝트의 앱을 실제로 구동하여 확인하는 스킬을 만듭니다.
create-formal-verification-skill은 경쟁이나 상태 전이처럼 테스트로는 포착하기 어려운 속성을 형식 검증(Formal Verification)으로 확인하는 스킬을 만듭니다.
저자가 말한 “실제로 구동하는 검증과 형식 검증의 조합”이 그대로 스킬로 구현된 것입니다.
Claude Code에서는 다음 명령어로 도입할 수 있습니다.
/plugin marketplace add cursor/plugins
/plugin install pstack@cursor-plugins
설치 후에는 /setup-pstack으로 역할별 모델을 선택하고, 이후에는 /pstack:poteto-mode에 작업을 맡기기만 하면 됩니다.
poteto-mode는 요청 내용을 보고 버그 수정이나 조사 등의 절차서(Playbook)를 선택하며, 필요한 스킬들을 호출해 줍니다.
시식으로 다시 진행한 버그 수정
시험 삼아 개인 앱의 코드를 수정 전 상태로 되돌린 후, pstack으로 다시 진행해 보았습니다.
/pstack:poteto-mode 월말(일본 시간 23시대)에 등록된 지출이 다음 달에 계상된다. 먼저 재현하고, 원인을 찾아낸 뒤 고쳐라. 완료 조건은, 월말 23시 30분의 지출이 당월 집계에 포함되는 것이다. 증거로, 수정 전 실패하고 수정 후 성공하는 테스트와 실제 집계 결과를 보여줘.
에이전트는 갑자기 코드를 작성하지 않았습니다.
먼저 재현 테스트를 작성했고, 그것이 수정 전 코드에서 실패함을 확인한 후에 원인 조사에 들어갔습니다.
수정 전에도 통과해 버리는 테스트는 수정의 근거가 될 수 없기 때문입니다.
원인은 날짜를 UTC 그대로 월별로 나누고 있었던 것이었습니다.
마지막으로, 수정 전에는 실패하고 수정 후에는 성공하는 테스트 결과를 나란히 보여주었습니다.
47건의 지적 사항으로는 발견하지 못했던 버그가, 단 하나의 실패하는 테스트 케이스를 통해 발견된 것입니다.
소요 시간은 20분 정도였고, 토큰 소비량도 적대적 리뷰를 할 때보다 훨씬 적게 끝났습니다.
「증거를 보여줘」 — AI 요청문에 작성하는 검증 방법
다시 해보니, 요청문(프롬프트)의 문구에 따라 결과가 크게 달라진다는 것을 알게 되었습니다.
pstack 공식 가이드에서도 에이전트에게 목표와 그 목표를 확인할 수 있는 방법을 함께 전달하도록 권장하고 있습니다.
앞서 사용한 요청문에서는 수정 방법에 대해 전혀 지정하지 않았습니다. 대신, 완료 조건과 보여주었으면 하는 증거를 작성했습니다.
'맛있는 수프를 만들어줘'가 아니라, '이 소금 간에 맞추고 시식한 결과도 보여줘'라고 부탁하는 이미지입니다.
여러분은 AI 요청문에 '어떻게 되어야 완료인지'를 적으시나요?
이것만 작성해도 pstack의 유무와 관계없이 산출물의 품질은 상당히 달라질 것이라 생각합니다.
적대적 리뷰가 남기는 역할
지금까지 적대적 리뷰(Adversarial Review)에 대해 부정적으로 이야기했지만, 리뷰 자체에 가치가 없다고는 생각하지 않습니다. 설계 의도를 공유하거나 보안상의 취약점을 발견하는 것은 단순히 구동만으로는 알 수 없는 부분입니다.
인간 간의 코드 리뷰에는 여전히 중요한 역할이 있습니다. 그리고 interrogate 역시 원래부터 '실행하여 증명할 수 있는 지적만을 남긴다'는 설계였습니다.
즉, 적대적 리뷰 안에서 진정으로 가치가 있었던 것은 처음부터 검증(Verification) 부분이었다고 생각합니다.
리뷰를 전부 할 필요는 없고, 먼저 시식(테스트)을 하고, 그 후에 리뷰를 하는 순서만으로도 충분하지 않을까요?
요약
- 코드의 차이점(diff)만을 전달받은 AI들 간의 적대적 리뷰는 트집 잡기나 앞선 제안에 빠지기 쉽습니다.
- 그 토큰은 실제로 구동하여 확인하는 검증에 사용하는 것이 더 효과적입니다.
- 그 검증 결과나 증거를 근거로 리뷰해야 합니다. (맛을 보고 싱겁다고 느낀 후에야 '소금을 조금 줄이는 게 좋겠다'는 제안이 가능합니다.)
- pstack은 원칙적으로 에이전트에게 검증을 강제하고, 검증 도구를 만드는 스킬까지 갖추고 있습니다.
- 요청문에는 절차(Procedure)보다 '완료 조건(Completion Condition)'과 '보여주었으면 하는 증거'를 작성하는 것이 요령입니다.
AI가 AI를 감시하게 하면 안심이라는 생각은 하나의 단계가 부족했을지도 모릅니다. 아무리 많은 사람에게 의견을 들어도, 음식이 맛있는지 여부는 먹어보기 전까지는 알 수 없습니다.
코드도 마찬가지로, 신뢰할 수 있는지 결정하는 것은 논의의 양이 아니라 확인된 사실의 양이라고 생각합니다.
혹시 AI 간의 리뷰 싸움에서 토큰을 소진한 경험이 있다면, 한번 그 토큰을 검증 시스템 구축에 사용해 보시길 바랍니다.
'저희는 이렇게 사용하고 있다'라는 이야기가 있다면 댓글란에 알려주시면 감사하겠습니다.
끝까지 읽어주셔서 감사합니다.
Discussion