Skip to main content

Codex를 잘 쓰는 사람의 프롬프트는 길지 않습니다. 대신 명확한 계약(Contract)이 있습니다. 무엇을 만들지(목표), 어디까지 할지(범위), 어떤 모양으로 줄지(산출물 형식), 어떻게 끝났다고 판단할지(검증)가 한눈에 읽힙니다. 긴 배경설명보다 "이 작업의 정의서"에 가까운 프롬프트가 결과를 안정적으로 만듭니다.12

이 챕터는 그 계약을 만드는 원칙과, 코딩 작업별로 바로 복사해 쓸 수 있는 템플릿을 제공합니다.

프롬프트는 '요청'이 아니라 '계약'이다

모델은 프롬프트를 읽고, 그 다음에 올 법한 텍스트를 계속 이어서 씁니다. 그래서 애매한 요청을 주면 모델은 추측으로 빈칸을 채웁니다. "대충 이런 느낌이겠지"가 들어가는 순간, 코드 스타일이 흔들리고, 범위가 넓어지고, 검증이 빠집니다.2

반대로, 계약이 명확하면 모델은 추측할 필요가 없습니다.

  • 무엇을 만들지(Outcome)

  • 무엇을 건드리지 말지(Scope)

  • 어떤 형식으로 낼지(Output)

  • 어떤 조건을 만족하면 완료인지(Done)

이 네 가지가 맞물릴 때, "긴 프롬프트" 없이도 결과가 단단해집니다.

4대 원칙: 구체성, 범위 제한, 산출물 형식, 단계적 진행

1) 구체성: '행동'과 '제약'을 문장으로 박아 넣기

구체성은 "상세 설명을 많이 한다"가 아닙니다. 오해가 생길 만한 지점을 미리 못 박는 것입니다. 예를 들어 "로그 추가"가 아니라 "logger.info를 사용하고, PII는 마스킹"처럼 행동과 제약을 한 문장에 같이 둡니다.

Codex는 높은 수준의 작업 설명으로도 출발할 수 있지만, 결과 품질은 "무엇을 하라/하지 마라"가 얼마나 명확한지에 크게 좌우됩니다.1

2) 범위 제한: '이번에 끝낼 것'과 '나중에 할 것'을 분리하기

범위가 넓으면 Codex는 자연스럽게 더 많은 파일을 바꾸고, 더 큰 설계를 제안합니다. 즉, 프롬프트가 짧아도 "스코프가 열린" 상태가 됩니다.

범위를 닫는 가장 쉬운 문장은 다음 둘입니다.

  • "이번 변경은 X까지만."

  • "Y는 건드리지 말 것."

이 한 줄이 PR 크기, 리스크, 승인(Approvals) 비용을 동시에 줄입니다.

3) 산출물 형식: '출력 계약(Output contract)'을 먼저 적기

형식 지정은 취향 문제가 아니라, 자동화와 재사용을 위한 기술 조건입니다. 산출물 형식이 없으면 응답은 매번 달라지고, 당신은 포맷을 맞추느라 다시 대화하게 됩니다.34

가장 자주 쓰는 형식 계약은 다음입니다.

  • "변경 파일 목록 + 각 파일 diff 요약"

  • "패치만(코드 블록만), 설명 금지"

  • "커밋 단위 계획(Commit plan) + 각 단위의 완료 조건"

형식 계약을 짧게라도 박아두면, Codex가 '좋은 말'을 하는 대신 '쓸 수 있는 결과'를 냅니다.3

4) 단계적 진행: '계획 → 실행 → 검증'으로 쪼개기

복잡한 작업을 한 번에 시키면, 결과가 커지고 검증이 약해집니다. 단계적 진행은 프롬프트를 길게 만드는 게 아니라, 대화를 여러 턴으로 설계하는 것입니다.

가장 실용적인 패턴은 이겁니다.

  • 1턴: 계획을 내고 멈추기

  • 2턴: 승인 후, 첫 번째 작은 변경만 실행하기

  • 3턴: 테스트/검증 결과를 근거로 다음 변경으로 넘어가기

이 방식은 에이전트가 맹목적으로 전진하는 걸 막고, 승인 흐름과도 잘 맞습니다.2

"긴 프롬프트"가 실패하는 이유

긴 프롬프트가 항상 나쁜 건 아닙니다. 다만 길어질수록 흔히 다음 문제가 생깁니다.

첫째, 규칙이 서로 충돌합니다. "간단히"와 "모든 예외를 다 다뤄라"가 같이 있으면 모델은 어느 쪽을 우선할지 추측합니다. 이런 충돌을 잡아내는 체크도구가 따로 있을 정도로 흔한 실패 패턴입니다.5

둘째, 중요한 요구사항이 뒤로 밀립니다. 모델은 전체를 읽지만, 실무에서는 앞쪽에 핵심 계약이 있어야 테스트와 반복이 편합니다(특히 팀에서 공유할 때).

셋째, '상시 규약'과 '이번 작업 지시'가 섞입니다. 상시 규약은 AGENTS.md에, 이번 작업 지시는 프롬프트에 둬야 안정적입니다. 규약을 프롬프트로 매번 들고 다니면, 길어지고 서로 다른 버전이 생깁니다.6

프롬프트 계약서: 10줄 골격

아래 골격은 길지 않지만, 필요한 걸 빠짐없이 담습니다. 팀 템플릿으로 고정해두면 매번 "무엇을 써야 하지?"가 사라집니다.

[GOAL] 한 문장 목표(무엇을 완성할지)
[CONTEXT] 레포/스택/관련 파일(짧게)
[SCOPE] 이번에 포함/제외할 범위
[REQUIREMENTS] 반드시 지킬 규칙(3~7개)
[OUTPUT] 산출물 형식(예: 변경 파일 목록 + diff 요약)
[VERIFICATION] 완료 조건(실행할 테스트/체크)
[NEXT] 모호하면 먼저 물어볼 질문

이 중에서 특히 [OUTPUT]와 [VERIFICATION]이 빠지면 결과가 "그럴듯한 코드"로 끝날 확률이 급격히 올라갑니다.

코딩 작업별 템플릿(복사 & 붙여넣기)

이 섹션의 템플릿은 Codex CLI/IDE 어디서든 그대로 쓸 수 있습니다. 핵심은 공통 골격은 유지하고, 작업 유형에 맞게 [VERIFICATION]을 바꾸는 것입니다.17

1) 기능 구현(새 코드 작성)

[GOAL] {{기능}}을(를) 구현해라.

[CONTEXT]
- 언어/프레임워크: {{예: TypeScript + React}}
- 관련 디렉터리/파일: {{경로}}
- 참고할 기존 패턴: {{비슷한 구현 파일 1~2개}}

[SCOPE]
- 포함: {{이번 PR에 넣을 범위}}
- 제외: {{인증/DB/스타일 리네이밍 등 이번에 하지 말 것}}

[REQUIREMENTS]
- 기존 아키텍처/패턴을 따를 것(새 패턴 도입 금지)
- 에러 처리는 {{프로젝트 방식}}으로 통일
- 접근성/로딩/빈 상태를 포함

[OUTPUT]
- 변경 파일 목록
- 각 파일에서 바뀐 핵심 diff 요약
- 필요 시, 새로 추가한 컴포넌트/함수의 사용 예

[VERIFICATION]
- {{단위 테스트 명령}}이 통과해야 함
- {{린트/타입체크}}를 통과해야 함

[NEXT]
- 시작 전에 확인이 필요한 질문이 있으면 3개 이내로 물어보고 기다려라.

포인트는 "기능 설명"보다 "스코프와 검증"이 더 중요하다는 점입니다. 목표는 한 문장이면 충분하고, 대신 제외 범위와 완료 조건이 계약을 닫아줍니다.

2) 버그 수정(재현 → 원인 → 패치)

[GOAL] 아래 버그를 재현 가능한 방식으로 고치고, 회귀 테스트를 추가해라.

[BUG]
- 증상: {{무슨 문제가 생기는지}}
- 재현 절차: {{1..n 단계}}
- 기대 동작: {{Expected}}
- 실제 동작: {{Actual}}
- 로그/에러: {{에러 메시지/스택 트레이스}}

[CONTEXT]
- 환경: {{OS, 버전, 런타임}}
- 관련 코드: {{파일/함수/라인}}

[SCOPE]
- 최소 변경으로 해결(리팩터링은 별도 제안만)

[OUTPUT]
1) 원인 분석(2~6문장)
2) 패치 요약(변경 파일 목록)
3) 추가/수정한 테스트와 커버하는 시나리오

[VERIFICATION]
- 새 테스트가 수정 전에는 실패하고, 수정 후에는 통과해야 함
- {{테스트 명령}} 실행 기준으로 설명할 것

버그 프롬프트는 "고쳐줘"가 아니라 버그 리포트에 가깝게 써야 합니다. 재현 절차, 기대/실제, 환경이 들어가면 Codex가 추측으로 빈칸을 채울 일이 줄어듭니다.8

3) 리팩터링(동작 유지 + 구조 개선)

[GOAL] 동작을 바꾸지 말고, {{대상}}을(를) 리팩터링해라.

[CONTEXT]
- 대상 파일/모듈: {{경로}}
- 현재 문제: {{가독성/중복/테스트 어려움 등}}

[CONSTRAINTS]
- 퍼블릭 API(함수 시그니처/엔드포인트/응답 스키마) 변경 금지
- 포맷터/린트 설정 변경 금지

[OUTPUT]
- 커밋 단위 계획(최대 3~5개): 각 커밋의 변경 범위와 이유
- 각 커밋별 완료 조건(테스트/린트)

[VERIFICATION]
- 리팩터링 전/후에 동일 테스트 세트가 통과해야 함

리팩터링에서 가장 흔한 실패는 "개선하려다 기능까지 바꾸는 것"입니다. 그래서 금지 조항을 계약으로 먼저 박습니다.

4) 테스트 생성(품질 향상)

[GOAL] {{대상 기능/모듈}}에 대한 테스트를 추가해 결함을 빨리 잡게 만들어라.

[CONTEXT]
- 테스트 프레임워크: {{예: Vitest/Jest/Pytest}}
- 대상 코드: {{파일/함수}}
- 현재 커버리지/취약 지점: {{알고 있는 한}}

[REQUIREMENTS]
- 성공 케이스 + 실패 케이스를 모두 포함
- 경계값(빈 입력/큰 입력/타임아웃 등)을 최소 2개 포함
- 테스트는 결정적(deterministic)이어야 함

[OUTPUT]
- 추가할 테스트 파일/케이스 목록
- 실제 테스트 코드

[VERIFICATION]
- {{테스트 명령}}으로 실행 가능해야 함

테스트 프롬프트는 산출물 형식을 "테스트 케이스 목록 → 코드"로 고정하면 좋습니다. 케이스 목록을 먼저 받으면, 실행 전에 사람이 의도를 검토할 수 있습니다.

5) 코드 리뷰(리스크 중심)

[GOAL] 아래 변경을 리뷰하고, 병합 전에 확인할 리스크를 정리해라.

[CONTEXT]
- 변경 diff 또는 PR 링크/내용: {{붙여넣기}}

[FOCUS]
- 보안: 입력 검증/권한/비밀정보 노출
- 안정성: 에러 처리/롤백 가능성
- 품질: 테스트 누락/복잡도 증가

[OUTPUT]
- High/Medium/Low로 나눈 리뷰 코멘트
- 반드시 수정해야 하는 항목(Blocking)과 선택 항목(Optional) 분리
- 제안이 있으면, '최소 diff' 대안도 함께 제시

리뷰는 "좋아 보입니다" 같은 총평이 아니라, 우선순위가 매겨진 체크리스트여야 의미가 있습니다.

6) 낯선 레포 온보딩(읽기 + 지도 만들기)

[GOAL] 이 레포에서 {{내가 하려는 작업}}을(를) 하기 위해 알아야 할 지도를 만들어라.

[CONTEXT]
- 내가 바라는 결과: {{예: 인증 로직 위치 파악, 로컬 실행}}

[OUTPUT]
1) 핵심 엔트리 포인트(시작 파일/라우팅/DI 등)
2) 주요 디렉터리 역할 요약
3) 내가 손대야 할 가능성이 높은 파일 후보 5개와 이유
4) 로컬 실행/테스트의 최소 명령

[NEXT]
- 추가로 확인해야 할 질문 3개를 제안해라.

온보딩 프롬프트는 "설명해줘"가 아니라 "지도를 만들어줘"로 바꾸면 좋아집니다. 그래야 산출물이 재사용 가능한 문서가 됩니다.

'예시 한 개'가 긴 설명 30줄을 이긴다(One-shot/Few-shot)

형식이나 스타일이 중요한 작업(예: 함수 시그니처, 에러 응답 구조)이라면, 설명을 늘리는 대신 예시를 1개 넣는 게 훨씬 잘 맞습니다. 모델은 예시를 강한 힌트로 삼아 출력 패턴을 맞추려 합니다.12

예를 들어, "이 프로젝트의 에러는 이런 형태로 리턴한다"를 문장으로 장황하게 쓰는 대신, 실제 코드 조각을 10줄 붙여두면 됩니다.

API/라이브러리를 모를 때: '설명'보다 '시그니처'로 알려주기

Codex가 모르는 내부 라이브러리나 최신 API를 쓰게 해야 할 때는 "문서 링크"보다 다음이 효과적입니다.

  • 함수 시그니처(입력/출력)

  • 최소 사용 예 1~2개

즉, 라이브러리를 작은 참조문서로 프롬프트 안에 포함시키는 방식입니다. 이러면 모델이 추측으로 API를 발명할 가능성이 줄고, 코드가 실제 인터페이스를 따라갑니다.1

실행 전 멈춤점 넣기: "계획만 내고 기다려"

Codex를 '비동기 에이전트'로 쓸수록, 한 번의 지시로 여러 파일을 바꾸게 됩니다. 이때 가장 간단한 안전장치는 프롬프트에 멈춤점을 박는 것입니다.

먼저 변경 계획만 제안하고, 내가 승인하기 전에는 파일 수정/명령 실행을 하지 마.

이 한 줄은 승인 모드(Approvals)와 함께 쓸 때 특히 강력합니다. "자동화"가 아니라 "통제된 자동화"가 되기 때문입니다.2

안티 패턴: 자주 망하는 프롬프트 5가지

실무에서 반복되는 실패는 패턴이 거의 정해져 있습니다.

첫째, 동사가 추상적입니다. "개선해줘", "정리해줘", "깔끔하게"는 모델이 마음대로 정의합니다.

둘째, 작업이 여러 개입니다. 기능 추가 + 리팩터링 + 마이그레이션 + 성능 개선을 한 번에 시키면, 무엇이 완료인지 정의되지 않습니다.

셋째, 형식 지정이 없습니다. 결과가 매번 달라지고, 다음 단계(리뷰/자동화)로 연결이 끊깁니다.3

넷째, 검증이 없습니다. 테스트, 재현, 완료 조건이 없으면 "돌아갈 것 같은 코드"로 끝납니다.

다섯째, 모순이 섞입니다. 짧게 쓰라면서 모든 케이스를 다 다루라고 요구하는 식의 모순은 결과 품질을 급격히 떨어뜨립니다.5

팀에서 프롬프트를 '공유 자산'으로 만드는 법

프롬프트는 개인 기술로 끝나기 쉽지만, 팀에서 효과를 보려면 템플릿을 문서화해야 합니다. 잘 되는 팀은 프롬프트를 '말'이 아니라 '템플릿'으로 관리합니다.7

가장 단순한 시작은 다음입니다.

  • 자주 하는 작업 5개(기능/버그/리팩터/테스트/리뷰)를 템플릿으로 고정

  • 성공한 프롬프트와 실패한 프롬프트를 함께 저장(무엇이 달랐는지 메모)

  • 템플릿도 버전 관리(v1, v2…)하고, 변경 이유를 남김

이렇게 하면 "누가 더 말을 잘하느냐"가 아니라 "팀이 어떤 계약서를 쓰느냐"가 성과를 결정합니다.

참고

1How to get Codex to produce the code you want! | Prompt Engineering

2Prompt engineering techniques - Microsoft Foundry | Microsoft Learn

3System message design for Azure OpenAI - Microsoft Foundry | Microsoft Learn

4Prompt Engineering for Coding: A Practical Framework + 12 Templates | PromptDC

5Optimize Prompts - developers.openai.com

6Prompt Engineering and Templates | openai/codex | Zread

7Prompt Engineering: Designing Structured Prompt Templates | Medium

8Prompt Writing for Programmers Cheatsheet

책 목록

OpenAI Codex 활용법: IDE·CLI·클라우드에서 코딩 에이전트로 일하기

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기