모델이 정말 중요한지 판단할 수 없는 이유
요약
AI 에이전트를 활용한 코드 리뷰 워크플로우 실험을 통해 모델의 계보보다 컨텍스트와 프롬프트 품질이 결과에 더 결정적인 영향을 미친다는 사실을 발견했습니다. Gemini와 Claude를 비교하며 저장소 컨텍스트 접근 권한이 리뷰 성능에 미치는 차이를 분석합니다.
핵심 포인트
- 모델의 종류(lineage)보다 컨텍스트와 프롬프트 품질이 코드 리뷰 성능을 결정함
- 저장소 전체 컨텍스트를 파악하지 못하는 모델은 심각한 오류를 놓칠 수 있음
- 적대적 프레임워크(adversarial framing)를 통한 에이전트 간 상호 검증의 유효성 확인
- GitHub Action 등 도구 사용 시 최신 버전 및 권한 설정의 중요성
이질적인 AI 코드 리뷰를 테스트하기 위해 시작했을 때 제가 실제로 발견한 것입니다.
지난 몇 달 동안 저는 터미널에서 두 개의 에이전트(agent)가 참여하는 코드 리뷰 워크플로우를 실행해 왔습니다. 왼쪽 창에서는 Claude Code가 구현을 담당하고, 오른쪽 창에서는 적대적인 역할을 수행하도록 프롬프트(prompt)가 설정된 두 번째 Claude Code 인스턴스가 왼쪽 창에서 생성된 결과물의 문제점을 찾아내는 작업을 수행합니다. 결과는 놀라울 정도로 좋았습니다.
몇 주 전, 누군가 Dan Shipper가 출연한 Lenny's Podcast 에피소드를 보내주었습니다. 그가 언급한 내용 중 하나는 코딩과 리뷰를 위해 서로 경쟁하는 프런티어 모델(frontier models)을 사용하는 것이었습니다. 모델의 계보(lineage)가 다르면 서로 다른 사각지대를 가지고 있으며, 작성자와 다르게 훈련된 리뷰어가 작성자가 놓치는 부분을 잡아낼 수 있다는 아이디어였습니다. 이는 워크플로우에서 중요한 공백처럼 느껴졌고, 저는 이를 채우기로 했습니다.
저는 모델의 다양성(model diversity)을 신뢰성 전략으로 다루는 글을 쓰게 될 것이라 예상했습니다. 하지만 결과는 달랐습니다.
코드와 맞닥뜨리며 무너진 계획
Gemini 코드 리뷰 GitHub Action을 검색하다가 적절한 README가 포함된 하나를 발견했습니다. 첫 번째 테스트는 의도적으로 잘못 작성된 변경 사항(changeset)을 대상으로 실행했습니다. Gemini 2.5 Pro는 몇 가지 사항을 지적했지만, 명백한 멀티 테넌시(multi-tenancy) 위반 사항을 완전히 놓쳤고, 실제 심각도와 상관없이 모든 항목을 중간 심각도로 분류했습니다. 이는 나중에 알게 된 것처럼 Gemini의 코드 리뷰 능력이 부족해서가 아니라, 해당 액션(action)이 저장소 컨텍스트(repo context) 없이 단 네 줄의 일반적인 프롬프트를 통해 diff 덩어리(hunks)를 전달했기 때문이었습니다. 이 세션의 기술적 노트는 이를 잘 설명합니다: "빨대를 통해 리뷰하는 프런티어 모델."
동일한 적대적 프레임워크(adversarial framing)를 사용하면서도 전체 저장소 접근 권한을 가진 터미널 Claude 리뷰어는, 잘못된 변경 사항에 심어둔 모든 문제점은 물론 계획되지 않았던 몇 가지 사항까지 찾아냈습니다.
이 격차는 하나의 가설을 불러일으켰습니다: 발견된 결과의 차이가 모델의 계보 때문인가, 아니면 컨텍스트와 프롬프트의 품질 때문인가? Gemini 액션은 둘 다 없었습니다. 터미널 리뷰어는 둘 다 가지고 있었습니다. 계보(lineage)라는 변수는 처음부터 혼란을 주는 요소였습니다.
이를 격리하기 위해, 다음으로 Claude GitHub Action을 투입했습니다. 기본 설정인 Sonnet 4.6은 Gemini 액션과 유사한 결함을 보였습니다. 전체 리포지토리 체크아웃 (full repo checkout)과 코드베이스의 핵심 규칙을 인코딩한 적대적 프롬프트 (adversarial prompt)를 적용하여 Opus 4.8로 업그레이드했으나, 결과는 터미널 리뷰어와 동일했습니다. 가설이 입증되었습니다. 컨텍스트 (Context)와 프롬프트 품질이 핵심적인 역할을 하고 있었습니다. 모델 계보 (Model lineage)는 기껏해야 부차적인 변수였습니다.
왜 공식 Gemini 액션을 그냥 사용하지 않았나요?
좋은 질문입니다. 공식 액션은 존재합니다. 세션 초반의 검색에서는 발견되지 않았습니다. Claude에게 직접 물었을 때 나온 답변은, Claude 측의 질문 방식이 미흡했다는 것이었습니다. 큰 실수였습니다. 그동안 실행되고 있었던 것은 버려진 프로젝트의 별점 2점짜리 포크 (fork) 버전이었으며, 마지막 업데이트는 14개월 전이었고, 지원이 중단된 (deprecated) Node 런타임에서 실행되고 있었으며, 풀 리퀘스트 (pull request)에 대한 쓰기 권한이 있는 가변적인 버전 태그에 고정되어 있었습니다. 마켓플레이스 (Marketplace)는 "좋은 것"이 아니라 "존재하고 README가 있는 것"에 보상을 줍니다. 쓰기 토큰 (write token)과 API 키를 넘겨주는 것이라면 무엇이든 소스 코드를 확인하십시오.
그래서 다음으로 퍼스트 파티 (first-party) 액션을 투입했습니다. 여기서부터 오후 작업이 복잡해졌습니다.
2.5 Pro가 탑재된 퍼스트 파티 Gemini 액션은 숨겨진 API 에러와 함께 빈 응답을 반환했습니다. Flash는 모든 호출에서 400 에러를 반환했습니다. MCP 서버를 완전히 우회하여 텍스트 프롬프트를 통해 PR 디프 (PR diff)를 API에 직접 전달하는 방식은 명령줄 (command line)에서 종료 코드 1 (exit 1)과 진단 출력 없이 실패했습니다. 몇 가지 설정을 더 시도해 보았으나, 어떤 것도 리뷰를 생성하지 못했습니다. 이 실패는 모델 계층 (model-layer) 문제, 구체적으로는 이 컨텍스트에서 2.5 Pro가 빈 응답을 반환하는 문제로 진단되었고, 해당 시도는 중단되었습니다.
새로운 가설이 등장했습니다: Gemini가 Claude보다 Gemini 툴링 (tooling)과 플로우 (flows)를 구현하는 방법을 더 잘 이해하고 있는가?
저는 로컬에 Gemini CLI를 설치하고, 지금까지 시도했던 이력과 PR, 그리고 작동하는 구현체가 무엇을 해야 하는지에 대한 설명을 전달했습니다. 12분 후, 질문 하나 없이 모든 것을 수정했다는 알림이 나타났습니다. 그 과정에서 무료 티어 (free tier) 할당량의 60%를 소모하기도 했습니다.
해결책: GEMINI_CLI_TRUST_WORKSPACE: true. 통합 도구의 이전 버전에서는 설정되어 있었으나, 코드 재작성 (rewrite) 과정에서 누락되었던 플래그입니다. 모델 계층 (model-layer)의 문제라고 확신하며 발생했던 빈 응답 (empty response) 실패는, 사실 재작성 과정에서 발생한 워크스페이스 신뢰 (workspace trust) 회귀 문제였으며, 이후 잘못 진단된 것이었습니다. Gemini가 버그를 찾아냈습니다. 세션은 해결책에 도달하기 직전에 중단되었습니다. 에이전트 (agent)가 일으킨 문제에 대해, 또 다른 에이전트가 잘못된 진단을 내린 상황이었습니다.
리포지토리 인지 (repo-aware) Gemini가 실제로 찾아낸 것
전체 리포지토리 컨텍스트 (repo context)를 확보하고 코드베이스의 핵심 규칙을 인코딩한 적대적 프롬프트 (adversarial prompt)를 사용하자, gemini-2.5-pro를 실행 중인 Gemini CLI는 이전에 차이점 기반 (diff-only) 액션이 보았던 것과 동일한 잘못된 피스처 (fixture)를 검토했습니다. 차이점 기반 버전이 완전히 놓쳤던 테넌트 간 데이터 유출 (cross-tenant data leak)을 포함하여, 테스트 미준수 정책 위반, SQL 인젝션 (SQL injection), 그리고 평문으로 로그에 기록된 하드코딩된 비밀값 (hardcoded secret) 등 네 가지의 결정적인 발견 사항이 있었습니다. 실제 차별화된 심각도 (severities)를 보여주었습니다. 동일한 모델 제품군 (model family)이었지만, 완전히 다른 하네스 (harness)를 사용했기에 완전히 다른 결과가 나왔습니다.
이것이 두 번 확인된 논지입니다. 차이점 기반 액션은 테넌트 스코핑 (tenant-scoping)이 리포지토리의 핵심 규칙이라는 점을 아무도 알려주지 않았고 직접 찾아볼 수도 없었기 때문에 멀티 테넌시 (multi-tenancy) 위반을 놓쳤습니다. 반면 리포지토리 인지 CLI는 이를 즉시 포착했습니다. 유일한 변수는 컨텍스트 (context)였습니다.
현재 실행 중인 구성과 여전히 알 수 없는 것
현재 구성: 기본 자동 리뷰어로 Claude Code 액션 사용, 전체 리포지토리 체크아웃 (checkout), CLAUDE.md 로드, 적대적 프롬프트 사용. 보조 온디맨드 (on-demand) 리뷰어로 Gemini CLI 사용, 동일한 적대적 프레임워크 (adversarial framing), 동일한 리포지토리 접근 권한. 계보의 다양성 (lineage diversity)이 신호 (signal)를 더하는지 아니면 그저 노이즈 (noise)를 더하는지에 대해 결론을 내리기 전까지 몇 주 동안 두 가지를 모두 실행할 예정입니다.
이번 세션을 통해 확정된 몇 가지 사항:
언제나 제3자 도구 (third-party)보다는 퍼스트 파티 (first-party) 도구가 우선입니다. 버려진 포크 (fork) 버전이 이번 세션 전체 동안 리뷰를 안정적으로 게시한 유일한 Gemini 통합 도구였습니다. 또한 다른 모든 척도로 보았을 때 최악의 옵션이기도 했습니다. 이것이 트레이드오프 (tradeoff)가 되어서는 안 되며, 앞으로도 그렇지 않을 것입니다.
컨텍스트 (Context)와 프롬프트 (prompt) 품질이 모델 선택을 지배합니다. 저장소 (repo)의 컨텍스트가 없는 리뷰어는 그 뒤에 어떤 모델이 있든 빨대를 통해 들여다보는 것과 같습니다. 가장 중요한 변수는 하네스 (harness)입니다.
모델들은 서로 다른 작업 스타일을 가지고 있으며, 이는 예상보다 더 중요한 요소임이 드러났습니다. Claude는 행동하기 전에 질문했습니다. Gemini CLI는 자율적으로 문제를 해결하고 완료되었을 때 알림을 띄웠습니다. 두 방식 모두 틀린 것은 아닙니다. 하지만 어떤 모드로 작업하고 있는지 아는 것이 이를 감독하는 방식을 변화시킵니다.
이번 세션 전체에서 버그를 가장 확실하게 잡아낸 것은 특정 리뷰어가 아니었습니다. 그것은 바로 코드를 실행하는 것이었습니다. 잘못 진단된 모든 실패, 환각 (hallucination)된 모든 수정 사항, 확신에 찬 모든 오답은 실제로 무언가가 실행되어 에러를 반환할 때 포착되었습니다. 에이전트 (Agent)들이 리뷰했습니다. 에이전트들이 분류 (triage)했습니다. 에이전트들이 잘못 진단했습니다. 실행 (Execution)이 이를 잡아냈습니다. 이 모든 것을 지시하는 인간 목자 (human shepherd)는 에러 체인 (error chain)에 포함되지 않았습니다. 다음 에이전트 실행이 포함되었습니다.
계보 다양성 (lineage-diversity) 가설은 여전히 열려 있습니다. 이번 세션이 확립한 것은 하네스 품질이 변수로서 모델의 능력 (capability)보다 우세하며, 적대적 프레이밍 (adversarial framing)과 전체 컨텍스트를 갖춘 동일 계보의 리뷰어는 실제로 중요한 측면에서 이미 이질적 (heterogeneous)이라는 점입니다. 그 위에 진정으로 다른 계보를 추가하는 것이 무언가를 더해줄지는 더 많은 데이터가 필요한 문제입니다.
다시 보고하겠습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기