공식 참고 자료: Best Practices · How OpenAI uses Codex · Subagents
커리큘럼 흐름
- Codex 시작하기 — 설치, 첫 작업, 체크포인트까지 — 입문 루프
- Codex 지시문 — AGENTS.md를 진짜 쓸모 있게 만드는 법 — 저장소 규칙
- Codex 샌드박싱 — 권한, 승인, 클라우드 환경 이해하기 — 권한과 승인
- Codex 작업 설계 — 소원 말고 이슈처럼 프롬프트 쓰기 — 좋은 task shape 만들기 ← 현재 문서
- Codex Skills — 반복 프롬프트를 재사용 가능한 워크플로우로 바꾸기 — 반복 워크플로우를 재사용 자산으로 만들기
- Codex 서브에이전트 — 병렬 실행과 위임 패턴 — 병렬 실행과 위임
- Codex MCP — 외부 컨텍스트를 복붙 대신 연결하기 — 외부 시스템 연결
- Codex 리뷰와 자동화 — /review, worktree, 반복 엔지니어링 운영하기 — 반복 작업 운영
- Codex Worktrees — 브랜치 충돌 없이 병렬 실행하기
- Codex 핸드오프 — 병렬 레인을 머지 가능한 결과로 연결하기
- Codex 검증 루프 — 머지 전에 동작을 증명하기
- Codex 릴리스 준비도 — 프로덕션 전 최종 게이트
- Codex 첫날 안전 루프 — 초반 실수를 줄이는 입문 워크플로우
- Codex 팀 딜리버리 플레이북 — 중급 레인 운영
- Codex 고위험 변경 거버넌스 — 크리티컬 릴리스를 위한 고급 통제
- Codex 운영 매뉴얼 — 팀의 일/주/릴리스 리듬 정렬하기
- Codex 사고 복구 플레이북 — 프로덕션 압박 상황에서의 결정론적 대응
- Codex 사고 후 하드닝 루프 — 복구를 내구성 있는 통제로 전환하기
- Codex 카오스 복원력 드릴 — 실패가 오기 전에 리허설하기
- Codex 복원력 지표와 SLO — 실패 전에 신뢰성을 측정하기
- Codex Ralph 지속 루프 — 긴 작업을 검증 가능한 완료까지 가져가기
이 문서에서 참고한 공식 문서
- Goal / Context / Constraints / Done when 구조 — Best practices
- Best-of-N과 task queue 아이디어 — How OpenAI uses Codex
- 병렬 작업이 필요한 경우 subagents 사용 — Subagents
핵심 원칙: 추측할 여지를 줄여라
Codex는 강한 실행기이지만, 사용자가 모호하게 말할수록 모델이 추측해야 할 영역이 커집니다. 좋은 프롬프트의 목적은 “멋진 문장”이 아니라 추측 비용을 줄이는 것입니다.
실무적으로는 “AI에게 요청한다”보다 작은 이슈를 하나 생성한다고 생각하는 편이 훨씬 잘 맞습니다. 누가 받아도 같은 방향으로 움직일 수 있는 작업 설명이면 Codex도 안정적으로 움직입니다.
가장 잘 먹히는 기본 틀
공식 best practices는 이슈나 PR 설명처럼 쓰는 방식을 권장합니다.
Goal:
무엇을 바꾸고 싶은가
Context:
어떤 파일, 에러, 기존 패턴이 중요한가
Constraints:
무엇을 건드리면 안 되는가
Done when:
무엇이 완료 기준인가이 구조는 단순하지만 강력합니다. Goal은 목표를 고정하고, Context는 시작점을 주고, Constraints는 범위를 묶고, Done when은 종료선을 분명히 합니다.
Goal / Context / Constraints / Done when에 실제로 무엇을 써야 하나
Goal: 결과를 한 문장으로 고정
Goal에는 “무엇을 하라”보다 무슨 상태를 만들고 싶은지를 적는 편이 좋습니다.
좋음:
- checkout 폼 제출 실패 시 사용자에게 원인 메시지를 보여준다
- docs sidebar에 새 Codex 섹션을 추가한다
- cart drawer 수량 변경을 optimistic update로 바꾼다
아쉬움:
- checkout 개선
- docs 정리
- cart 쪽 손보기
Goal이 넓으면 뒤의 Context와 Constraints가 아무리 좋아도 작업이 퍼집니다.
Context: 로컬 앵커를 붙여라
Context는 “배경 설명”이 아니라 탐색 시작점입니다. 추상 명사보다 로컬 파일 앵커가 훨씬 유효합니다.
좋은 로컬 앵커 예시:
- 관련 파일 경로:
src/components/cart/CartDrawer.tsx - 서버 로직 위치:
src/app/actions/cart.ts - 따라야 할 패턴:
src/features/wishlist/useWishlistMutation.ts - 실패 로그/재현 명령:
pnpm test cart-drawer -- --runInBand - 함께 봐야 할 검증 파일:
tests/cart-drawer.spec.ts
즉, “wishlist 구현처럼”만 쓰지 말고 어느 파일이 reference인지를 적어 주세요. 가능하면 폴더 이름보다 실제 파일 이름을 주는 편이 좋습니다.
Constraints: 팀 경계를 대신 말해준다
제약은 Codex를 묶는 족쇄가 아니라, 팀 기준으로 유도하는 가드레일입니다. 특히 아래처럼 하지 말아야 할 것을 쓰면 불필요한 확장을 크게 줄일 수 있습니다.
자주 쓰는 제약:
- 새 의존성 추가 금지
- public API shape 유지
src/payments/밖 수정 금지- generated file 수정 금지
- diff를 작게 유지
- 우선 plan만 제안하고 구현은 하지 말 것
Done when: 사람이 리뷰할 조건으로 써라
Done when은 “잘 되게 해줘”가 아니라 리뷰어가 체크할 항목이어야 합니다.
좋음:
- 수량 변경이 UI에 즉시 반영된다
- 실패 시 이전 값으로 rollback 된다
pnpm lint와 cart 관련 테스트가 통과한다- public API 응답 shape는 바뀌지 않는다
아쉬움:
- UX가 좋아진다
- 깔끔하게 정리된다
- 적절히 처리된다
예시: 나쁜 프롬프트 vs 좋은 프롬프트
나쁨:
cart 쪽 개선해줘나음:
Goal:
cart drawer의 수량 변경에 optimistic update를 추가해.
Context:
- UI는 src/components/cart/ 아래에 있음
- server action은 src/app/actions/cart.ts 에 있음
- loading 상태 패턴은 src/features/wishlist/useWishlistMutation.ts 를 따를 것
- 관련 테스트는 tests/cart-drawer.spec.ts 를 먼저 확인할 것
Constraints:
- public API shape는 바꾸지 말 것
- 새 상태관리 라이브러리 추가 금지
- cart drawer 외 UX 변경 금지
Done when:
- 수량 변경이 즉시 반영되어 보일 것
- 실패 시 rollback 될 것
- lint, 관련 테스트, 필요 시 build가 통과할 것이슈처럼 쓰는 것이 왜 중요한가
이 형식은 단지 보기 좋은 템플릿이 아니라, Codex의 실행 순서를 정리해 줍니다.
- Goal이 작업의 중심축을 고정
- Context가 탐색 비용을 줄임
- Constraints가 scope creep를 막음
- Done when이 검증 루프를 결정
결국 좋은 프롬프트는 “긴 프롬프트”가 아니라 작업 순서가 암시된 프롬프트입니다.
scope는 검증 루프 하나로 잘라라
작업 크기를 잡을 때 가장 좋은 기준은 “기능 단위”가 아니라 검증 루프 단위입니다. 한 번의 review/lint/test/build 판단으로 건강 상태를 알 수 없다면 대개 너무 큽니다.
검증 루프 크기 감각
| 크기 | 보통 이런 작업 | 검증 예시 |
|---|---|---|
| 작음 | 단일 문서 보강, 특정 에러 메시지 수정, 한 컴포넌트 개선 | 관련 파일 확인 + targeted test/lint |
| 적당함 | 한 기능의 버그 수정, 한 폴더 내 refactor, 특정 API 적응 | lint + 관련 테스트 + 필요 시 build |
| 큼 | auth/billing/onboarding 동시 변경, 전면 리네이밍, 전역 상태 재설계 | 한 번의 루프로 의미 있는 판단이 어려움 |
좋은 작업:
- 한 폴더 안의 refactor
- 재현 가능한 버그 수정
- 특정 API 변경에 맞춘 문서 업데이트
- 테스트 하나가 깨지는 이유를 좁혀서 수정
나쁜 작업:
- auth, onboarding, billing을 한 번에 재설계
- 기술부채를 전체적으로 정리
- 앱을 전반적으로 modernize
- 문서·코드·배포 설정을 한 요청에 묶기
plan-first가 더 안전한 작업도 있다
다음 조건이면 바로 구현보다 먼저 plan을 요청하는 편이 낫습니다.
- 파일/도메인이 세 군데 이상 걸침
- 구현보다 설계 판단 비중이 큼
- rollback 비용이 큼
- 여러 reasonable solution이 있음
- 작업 순서가 맞지 않으면 후속 diff가 다 깨질 수 있음
이럴 때는 아래처럼 먼저 plan만 고정하세요.
먼저 구현하지 말고 plan만 제안해.
변경 파일, 위험, 비가역 포인트, 검증 방법을 포함해.
작업을 검증 루프 기준으로 2~4단계로 나눠줘.plan-first가 특히 맞는 예:
- 데이터 마이그레이션
- 설정 파일과 앱 코드가 함께 바뀌는 작업
- API 계약 변경
- 팀 합의가 필요한 구조 리팩터링
로컬 파일 앵커를 주면 추측이 급감한다
Codex는 추상적인 “우리 스타일대로”보다 구체적인 “이 파일처럼”에 훨씬 강합니다.
좋은 예:
src/features/profile/actions.ts패턴을 따르기docs/releases/2026-03-01.mdx포맷에 맞추기src/components/ui/Button.tsxvariant naming을 재사용하기tests/auth/login.spec.ts의 검증 방식과 맞추기
가능하면 기존 구현과 검증 파일을 함께 참조점으로 붙여주세요. 재현 명령이나 실패 로그까지 있으면 더 좋습니다.
Context:
- 구현 참고: src/features/profile/actions.ts
- 검증 참고: tests/profile-actions.spec.ts
- 현재 실패: pnpm test profile-actions 에서 2번째 케이스 실패제약 조건은 결과 품질을 올린다
제약은 품질을 낮추는 요소가 아니라, Codex가 팀 기준을 덜 벗어나게 만드는 장치입니다.
제약을 적을 때는 세 가지 층위로 생각하면 편합니다.
1. 수정 범위 제약
docs/만 수정src/auth/밖 변경 금지- migration 생성은 허용하지만 적용은 금지
2. 구현 방식 제약
- 새 의존성 추가 금지
- 기존 fetch wrapper 재사용
- server action 패턴 유지
3. 운영 제약
- plan만 작성, 구현 금지
- 테스트 추가 가능하지만 fixture 구조 변경 금지
- human review 없이 merge 가능한 단계는 만들지 말 것
언제 skill, MCP, subagent로 승격할까
같은 작업을 여러 번 반복하면 프롬프트만 계속 다듬지 말고 표면을 바꾸는 게 낫습니다.
| 상황 | 더 맞는 도구 | 이유 |
|---|---|---|
| 같은 절차를 반복한다 | Skills | 순서와 체크리스트를 재사용 가능 |
| repo 밖 사실이 필요하다 | MCP | 공식 문서, 티켓, 런북 같은 외부 근거를 직접 읽게 함 |
| 독립적인 탐색/비교/구현이 병렬로 가능하다 | Codex 서브에이전트 | 역할을 나눠 벽시계 시간을 줄일 수 있음 |
| 단일 파일 수정이거나 공유 맥락이 크다 | 단일 에이전트 유지 | 위임 오버헤드가 더 큼 |
실무 감각으로는 반복 절차면 skill, 외부 근거면 MCP, 병렬 역할 분담이면 subagent, 하나의 집중 수정이면 단일 세션입니다. 공식 subagents 문서는 Codex가 명시적으로 요청했을 때만 subagent를 띄우고 현재 sandbox policy를 상속한다고 설명합니다. 병렬화는 강력하지만 비용도 함께 늘어납니다.
Best-of-N은 비교가 진짜 필요할 때만
OpenAI는 어려운 작업에서 Best-of-N을 강조합니다. 하지만 무조건 여러 안을 뽑는다고 좋아지지는 않습니다.
특히 아래에서 유용합니다.
- 네이밍과 구조 선택이 중요한 작업
- 구현 후보가 둘 이상 타당한 작업
- merge 전에 trade-off를 비교해야 하는 작업
반대로 정답이 거의 하나인 버그 수정이라면 Best-of-N보다 좋은 Context와 좁은 Constraints가 더 중요합니다.
바로 복붙해 쓸 수 있는 task 템플릿
Goal:
- 바꾸고 싶은 최종 상태 1~2줄
Context:
- 관련 파일: path/to/fileA, path/to/fileB
- 따라야 할 패턴: path/to/reference-file
- 재현/검증 명령: pnpm test ...
- 필요한 배경: 현재 왜 이 변경이 필요한지 1~2줄
Constraints:
- 수정 가능 범위
- 금지할 구현 방식
- diff / dependency / API 관련 제한
Done when:
- 사용자/운영자 기준 완료 조건
- 통과해야 할 검증 명령
- 리뷰 시 확인할 비가역 포인트두 가지 템플릿을 구분하면 더 편하다
1. 바로 구현하는 템플릿
위 템플릿은 범위가 좁고 검증 루프가 분명한 작업에 적합합니다.
2. plan-first 템플릿
Goal:
- 바꾸고 싶은 최종 상태 1~2줄
Context:
- 영향이 갈 것 같은 파일/폴더
- 현재 가장 큰 위험이나 불확실성
- 참고해야 할 로컬 예시
Constraints:
- 아직 구현하지 말 것
- 되돌리기 쉬운 순서로 제안할 것
- 사람 승인 지점을 표시할 것
Done when:
- 단계별 계획이 정리된다
- 예상 변경 파일이 적힌다
- 위험과 검증 방법이 드러난다작업이 크거나 구조 판단이 중요하면 처음부터 구현 템플릿보다 plan-first 템플릿이 더 안전합니다.
흔한 task-design 실패 패턴
“어디가 문제인지 찾아서 고쳐줘”
탐색과 수정이 한 문장 안에 섞여 있어 scope가 쉽게 퍼집니다.
“일단 다 정리해줘”
검증 루프가 없는 큰 작업일 가능성이 높습니다.
“테스트만 통과하게 해줘”
행동 변화가 무엇인지 말하지 않으면 Done when이 너무 약해집니다.
“이 파일처럼”이 빠져 있다
로컬 앵커가 없으면 Codex가 팀 스타일을 추측하게 됩니다.
프롬프트를 보내기 전 체크리스트
프롬프트를 보내기 전에 아래를 확인해 보세요.
- 목표가 한 문장으로 말해지는가?
- 관련 파일/폴더를 적었는가?
- “이 파일처럼”이라는 로컬 앵커가 있는가?
- 금지할 것을 적었는가?
- 완료 기준을 측정 가능하게 적었는가?
- 한 번의 review로 판단 가능한 크기인가?
- 이 작업이 반복되면 skill로 올릴지 생각했는가?
- repo 밖 근거가 필요하면 MCP로 읽게 할 준비가 되어 있는가?
- 독립 작업이 둘 이상이면 subagent 병렬화가 진짜 이득인가?
빠르게 기억할 운영 조언
다섯 가지만 기억한다면 아래를 기억하세요.
- 사람 리뷰어도 이해할 수 있는 task로 써라.
- 로컬 파일 앵커를 넣어 추측을 줄여라.
- Constraints로 diff 확장을 막아라.
- 작업 크기는 기능이 아니라 검증 루프로 잘라라.
- 반복 절차, 외부 근거, 병렬 분해가 필요할 때만 skill/MCP/subagent로 승격하라.
Codex 작업 설계의 본질은 특별한 프롬프트 공식이 아니라, 사람 엔지니어에게도 명확한 작업을 만드는 것입니다. 좋은 task shape를 만들면 Codex의 성능이 올라가는 동시에 리뷰 난이도와 재작업 비용도 함께 내려갑니다.