블로그 목록
AI

Vercel AI SDK로 이미지 생성하기 — experimental_generateImage 써보기

프로젝트에 썸네일 자동 생성 기능을 붙여야 했다. 사용자가 글을 쓰면 제목을 기반으로 대표 이미지를 하나 만들어주는 식이다. OpenAI SDK를 직접 붙일까 하다가, 이미 챗봇 쪽에서 Vercel AI SDK를 쓰고 있어서 이미지도 같은 SDK로 처리할 수 있는지 찾아봤다.

ai 패키지에 experimental_generateImage라는 함수가 있다. 텍스트 생성의 generateText와 거의 똑같은 모양으로 이미지를 뽑는다. 텍스트 모델과 이미지 모델을 한 SDK에서 같은 패턴으로 다룰 수 있다는 게 제일 편했다.

기본 사용법

먼저 provider 패키지를 설치한다. OpenAI를 쓴다면 @ai-sdk/openai다.

npm install ai @ai-sdk/openai

서버 액션이나 라우트 핸들러에서 이렇게 호출한다.

// app/api/thumbnail/route.ts
import { experimental_generateImage as generateImage } from 'ai';
import { openai } from '@ai-sdk/openai';

export async function POST(req: Request) {
  const { prompt } = await req.json();

  const { image } = await generateImage({
    model: openai.image('gpt-image-1'),
    prompt,
    size: '1024x1024',
  });

  return Response.json({ image: image.base64 });
}

포인트는 openai.image(...)다. 텍스트는 openai(...)인데 이미지는 .image()로 모델을 지정한다. 반환값 image에는 base64uint8Array 두 형태가 다 들어있어서, 화면에 바로 뿌리든 파일로 저장하든 골라 쓰면 된다.

화면에 띄우기

base64를 그대로 <img>src에 data URL로 넣으면 별도 업로드 없이 미리보기가 된다.

'use client';
import { useState } from 'react';

export function ThumbnailMaker() {
  const [src, setSrc] = useState('');

  async function generate() {
    const res = await fetch('/api/thumbnail', {
      method: 'POST',
      body: JSON.stringify({ prompt: '따뜻한 색감의 개발 블로그 썸네일' }),
    });
    const { image } = await res.json();
    setSrc(`data:image/png;base64,${image}`);
  }

  return (
    <div>
      <button onClick={generate}>생성</button>
      {src && <img src={src} alt="생성된 썸네일" width={256} />}
    </div>
  );
}

알아두면 좋은 것

여러 장이 필요하면 n 옵션을 주면 되는데, 모델이 한 번에 한 장만 지원하는 경우 SDK가 알아서 요청을 여러 번 병렬로 나눠 보낸다. 반환은 images 배열로 받는다.

const { images } = await generateImage({
  model: openai.image('gpt-image-1'),
  prompt,
  n: 4,
});

provider만 바꾸면 코드는 거의 그대로다. Google이나 다른 이미지 모델로 갈아탈 때 호출부를 손댈 필요가 거의 없다.


챗봇 붙이던 감각 그대로 이미지 생성까지 처리되니 새로 배울 게 별로 없었다. base64를 data URL로 바로 띄우면 프로토타입은 스토리지 없이도 확인되고, 실제 배포에선 생성된 이미지를 S3나 R2에 올려 URL로 관리하면 된다. 아직 experimental_ 접두사가 붙어 있으니 시그니처가 바뀔 수 있다는 것만 염두에 두면 된다.