Codex 이미지 생성: 커스텀 프로바이더에서 imagegen 켜기
config.toml에 두 줄을 넣으면 릴레이 위의 Codex에서도 내장 imagegen이 동작합니다. 2026년 10월 29일에 실제로 돌린 설정, 이미지가 저장되는 위치, 릴레이가 돌려줘야 하는 응답을 정리합니다.
이 페이지 목차
- 커스텀 프로바이더에서 imagegen이 사라지는 이유
- imagegen을 켜는 config.toml
- 이미지 한 장을 만들고 파일 위치 확인하기
- 기존 이미지 편집하기
- 투명 배경
- 릴레이가 돌려줘야 하는 것(gpt-image-2, b64_json)
- 오류와 해결
- Codex가 이미지 도구가 없다고 말할 때
- Codex가 OPENAI_API_KEY를 요구할 때
- failed to decode image generation response: missing field b64_json
- 이미지 요청이 model_not_found로 실패할 때
- Reconnecting... 1/5 (stream disconnected before completion)
- 자주 묻는 질문
- imagegen에 OPENAI_API_KEY가 필요한가요?
- 다른 이미지 모델이나 크기, 품질을 고를 수 있나요?
- $imagegen을 직접 입력해야 하나요?
- Codex 데스크톱 앱에서도 되나요?
- 확인한 출처
Codex 이미지 생성을 커스텀 프로바이더(릴레이)에서 쓰려면, Codex 0.165.0의 프로바이더 설정에 x-openai-actor-authorization이라는 http_headers 항목을 한 줄 넣고 값을 비어 있지 않게 두면 됩니다. requires_openai_auth = false는 기본값 그대로 둡니다. 그러면 Codex가 이미지 요청을 릴레이의 /images/generations로 모델 gpt-image-2와 함께 보내고, PNG를 ~/.codex/generated_images/에 저장합니다. 2026년 10월 29일에는 1024×1024 PNG가 29.0초에 나왔습니다. 헤더를 뺀 같은 설정에서는 이미지 도구 자체가 나타나지 않았습니다.
테스트는 macOS의 Codex CLI 0.165.0에서 했고, 커스텀 프로바이더로는 자체 API 게이트웨이인 OmniaKey를 썼습니다.
커스텀 프로바이더에서 imagegen이 사라지는 이유
Codex 0.165.0은 모델에 이미지 도구를 줄지 말지를 함수 하나에서 정합니다. 기준은 프로바이더 설정과 저장된 로그인 상태입니다: image_generation_available.
requires_openai_auth = false에 actor 헤더 없음: 이미지 도구가 없습니다. 이 설정으로 실행하자 Codex는 "I don’t have a built-in image generation tool available in this session."(이 세션에는 내장 이미지 생성 도구가 없습니다)라고 답했습니다.requires_openai_auth = false에x-openai-actor-authorization추가: 도구가 나타납니다. 헤더를 넣고 돌린 세 번(새 이미지, 편집, 투명 스티커)은 모두 도구를 호출했습니다.requires_openai_auth = true에 API 키 로그인: 이미지 도구가 없습니다. Codex 0.165.0 소스에서 이 판정은 ChatGPT 로그인을 요구하며, API 키 로그인은 인정하지 않습니다.
이 판정 뒤에는 작은 조건 두 개가 더 있습니다. 둘 다 Codex 0.165.0 소스에 있습니다. 무료 ChatGPT 요금제 로그인이 저장되어 있으면 커스텀 프로바이더에서도 도구가 숨겨집니다. 또 하나는 채팅 모델이 이미지 입력을 받아야 한다는 점입니다. Codex는 자기 목록에 없는 모델 이름은 이미지를 받는 것으로 가정합니다.
도구가 없을 때 Codex의 답은 두 가지입니다. 헤더 없이 실행했을 때처럼 내장 이미지 도구가 없다고 말하거나, imagegen 스킬이 OPENAI_API_KEY가 필요한 CLI 대체 경로를 안내합니다.
imagegen을 켜는 config.toml
~/.codex/config.toml을 엽니다. 릴레이용 프로바이더 블록에 http_headers 줄을 넣고, requires_openai_auth가 false(기본값)인지 확인합니다.
model = "gpt-6.1-sol" # 릴레이가 제공하는 채팅 모델
model_provider = "relay"
[model_providers.relay]
name = "My relay"
base_url = "https://api.omniakey.com/v1"
env_key = "RELAY_API_KEY"
wire_api = "responses"
requires_openai_auth = false
http_headers = { "x-openai-actor-authorization" = "local-relay" }
[features]
image_generation = true # Codex 0.165.0에서는 기본으로 켜져 있음
model과 model_provider는 최상위 키이므로 첫 [section] 줄보다 위에 두어야 합니다. TOML은 [section] 헤더 뒤의 모든 줄을 그 섹션에 속한 것으로 읽습니다.
requires_openai_auth = false는 Codex가 환경 변수의 키를 쓰게 합니다. 변수 이름은env_key에 적은 것입니다. OpenAI 인증 문서(2026년 10월 29일 확인)는 "Whenrequires_openai_auth = true, Codex ignoresenv_key."(true이면 Codex는env_key를 무시합니다)라고 밝힙니다.http_headers에 들어가는 것이 actor 헤더입니다. OpenAI 설정 레퍼런스는 이를 "Static HTTP headers added to provider requests"(프로바이더 요청에 붙는 고정 헤더)라고 부릅니다. Codex는 값이 비어 있지 않은지만 확인하므로(Codex 소스의 해당 검사),local-relay는 자리 표시자이고 비밀번호가 아닙니다.[features] image_generation = true는 0.165.0에서 생략할 수 있습니다. 기능이 안정 상태이고 기본으로 켜져 있으며,codex features list는image_generation stable true를 출력합니다. 실행할 때는 이 두 줄을 넣지 않았습니다.wire_api = "responses"는 OpenAI 설정 레퍼런스가 지원하는 유일한 값입니다.
키를 설정하고 Codex를 시작합니다:
export RELAY_API_KEY="your-relay-key"
codex
Codex가 이미 실행 중이라면 종료하고 새 세션을 엽니다. 그래야 새 설정을 읽습니다.
이미지 한 장을 만들고 파일 위치 확인하기
2026년 10월 29일 실행은 커스텀 프로바이더를 거쳤습니다. 헤더 없이 확인한 실행 2에서는 이미지가 만들어지지 않았습니다. 나머지 세 번은 모두 1024×1024 PNG를 한 장씩 저장했습니다. 시간은 이미지 호출만 잰 값이고, 턴 전체 시간이 아닙니다.
| 실행 | 요청한 내용 | 이미지 호출 |
|---|---|---|
| 1 | 새 앱 아이콘 | 29.0 s |
| 3 | 실행 1의 이미지 편집 | 37.6 s |
| 4 | 투명 스티커 | 19.8 s |
실행 1은 프롬프트 하나였습니다:
Create an app icon for a note-taking app called Inkwell: a fountain pen nib over a deep blue gradient, flat vector style, no text. Generate it with your image tool, then tell me where the file was saved.
Codex는 프롬프트에 $imagegen이 없는데도 imagegen 스킬을 스스로 열고 도구를 호출했습니다. 호출은 29.0초 걸렸고, 턴은 1024×1024 PNG 한 장으로 끝났습니다.
파일은 ~/.codex/generated_images/<session id>/<call id>.png에 놓입니다. ~/.codex는 CODEX_HOME의 기본값입니다. 경로를 출력한 것은 프롬프트에서 물었기 때문입니다. 이미지를 프로젝트에서 쓸 거라면 프롬프트에 목적지를 적습니다. 그러면 스킬이 Codex에게 파일을 옮기거나 복사하라고 지시합니다.
기존 이미지 편집하기
실행 1의 PNG를 inkwell.png로 작업 폴더에 옮기고 이렇게 요청했습니다:
Edit the image ./inkwell.png: change the background to a warm orange gradient and keep the pen nib as it is. Use your built-in image tool, then tell me where the edited file was saved.
Codex는 파일을 referenced_image_paths에 넣었고, 요청은 /images/edits로 갔습니다. 호출은 37.6초 걸렸고 원본 inkwell.png는 그대로였습니다. OpenAI 이미지 생성 문서(2026년 10월 29일 확인)는 "When editing an existing image, say exactly what should change and what must stay the same."(기존 이미지를 편집할 때는 바꿀 점과 그대로 둘 점을 정확히 말하라고) 안내합니다. 나머지는 GPT-Image 2 프롬프트 가이드에서 다룹니다.


투명 배경
실행 4는 스티커를 요청했습니다:
Create a PNG sticker of a single fountain pen nib on a fully transparent background (no backdrop at all), flat vector style, no text. Generate it with your built-in image tool, then tell me where the file was saved.
Codex는 transparent_background를 true로 설정했고 호출은 19.8초 걸렸습니다. 저장된 PNG는 픽셀의 85.0%가 완전히 투명합니다. OpenAI Images API 레퍼런스는 gpt-image-2의 투명 배경을 "in preview"(프리뷰)로 표시합니다. 이번 실행에서는 됐지만 여전히 프리뷰 기능입니다.

릴레이가 돌려줘야 하는 것(gpt-image-2, b64_json)
새 이미지는 POST <base_url>/images/generations, 편집은 POST <base_url>/images/edits로 갑니다. 둘 다 JSON이고 모델은 gpt-image-2, 즉 릴레이가 제공해야 하는 GPT-Image 2의 ID입니다. 품질과 크기는 "auto", background는 "opaque" 또는 "transparent"이고, 요청에 response_format과 n은 들어가지 않습니다. base URL과 키는 채팅 요청과 같습니다. 편집은 원본 이미지를 파일 업로드 대신 data URL로 JSON 안에 담아 보냅니다.
Codex가 읽는 답은 created와 data 목록을 가진 JSON이고, b64_json은 그 첫 항목에 있습니다. 다른 필드는 무시합니다(images.rs). 파싱에 실패하면 메시지는 "failed to decode image generation response:"로 시작합니다.
Codex 없이도 릴레이를 확인할 수 있습니다. 다음을 relay-check.sh로 저장합니다:
curl -s https://api.omniakey.com/v1/images/generations \
-H "Authorization: Bearer $RELAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "gpt-image-2", "prompt": "a red apple on a white table", "background": "opaque", "quality": "auto", "size": "auto"}' \
| python3 -c 'import json,sys; r=json.load(sys.stdin); print(r.get("error") or sorted(r["data"][0]))'
base URL을 자기 릴레이로 바꾸고 키를 RELAY_API_KEY로 내보냅니다. 2026년 10월 29일 자체 게이트웨이에 실행하자 HTTP 200이 25.0초에 돌아왔고 이렇게 출력됐습니다:
['asset_id', 'b64_json', 'expires_at', 'revised_prompt', 'url']
이 목록에 b64_json이 없으면 Codex도 같은 답에서 실패합니다. 릴레이가 오류를 돌려주면 확인 스크립트가 그 오류를 그대로 출력합니다.
이미지를 파일로 저장하는 릴레이가 여기서 깨집니다. 같은 Images API 레퍼런스(2026년 10월 29일 확인)는 response_format을 "Legacy response format parameter for retired image models. Unsupported for GPT image models, which always return base64-encoded images"(퇴역한 이미지 모델용 구형 응답 형식 파라미터. GPT 이미지 모델은 지원하지 않으며 항상 base64로 반환)라고 설명하고, b64_json은 "Returned by default for GPT image models"(GPT 이미지 모델은 기본으로 반환)이라고 밝힙니다. OpenAI 응답을 그대로 전달하는 릴레이는 문제가 없습니다. 링크만 돌려주는 릴레이는 Codex를 실패시킵니다.
OmniaKey 게이트웨이도 2026년 10월 29일 수정 전에는 같은 문제가 있었습니다. 수정 기록에는 Codex가 "missing field b64_json"으로 실패했다고 적혀 있습니다. 지금은 호출하는 쪽이 URL을 요구하지 않는 한 게이트웨이가 b64_json을 유지합니다.
릴레이가 이 확인을 통과하지 못한다면, OmniaKey에서는 gpt-image-2와 gpt-6.1-sol 같은 채팅 모델을 키 하나로 쓸 수 있습니다. 이미지 응답에 b64_json이 들어갑니다(위 확인 결과 그대로). 그 프로바이더 블록에 base_url = "https://api.omniakey.com/v1"을 넣고 env_key가 가리키는 변수에 OmniaKey 키를 넣습니다. 나머지 설정은 Codex CLI 가이드에, 현재 요금은 요금 페이지에 있습니다.
오류와 해결
Codex가 이미지 도구가 없다고 말할 때
첫 절의 조건 중 하나가 충족되지 않았습니다. http_headers 줄을 넣고 requires_openai_auth = false와 env_key를 그대로 둔 채 새 세션을 엽니다. 그래도 안 되면 codex login status를 실행합니다. 무료 ChatGPT 요금제라면 codex logout으로 저장된 로그인을 지우면 되고, env_key의 키만 있으면 됩니다.
Codex가 OPENAI_API_KEY를 요구할 때
내장 도구를 쓸 수 없어서 imagegen 스킬이 CLI 대체 경로인 scripts/image_gen.py를 안내합니다. 이 경로에는 OPENAI_API_KEY가 필요합니다. 대신 위 설정으로 내장 도구를 고칩니다. 내장 모드에서 키는 env_key에서 옵니다.
failed to decode image generation response: missing field b64_json
릴레이가 b64_json 없이 답했습니다. 대개 저장한 파일 링크만 보낸 경우입니다. 릴레이 절의 확인 스크립트를 실행해 결과를 운영 담당자에게 보냅니다. Codex는 data 첫 항목의 base64 문자열을 원합니다.
이미지 요청이 model_not_found로 실패할 때
그 키에는 이 릴레이의 gpt-image-2가 없습니다. Codex는 항상 이 ID를 보내고, 설정으로 바꿀 방법이 없습니다. 자체 게이트웨이에 없는 이미지 모델로 요청하자 HTTP 503과 코드 model_not_found가 돌아왔습니다. gpt-image-2를 목록에 가진 키와 릴레이를 쓰면 됩니다.
Reconnecting... 1/5 (stream disconnected before completion)
채팅 요청이 끊겨 Codex가 다시 시도했고, 카운터는 다섯 번 중 몇 번째인지를 보여줍니다. 실행 1에서 한 번("Concurrency limit exceeded for account, please retry later"), 실행 3에서 한 번(전송 오류) 나타났고 둘 다 재시도 뒤에 끝까지 진행됐습니다. 계속 반복되면 릴레이의 한도를 확인합니다. 채팅 쪽 문제는 Codex 호환성 키트에서 다룹니다.
자주 묻는 질문
imagegen에 OPENAI_API_KEY가 필요한가요?
아니요. 내장 모드의 키는 env_key에 적은 변수에서 옵니다. OPENAI_API_KEY를 읽는 것은 스킬의 CLI 대체 경로뿐입니다.
다른 이미지 모델이나 크기, 품질을 고를 수 있나요?
Codex 0.165.0에서는 안 됩니다. 도구는 gpt-image-2를 품질과 크기 "auto"로 보내고, config.toml에 이들을 바꾸는 키가 없습니다. 실행에서 받은 이미지는 모두 1024×1024였습니다. 다른 크기나 모델이 필요하면 릴레이의 이미지 엔드포인트를 직접 호출합니다.
$imagegen을 직접 입력해야 하나요?
아니요. 실행에서 Codex는 imagegen 스킬을 스스로 열었습니다. OpenAI 문서에 따르면 프롬프트에 $imagegen을 쓰면 스킬을 명시적으로 호출합니다. Codex가 스스로 고르지 않을 때 도움이 됩니다.
Codex 데스크톱 앱에서도 되나요?
데스크톱 앱은 테스트하지 않았고 CLI만 확인했습니다. 커뮤니티 수정 저장소에 따르면 실행 중인 Codex Desktop은 새 환경 변수를 읽지 않습니다. macOS 스크립트가 LaunchAgent를 설치하고, 그다음 Codex를 완전히 종료한 뒤 새 작업을 여는 순서입니다.
확인한 출처
이 글에서 다루는 모델
관련 글
GPT-5.6 모델을 찾을 수 없음 오류 해결
먼저 오류를 일치시킨 다음 모델 액세스, API 및 Codex를 별도로 테스트하세요.
GPT Image 2 프롬프트 가이드: 구조, 예시, 실제 생성 이미지
프롬프트 8개, 실제 이미지 9장: GPT Image 2가 정확히 맞춘 점, 제멋대로 더한 점, 고치는 법을 정리했습니다.
Codex용 최적 GPT-5.6 모델
복잡한 코딩은 GPT-6.1 Sol, 집중해서 반복하는 작업은 GPT-6 Luna, GPT-5.6을 계속 쓰는 작업은 그 세 모델에서 고르세요.
