한 AI에게 다른 AI를 위한 핸드오프 프롬프트를 파괴하라고 시켰더니, 내용이 비어 있어도 통과되는 테스트를 찾아냈습니다
요약
Claude Code를 활용한 에이전트 워크플로우에서 '커맨더'와 '워커' 간의 핸드오프 프롬프트가 가진 위험성을 다룹니다. 프롬프트가 실제 코드와 일치하지 않을 경우 발생하는 오류를 방지하기 위해, 지침을 파괴하고 검증하는 '서브에이전트' 도입의 중요성을 강조합니다.
핵심 포인트
- 핸드오프 프롬프트는 AI 에이전트 간의 핵심 명세서 역할을 함
- 프롬프트의 지침이 실제 코드 구현 상태와 다를 경우 심각한 오류 유발
- 검증을 위해 지침의 허점을 찾는 '파괴 에이전트(Demolition Agent)' 활용 권장
- 테스트 통과 기준(DoD)이 실제 성공 여부를 보장하는지 엄격히 확인 필요
저는 지금 Claude Code를 사용하여 앱을 구축하고 있습니다.
설정이 조금 독특합니다. 하나의 "커맨더 (commander)" 세션이 지침을 작성하면, 별도의 "워커 (worker)" 세션들이 이를 병렬로 구현합니다.
커맨더는 직접 키보드를 만지지 않습니다. 커맨더의 유일한 업무는 "다음에 무엇을 할지"를 워커가 읽고 바로 실행할 수 있는 핸드오프 프롬프트 (handoff prompt)로 변환하는 것입니다.
그리고 그 핸드오프 프롬프트는 전체 루프에서 조용히 가장 무서운 요소입니다.
제가 그것을 넘겨주는 순간, 워커는 그것을 명세 (spec)로 신뢰하고 전력 질주를 시작합니다.
만약 명세가 잘못되었다면, 잘못된 것이 구축됩니다. 그것도 아주 빠르고 자신감 있게 말이죠.
넘겨주기 전, 저는 평소 하던 의식을 치렀습니다
최근에 습관이 하나 생겼습니다. 지침을 워커에게 던지기 전에, **그 지침을 파괴하는 것이 유일한 업무인 서브에이전트 (subagent)**에게 검토를 맡깁니다.
이 에이전트는 절대 승인하지 않고, 허점을 찾아내며, 절대로 "대체로 합리적으로 보입니다"라는 말로 마무리하지 않도록 정의되어 있습니다.
이번에 달랐던 점은 이 에이전트가 단순히 제 프롬프트의 문장만 읽은 것이 아니라는 점입니다. 에이전트는 실제 코드까지 읽었습니다.
그리고 돌아온 답변을 보고 저는 가슴이 철렁했습니다.
반론 1: "테스트를 통과하게 만드세요 (go green)"라고 썼지만, 그 테스트의 '그린'은 아무런 의미가 없었습니다
지침에 저는 완료 정의 (definition of done, DoD)로 다음과 같이 적었습니다:
"XX 테스트를 통과하게 만드세요 (green)."
파괴 에이전트의 답변은 다음과 같았습니다:
"해당 테스트는 테스트 대상이 실패하더라도 그린 (green) 상태가 됩니다."
읽어보니 사실이었습니다.
그 테스트는 단지 "프로세스가 끝까지 실행되었는가"만을 확인합니다. 가장 중요한 것, 즉 "성공했는가?"는 전혀 확인하지 않습니다.
실패하더라도 "실패 결과를 반환하고 실행을 마쳤다면" 그린 상태가 됩니다.
게다가 배치 경로 (batch path)에서 예외 (exceptions)를 삼켜버리고 있어서, 무엇이 터지든 여전히 그린 상태였습니다.
따라서 워커가 "DoD 충족, 테스트 그린!"이라고 보고하더라도, 실제로 증명된 것은 아무것도 없었습니다.
제가 직접 작성한 완료 기준은 빈 껍데기 통과였습니다.
반론 2: "플래그를 바꾸기만 하면 됩니다"라고 썼지만, 그 스위치는 존재하지 않았습니다
하나 더 있습니다.
저는 마치 이미 존재하는 기능인 것처럼 "설정 플래그(config flag)를 전환하면 실제 컴포넌트로 교체됩니다"라고 적었습니다.
파괴 에이전트(demolition agent)는 코드를 추적한 뒤 다음과 같이 답했습니다:
"그 배선(wiring)은 어디에서도 호출되지 않습니다. 함수는 존재하지만, 아무것도 그것에 연결되어 있지 않습니다."
이 또한 사실이었습니다.
교체 함수는 있었지만, UI의 그 어떤 것도 그 함수에 도달하지 못했습니다.
작업자(worker)는 존재하지 않는 스위치를 찾기 위해 한 시간을 허비하거나, 찾는 것에 지쳐 "그럴듯한" 무언가를 조작해낼 뻔한 상황에서 단 한 걸음 차이로 놓칠 뻔했습니다.
저를 무섭게 했던 것은 제가 두 가지 모두를 사실로서 기술했다는 점입니다
두 번 모두, 저는 완전히 확신에 차서 작성했습니다.
"테스트가 통과됩니다." "플래그가 그것을 교체합니다."
그것들을 작성할 당시, 저는 진심으로 그렇게 믿었습니다.
파괴 에이전트는 제가 다시 읽어보지 않았던 코드를 읽었을 뿐입니다. 그것이 모든 차이였습니다.
핸드오프 프롬프트(handoff prompt)는 사실상 명세서(spec)입니다.
그리고 거짓말은 정확히 작업이 인계되는 순간 — 사람에서 AI로, AI에서 AI로, 혹은 오늘의 내가 다음 주의 나에게 — 슬그머니 끼어드는 경향이 있습니다.
내용은 비어 있지만 통과(green)된 테스트. "있어야 할" 배선.
산문(prose)을 읽고 고개를 끄덕이며 승인하는 리뷰는 이를 잡아내지 못할 것입니다. 오직 실제 코드를 읽고 거침없이 몰아붙이는 리뷰만이 이를 잡아낼 수 있습니다.
시사점
"테스트가 통과(green)되었다"는 것은 단지 그 테스트가 올바르다는 것만을 보장합니다.
그리고 당신이 직접 작성한 완료 기준(completion criteria)은 당신이 가장 의심하지 않을 가능성이 높은 항목들입니다.
그러니 어쩌면 타이핑을 시작하기 전에 당신이 파괴해야 할 것은 코드가 아니라, 바로 **지시 사항(instructions)**일지도 모릅니다.
구현을 위해 10시간을 돌린 후에야 "그 통과(green)가 아무 의미 없었다"는 사실을 깨닫는 것은, 인계하기 전 3분 동안 수행하는 적대적 리뷰(adversarial review)보다 훨씬 더 많은 비용이 듭니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기