OpenAI Codex가 이제 범위가 지정된 작업의 85%를 완료합니다. 이를 가능하게 하는 /goal 워크플로우를 소개합니다.
요약
OpenAI Codex의 새로운 /goal 워크플로우를 소개합니다. 이 기능은 사용자가 설정한 목표가 완료될 때까지 Codex가 스스로 루프를 반복하며 작업을 수행하도록 지원합니다.
핵심 포인트
- /goal 기능은 목표 완료 시까지 자동 루프를 수행합니다.
- 버전 0.133.0부터 CLI, IDE, 앱 전반에 걸쳐 일반 제공됩니다.
- 전용 저장소를 통해 세션이 종료되어도 작업 상태가 유지됩니다.
- 토큰 예산 관리와 자동 프롬프트 주입으로 효율적인 에이전트 동작을 구현합니다.
OpenAI Codex가 이제 범위가 지정된 작업의 85%를 완료합니다. 이를 가능하게 하는 /goal 워크플로우를 소개합니다.
OpenAI는 잘 정의된 범위의 유지보수 작업(maintenance work)에 대해 Codex가 85~90%의 성공률을 보이고 있다고 언급해 왔습니다. 이 수치는 독립적인 벤치마크가 아닌 내부 테스트에서 나온 것입니다. 하지만 그 이면의 메커니즘은 실재하며, 이는 왜 Codex가 작동하는지, 그리고 언제 실패하는지를 모두 설명해 줍니다.
해당 기능은 /goal입니다. 이 기능은 Codex CLI 0.128.0 버전에서 출시되었으며, 2026년 5월 21일 버전 0.133.0을 통해 CLI, IDE 확장 프로그램 및 Codex 앱 전반에 걸쳐 일반적으로 사용 가능(generally available)하게 되었습니다. 요약하자면, 사용자가 목표(goal)를 설정하면 Codex는 목표가 완료되었다고 판단할 때까지 루프(loop)를 반복하며, 유일한 중단 조건은 "완료"라고 말하는 평가(evaluation)가 내려지거나 토큰 예산(token budget)이 소진되는 경우뿐입니다.
특정 작업에 대해 이 루프가 왜 성공하거나 실패하는지를 이해하는 것이 핵심입니다.
TL;DR (요약)
| 시나리오 | 결과 | 이유 |
|---|---|---|
| 알려진 에러 메시지가 있는 실패하는 테스트 수정 | 높은 통과율 | 범위가 좁고, 완료 여부를 검증할 수 있음 |
| ... |
1. /goal이 하는 역할과 "지속성(persisted)"이 중요한 이유
표준적인 Codex 턴(turn)은 상태 비저장(stateless) 방식입니다. 질문을 던지면 실행되고 세션이 종료됩니다. /goal은 이러한 패턴을 깨뜨립니다.
목표를 설정하면 Codex는 매 턴이 끝날 때마다 goals/continuation.md와 goals/budget_limit.md라는 두 개의 프롬프트(prompt)를 자동으로 주입합니다. 첫 번째는 모델에게 목표가 완료되었는지 확인하고 계속 진행할지 결정하도록 지시합니다. 두 번째는 토큰 소비량을 추적하여 예산을 초과하기 전에 루프를 중단시킵니다. 루프는 이 두 가지 조건 중 하나가 트리거될 때까지 앞으로 진행됩니다.
버전 0.133.0 이전에는 목표가 세션 범위(session-scoped)였습니다. CLI 프로세스가 종료되면 목표도 사라졌습니다. 0.133.0 릴리스는 전용 저장소(dedicated storage)를 통해 목표를 백업함으로써, CLI 재시작을 포함하여 활성 턴(active turns) 전반에 걸쳐 진행 상황을 추적할 수 있게 했습니다. 이것이 바로 "지속성(persisted)" 부분입니다. 목표 상태는 재부팅 후에도 유지됩니다.
버전 0.132.0 (2026년 5월 19일)에서 중요한 수정 사항이 하나 추가되었습니다. 이제 목표 지속(goal continuations)이 무한히 회전하는 대신 사용량 제한(usage limits)에서 멈춥니다. 이 수정 전에는 명확한 완료 신호가 없는 목표의 경우, 프로세스가 종료되거나 계정이 속도 제한(rate limit)에 도달할 때까지 실행되었습니다.
OpenAI가 여기서 사용하는 루프 패턴은 새로운 것이 아닙니다. 실무자들은 이를 "Ralph loop"라고 부릅니다. 이는 자신의 출력을 확인하고 계속 진행할지 여부를 결정하는 에이전트(agent)를 의미합니다. Codex는 그 위에 예산 관리(budget accounting)와 지속성 계층(persistence layer)을 추가했습니다. 프롬프트 주입(prompt injection)은 자동으로 실행되며, 사용자가 직접 지속 프롬프트(continuation prompts)를 작성할 필요는 없습니다.
2. 85%의 성공률을 달성하는 작업의 형태
세 가지 속성이 작업을 높은 성공 범위로 밀어 넣습니다.
목표는 이진 성공 확인(binary success check)이 가능해야 합니다. "src/auth의 실패하는 테스트를 수정하라"는 가능합니다. 하지만 "인증 모듈을 개선하라"는 불가능합니다. 에이전트는 검증 단계(verification step)를 실행하고 예(yes) 또는 아니오(no)의 결과를 얻어야 합니다. CI 통과는 예 또는 아니오입니다. "더 나은 코드"는 아닙니다.
범위(scope)는 좁게 유지되어야 합니다. 하나의 모듈이나 하나의 인터페이스 정의를 다루는 목표는 에이전트에게 작은 탐색 공간(search space)을 제공합니다. 만약 수정 사항이 코드베이스의 서로 관련 없는 다섯 군데를 변경해야 한다면, 에이전트는 그중 세 군데를 해결하고 네 번째에서 멈추게 되며, 자신이 멈췄다는 사실을 알 방법이 없습니다.
성공 조건은 세션 내부에서 관찰 가능(observable)해야 합니다. 성공 시 0을 반환하고 실패 시 0이 아닌 값을 반환하는 셸 명령어를 작성하면 에이전트가 스스로 확인할 수 있습니다. 테스트가 명확한 예시입니다. 타입 체크(Type checks)도 가능합니다. 린트 규칙(Lint rules)도 가능합니다. "PR이 리뷰를 통과한다"는 에이전트가 해당 확인 작업을 수행할 수 없기 때문에 불가능합니다.
제가 잘 작동하는 것을 본 작업들은 다음과 같습니다:
- 특정 함수에 대한 누락된 테스트를 작성하고, 통과(green) 확인
- 기존의
as캐스트를 충족하는 TypeScript 인터페이스 추가 - 의존성 버전을 올리고 그로 인해 발생하는 타입 오류 수정
- 반복되는 코드 블록을 공유 유틸리티로 추출하고 한 디렉토리 내의 모든 호출 지점 업데이트
이 모든 작업에는 에이전트가 도달하고 측정할 수 있는 결승선이 있습니다.
3. 실패하는 작업의 형태
실패 모드 (failure modes)는 범위 확장 (scope creep)과 증명 불가능한 완료 (unprovable completion)라는 두 가지 범주로 나뉩니다.
범위 확장 (scope creep)은 에이전트가 한 가지 문제를 해결하면서 또 다른 문제를 드러낼 때 발생합니다. 예를 들어, 실패하는 통합 테스트 (integration test)를 수정하라고 요청하면, 에이전트는 모의 객체 (mock)를 업데이트하여 테스트를 통과시킵니다. 하지만 이 모의 객체는 이제 실제 API와 달라지게 됩니다. 에이전트에게 이를 확인하라는 지침이 없으므로, 에이전트는 완료되었다고 선언합니다. CI는 로컬에서 통과하지만, 이틀 뒤 스테이징 (staging) 환경에서 실패합니다. 에이전트는 당신이 말한 것을 정확히 수행했습니다. 목표가 너무 좁았던 것입니다.
증명 불가능한 완료 (unprovable completion)는 에이전트가 스스로를 점검할 수 없을 때 발생합니다. "이 서비스를 더 읽기 쉽게 리팩터링 (refactor) 하세요"라는 명령은 에이전트에게 검증할 수 있는 기준을 전혀 주지 않습니다. 에이전트는 변경 사항을 만들고, 그 변경 사항이 합리적으로 보인다고 판단한 뒤, 목표를 완료로 표시하고 멈출 것입니다. 코드가 더 잘 읽히는지 여부는 인간의 판단 영역입니다. 에이전트는 결과물을 만들어내고, 결과가 어떻든 상관없이 자신 있게 멈출 것입니다.
아키텍처 변경 (Architectural changes)은 거의 매번 실패합니다. 만약 작업이 모듈 경계 (module boundary)를 어디에 둘지, 혹은 어떤 서비스가 특정 책임을 가질지 결정해야 하는 경우라면, 에이전트는 모호함에 부딪혀 임의로 하나를 선택하거나 예산 (budget)이 소진될 때까지 루프 (loop)를 돌게 됩니다. 이것은 능력의 격차가 아닙니다. 작업 자체가 진정으로 미결정 (underdetermined) 상태인 것입니다. 아무리 루프를 돌려도 이 문제는 해결되지 않습니다.
85%라는 수치는 정확한 측정 방식이 무엇이든 간에, 명확한 성공 기준이 있는 선별된 유지보수 작업 세트에 거의 확실히 적용되는 수치입니다. 만약 /goal을 개방형 설계 작업 (open-ended design work)에 지정한다면, 당신은 85% 안에 들지 못할 것입니다. 당신은 완전히 다른 분포에 속하게 됩니다.
4. 설정 및 /goal 호출 샘플
Codex CLI를 설치하거나 업데이트하세요:
npm install -g @openai/codex
codex --version
# 지속적인 목표 (persistent goals)를 위해 0.133.0 이상 버전 필요
목표 (goals)가 활성화되어 있는지 확인하세요 (0.133.0부터 기본적으로 활성화되어 있지만, 확인해 볼 가치가 있습니다):
codex doctor
# 다음 항목을 확인하세요: goals: enabled, storage: ok
CLI에서 목표를 설정하세요:
codex goal set "All tests in src/payments pass with no TypeScript errors"
저장소 (repo)에서 세션을 시작하고 실행되도록 두세요:
cd /your/repo
codex
# Codex가 활성화된 목표를 파악하고 루프를 시작합니다
루프가 작동하는 것을 확인하세요:
codex goal status
# 표시 내용: 활성 목표(active goal), 완료된 턴(turns completed), 사용된 토큰(tokens used), 마지막 평가 결과(last evaluation result)
에이전트는 각 턴의 끝에서 npm test 또는 설정된 테스트 명령어를 실행하고, 출력을 확인한 뒤 계속 진행할지 여부를 결정합니다. 만약 테스트 명령어를 찾을 수 없는 경우, package.json 스크립트에서 test, typecheck, 또는 lint라는 이름의 스크립트를 해당 순서대로 탐색합니다.
범위가 더 좁은 작업의 경우, 성공 명령어를 인라인(inline)으로 지정할 수 있습니다:
codex goal set "Fix TypeScript errors in src/api/routes.ts" \
--verify "npx tsc --noEmit --project tsconfig.json"
--verify 플래그는 Codex가 명령어를 추론하는 대신, 어떤 명령어를 완료 확인(done-check) 용도로 사용할지 알려줍니다. 성공 시 종료 코드 0(exit 0)을 반환하는 것이라면 무엇이든 전달할 수 있습니다.
정체된 목표를 취소하려면:
codex goal cancel
과거의 목표와 그 결과를 나열하려면:
codex goal list --limit 10
5. 안전을 위해 /goal을 CI에 연결하기
이 루프가 CI(지속적 통합)를 대체하는 것은 아닙니다. CI가 실행되기 전에 테스트를 통과(green) 상태로 만들기 위한 방법으로 취급하세요. 에이전트의 출력물은 다른 코드와 마찬가지로 머지(merge)되기 전에 타입 체크(type check), 린트(lint), 그리고 테스트를 거칩니다.
Codex가 생성한 변경 사항을 검증하는 GitHub Actions 작업 예시:
name: verify-codex-output
on:
...
범위 확장(scope-creep) 체크는 에이전트가 작성한 PR(Pull Request)을 위해 제가 특별히 추가한 것입니다. 만약 5개의 파일만 다뤄야 하는 작업에서 Codex가 20개 이상의 파일을 건드린다면, 누군가는 무슨 일이 일어났는지 확인해야 합니다. 이 경고가 PR을 차단하지는 않지만, 더 신중한 리뷰가 필요하도록 플래그(flag)를 표시합니다.
중요한 CI 규칙: 에이전트가 생성한 코드라고 해서 기존의 품질 게이트(quality gates)를 절대 완화하지 마세요. 오히려 파일 개수 체크를 추가하십시오. 자신의 범위를 측정할 수 없는 에이전트는 한 줄짜리 버그를 고치기 위해 40개의 파일을 수정하는 것을 스스로 멈추지 않을 것입니다.
Pre-commit hook은 또 다른 계층입니다. 커밋이 CI에 도달하기 전에 빠른 타입 체크를 추가하세요:
# .pre-commit-config.yaml (pre-commit 사용 시)
repos:
- repo: local
...
또는 husky를 사용하여 package.json에 직접 연결할 수 있습니다:
{
"scripts": {
"prepare": "husky install"
...
# .husky/pre-commit
npm run typecheck
이제 에이전트가 /goal 루프를 통해서든 단일 턴 (single turn)을 통해서든 수행하는 모든 커밋은 푸시(push)하기 전에 로컬에서 타입 체크 (type check)를 거치게 됩니다.
핵심 요약 (The bottom line)
/goal 루프는 "완료" 여부에 대해 에이전트가 스스로 확인할 수 있는 이진적 (binary) 답변이 존재하는 작업에서 작동합니다. 목표 (goal)를 설정하기 전에 해당 검증 명령어를 먼저 작성하십시오. 만약 그 명령어를 작성할 수 없다면, 에이전트에게 넘기기 전에 해당 작업의 범위 (scoping)를 더 구체화해야 합니다.
85%라는 수치는 큐레이션된 유지보수 작업 (maintenance tasks)을 대상으로 합니다. 이 성공률을 도구에 맡기는 모든 작업에 그대로 적용할 수는 없습니다. 아키텍처 결정 (Architectural decisions), 모호한 리팩터링 (ambiguous refactors), 그리고 횡단 관심사 변경 (cross-cutting changes)은 턴 횟수와 관계없이 해당 수치에 도달하지 못할 것입니다.
0.133.0 버전에 출시된 지속성 계층 (persistence layer)이 진정한 돌파구입니다. CLI 재시작 후에도 유지되는 목표 (goal)는 작업을 실행해 두고 터미널을 닫은 뒤, 끊긴 세션이 아닌 결과물을 확인하러 돌아올 수 있음을 의미합니다. 이는 워크플로우를 "감독되는 에이전트 (supervised agent)"에서 느린 비동기 작업 (slow async job)에 더 가까운 무언가로 변화시킵니다. 이를 CI에 연결하고, 예산 (budget)을 제한하며, 출력물을 다른 검토되지 않은 PR (unreviewed PR)처럼 취급하십시오.
백로그 (backlog) 중에서 테스트 기반의 명확한 완료 조건이 있는 첫 번째 유지보수 작업은 무엇인가요? 그것이 바로 /goal을 가장 먼저 시도해 볼 작업입니다.
GDS K S · thegdsks.com · follow on X @thegdsks
목표를 설정하기 전에 검증 명령어를 설정하십시오. 만약 작성할 수 없다면, 범위 (scope)가 준비되지 않은 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기