ㅇㅅㅇ

Gemini API 모델 자동 갱신 구현 본문

챌린지 모음/타로*MBTI 운세상담 개발

Gemini API 모델 자동 갱신 구현

소 아 2025. 11. 9. 19:21

지난 오류 해결 과정에서, 사이드 프로젝트에서 사용하던 gemini-1.5-flash 모델이 지원 종료되면서 500 서버 에러를 겪었습니다.
급한 불을 끄기 위해 모델명을 gemini-2.0-flash로 수정해 임시 조치를 했지만, 이 방식은 신규 모델 출시나 구 모델 지원 중단 시 또다시 에러를 유발할 수 있는 ‘코드 속 시한폭탄’과 같다는 생각이 들었습니다.
그래서 이번에는 같은 문제가 반복되지 않도록, 보다 근본적인 해결책을 찾기로 했습니다.

오류 복구 과정을 블로그 챌린지 회고글로 정리해 올렸는데, 그 글을 본 한 분이 감사하게도 조언을 주셨습니다.
그 조언은 바로 Google API에서 제공하는 https://generativelanguage.googleapis.com/v1/models 엔드포인트를 활용하라는 것이었습니다.
즉, 모델명을 코드에 하드코딩하는 대신, 지원 가능한 모델 목록을 API로 직접 조회하여 최신 모델을 자동으로 선택하면, 향후 모델 변경으로 인한 장애를 예방할 수 있다는 아이디어였습니다.

이번 회고에서는 그 조언을 실제 코드로 구현하며, ‘하드코딩 없이 항상 최신 모델을 사용하는 구조’를 완성하기까지의 과정을 정리해봤습니다.


엔드포인트(Endpoint)란?

엔드포인트는 API 서버에서 특정 기능이나 데이터를 제공하기 위한 접속 주소를 의미합니다. 클라이언트가 서버에 요청을 보낼 때 실제로 접근하는 "출입구" 같은 개념입니다.
/v1/models 엔드포인트를 호출하면 Google Generative AI에서 사용 가능한 모델 목록(JSON 형태)을 받을 수 있습니다.


구현 과정

1. 모델 목록에서 최신 Flash 모델 선택

const API_KEY = process.env.GEMINI_API_KEY;
const genAI = API_KEY ? new GoogleGenerativeAI(API_KEY) : null;

async function getLatestModel(
  pattern = /gemini-\d+\.\d+-flash/
): Promise<string> {
  if (!API_KEY) throw new Error("GEMINI API 키가 설정되어 있지 않습니다.");

  const res = await fetch(
    `https://generativelanguage.googleapis.com/v1/models?key=${encodeURIComponent(API_KEY)}`
  );
  if (!res.ok) throw new Error(`모델 목록 응답 오류(${res.status})`);

  const data = await res.json();
  const candidates = (data.models as ModelInfo[])
    .map((m) => m.name.replace("models/", ""))
    .filter((name) => pattern.test(name))
    .sort()
    .reverse();

  if (!candidates.length) throw new Error("조건에 맞는 모델 없음");
  return candidates[0];
}
  • Google의 models.list 엔드포인트를 직접 호출해 현재 제공 중인 Flash 계열 모델 중 최신 버전을 선택했습니다.
  • 응답이 실패하거나 조건에 맞는 모델이 없을 경우 에러를 명시적으로 던지고, 로그로 남겨 장애 원인을 빠르게 파악할 수 있도록 했습니다.

2. API 핸들러에 적용

if (!genAI) {
  return res.status(500).json({ error: "필수 환경변수가 설정되지 않았습니다." });
}

try {
  const latestModel = await getLatestModel();
  const model = genAI.getGenerativeModel({ model: latestModel });
  const result = await model.generateContent(prompt);
  const text = await result.response.text();
  res.status(200).json({ output: text });
} catch (error) {
  console.error("Gemini API 오류:", error);
  res.status(500).json({ error: "AI 응답 생성 중 오류가 발생했습니다." });
}
  • getLatestModel()로 최신 모델명을 받아와 SDK에 주입해 사용했습니다.
  • 오류 발생 시에는 콘솔에 상세 로그를 남기고, 클라이언트에는 단순화된 메시지만 전달했습니다.

정리 및 회고

  • 더 이상 모델명을 하드코딩하지 않습니다.
  • 지원 중단이 와도 자동으로 최신 모델로 전환됩니다.
  • 회고를 통해 구조를 개선하면서, 같은 문제를 예방할 수 있었습니다.

이번 대응을 통해 “외부 API의 변화는 언제든 일어난다”는 사실을 다시 한번 체감했습니다. 장애 복구에서 한 발 더 나아가, 장애를 예방하는 구조를 갖추게 되어 다음 변화에도 조금은 여유롭게 대응할 수 있을 것 같습니다.