path
Jin's Lab
코드로 실험하고 기록하는 개발 일지 · J.Lab

Jin's Lab

코드로 실험하고 기록하는 개발 일지. 커리어와 삶의 방향을 탐색하며 기록하는 공간입니다

API-Deprecation

LLM API 모델 단종 대응, 404 에러 안 무너지는 코드 구조 만들기

J.Lab ·
목차

    매일 아침 일과를 시작하기 전, 자동으로 세상의 트렌드를 요약해 주는 나만의 IssueLog 자동발행 시스템이 있다. 몇 달 동안 아무 문제 없이 조용히 제 역할을 하던 이 녀석이 최근 들어 이상한 조짐을 보이기 시작했다. 매일 새벽 4시에 발송되던 자동 발행이 실패했다는 알림이 오더니, 정작 오전 7시나 10시에 수동으로 트리거를 실행하면 또 멀쩡하게 성공하는 것이었다. 일정한 패턴도 없이 간헐적으로 발생하는 에러 때문에 아침마다 머리를 싸매야 했다.

    로그를 확인해 보니 원인은 싱겁게도 외부 LLM API 호출 과정에서 발생한 404 에러였다. 구체적으로는 잘 쓰고 있던 models/gemini-2.5-flash 모델을 호출할 때 서버를 찾을 수 없다는 응답이 돌아오고 있었다. 왜 어떤 시간대에는 성공하고 어떤 시간대에는 실패하는지 처음에는 도무지 이해할 수 없었다. 이 의문을 풀기 위해 공식 가이드를 뒤져보며 본격적인 원인 분석에 들어갔다.

    서버 장애와 404 에러를 시각화한 아이소메트릭 일러스트

    새벽 4시의 경고음, 간헐적 404 에러의 원인

    원인을 파헤쳐 보니 바로 Gemini deprecation, 즉 모델 단종 절차 때문이었다. 구글은 구버전 모델을 한 번에 중단하지 않고 단계적으로 서비스 요청을 차단하는 유예기간 롤아웃 방식을 적용하고 있었다. 올해 10월 중순 완전히 종료되는 일정을 앞두고, 특정 시간대나 일부 요청에 대해 고의로 404 에러를 반환하며 개발자들에게 경고를 보내고 있었던 것이다. 새벽 4시의 실패와 아침 시간대의 성공은 결국 구글이 보낸 점진적 단종 신호였다.

    문제를 인지했으니 당장 해결해야 했다. 하지만 내 시스템은 구글 앱스 스크립트(GAS) 기반으로 총 4개의 독립적인 프로젝트에 API 호출 로직이 흩어져 있었다. 소스코드를 열어보는 순간 눈앞이 아찔해졌다. 부끄럽게도 모든 코드 안에 models/gemini-2.5-flash라는 문자열이 고스란히 하드코딩되어 박혀 있었기 때문이다. API 주소를 하나씩 찾아다니며 수정해야 하는 비효율적인 상황을 마주하게 되었다.

    하드코딩된 코드를 상수로 리팩토링하는 과정을 나타낸 일러스트

    하드코딩된 모델명을 상수로 일괄 분리하기

    더 이상 미룰 수 없다는 생각에 즉시 리팩토링에 착수했다. 가장 먼저 수행한 작업은 모델명 상수 관리 구조를 도입하는 것이었다. 각 스크립트 상단에 GEMINI_MODEL이라는 전역 상수를 정의하고, 모든 API 호출부에서 이 상수를 참조하도록 코드를 변경했다. 이렇게 하면 앞으로 또 다른 LLM API 모델 단종 대응 상황이 발생하더라도 상수의 값 하나만 바꾸면 되기 때문에 유지보수가 극적으로 쉬워진다.

    상수 분리를 마치고 기존의 단종 대상 모델 대신 최신 버전인 gemini-3.5-flash로 모델명을 이전했다. 다행히 이번 마이그레이션은 비용 부담이 없었다. Gemini 3.5-flash 역시 기존 무료 티어인 분당 10회(10 RPM), 하루 1,500회(1500 RPD) 제한 조건이 그대로 유지되었기 때문이다. Pro 모델과 달리 Flash 모델은 여전히 무료로 쓸 수 있어서 결제 카드를 등록하거나 유료 전환을 거치지 않고도 깔끔하게 이전을 완료했다. 준비된 4개의 GAS 프로젝트 모두에 이 상수화 작업과 모델 업그레이드를 적용해 주었다.

    API 에러 발생 시 재시도 흐름과 404 예외 처리를 묘사한 흐름도 일러스트

    API 404 재시도에 대한 고찰과 교훈

    이번 삽질을 통해 시스템 안정성에 대한 중요한 교훈을 얻었다. 보통 외부 API가 일시적으로 실패할 것에 대비해 API 404 재시도 로직을 설계해야 하는지 고민할 때가 있다. 네트워크 불안정이나 일시적인 서버 과부하로 인한 5xx 에러, 혹은 429 Rate Limit 에러는 백오프 알고리즘을 적용한 재시도가 매우 유용하다. 하지만 이번처럼 모델 단종으로 인한 404 에러는 자원이 완전히 사라졌음을 의미하므로 재시도를 해봤자 리소스만 낭비할 뿐이다.

    따라서 에러 핸들링 코드를 작성할 때 404 응답은 절대 재시도 대상이 아님을 다시 한번 명확히 정의하고 코드를 가다듬었다. 또한 서비스의 핵심 동력인 외부 API의 모델명은 절대로 코드 깊숙한 곳에 직접 작성해서는 안 된다는 기본을 뼈저리게 느꼈다. 이번 대대적인 상수화 작업 덕분에 앞으로 구글이 또 어떤 모델을 갑작스럽게 단종시키더라도 몇 초 만에 의연하게 대처할 수 있는 단단한 코드 구조를 갖추게 되었다.

    API-Deprecation Error-Handling Gemini Google-Apps-Script Refactoring
    ← 이전 글
    최근 게시물
    다음 글 →
    이전 게시물
    ≡ 글 목록으로
    소개
    path
    J.Lab

    커리어와 삶의 방향을 탐색하며
    기록하는 공간입니다

    카테고리
    403 Forbidden Error 1 AdSense 1 AdSense Bot Detection 1 AI Automation 1 AI Image Generation 1 ai-automation 2 AI-Prompting 1 AIBlogAutomation 1 AICodeLog 1 AIContentGeneration 1 AIImageGeneration 1 AIWritingErrors 1 API Automation 2 API Retry Design 1 api-automation 1 API-Deprecation 1 api-error 1 api-fallback 1 api-retry-strategy 1 api-troubleshooting 1 APIDebugging 1 APIError 1 APIErrorHandling 1 APIIntegration 1 APITokenRenewal 1 AppsScript 1 appsScriptAutomation 1 AutomatedBlogging 1 automation 1 Automation 2 AutomationTroubleshooting 1 Backoff Algorithm 1 Base64Encoding 1 BatchProcessing 1 blog-automation 1 blog-customization 1 blog-migration 3 Blog-Sorting 1 blog-strategy 1 blog-theme-customization 1 blog-workflow 1 blogautomation 1 BlogAutomation 2 Blogger 4 Blogger API 2 Blogger Automation 1 Blogger SEO 1 blogger-api 3 blogger-automation 1 blogger-error-400 1 blogger-labels 1 blogger-seo 1 blogger-tips 1 Blogger-Tips 1 BloggerAPI 3 BloggerBypath 1 BloggerCustomization 2 BloggerFavicon 1 BloggerTemplate 1 BloggerTemplateEditing 1 BloggerTheme 1 BloggerThemeCustomization 1 BloggerXMLStructure 1 Blogging-Automation 1 BloggingTools 1 BlogQuality 1 BlogSpot 1 BWidgetBIncludable 1 CardClickHandler 1 CDATA 1 clamping-text 1 Code Integration 1 codelog 1 CodeLog 1 codeRefactoring 1 contentsequencing 1 cost-reduction 1 CSSOverlay 1 data-parsing 1 DatabaseDesign 1 DataRecovery 1 DateInjection 1 Debugging 2 dev-journey 1 DeveloperJourney 2 DevJourney 1 display-none-seo 1 dom-manipulation 1 dynamic-menu 1 Error-Handling 1 ErrorHandling 1 Execution Timeout 1 ExecutionLimit 1 exponential-backoff 1 FactChecking 1 FaviconEmbedding 1 Feed-API 1 filesystem 1 Flat Illustration 1 FluxModel 1 FreeAIImage 1 FrontEndDev 1 FrontendTips 1 GAS Blogger API 1 gas-automation 1 gas-optimization 1 gas-trigger 1 GASTimeout 1 gasTriggerManagement 1 GCP Project Linkage 1 Gemini 1 Gemini API 1 gemini-api 1 GeminiAPI 1 GeminiPrompt 1 GeminiPromptEngineering 1 GmailRestrictions 1 Google Apps Script 7 Google Discover 1 google-apps-script 3 Google-Apps-Script 1 google-blogger 1 googleAppsScript 1 GoogleAppsScript 6 googlesapps-script 1 hero-image 1 HTMLWidgetBlogger 1 http-429 1 HuggingFace 1 HuggingFaceAPI 1 ico-generator 1 Image Optimization 1 image-automation 1 image-optimization 1 In-App Browser 1 invalid-argument 1 javascript 3 JavaScript 2 javascript-automation 1 javascript-toc 1 jlab-codelog 1 JLabDevLog 1 json-schema 1 label-length-limit 1 linux 1 meta-description 1 Negative Prompt 1 notion-api 1 notion-database 1 notion-gas-integration 1 NotionAPI 1 NotionAutomation 1 notionintegration 1 NotionIntegration 1 OAuth Scope 1 pagination 1 payload-validation 1 permalink-management 1 PersonaDesign 1 pil-image-processing 1 Pinterest 1 Pollinations 1 Pollinations Flux 1 pollinations-api 1 PollinationsAI 1 PositionAbsolute 1 Prompt Design 1 Prompt Engineering 1 prompt-engineering 1 Prompt-Engineering 1 PromptEngineering 1 publishorder 1 python-favicon 1 queue-stuck 1 RandomDelay 1 rate-limiting 1 Refactoring 1 rfc3339 2 Robots Meta Tag 1 RSS Feed 1 scriptNotFound 1 Search Engine Optimization 2 Search-Engine-Optimization 1 SEO Tips 1 seo-optimization 4 SEO-Optimization 1 seriesmanagement 1 SidebarLinks 1 SNSMarketing 1 SVGIcon 1 table-of-contents 1 TechJournal 1 Template 1 ThreadsAPI 1 tistory-migration 1 transparent-favicon 1 triggerCleanup 1 Troubleshooting 1 unzip 1 URL Slug 1 vanilla-js 1 Web Development 1 Web Publishing 2 Web Security 1 web-development 1 Web-Development 1 web-development-tips 1 web-performance 1 web-scraping 1 WebAccessibility 1 WebDevelopment 3 WebDevelopmentTips 1 WebDevJourney 1 windows 1 WorkflowAutomation 1 XMLParser 1 XMLSpecialCharacters 1 XMLTheme 1 zip 1
    인기 글
    GAS에서 Blogger API 403 오류 완전 정복 — appsscript.json 스코프와 GCP 프로젝트 연결
    GAS에서 Blogger API 403 오류 완전 정복 — appsscript.json 스코프와 GCP 프로젝트 연결
    Google Apps Script 실행 시간 6분 제한 — Gmail 계정 함정과 랜덤 딜레이 설계
    Google Apps Script 실행 시간 6분 제한 — Gmail 계정 함정과 랜덤 딜레이 설계
    Blogger 테마 XML 직접 뜯어봤더니 알게 된 것들
    Blogger 테마 XML 직접 뜯어봤더니 알게 된 것들
    다른 블로그
    IssueLog
    IssueLog
    issuelog.jinbytes.com
    KidStory
    KidStory
    kidstory.jinbytes.com
    IT Story
    IT Story
    jinbytes.com
    © Jin's Lab · J.Lab · All Rights Reserved
    jinbytes.com · Powered by Blogger