Codex가 Claude의 코드를 검토하는 방법: '완료'의 정의, 내부 규칙 및 라운드 규칙
요약
본 글은 Claude Code와 Codex를 활용하여 코드 리뷰 프로세스의 비효율성을 개선하는 방법을 제시합니다. 기존 루프는 '완료'의 정의가 모호하여 끝없이 반복되는 문제가 있었으나, 이를 해결하기 위해 '완료의 정의', '내부 규칙', '라운드 규칙' 세 가지 요소를 도입했습니다. 이 시스템은 명확한 게이트와 커밋 기반 검토를 통해 리뷰 과정을 구조화하고 자동화합니다.
핵심 포인트
- 코드 작성과 검토를 분리하여 비효율적인 반복을 방지합니다.
- 명확한 '완료의 정의'와 '내부 규칙'으로 모호성을 제거했습니다.
- 자동 게이트(two-engines-gate)를 통해 구조화된 커밋 기반 리뷰가 가능합니다.
이전 게시물(my last post)에서 저는 기본적인 루프를 보여주었습니다. Claude Code가 자체 작업 트리에 코드를 작성하고, Codex가 해당 커밋을 읽기 전용으로 검토하며, 테스트는 그 동일한 커밋에서 실행되고, 두 증거가 모두 존재하지 않으면 스크립트가 병합(merge)을 거부합니다.
이 루프에는 약점이 있습니다. '완료(done)'가 무엇을 의미하는지 모르는 리뷰어는 자신의 취향에 따라 검토를 진행합니다. 스타일 문제를 지적하고, 중요했던 요구사항 하나를 놓치며, 매 라운드마다 새로운 것을 발견합니다. 이 루프는 끝나지 않거나, 당신이 지칠 때까지 계속됩니다.
본 게시물은 세 가지 요소로 이를 해결합니다: 리뷰어가 줄 단위로 확인하는 '완료의 정의(definition of done)', 동일한 방식으로 검토하는 '내부 규칙(house rules)', 그리고 루프를 멈추게 하는 '라운드 규칙(round rules)'. 저는 첫 Codex와 Claude CLI부터 이것을 구축해 왔으며, 이 세 가지는 제가 진행하는 모든 프로젝트 리뷰에 포함됩니다.
마감선이 없는 검토는 단순한 의견일 뿐입니다.
한 문단으로 설명하는 설정 방법
Claude Code가 코드를 작성합니다. 브랜치별로 각 변경 사항을 커밋하고 멈춥니다. Codex는 이 커밋을 읽기 전용의 샌드박스에서 검토합니다: 파일은 읽고 git diff와 같은 읽기 전용 명령을 실행할 수 있지만, 아무것도 쓸 수는 없습니다. 프롬프트는 절대 패치(patch)를 돌려주지 않도록 지시하므로, 모든 수정 사항은 새로운 커밋으로 Claude Code에게 돌아가고, 이 새 커밋은 새로운 검토를 받습니다. 최종 판결은 한 줄로, 리뷰된 커밋의 이름으로 된 파일에 Verdict: ACCEPT 또는 Verdict: CHANGES REQUIRED가 저장됩니다.
이 부분이 바로 실행할 수 있도록 준비되어 있다면, 무료 게이트는 github.com/IliyaOblakov/two-engines-gate (MIT)에 있습니다. 아래 내용은 이 위에 있거나, 사용자의 자체 스크립트 위에 놓입니다.
1단계: 코드보다 먼저 간략한 개요 작성하기
대부분의 리뷰 노이즈는 코드가 존재하기도 전에 시작됩니다. 만약 Claude Code가 받은 유일한 지침이
“완료(Done)”의 의미 아래에 있는 모든 줄은 검토자가 diff나 테스트를 통해 확인할 수 있는 내용이어야 합니다. “Export works well” 같은 것은 한 줄이 아닙니다. “쉼표가 포함된 고객 이메일은 escape 처리되었다” 같은 것이 한 줄입니다.
4번 항목만 따로 떼어내도 가치가 있습니다. 코드를 작성하는 엔진은 테스트 코드도 함께 작성하는 경우가 많고, 이전 코드에서 이미 통과한 테스트는 변경 사항에 대해 아무것도 증명하지 못합니다. 작성자에게 모든 새로운 테스트를 base 커밋에 대해 한 번씩 실행하고, 그곳에서 실패했음을 보여달라고 요청하세요.
간략 설명(brief)이 어디에 위치하는지가 중요합니다. 변경 사항과 함께 커밋하거나, 아니면 .ai/ 아래에 보관하세요. 무료 게이트는 다른 곳의 미커밋된 변경 사항이나 추적되지 않은 파일이 있는 체크아웃을 검토하기를 거부하며, 정확히 이런 종류의 작업 파일을 위해 .ai/는 건너뜁니다. 만약 .gitignore에 .ai/를 추가한다면, 그 변경 사항도 함께 커밋하거나, 편집된 .gitignore 자체를 검토 요청하면 거부됩니다.
2단계: 검토자가 grep 할 수 있는 내부 규칙(house rules)
간략 설명은 이 작업을 다룹니다. 내부 규칙은 모든 작업을 다룹니다. 오류가 처리되는 방식, 설정 파일의 위치, 로그에 절대 들어가지 않는 것 등입니다. 그렇지 않으면 매번 검토할 때 반복해야 하는 사항들입니다.
내부 규칙도 간략 설명처럼, 즉 검토자가 diff에서 찾을 수 있는 내용으로 작성하세요:
## 내부 규칙
- 이유를 명시하는 줄이 없으면 새로운 의존성을 추가해서는 안 됩니다.
- 설정은 config.ts에서 읽어오는 환경 변수로부터만 가져와야 합니다.
...
두 엔진이 이미 읽고 있는 파일에 넣으세요: Claude 코드는 CLAUDE.md로, Codex는 AGENTS.md로요. 작성자는 이를 따르면서 글을 쓰고, 검토자는 동일한 텍스트를 기반으로 확인합니다. AGENTS.md 섹션은 짧게 유지하세요: Codex는 지침 파일의 결합 크기가 기본값인 project_doc_max_bytes, 즉 32 KiB에 도달하면 추가하는 것을 중단합니다.
규칙을 한 번 작성하고, 매번 확인하세요.
3단계: 검토자가 모든 줄에 답하도록 만들기
이제 요청하는 내용을 변경하세요. “이 diff를 검토해 주세요” 대신, 줄별로 답변을 요구하세요:
The brief for this change is in .ai/brief.md.
“완료(Done)”의 의미 아래에 있는 모든 줄과 각 내부 규칙에 대해 다음 중 하나로 답해주세요:
...
무료 게이트(free gate)를 사용하면, 프로젝트 규칙을 편집할 수 있도록 존재하는 review-prompt.md에 이것을 추가하세요. 자체 스크립트를 사용하는 경우, Codex가 보내는 모든 프롬프트에 이 내용을 붙여넣으세요.
이제 검토자는 자유 형식으로 작성하는 대신 목록을 확인합니다. 그리고 '검증 불가(not checkable)' 답변은 당신의 간략한 설명서(brief)에 대한 발견 사항입니다. 즉, 아무도 검증할 수 없는 요구사항을 작성했다는 의미입니다.
4단계: 라운드 제한 설정 (cap the rounds)
라운드 규칙이 없으면, 노력이 많은 검토자가 매 라운드마다 새로운 사소한 지적(nit)을 발견하여 변경 사항이 결코 반영되지 않을 수 있습니다. 따라서 각 라운드는 하나의 임무를 갖습니다:
- 1차 라운드 (Round 1): 모든 발견 사항을 나열합니다. 나중에 위해 아껴두는 것은 없습니다.
- 2차 라운드 (Round 2): 수정 사항을 확인하고, 수정 사항으로 인해 깨진 것만 추가할 수 있습니다.
- 3차 라운드 이후 (Round 3 and later): 블로커(blockers)와 보안 발견 사항만이 병합(merge)을 막을 수 있습니다. 블로커는 재현 가능한 실패를 필요로 합니다. 그 외의 모든 것은 후속 파일에 대한 사소한 지적이며, 검토자가 승인할 수 있습니다.
- 제한 도달 시 (At the cap): 마지막 허용 라운드에서도 '수정 사항 필요(CHANGES REQUIRED)'라고 표시되면, 수정 사항 전송을 중단합니다. 판결은 계속 '수정 사항 필요'로 유지되므로 병합은 차단되며, 사람이 개입하여 접근 방식을 변경하거나, 변경 사항을 분할하거나, 의도적으로 한 라운드를 더 허용할지 결정해야 합니다.
이 규칙들을 프롬프트에 추가하세요:
Round rules. Round 1: list every finding. Round 2: confirm the fixes and
add only what the fixes broke. Round 3 and later: only blockers and
security findings may hold the merge; mark everything else as a nit for
...
검토자는 또한 현재 몇 번째 라운드인지 알아야 합니다. 변경 사항당 작은 파일에 라운드를 계산하세요:
#!/usr/bin/env bash
# rounds.sh <change-name>: count review rounds for one change; exit 3 at the cap
name="${1:?usage: rounds.sh <change-name>}"; max="${MAX_ROUNDS:-3}"
...
그런 다음 이 카운트를 프롬프트에 공급합니다. 무료 게이트를 사용하면 간단한 래퍼(wrapper)가 이를 처리합니다. rounds.sh와 같은 디렉토리에 루트에 review-round.sh로 저장하고, 해당 루트에서 실행하세요:
#!/usr/bin/env bash
# review-round.sh <change-name>: one counted review round with the free gate
round="$(bash rounds.sh "$1")" || exit
...
두 스크립트를 모두 커밋하거나, .gitignore에 나열하고 그 변경 사항을 커밋하여 게이트가 거부하지 않도록 하세요. 작성된 .rounds 파일과 .ai/prompt.md는 .ai/ 아래에 위치하므로 게이트가 건너뜁니다.
판단(verdict) 없이 실패하는 검토도 라운드 하나를 소모합니다. 다시 실행하기 전에 .rounds 파일의 마지막 줄을 삭제하세요.
캡(cap)은 절대 ACCEPT로 바뀌지 않습니다. 단지 루프를 멈추고 결정을 사용자에게 넘겨줄 뿐입니다.
단계 5: Claude Code와 Codex가 의견이 다를 때
때로는 작성자가 발견된 내용에 반박하고, 때로는 그게 맞습니다. 두 엔진이 다섯 라운드 동안 논쟁하게 내버려두지 마세요. 한 가지 규칙이 있습니다. 재현 가능한 실패(reproducible failure)와 함께 제시되는 발견은 유효하며, 그렇지 않은 것은 후속 조치로 넘어갑니다. 범위나 사용자가 볼 수 있는 것과 같이 브리프가 결정하지 못한 모든 것은 사용자님의 판단에 달려있습니다. 이것은 또 다른 라운드가 아니라 사용자님께 드리는 짧은 질문 하나입니다.
증거가 승리합니다. 의견은 기다립니다.
이 기능이 하지 않는 것들
이것들은 코드를 올바르게 만들지 않습니다. 검토자는 한 줄을 '충족됨(met)'으로 표시할 수 있지만 틀릴 수도 있고, 테스트는 자신이 테스트하는 것만 확인합니다. 사용자님이 중요하다고 말한 것들을 검사하고 루프를 종료시키는 검토 결과를 얻게 됩니다.
사용해보기
무료 게이트는 읽기 전용 검토, 커밋 이름으로 지정된 판단(verdict), 테스트 통과 기록, 그리고 둘 다 없으면 거부하는 병합 확인(merge check)을 제공합니다. 또한 CLI가 필요 없는 오프라인 데모도 있습니다. 이 게이트는 양방향으로 작동합니다: BUILDER=codex를 사용하면 Claude Code가 검토자가 됩니다.
제가 사용하는 전체 워크플로우를 원하신다면, Two Engines Kit이라는 유료 키트를 만들었습니다. 이 키트는 두 엔진 모두에 로드되는 규칙서 하나, 두 엔진 모두를 위한 훅(hooks) 및 설정, 검토된 커밋을 정확히 병합하는 GitHub 병합 스크립트, 그리고 모든 변경 사항을 미리 보고 바이트 단위로 되돌릴 수 있는 설치 프로그램이 포함되어 있습니다. 처음 30개 판매 건은 $29이고, 그 이후는 $39입니다: [https://rayastats.com/en/two-engines-kit]
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기