이미지 생성

이미지 생성 (Image Generation)

Pydantic AI는 전용 이미지 모델로 이미지를 생성·편집하는 프로바이더에 구애받지 않는(provider-agnostic) API를 제공해요. 애플리케이션이(에이전트가 아니라) 이미지를 만들 시점을 결정할 때는 ImageGenerator를 사용하세요. 에이전트가 그 결정을 내려야 한다면, ImageGeneration capability를 쓰세요.

출처: 문서

본문

빠른 시작 (Quick Start)

사용하려는 프로바이더의 선택 그룹을 설치하세요. 예를 들어 OpenAI:

pip install "pydantic-ai-slim[openai]"
uv add "pydantic-ai-slim[openai]"

API 키를 환경 변수로 설정합니다:

export OPENAI_API_KEY='your-api-key'

그런 다음 프로바이더 프리픽스가 붙은 모델 이름을 ImageGenerator에 넘기고 generate()를 호출하세요:

from pathlib import Path

from pydantic_ai import ImageGenerator

generator = ImageGenerator('openai:gpt-image-2')


async def main():
    result = await generator.generate('A watercolor map of a floating city.')
    image = result.image
    Path('floating-city.png').write_bytes(image.data)

(이 예제는 완전해서 "그대로" 실행할 수 있어요. main을 실행하려면 asyncio.run(main())을 추가하면 됩니다.)

generate_sync()는 동기 코드에 같은 인터페이스를 제공해요.

각 프로바이더가 쓰는 설치 그룹과 환경 변수는 프로바이더를 참고하세요.

모델 고르기 (Choosing a model)

이미지를 생성하는 세 가지 모델 패밀리가 있어요:

프로바이더가 모델 이름을 검증하므로, 이 패밀리 중 현재 모델이라면 당신이 설치한 Pydantic AI 버전 이후에 출시된 것도 동작해요. KnownImageGenerationModelName은 자동 완성을 위해 Pydantic AI가 인식하는 이름을 담고요, 다른 이름은 변경 없이 그대로 전달됩니다. 각 프로바이더의 문서에서 그 모델의 비용과 강점을 확인하세요.

각 패밀리가 만들 수 있는 정확한 형태는 다르고, 이식 가능한(portable) 지오메트리 설정도 모델별로 매핑되므로, 고정 레이아웃에 모델을 확정하기 전에 출력 지오메트리aspect_ratio의 정규 차원을 확인하세요.

이미지 편집 (Editing Images)

images를 통해 참조 이미지를 전달해 편집하거나 변환할 수 있어요. 입력은 BinaryImage, ImageUrl, 또는 UploadedFile 객체를 담을 수 있어요:

from pydantic_ai import BinaryImage, ImageGenerator

generator = ImageGenerator('google:gemini-3.1-flash-lite-image')


async def replace_subject(source: BinaryImage) -> BinaryImage:
    result = await generator.generate(
        'Replace the cat with a dog while preserving the composition.',
        images=[source],
    )
    return result.image

여러 참조 이미지의 순서는 보존돼요. 프로바이더 호스팅 파일은 Google과 xAI에서 지원되며, UploadedFile.provider_name은 파일이 업로드된 프로바이더를 가리켜야 해요. xAI에서는 그것이 정확히 선택한 프로바이더의 이름이고, Google은 추가로 pre-v2 이름 google-gla를 받으며, Gemini Files API 가용성을 프로바이더 이름이 아니라 클라이언트 전송에서 읽어요(Google 이미지 생성 참고). OpenAI의 image-edit 엔드포인트는 파일 콘텐츠를 요구하므로 OpenAI에서는 BinaryImage 또는 ImageUrl을 사용하세요. Pydantic AI가 다운로드하는 이미지 URL은 50 MiB로 제한돼요.

편집은 전체 이미지에 적용돼요. 마스크가 편집을 영역으로 제한하는 마스크 편집은 지원되지 않습니다. 아래 프로바이더 중 OpenAI만이 그 프리미티브를 노출하므로, 아직 그것에 매핑할 이식 가능한 대상이 없어요.

프로바이더 생성 참조 편집 UploadedFile 여러 출력 참고
OpenAI 참조 이미지는 PNG·JPEG·WebP여야 하며, 다른 미디어 타입은 UserError 발생
Google Gemini API UploadedFile.file_id는 Files API URI(file.uri, https://로 시작)여야 하며 files/... 리소스 이름이 아니어야 함. 다른 값은 UserError 발생. Uploaded Files 참고
Google Cloud (Vertex AI) Vertex AI에는 Gemini Files API가 없고 어댑터도 Vertex가 쓰는 gs:// URI를 받지 않으므로 참조 이미지는 BinaryImage 또는 ImageUrl로 전달
xAI xAI는 참조 이미지 최대 5개를 문서화하고 스스로 한도를 강제. grok-imagine-image에 6개 참조는 INVALID_ARGUMENT로 반환되며 400 ModelHTTPError로 나타남. 모든 UploadedFileImageUrl·BinaryImage보다 앞에 와야 함

google:는 Gemini Developer API(Google AI Studio)이고 google-cloud:는 Vertex AI로, 대화 모델과 정확히 같아요. gateway/google:는 Gemini를 Pydantic AI Gateway로 라우팅하는데, 이는 Vertex 위에서 서빙돼요. gateway/openai:gateway/xai:UserError를 발생시켜요. 게이트웨이가 OpenAI의 이미지 엔드포인트를 미지원으로 보고하고, xAI 업스트림이 없기 때문이에요. Google 어댑터는 ImageGenerator 결과 계약에 맞춰 이미지 전용 출력을 Gemini에 요청해 사용하지 않는 텍스트 출력을 피해요.

프로바이더 (Providers)

'provider:model-name' 문자열은 프로바이더를 보통의 환경 변수로 구성해요.

OpenAI

OpenAIImageGenerationModel은 OpenAI의 Images API와 GPT Image 모델 패밀리와 함께 동작해요.

설치

pydantic-ai를 설치하거나, openai 선택 그룹으로 pydantic-ai-slim을 설치해야 합니다:

pip install "pydantic-ai-slim[openai]"
uv add "pydantic-ai-slim[openai]"
구성

platform.openai.com에 가서 API 키를 생성하고 환경 변수로 설정하세요:

export OPENAI_API_KEY='your-api-key'

프로바이더별 동작은 OpenAI 이미지 생성 노트를 참고하세요.

Google

GoogleImageGenerationModel은 Gemini API(Google AI Studio) 또는 Google Cloud(구 Vertex AI)를 통해 Gemini 이미지 모델과 함께 동작해요.

설치

pydantic-ai를 설치하거나, google 선택 그룹으로 pydantic-ai-slim을 설치해야 합니다:

pip install "pydantic-ai-slim[google]"
uv add "pydantic-ai-slim[google]"
구성

aistudio.google.com에 가서 API 키를 생성하고 환경 변수로 설정하세요:

export GOOGLE_API_KEY='your-api-key'

google-cloud: 프리픽스는 대신 Google Cloud를 사용하며, API 키가 아니라 Application Default Credentials으로 인증해요. 프로바이더별 동작은 Google 이미지 생성 노트, 자격 증명 옵션은 Google Cloud 구성 참고.

xAI

XaiImageGenerationModel은 공식 xAI SDK(이건 gRPC로 연결됨)를 통해 Grok Imagine 모델과 함께 동작해요.

설치

pydantic-ai를 설치하거나, xai 선택 그룹으로 pydantic-ai-slim을 설치해야 합니다:

pip install "pydantic-ai-slim[xai]"
uv add "pydantic-ai-slim[xai]"
구성

console.x.ai에 가서 API 키를 만들고 환경 변수로 설정하세요:

export XAI_API_KEY='your-api-key'

프로바이더별 동작은 xAI 이미지 생성 노트를 참고하세요.

프로바이더 커스터마이징 (Customizing the provider)

인증·베이스 URL·기본 SDK 클라이언트를 커스터마이즈하려면 프로바이더의 이미지 모델 클래스를 직접 만들어 ImageGenerator에 넘기세요. 각각 자체 SDK가 쓰는 Provider를 받으므로, OpenAI 호환 게이트웨이나 미리 구성된 클라이언트는 대화 모델과 같은 방식으로 동작해요:

from pydantic_ai import ImageGenerator
from pydantic_ai.images.openai import OpenAIImageGenerationModel
from pydantic_ai.providers.openai import OpenAIProvider

model = OpenAIImageGenerationModel(
    'gpt-image-2',
    provider=OpenAIProvider(base_url='https://my-provider.com/v1', api_key='your-api-key'),
)
generator = ImageGenerator(model)

설정 (Settings)

ImageGenerationSettings은 이식 가능한 설정을, 프로바이더 설정 클래스는 프로바이더 프리픽스가 붙은 제어를 제공해요.

설정은 모델, 생성기 수준(모든 호출에 적용), 호출별로 지정할 수 있어요. 이 순서로 병합되며, 나중 설정이 같은 키의 이전 값을 오버라이드하고 이전 레이어에만 설정된 값은 유지돼요. 아래 예제는 한 호출에 대해 생성기 기본값을 확장합니다:

from pydantic_ai import ImageGenerator
from pydantic_ai.images import ImageGenerationSettings
from pydantic_ai.images.openai import OpenAIImageGenerationSettings

generator = ImageGenerator(
    'openai:gpt-image-2',
    settings=OpenAIImageGenerationSettings(openai_quality='low', openai_output_format='jpeg'),
)


async def main():
    result = await generator.generate(
        'A cinematic desert observatory at dusk.',
        settings=ImageGenerationSettings(dimensions=(1280, 720)),
    )
    assert result.image.media_type.startswith('image/')

네 가지 설정은 선택한 요청에 그에 대한 필드가 없어 경고와 함께 버려질 수 있어요. 편집에서 openai_moderation, 생성에서 openai_input_fidelity, 그리고 gRPC 전송에 요청별 헤더·본문 탈출구가 없는 xAI에서 extra_headersextra_body입니다. Google은 extra_body가 문자열 키 매핑이 아닐 때 같은 경고와 함께 버려요. JSON 요청 본문에 병합될 수 있는 것은 매핑뿐이기 때문이에요. 그 외에는 모두 프로바이더로 전달되거나, 지오메트리의 경우 요청 전에 거부됩니다 — 출력 지오메트리 참고.

OpenAI 투명 배경은 openai_output_format='png' 또는 'webp'가 필요하고 모델 지원이 달라요. 프로바이더별 설정은 포워딩되므로 프로바이더가 현재 모델 지원의 권위자로 남아요. OpenAI 이미지 생성 노트 참고.

출력 지오메트리 (Output Geometry)

다음 설정 중 하나로 출력 지오메트리를 제어하세요:

  • dimensions=(width, height) — 정확한 픽셀 형태 요청. 선택한 모델이 그 정확한 형태를 만들 수 없으면 UserError 발생
  • aspect_ratio='16:9' — 비율 요청. Pydantic AI가 모델별 정규 형태를 선택

dimensionsaspect_ratio는 상호 배타적이에요. 프로바이더별 지오메트리 제어(openai_size, google_image_config.aspect_ratio, google_image_config.image_size, xai_aspect_ratio, xai_resolution)는 프로바이더들이 다른 개념과 값 범위를 쓰므로 프리픽스가 유지돼요. 명시적인 프로바이더별 지오메트리 설정은 이식 가능한 설정이 매핑하는 값보다 우선하며, 둘이 다를 때만 경고해요.

Gemini는 종횡비를 네이티브 요청 필드로 받으므로, 요청한 비율이 그대로 전송되고 Gemini가 이를 지킬 수 있는지 결정해요. 거부는 ModelHTTPError로 도착합니다. OpenAI와 xAI는 모든 비율을 담을 수 없어요. OpenAI에는 비율 필드가 전혀 없어 Pydantic AI가 비율을 모델 패밀리의 열거된 크기 중 하나로 매핑하고, xAI는 이식 가능한 일부 값에 멤버가 없는 열거형을 받아요. 둘 다 표현할 수 없는 비율에 대해, 버리고 모델 기본 형태로 청구하기보다는 UserError를 발생시켜요.

dimensions는 같은 유선(wire) 형태로 나뉘어요. OpenAI의 size는 평범한 픽셀 문자열이므로, Pydantic AI가 표를 갖지 않은 모델의 형태도 OpenAI가 판단하도록 전송되고, Google과 xAI는 비율과 크기 등급을 보내므로 선택한 모델 표 밖의 형태는 유선 표현이 아예 없어 요청 전에 UserError를 발생시켜요.

Pydantic AI가 인식하지 못하는 OpenAI 모델(설치한 Pydantic AI 버전보다 새로운 GPT Image 릴리스)은 구조적으로 유효한 dimensions를 받아들이고, 그것은 OpenAI가 검증하도록 평범한 size 문자열로 전송돼요. 그러한 모델에서 aspect_ratio는 여전히 UserError를 발생시켜요. Pydantic AI가 비율을 매핑할 정규 형태가 없기 때문이에요. dimensionsopenai_size를 쓰세요.

dall-e-2dall-e-3은 그 폴스루의 예외예요. OpenAIImageGenerationModel이 둘 모두에 대해 생성 시 UserError를 발생시켜요. 응답 형식·크기 집합·이미지 수·품질 어휘에서 GPT Image 계약과 다르기 때문이에요.

aspect_ratio의 정규 차원 (Canonical Dimensions for aspect_ratio)

aspect_ratio만 제공되면, 이것들이 정규 정확 차원이에요. Pydantic AI는 비율을 담을 필드가 없는 OpenAI의 형태를 고르고, Gemini와 Grok Imagine은 비율과 크기 등급을 네이티브 요청 필드로 받으며, 표는 그 비율에 대해 반환하는 형태를 기록해요. 대시는 모델 패밀리가 그 비율에 대한 정규 형태를 이름 짓지 않음을 뜻해요. OpenAI와 Grok Imagine은 UserError를 발생시키고, Gemini는 여전히 비율을 받아 스스로 답해요. Grok Imagine의 모든 대시는 모델이 아니라 전송 문제예요. xai-sdk가 생성하는 gRPC ImageAspectRatio 열거형에 1:4, 1:8, 4:1, 4:5, 5:4, 8:1, 21:9에 대한 멤버가 없어 요청이 그것들을 담을 수 없기 때문이에요.

비율 GPT Image 1.x GPT Image 2 Gemini 2.5 Flash Gemini 3 Pro Gemini 3.1 Flash / Flash Lite Grok Imagine
1:1 1024×1024 1024×1024 1024×1024 1024×1024 1024×1024 1024×1024
1:2 -- 704×1408 -- -- -- 704×1408
1:4 -- -- -- -- 512×2064 --
1:8 -- -- -- -- 352×2928 --
2:1 -- 1408×704 -- -- -- 1408×704
2:3 1024×1536 832×1248 832×1248 848×1264 848×1264 832×1248
3:2 1536×1024 1248×832 1248×832 1264×848 1264×848 1248×832
3:4 -- 864×1152 864×1184 896×1200 896×1200 864×1152
4:1 -- -- -- -- 2064×512 --
4:3 -- 1152×864 1184×864 1200×896 1200×896 1152×864
4:5 -- 896×1120 896×1152 928×1152 928×1152 --
5:4 -- 1120×896 1152×896 1152×928 1152×928 --
8:1 -- -- -- -- 2928×352 --
9:16 -- 720×1280 768×1344 768×1376 768×1376 720×1280
9:19.5 -- 672×1456 -- -- -- 576×1248
9:20 -- 720×1600 -- -- -- 576×1280
16:9 -- 1280×720 1344×768 1376×768 1376×768 1280×720
19.5:9 -- 1456×672 -- -- -- 1248×576
20:9 -- 1600×720 -- -- -- 1280×576
21:9 -- 1568×672 1536×672 1584×672 1584×672 --

지원되는 정확 dimensions (Supported Exact dimensions)

dimensions는 선택한 모델이 문서화했거나 정확히 생성함이 검증된 경우 비정규 지오메트리도 받아요:

  • GPT Image 1.x (gpt-image-1, gpt-image-1-mini, gpt-image-1.5): 1024×1024, 1024×1536, 1536×1024
  • GPT Image 2: 양변이 16의 배수이고, 가장 긴 변이 최대 3840, 종횡비가 3:1을 넘지 않고, 총 면적이 655,360~8,294,400 픽셀인 임의의 양수 차원
  • 그 외 OpenAI 모델(DALL·E 제외): OpenAI가 받아들이거나 거부하도록 size로 전달되는 임의의 양수 차원
  • Gemini 2.5 Flash Image: 위 정규 열의 10개 차원. 이 모델은 별도 해상도 등급이 없음
  • Gemini 3.1 Flash Lite Image: 위 열의 14개 1K 차원. 이 모델은 다른 등급을 서빙하지 않음
  • Gemini 3 Pro Image: 위 10개 1K 차원 + 양변을 2·4배 한 2K·4K 변형
  • Gemini 3.1 Flash Image: 위 10개 표준 1K 차원, 양변을 2·4배 한 2K·4K 변형, 양변을 절반으로 한 512 변형 + 등급이 균일하게 조정되지 않는 아래 표의 다섯 행
  • Grok Imagine (grok-imagine-image, grok-imagine-image-quality, 그리고 그들로 해석되는 날짜·-latest·-pro 이름): 아래 표의 검증된 1k·2k 차원

이 Gemini 3.1 행들은 라이브 API에 대해 검증된 것인데, 네 개의 확장 비율에 대해 Google의 공개 표와 다른 형태를 반환해요. Flash Lite는 1K 열만 서빙합니다:

비율 512 1K 2K 4K
1:4 256×1024 512×2064 1024×4128 2048×8256
1:8 176×1456 352×2928 704×5856 1408×11712
4:1 1024×256 2064×512 4128×1024 8256×2048
8:1 1456×176 2928×352 5856×704 11712×1408
21:9 784×336 1584×672 3168×1344 6336×2688

xAI는 비율과 해상도 등급을 문서화하지만 그들의 완전한 정확 픽셀 매핑은 문서화하지 않아요. 이 차원들은 grok-imagine-image, grok-imagine-image-quality, 그리고 그들로 해석되는 날짜·-latest·-pro 이름에 대해 검증된 것이에요. grok-imagine-image-2.0은 아무도 탐색하지 않은 별도 모델이라, dimensions는 거기서 UserError를 발생해요. xAI가 스스로 검증하는 aspect_ratioxai_-프리픽스 설정을 쓰세요:

비율 1k 2k
1:1 1024×1024 2048×2048
1:2 704×1408 1456×2912
2:1 1408×704 2912×1456
2:3 832×1248 1664×2496
3:2 1248×832 2496×1664
3:4 864×1152 1776×2368
4:3 1152×864 2368×1776
9:16 720×1280 1584×2816
16:9 1280×720 2816×1584
9:19.5 576×1248 1344×2912
19.5:9 1248×576 2912×1344
9:20 576×1280 1440×3200
20:9 1280×576 3200×1440

프로바이더 한도와 새로 출시된 모델은 현재 OpenAI, Gemini, xAI 문서를 참고하세요.

프로바이더별 설정 (Provider-Specific Settings)

이식 가능하지 않은 옵션이 필요하면 프로바이더 설정 타입을 사용하세요:

이 타입들은 ImageGenerationSettings를 확장해요. 프로바이더 프리픽스 필드는 해당 프로바이더 SDK에서 타입을 쓸 수 있을 때 공개 타입을 사용합니다. 프로바이더별 설정과 한도는 OpenAI, Google, xAI 페이지를 참고하세요.

이미지 수·출력 형식·품질·배경·모더레이션·입력 충실도·압축·프로바이더 해상도는 이식 가능한 설정이 아니므로, OpenAI와 xAI는 그것들을 프리픽스 필드로 노출해요. Google은 예외예요. Gemini 요청이 모든 이미지 옵션을 하나의 네이티브 객체에 담으므로, GoogleImageGenerationSettingsgoogle_image_config만 추가합니다.

하나 이상의 이미지를 요청하는 것이 프리픽스 설정을 가장 많이 찾는 용도예요. OpenAI에서 openai_n, xAI에서 xai_n. 각 프로바이더가 자체 상한을 검증하고 초과 요청을 ModelHTTPError로 보고합니다:

from pydantic_ai import ImageGenerator
from pydantic_ai.images.openai import OpenAIImageGenerationSettings
from pydantic_ai.images.xai import XaiImageGenerationSettings

openai_generator = ImageGenerator('openai:gpt-image-2', settings=OpenAIImageGenerationSettings(openai_n=3))
xai_generator = ImageGenerator('xai:grok-imagine-image', settings=XaiImageGenerationSettings(xai_n=3))

Gemini는 요청당 이미지 하나를 반환하므로 Google 등가물은 없어요.

결과와 사용량 (Results and Usage)

ImageGenerationResult는 정규화된 GeneratedImage 객체, 요청 사용량, 모델·프로바이더 정체성, 그리고 프로바이더별 응답 세부사항을 담아요. 이미지 바이트는 항상 result.images[n].content를 통해 BinaryImage로 사용 가능합니다.

결과는 항상 이미지를 하나 이상 담으므로, result.image가 첫 번째 이미지의 BinaryImage를 직접 반환해요. 하나 이상의 이미지를 요청했거나 revised_prompt 같은 이미지별 메타데이터가 필요하면 result.images를 사용하세요.

from pydantic_ai import ImageGenerator

generator = ImageGenerator('openai:gpt-image-2')


async def main():
    result = await generator.generate('A watercolor map of a floating city.')

    print(result.image.media_type)
    #> image/png
    print(len(result.images))
    #> 1
    print(result.images[0].output_format)
    #> png
    print(result.usage.input_tokens)
    #> 8

(이 예제는 완전해서 "그대로" 실행할 수 있어요. main을 실행하려면 asyncio.run(main())을 추가하면 됩니다.)

OpenAI의 provider_details는 API가 되돌려주는 size, quality, background 값을 담아요. 그것들은 반환된 바이트의 측정값이 아니라 요청 파라미터예요. 그래서 GeneratedImage의 유일한 지오메트리 관련 필드는 바이트에서 파생된 output_format이에요.

xAI의 provider_details는 xAI가 보고한 cost_usd를 담을 수 있어요. 이것은 이식 가능한 비용 계산이 아니라 프로바이더 메타데이터이며, cost()와 분리되어 유지돼요. xai_n이 1보다 크면 cost_usd는 이미지 하나가 아니라 배치 전체의 비용이에요. xAI는 배치 전체 사용 레코드 하나를 담은 단일 응답으로 배치에 답하기 때문이에요.

이미지 가격 책정

ImageGenerationResult.cost()는 GPT Image와 Gemini 이미지 패밀리처럼 토큰당 가격이 매겨진 모델을 다뤄요. Grok Imagine 패밀리는 LookupError를 발생시켜요. genai-prices에 항목이 없고, 가격을 매길 생성된 이미지를 세는 단위도 없기 때문이에요. 어느 쪽이든 사용량 세부사항과 프로바이더 보고 메타데이터는 결과에 보존됩니다.

오류 처리 (Error Handling)

이미지 생성은 Pydantic AI의 나머지와 같은 예외를 발생시켜요:

  • ContentFilterError — 프로바이더가 콘텐츠 모더레이션으로 요청이나 출력을 차단할 때. OpenAI는 moderation_blocked 응답에 대해, Google은 안전·recitation·금지 콘텐츠·Model Armor 차단에 대해, xAI는 배치의 모든 이미지가 플래그될 때 발생
  • UserError — 빈 프롬프트, 선택한 프로바이더가 받지 않는 참조 이미지 타입, 또는 선택한 모델이 정확히 만들 수 없는 dimensions처럼 요청을 만들 수 없을 때
  • ModelHTTPError — 그 외 4xx·5xx 프로바이더 응답, 그리고 ModelAPIError는 프로바이더에 닿을 수 없을 때. xAI의 gRPC 상태 코드는 이 두 예외에 매핑돼요.

차단이 빈 결과가 아니라 예외로 보고되므로, 거부된 프롬프트를 명시적으로 재시도할 수 있어요:

from pydantic_ai import ImageGenerator
from pydantic_ai.exceptions import ContentFilterError

generator = ImageGenerator('openai:gpt-image-2')


async def main():
    try:
        result = await generator.generate('A watercolor map of a floating city.')
    except ContentFilterError:
        result = await generator.generate('A watercolor map of a quiet harbor.')
    print(result.image.media_type)
    #> image/png

(이 예제는 완전해서 "그대로" 실행할 수 있어요. main을 실행하려면 asyncio.run(main())을 추가하면 됩니다.)

xAI는 올-오어-낫싱 규칙의 예외예요. 조용히 모더레이션하므로, 부분적으로 차단된 배치는 오류를 발생시키는 대신 깨끗한 이미지를 반환하고 차단된 위치를 보고해요. xAI 이미지 생성 노트 참고.

이미지 생성은 느려요. 복잡한 프롬프트는 수 분이 걸릴 수 있고, 프런트 프록시가 60~180초에 연결을 끊는 경우가 많으므로, 클라이언트와 프록시 타임아웃을 최악의 경우보다 위로 잡으세요.

계측 (Instrumentation)

하나의 생성기 또는 모든 생성기에 OpenTelemetry 계측을 활성화하세요:

import logfire

from pydantic_ai import ImageGenerator

logfire.configure()

generator = ImageGenerator('openai:gpt-image-2', instrument=True)

# Or instrument all image generators globally
ImageGenerator.instrument_all()

Pydantic AI 이미지 생성 스팬은 모델 정체성, 사용량, 이미지 수, 비바이너리 출력 메타데이터를 포함해요. 참조 이미지 콘텐츠, 생성된 바이트, URL, 프로바이더 파일 ID는 포함하지 않아요. 프로바이더 SDK는 자체 독립 스팬을 방출할 수 있고 별도로 구성해야 합니다. extra_headersextra_body 요청 탈출구도 코어 모델 계측과 마찬가지로 제외돼요.

각 호출은 image_generation {model}이라는 이름의 스팬을 열고 gen_ai.operation.name='image_generation'gen_ai.output.type='image'를 담아요. image_generation은 커스텀 연산 이름이에요. OpenTelemetry GenAI 규약이 이미지 생성에 대한 값을 열거하지 않고, image는 그 표준 출력 타입 중 하나이기 때문이에요.

Pydantic AI에서 Logfire를 쓰는 자세한 내용은 디버깅·모니터링 가이드를 참고하세요.

테스팅 (Testing)

API 호출 없이 결정적 테스트를 하려면 TestImageGenerationModel을 사용하세요:

from pydantic_ai import ImageGenerator
from pydantic_ai.images import ImageGenerationSettings, TestImageGenerationModel


async def test_image_workflow():
    generator = ImageGenerator('openai:gpt-image-2')
    test_model = TestImageGenerationModel()

    with generator.override(model=test_model):
        result = await generator.generate(
            'A test image',
            settings=ImageGenerationSettings(dimensions=(1024, 1024)),
        )

        # TestImageGenerationModel returns a single 1x1 PNG
        assert len(result.images) == 1

        # Check what settings were used
        assert test_model.last_settings == {'dimensions': (1024, 1024)}

ALLOW_MODEL_REQUESTSFalse로 설정하면 이미지 생성 요청도 차단돼요. 오버라이드하지 않은 생성기는 조용히 프로바이더를 호출하는 대신 오류를 던져요. TestImageGenerationModel은 프로바이더에 닿지 않으므로 영향받지 않아요.

커스텀 이미지 생성 모델 구축 (Building Custom Image Generation Models)

Pydantic AI가 제공하지 않는 이미지 프로바이더를 통합하려면 ImageGenerationModel을 서브클래스하세요:

from collections.abc import Sequence

from pydantic_ai import BinaryImage
from pydantic_ai.images import (
    GeneratedImage,
    ImageGenerationInput,
    ImageGenerationModel,
    ImageGenerationResult,
    ImageGenerationSettings,
)


class MyCustomImageGenerationModel(ImageGenerationModel):
    @property
    def model_name(self) -> str:
        return 'my-custom-model'

    @property
    def system(self) -> str:
        return 'my-provider'

    async def generate(
        self,
        prompt: str,
        *,
        images: Sequence[ImageGenerationInput] | None = None,
        settings: ImageGenerationSettings | None = None,
    ) -> ImageGenerationResult:
        prompt, images, settings = self.prepare_generate(prompt, images=images, settings=settings)

        # Call your image generation API here
        data = b'...'  # Placeholder

        return ImageGenerationResult(
            images=[GeneratedImage(content=BinaryImage(data=data, media_type='image/png'))],
            prompt=prompt,
            model_name=self.model_name,
            provider_name=self.system,
        )

prepare_generate()는 프롬프트와 참조 입력을 검증하고 모델 자신의 기본 설정을 전달된 것 아래로 병합해요. 서브클래스가 내장 어댑터와 같은 이식 가능한 동작을 얻도록요. 이미지를 하나 이상 반환하세요. generate()가 비어 있지 않은 결과를 약속하고, result.image가 그에 의존합니다.

캐싱이나 로깅 같은 커스텀 동작을 추가하려고 기존 모델을 래핑하려면 WrapperImageGenerationModel을 사용하세요.

에이전트와 함께 이미지 생성 사용하기 (Using Image Generation with an Agent)

직접 API와 에이전트 이미지 생성은 다른 사용 사례를 제공해요:

API 사용 시점
ImageGenerator 애플리케이션이 명시적으로 이미지를 생성·편집하거나, 여러 출력이 필요하거나, 참조 이미지를 제공할 때
ImageGeneration 에이전트가 이미지를 생성할 시점을 결정해야 하고, 가능하면 네이티브 실행, 아니면 직접 이미지 모델 폴백을 쓸 때
ImageGenerationTool 대화 모델 프로바이더의 네이티브 이미지 생성 도구를 직접 제어해야 할 때

프로바이더 적응형 에이전트 사용은 ImageGeneration capability를 참고하세요.

더 알아보기 (Learn more)