Claude Code × Codex CLI 멀티 AI 오케스트레이션 — 역할 분담으로 '알아서 돌아가는 AI'를 제어하기
요약
Claude Code를 오케스트레이터로, Codex CLI를 구현 워커로 활용하여 AI 간의 역할 분담을 통해 개발 프로세스를 자동화하는 멀티 AI 오케스트레이션 전략을 소개합니다. Claude는 사양 판단과 대화를 담당하고, Codex CLI는 'verify 루프'를 통해 코드가 통과될 때까지 스스로 수정하며, 별도의 Claude 세션이 독립적인 리뷰를 수행하는 3층 구조를 제안합니다.
핵심 포인트
- Claude Code는 대화와 사양 판단(Plan 모드)에 최적화된 오케스트레이터 역할을 수행함
- Codex CLI는 코드 생성과 차분 편집(Diff Editing) 및 자기 수정(Self-correction) 루프에 특화됨
- 독립된 컨텍스트를 가진 제3의 AI를 리뷰어로 배치하여 코드 품질의 객관성을 확보함
- verify 루프를 통해 빌드 및 테스트가 통과될 때까지 AI가 스스로 코드를 수정하는 자동화 메커니즘 구현 가능
서론: 왜 두 개의 AI를 조합하는가
Claude Code도 Codex CLI도 단독으로 "코드를 작성"할 수는 있습니다. 그렇다면 왜 굳이 두 개를 조합하는 것일까요?
결론부터 말하자면, "사양 판단"과 "구현" 그리고 "리뷰"를 서로 다른 AI에게 나누면, 각 AI가 가장 잘할 수 있는 환경에서 일하게 할 수 있기 때문입니다.
- Claude Code는
대화와 판단에 최적화되어 있음 — 사양을 되묻기도 하고, 트레이드오프(Trade-off)를 언어화해 줌 (Plan 모드라는 "코드를 쓰기 전에 방침만 정하는" 전용 모드가 마련되어 있다는 점에 그 사상이 단적으로 나타나 있음) - Codex CLI는
**코드 생성과 차분 편집(Diff Editing)**에 최적화되어 있음 — 어쨌든 동작하는 코드를 내놓음 - "작성한 본인이 리뷰한다"는 점은 맹점을 놓치기 쉬움 →
독립된 제3자 AI에게 리뷰를 맡김
본 기사에서는 Claude Code를 오케스트레이터(Orchestrator), Codex CLI를 구현 워커(Worker), 별도의 컨텍스트를 가진 Claude를 독립 리뷰어로 조합하는 구성을 NestJS 프로젝트 실증과 함께 소개합니다.
1. 전체상: 3층 구조로 역할을 분담한다
| 역할 | 담당 | 실체 |
|---|---|---|
| 사양 분해·판단·대화 | Claude (메인) | 인간과 직접 대화하는 세션 |
| 구현·테스트·verify | Codex CLI | codex-worker 서브 에이전트(Sub-agent)를 경유 |
| 독립 리뷰 | Claude (별도 컨텍스트) | claude-reviewer 서브 에이전트 |
포인트는 인간이 대화하는 상대는 Claude 오케스트레이터뿐이라는 점입니다. Codex는 전면에 나서지 않는 구현 전문가로서 묵묵히 일하고, 리뷰어는 별개의 인격으로서 독립적인 판정을 내립니다. 인간은 "하고 싶은 것"과 "최종 결과"만을 보는 구조가 됩니다.
verify.sh와 「verify」의 차이
용어 정리: 「verify」, 「verify 루프」, 그리고 「verify.sh」라는 단어가 세 가지 문맥으로 등장합니다. 먼저 구분해 두겠습니다.
| 용어 | 의미 |
|---|---|
verify.sh | 이 프로젝트에서 준비한 셸 스크립트(Shell Script) 본체. npm test (Jest unit) → npm run build → npm run test:e2e를 순차적으로 실행하여, 모든 단계가 통과(Green)되면 exit 0, 중간에 실패하면 exit 비0로 종료됨 |
| verify (동사) | "verify.sh를 실행하여 변경 사항이 망가지지 않았는지 확인하는" 작업 |
| verify 루프 | Codex CLI가 가진 자기 수정(Self-correction) 동작 패턴 — 자신이 내놓은 변경 사항에 대해 verify.sh 상당의 명령어를 실행하고, 실패하면 자기 수정 후 재실행하는 과정을 통과(Green)할 때까지 자동으로 반복하는 메커니즘. Codex CLI의 "코드 편집에 특화된 래퍼(Wrapper)" 핵심 기능 중 하나 |
즉 관계는 다음과 같습니다:
verify.sh= 테스트/빌드 일괄 실행 스크립트 (= 하네스(Harness), 내용물)- verify =
verify.sh를 1회 호출하는 작업 - verify 루프 = Codex가
verify.sh가 통과할 때까지 자동으로 다시 호출하는 동작
본 기사의 예시 (§6)에서는 Codex가 한 번 TS1272로 빌드 실패 → 스스로 import type으로 수정 → verify.sh 재실행 → 통과(Green)라는 "verify 루프"가 자동으로 돌아갔습니다. Codex를 구현 워커로 세우는 가치의 절반은 바로 여기에 있습니다. Claude에게 시키면 "고쳤습니다(사실은 안 고침)"라고 하기 쉬운 부분을, Codex는 통과(Green)가 나올 때까지 물리적으로 손을 멈추지 않습니다.
2. 설계 사상: 왜 이 역할 분담이 효과적인가
벤치마크상 Claude와 Codex (GPT-5 계열)의 생코드(Raw Code) 생성 능력은 거의 대등합니다. 그럼에도 역할을 나누었을 때 효과가 있는 이유는, 양자의 차이가 **능력의 고저가 아니라 출력 스타일과 최적화 대상 (= RLHF의 밀도 방향)**에 있기 때문입니다.
- Claude는 "판단을 언어화하는" 방향으로 학습 밀도가 높음 → 사양을 되묻거나 트레이드오프를 제시하는 것이 자연스럽게 나옴
- Codex는 "통과하는(Green) 코드를 내놓는" 방향으로 학습 밀도가 높음 → 확인보다 먼저 손이 움직이며, verify 루프를 끈질기게 수행함
같은 작업을 시키면 비슷한 코드를 작성하겠지만, 행동의 초기값(initial value)이 다릅니다. 그렇기 때문에 각 모델이 '편안함을 느끼는 역할'에 배치해야 무리 없이 역량을 발휘합니다.
2.1 전문 영역 맵 (Expertise Map)
사분면을 읽는 방법은 다음과 같습니다:
- 좌하단 = Claude 메인 (Orchestrator) — 사양 분해 · 설계 판단 · 인간과의 대화
- 좌상단 = Claude reviewer (별도 컨텍스트) — 엄격하게 리뷰를 언어화
- 우상단 = Codex (Implementation Worker) — 차분(diff) 구현 · 테스트 추가 · verify 루프
'능력 차이'가 아니라 '각자가 편안함을 느끼는 사분면이 다르다'는 것이 본질입니다.
2.2 모델 특성 대비
| 관점 | Claude (Sonnet/Opus 4.x) | Codex CLI (GPT-5 계열) |
|---|---|---|
| 최적화 대상 | 판단 · 요건 분해 · 트레이드오프(Trade-off) 제시 | 코드 생성 · 차분 편집 · 테스트 통과 |
| 특기 출력 | 사양서, 설계 판단, 리뷰 지적, 인간용 해설 | 구현/테스트 코드, 차분 패치(diff patch), 리팩토링 |
| 약점 / 리스크 | 코드를 쓰게 하면 말이 많아지거나 추상적으로 변하기 쉬움 | 사양이 모호하면 마음대로 보완하여 실행함 |
| 토큰 밀도 | 중간 (설명문 포함) | 높음 (차분에 집중) |
| 장시간 루프 내성 | 컨텍스트 일관성이 강함 | reasoning_effort를 조정하여 속도/품질을 제어 |
| 자기 리뷰 편향 | 비교적 엄격하지만 애착이 남음 | 관대해지기 쉬움 → 별도 모델로 리뷰할 가치가 큼 |
2.3 'Codex가 코드를 잘한다'는 실체
- OpenAI는 Codex CLI를 코드 편집에 특화된 프로덕트로 제공하며, 파일 편집 도구 · verify 루프 등 **코드 워크플로우에 최적화된 얇은 래퍼(Wrapper)**를 가지고 있습니다. 출력 경향으로서 "코드를 직접 쓰는 것"에 집중합니다. Claude가 "먼저 이 설계로 할까요?"라며 확인 단계로 들어가기 쉬운 반면, Codex는 "일단 돌아가는 코드를 내놓습니다."
2.4 'Claude가 사양/판단에 강하다'는 실체
- Anthropic은 판단을 언어화하게 만드는 데 강한 설계를 의도하고 있으며, Agentic Tool Use와 의사결정을 위한 RLHF(Reinforcement Learning from Human Feedback)가 두텁게 쌓여 있습니다. 인간과의 대화로 요건을 끌어내고 · 트레이드오프를 나열하며 · "왜 그것을 선택했는가"를 남기는 용도로 Claude를 중심에 두면, 나중에 다시 읽었을 때의 정보 밀도가 높습니다.
- Claude Code는 Plan 모드(코드를 전혀 쓰지 않고 조사와 방침 합의만 진행하는 전용 모드)를 가지고 있어, "설계 → 합의 → 구현"을 명확히 분리하는 사상이 프로덕트 기능으로 내장되어 있습니다. 워커(Worker) 측이 움직이기 전에 오케스트레이터(Orchestrator) 측에서 사양을 확정한다는 본 구성의 역할 분담에 그대로 올라탈 수 있습니다.
- Task tool / Skill / 메모리를 포함하여, Claude Code는 오케스트레이터로서 인간과 병행하는 설계로 되어 있어, 이를 구현 워커로 사용하는 것은 과잉입니다.
3. 핵심 설계 판단: 왜 그렇게 했는가
3.1 왜 Codex를 Claude의 서브 에이전트(Sub-agent)를 통해 호출하는가
Claude Code의 Task tool이 제공하는 "병렬 기동 · 컨텍스트 분리 · 결과 집약"을 무료로 사용하기 위해서입니다.
직접 Bash로 Codex를 호출하면, Codex의 장황한 출력(diff, 로그, 사고 과정)이 모두 메인 Claude의 컨텍스트로 흘러 들어와 오염시킵니다. codex-worker라는 서브 에이전트를 사이에 두면, 그곳에서 별도 컨텍스트로 흡수해주고 요약본만 메인으로 반환됩니다.
3.2 왜 독립 리뷰어를 분리하는가
"구현한 본인이 리뷰하면 맹점을 깨닫지 못한다"는 다중 AI 협업의 핵심 원칙 때문입니다. Codex도 메인 Claude도 자신이 쓴 것에는 애착이 생깁니다. 그렇기에 별도 컨텍스트의 Claude에게 판정을 맡깁니다. 이를 통해 규약 위반이나 논리적 실수를 발견하기 쉬워집니다.
3.3 왜 래퍼 스크립트 (codex-run.sh)를 필수적으로 사용하는가
안전 및 비용 기본값의 일원화를 위해서입니다. reasoning_effort=medium, --sandbox, --skip-git-repo-check 등의 옵션을 매번 작성할 필요가 없습니다. 에스컬레이션(escalate)하고 싶을 때만 --high를 사용하면 됩니다.
전달하는 방식으로 운영할 수 있습니다.
reasoning_effort 선택 방법
Codex CLI의 reasoning_effort는 low / medium / high의 3단계로 구성됩니다. 기본값은 medium으로 설정하는 것을 권장합니다.
| 레벨 | 속도·비용 | 품질 | 권장 용도 |
|---|---|---|---|
low | 가장 빠름·가장 저렴 | 얕음 (템플릿 수준) | 정형화된 태스크 (boilerplate 생성, 이름 변경, 포맷 적용) |
(기본값) medium | 중간 | 실용적인 수준 | 일반적인 기능 추가, DTO/Service/Controller의 전형적인 추가, 테스트 추가 |
high | 느림·높은 비용 | 깊은 추론 | 후술할 escalate 조건에 해당하는 경우에만 |
high로 escalate(에스컬레이션)해야 하는 타이밍:
- 동일한 사양으로 시도할 때 — Codex가 루프(loop)를 돌고 있다는 신호이므로 추론을 강화합니다.
medium이 2회 실패했을 때 — 실패를 다시 학습하기를 바라는 국면입니다.- 크로스 모듈(cross-module)로 영향 범위가 넓은 변경 (예: 인증 플로우 전면 개편, 도메인 모델 재설계) —
medium단계에서는 문맥(context)을 놓치기 쉽습니다. - 알고리즘적·수치적 정확성이 필요한 변경 (예: 병행 제어, 트랜잭션 경계, 계산 정밀도) — 얕은 추론으로는 미묘한 버그가 남을 수 있습니다.
- 기존 코드 리팩토링에서 '파괴하지 않는 것'이 가장 중요할 때 — 영향 범위 분석에 추론 비용을 투자할 가치가 있습니다.
reviewer가 REQUEST_CHANGES를 반환한 후의 재위임
반대로 low로 낮춰도 되는 경우는 템플릿 생성, 이름 변경, 의존성 추가와 같이 생각하기보다 손을 움직이는 것이 더 빠른 태스크입니다. 본 기사의 POST /items 정도라면 medium으로도 충분히 통과합니다 (§6 참조). 운영 측면에서는 ./scripts/codex-run.sh "<spec>"을 기본 medium으로 실행하고, 필요한 경우에만 ./scripts/codex-run.sh --high "<spec>"으로 에스컬레이션하는 스위치 방식의 운영이 심플합니다.
3.3 AGENTS.md를 정본(Source of Truth)으로 삼는 이유
그 이유는 이것이 **크로스 에이전트 호환 규격 (cross-agent compatibility standard)**이기 때문입니다.
CLAUDE.md는 Claude 전용.codex/config.toml은 Codex 전용AGENTS.md는 양쪽 모두가 읽음
따라서 CLAUDE.md는 @AGENTS.md 한 줄로 간소화하여, 규약의 진실원(Source of Truth)을 AGENTS.md로 일원화합니다. 두 AI가 동일한 규약을 읽기 때문에, 한쪽만 알고 있는 규칙이 발생하는 상황을 방지할 수 있습니다.
4. 구성 파일
| 경로 | 역할 |
|---|---|
AGENTS.md | 모든 에이전트 공통 계약 (규약 + 연동 플로우). 정본 |
CLAUDE.md | @AGENTS.md 한 줄만 포함 |
.codex/config.toml | model / reasoning_effort를 프로젝트 단위로 고정 |
.codex/skills/run-verify/SKILL.md | verify.sh 표준 호출 절차 |
.claude/agents/codex-worker.md | Codex 위임 워커 (Bash로 래퍼 실행) |
.claude/agents/claude-reviewer.md | 독립 리뷰어 (별도 컨텍스트) |
scripts/codex-run.sh | reasoning/sandbox 기본값 래퍼 |
scripts/verify.sh | test + build + e2e 하네스 (harness) |
5. 실행 플로우: 1개 태스크가 완료될 때까지
사람이 "POST /items를 validation을 포함하여 추가해줘"라고 요청한 시점부터 완료 보고까지의 시퀀스입니다.
주목할 포인트:
- 오케스트레이터(Orchestrator)는 사양을 6개 섹션(Context/Task/Files/Contract/Constraints/Verify)으로 분해한다. 모호한 요청을 모호한 상태 그대로 Codex에 던지면 멋대로 보완하여 폭주할 수 있으므로, 여기서 구조화한다.
- codex-worker는 Codex의 자기 보고를 Read로 재검증한다. "수정했습니다"라는 말을 믿지 않고, 파일을 실제로 읽는다.
- APPROVE가 나올 때까지 commit 하지 않는다. 리뷰어가 REQUEST_CHANGES를 반환하면, 사양을 더 구체적(more specific)으로 만들어 재위임한다.
POST /items
API를 만들어 보기
- 예: NestJS 11에서 ### 6.1 주제
NestJS 11 (Express) 신규 프로젝트에 POST /items API를 추가. DTO validation 포함.
verify.sh의 최종 결과
6.2 ```
=== 1/3 npm test (Jest unit) ===
Test Suites: 2 passed, 2 total
Tests: 4 passed, 4 total
...
###
`codex-worker` 리포트 (발췌)
6.3 -
**Files changed**: 10 (`src/items/*` 신규 + `src/app.module.ts`, `src/main.ts`, `package.json`, `package-lock.json`)
**Reasoning used**: medium (`--high` 없음)
**중간 에러**: 한 차례 `TS1272` (isolatedModules + value import)로 빌드 실패 → **Codex 스스로가** `import type { Item }`으로 수정하여 재 검증(verify) → pass
**Verdict**: SUCCESS
###
`claude-reviewer` 리포트 (발췌)
6.4 -
**Files reviewed**: 10
**CRITICAL**: 0 /**HIGH**: 0 /**MEDIUM**: 0 /**LOW**: 3
- E2E에서 `ValidationPipe`를 재선언하여 `main.ts`와 중복 (NestJS 관례이나 drift 리스크 주의)
- `Item` 타입을 `type`으로 export (`interface`가 다소 관례적)
- `import type { Item }`은 적절 (확인 메모)
- E2E에서
**Verdict**: APPROVE
### 6.5 E2E 커버리지 (Coverage)
| 케이스 | 기대 결과 | 결과 |
|---|---|---|
| 유효한 페이로드 (Valid Payload) | 201 + Item with id/createdAt | ✅ |
| ... | ... | ... |
사람이 한 것은 "사양을 작성하는 것"과 "APPROVE를 확인하는 것"뿐입니다. 구현 단계는 약 15분 만에 완료되었습니다.
## 7. 다른 프로젝트로의 수평 전개(Horizontal Expansion) 절차
새로운 NestJS 리포지토리에서 본 구성을 구축하는 절차를 그대로 매뉴얼화한 것:
`nest new <name> --package-manager npm --skip-git`
- (NestJS 템플릿 + `.gitignore`를 수동 생성 `.serena/` + `AGENTS.override.md`)
- `git init -b main` → 첫 번째 commit (예: `chore: initial NestJS scaffold`)
- 아래 내용을 복사하여 배치 (내용 중 `AGENTS.md`와 `verify.sh`만 프레임워크에 의존):
- `AGENTS.md`, `CLAUDE.md` (`@AGENTS.md` 1행 포함)
- `.codex/config.toml`, `.codex/skills/run-verify/SKILL.md` + `agents/openai.yaml`
- `.claude/agents/codex-worker.md`, `claude-reviewer.md`
- `scripts/codex-run.sh` (+x), `scripts/verify.sh` (+x)
- `./scripts/verify.sh`
그린(Green) 확인 → commit (`chore: add orchestration scaffolding`)
- 실제 태스크의 사양을 **Context / Task / Files / Contract / Constraints / Verify**의 6개 섹션으로 작성
- Task tool → `codex-worker` 역할로 Codex 구현
- Task tool → `claude-reviewer` 역할로 독립적인 리뷰 수행
- APPROVE 시 commit, REQUEST_CHANGES 시 사양을 더 구체적(more specific)으로 만들어 재위임
**소요 시간 (실측)**: scaffold + 설계 이식 + API 구현 + 리뷰 + commit 포함 약 **30분** (이 중 Codex 구현 단계 약 15분).
## 8. 재사용 가능한 부품
다른 프로젝트에 가져갔을 때 효과가 큰 순서:
| 부품 | 효과 |
|---|---|
| `scripts/codex-run.sh` (래퍼 필수화) | 대(大) — 안전/비용 기본값의 일원화 |
| `.claude/agents/codex-worker.md` | 대(大) — 병렬 기동 + 컨텍스트 분리가 무료 |
| `.claude/agents/claude-reviewer.md` | 대(大) — '작성자 본인 리뷰'의 맹점 방지 |
| `.codex/skills/<name>/SKILL.md` | 중(中) — 빈번한 작업의 스킬화 |
| `AGENTS.md` 기반 운용 | 중(中) — Codex/Claude 공통 계약 |
특히 효과적이었던 설계 판단:
- `CLAUDE.md`를 `@AGENTS.md` 한 줄로 간소화
- Codex 측에서 수행할 수 없는 역할은 Claude 측으로 넘기는 유연성 확보
## 9. 요약: 무엇이 좋은가
이 구성을 실행해 보면서 본질적으로 효과적이었던 점은 다음 3가지였습니다.
**① 컨텍스트 오염 (Context Pollution)을 방지할 수 있음**
Codex의 장황한 출력은 `codex-worker`가 흡수합니다. 메인 Claude는 '사양'과 '결과 요약'만을 보고 판단할 수 있습니다. 장시간 세션에서도 사고가 명확하게 유지됩니다.
**② 자기 리뷰 편향 (Self-review Bias)을 제거할 수 있음**
작성자 본인(Codex와 Claude 모두)에게는 애착이 생기기 마련입니다. 별도의 컨텍스트를 가진 Claude에게 리뷰를 맡기면, 규약 위반이나 논리적 오류를 담담하게 지적해 줍니다.
**③ 사양의 구조화가 강제됨**
Codex에 던지기 전에 Context/Task/Files/Contract/Constraints/Verify의 6개 섹션으로 다시 작성해야 하므로, **인간 자신의 사고가 정리됩니다**. AI에게 맡긴 결과, 인간의 업무 질이 올라가는 역설적인 효과가 나타납니다.
'AI에게 코드를 쓰게 하는 것'이 아니라, '**AI들에게 역할을 부여하여 협조하게 하는 것**'. 멀티 AI 협업은 능력 차이가 아니라 **최적화 대상의 차이**를 활용하는 설계입니다. 꼭 여러분의 프로젝트에서 시도해 보시기 바랍니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기