본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 15. 14:00

LLM 비용을 95% 절감한 방법: PHP에서의 Cache + Batch + Cascade 활용

요약

PHP 기반 뉴스 플랫폼에서 LLM 비용을 95% 절감하기 위해 도입한 Cache, Batch, Cascade 아키텍처를 소개합니다. 프론트티어 모델에 대한 무분별한 호출 대신 계층적 구조와 품질 게이트를 활용하여 효율적인 운영 방식을 제안합니다.

핵심 포인트

  • Cache: 작업 유형과 콘텐츠 해시를 기반으로 중복 호출 방지
  • Batch: 비실시간 작업을 모아 처리하여 비용 및 효율 최적화
  • Cascade: 작업 난이도에 따라 저렴한 모델부터 고성능 모델까지 단계적 활용
  • 프롬프트 버전을 캐시 키에 포함하여 프롬프트 변경 시 정확한 결과 보장

LLM 비용을 95% 절감한 방법: PHP에서의 Cache + Batch + Cascade 활용

우리는 Alesta WEB에서 200개 이상의 퍼블리셔가 사용하는 콘텐츠 플랫폼인 뉴스 소프트웨어를 구축합니다. 뉴스룸 워크플로우(헤드라인 제안, 요약, SEO 필드, 태그 추출, 초안 구성)에 언어 모델(Language Models)을 연결하자마자, 예측 가능한 일이 발생했습니다. AI 청구서가 기능 목록보다 더 빠르게 늘어나기 시작한 것입니다.

"AI를 추가한다"는 식의 순진한(Naive) 방식은 매 요청마다 새로운 호출을 수행하는 하나의 비싼 프론티어 모델(Frontier Model)을 얇게 감싸는(Wrapper) 형태입니다. 데모에서는 작동합니다. 하지만 하루에 수천 개의 기사를 처리하는 프로덕션 환경에서는 돈을 태워버리는 느린 방법일 뿐입니다.

이것은 18개월 동안 운영한 끝에 우리가 정착한 아키텍처입니다. 세 가지 계층 — 캐시 (Cache), 배치 (Batch), 캐스케이드 (Cascade) — 그리고 저렴한 계층을 안전하게 신뢰할 수 있게 만드는 품질 게이트(Quality Gates)를 결합했습니다. 그 결과, 편집 품질의 측정 가능한 저하 없이, "캐시 없는 프론티어 모델 전용"이라는 순진한 베이스라인 대비 작업당 비용을 약 95% 절감했습니다.

코드는 PHP입니다. 플랫폼이 PHP이기 때문입니다. 아이디어는 언어에 구애받지 않습니다.

1. 순진한 접근 방식 (그리고 그 비용)

거의 모든 사람이 처음에 배포하는 방식은 다음과 같습니다:

function generateHeadline(string $articleBody): string
{
    $response = $client->chat([
...

이 코드 자체에는 잘못된 것이 없습니다. 문제는 그 주변의 _사용 패턴(Usage Pattern)_입니다:

  • 동일한 통신사 기사가 수십 개의 사이트에 게시되므로, 거의 동일한 헤드라인을 반복해서 생성하게 됩니다.
  • 편집자들이 옵션을 비교하기 위해 세 번 또는 네 번씩 다시 생성합니다.
  • 태그 추출이나 카테고리 정규화와 같이 훨씬 저렴한 모델로도 충분히 수행할 수 있는 작업을 프론티어 모델이 수행하고 있습니다.
  • 작업의 어떤 부분도 긴급하지 않은 상황에서도 모든 호출이 동기식(Synchronous) 및 실시간으로 이루어집니다.

"매번 새로운 프론티어 호출"을 실제 뉴스룸의 볼륨으로 곱하면, 기사당 AI 비용은 CFO가 불편한 질문을 던질 만한 수준에 도달합니다. 아래의 세 가지 계층은 각각 이러한 낭비 요인 중 하나를 해결합니다.

2. Layer 1 — Cache: 무엇을 캐싱할 것인가, 그리고 무엇을 하지 않을 것인가

가장 큰 성과는 가장 지루한 방법에서 나옵니다. 바로 같은 질문을 두 번 하지 않는 것입니다.

뉴스 시스템에서의 LLM 호출 중 상당 부분은 기능적으로 동일합니다. 핵심 통찰은 캐시 키(Cache key)를 원시 요청 객체(Raw request object)가 아니라, 의미 있는 입력값들—작업 유형(Task type), 모델(Model), 프롬프트 템플릿 버전(Prompt template version), 그리고 콘텐츠의 정규화된 해시(Normalized hash)—로부터 도출해야 한다는 점입니다.

function cachedComplete(string $task, string $content, callable $compute): string
{
    $key = sprintf(
...

선택한 캐시 엔진(우리는 Redis를 사용하지만, 데이터베이스 테이블도 가능합니다)보다 더 중요한 두 가지 세부 사항이 있습니다.

키(Key)에 프롬프트 버전을 포함하세요. 프롬프트 템플릿을 변경할 때, 해당 작업에 대해 캐싱된 모든 답변이 미스(Miss)가 되기를 원할 것입니다. 키에 PROMPT_VERSION 상수를 넣으면, 프롬프트 수정이 일주일 동안 추적해야 하는 오래된 출력(Stale-output) 버그가 되는 대신, 깔끔하고 즉각적인 무효화(Invalidation)로 이어집니다.

캐싱하지 말아야 할 것을 파악하세요. 개인화된 것, 실시간 정보, 그리고 두 개의 동일한 입력이 정당하게 서로 다른 출력을 생성해야 하는 경우(예: "새로운 대안을 보여줘" 버튼)는 반드시 캐시를 우회해야 합니다. 우리는 TTL(Time-to-live)에만 의존하는 대신, 이러한 작업들을 명시적으로 표시합니다.

우리의 워크로드(Workload)에서 캐시 히트율(Cache hit rate)은 약 60~70%를 유지하는데, 이는 주로 뉴스 제휴 콘텐츠가 여러 사이트에서 반복되기 때문입니다. 이 계층 하나만으로도 지출의 절반 이상을 제거할 수 있습니다.

3. Layer 2 — Batch APIs: 비용을 위해 지연 시간(Latency)을 양보하라

뉴스룸에서의 LLM 작업 중 놀라울 정도로 많은 양이 시간에 민감하지 않습니다. 아카이브의 야간 재태깅(Re-tagging), 전날 기사의 요약 생성, 오래된 콘텐츠의 SEO 설명 백필(Backfilling) 등이 그 예입니다. 이 중 그 어떤 것도 800밀리초(ms) 이내의 답변을 필요로 하지 않습니다.

주요 제공업체들은 비동기(Asynchronously)로 실행되는 배치 엔드포인트(Batch endpoints)를 제공합니다. 요청 파일들을 제출하면 특정 시간 범위(통상 최대 24시간) 내에 결과를 돌려받으며, 비용은 동기식(Synchronous) API의 약 절반 수준입니다.

// 긴급하지 않은 작업들을 하나의 배치 (batch) 제출로 모읍니다
$lines = [];
foreach ($pendingJobs as $job) {
...

이 과정이 강제하는 규율은 매우 건강합니다. 각 작업을 대화형 (interactive) (에디터가 기다리고 있는 상태)인지, 아니면 지연형 (deferred) (오늘 밤 크론 잡 (cron job)이 처리할 수 있는 상태)인지 분류해야 하기 때문입니다. 이러한 감사를 수행한 결과, 예상보다 훨씬 더 많은 작업이 지연 가능한 것으로 나타났습니다. 캐싱 (caching)을 적용한 후 남은 지출의 약 4분의 1이 배치 가격 (batch pricing) 모델로 전환되었으며, 이를 통해 해당 부분에서 약 50%의 고정 할인을 받았습니다.

주의할 점이 있습니다. 배치 가격은 제공업체(provider)마다 다르며, 완료 시간 범위(completion window)와 실패 동작(failure behavior)도 제각각입니다. 제공업체를 쉽게 교체할 수 있도록 인터페이스 (interface) 뒤에 배치 레이어 (batch layer)를 구축하십시오. 또한 부분적 실패 (partial failures)를 항상 처리해야 합니다. 예를 들어, 5,000개의 요청이 포함된 배치는 가끔 4,997개만 반환될 수 있습니다.

4. 레이어 3 — 캐스케이드 라우팅 (Cascade Routing): 작업에 맞는 모델 매칭

마지막 레이어는 사람들이 가장 저항하는 부분인데, 이는 마치 편법을 쓰는 것처럼 느껴지기 때문입니다. 하지만 그렇지 않습니다. 이는 유치원 수준의 작업에 최첨단 (frontier) 모델의 가격을 지불하기를 거부하는 것입니다.

모든 작업에 가장 똑똑한 모델이 필요하지는 않습니다. 이야기에서 태그를 추출하거나, 카테고리를 매핑하거나, 공백을 정리하거나, 감정을 분류하는 작업 등은 작고 저렴한 모델들이 완벽하게 처리합니다. 비싼 모델은 진정으로 어려운 생성 작업, 즉 미묘한 요약, 편집 리라이팅 (editorial rewriting), 혹은 실수가 독자에게 바로 눈에 띄는 모든 작업에 위해 아껴두십시오.

const TASK_TIER = [
    'tag_extraction'   => 'cheap',
    'category_map'     => 'cheap',
...

우리는 하나의 인터페이스 뒤에서 6개의 제공업체를 운영합니다 (편집 팀은 어떤 업체가 응답했는지 전혀 알 수 없습니다). 이는 캐스케이드 라우팅 (cascade routing)이 장애 조치 (failover)를 수행할 수 있음을 의미합니다. 즉, 저렴한 모델의 출력이 품질 게이트 (quality gate)를 통과하지 못하면, 해당 작업은 자동으로 한 단계 높은 티어 (tier)에서 다시 실행됩니다. 이를 통해 잘 처리되는 90% 이상의 사례에서는 저렴한 티어의 비용을 유지하면서, 그렇지 못한 사례에서는 비싼 티어의 안정성을 확보할 수 있습니다.

캐스케이드 라우팅은 여러분을 "큰 절약"의 단계에서 "대다수의 쉬운 작업은 거의 무료"인 단계로 끌어올려 주는 핵심 요소입니다.

5. 품질 게이트 (Quality Gates): 저렴한 모델의 신뢰성 유지

Cascade routing(계층형 라우팅)은 저렴한 모델이 틀렸을 때를 _감지(detect)_할 수 있을 때만 작동합니다. 그렇지 않으면 돈을 주고 쓰레기를 사는 꼴이 됩니다. 품질 게이트(Quality Gates)는 출력이 수락되기 전에 실행되는 저렴하고 결정론적인(deterministic) 검사입니다:

function passesGate(string $task, string $output): bool
{
    return match ($task) {
...

이 중 그 어떤 것도 LLM을 호출하지 않습니다. 이들은 문자열 길이, 형식 유효성, 구조 검사 등 비용이 전혀 들지 않으면서도 저렴한 모델에서 발생하는 가장 흔한 실패 사례(중단(truncation), 잘못된 형식, 빈 출력)를 잡아내는 방식입니다. 게이트가 실패하면, Cascade(계층형 구조)는 해당 작업을 한 단계 상위 티어로 다시 실행하고 이를 로그에 기록합니다. 특정 작업이 게이트를 너무 자주 통과하지 못한다면, 이는 해당 작업을 영구적으로 상위 티어로 이동시켜야 한다는 신호입니다.

이 부분이 전체 아키텍처를 신뢰할 수 있게 만드는 핵심 요소입니다. 게이트가 없다면 "더 저렴한 모델을 사용하라"는 말은 도박에 불과합니다. 하지만 게이트가 있다면, 이는 자동화된 안전망을 갖춘 측정 가능한 결정이 됩니다.

6. 실제로 확인하게 되는 비용 대시보드

측정할 수 없는 것은 최적화할 수 없습니다. 우리는 모든 LLM 호출을 네 가지 필드(작업(task), 티어(tier), 캐시 히트(cache hit) 여부, 토큰 수)와 함께 기록합니다. 이는 중요한 질문들에 답하기에 충분합니다:

  • 어떤 작업이 가장 많은 비용을 발생시키는가? (보통 여기서 놀라운 점은 "저렴한" 작업이 백만 번 호출되고 있다는 사실입니다.)
  • 작업별 실제 캐시 히트율(cache hit rate)은 얼마인가?
  • Cascade(계층형 구조)가 얼마나 자주 상위 단계로 에스컬레이션(escalating)되는가 — 그리고 어떤 작업들이 그러한가?

작업별 경제성을 주 단위로 정리하면, 비용 관리는 공포("청구서가 두 배로 늘었어!")에서 일상적인 업무("태그 추출 에스컬레이션 비율이 상승했으니, 프롬프트가 변질되었는지 확인하고 템플릿을 수정하자")로 변합니다. 대시보드는 의도적으로 지루하게 설계되었습니다. 지루하다는 것은 통제되고 있다는 뜻입니다.

7. 18개월 후의 수치

단순한 기준점(하나의 최첨단 모델(frontier model)을 사용하며, 모든 호출을 매번 새로 동기식으로 처리하는 방식)과 비교했을 때, 각 계층의 효과는 복리로 작용합니다:

  • **Cache(캐시)**가 호출의 약 60~70%를 즉시 제거합니다.
  • **Batch(배치)**가 남은 호출 중 의미 있는 부분의 약 50%를 줄여줍니다.
  • **Cascade(계층형 구조)**가 나머지 작업의 대다수를 최첨단 모델 가격의 아주 일부만 비용으로 지불하는 모델로 라우팅합니다.

이것들을 중첩하면 동일한 워크로드에 대해 작업당 비용이 약 95% 절감됩니다. 또한, 캐시 히트(Cache hit)는 즉각적이고 저렴한 모델은 빠르기 때문에, AI 기능의 중앙값(median) 지연 시간(latency)은 실제로 개선되었습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0