Node.js로 LLM API 게이트웨이 구축하기
요약
LLM API 호출을 중앙 집중식으로 관리하여 비용을 추적하고 거버넌스를 강화하는 API 게이트웨이 구축 방법을 소개합니다. Node.js 환경에서 LiteLLM을 활용해 모델 제공자를 유연하게 교체하고 속도 제한 및 라우팅을 제어하는 가이드를 제공합니다.
핵심 포인트
- 중앙 집중식 게이트웨이를 통해 LLM 비용 가시성 및 거버넌스 확보
- 애플리케이션 코드 수정 없이 모델 제공자(OpenAI, Anthropic 등) 교체 가능
- LiteLLM, Portkey, Cloudflare AI Gateway의 특징 비교 및 선택 기준 제시
- 프로젝트 초기 단계에 게이트웨이를 도입하여 기술 부채 방지 권장
LLM 비용이 갑자기 세 배로 뛰었는데 팀원 중 누구도 그 이유를 설명하지 못하고 있나요? 익숙한 상황인가요? 만약 스택 내의 모든 서비스에서 OpenAI나 Anthropic을 직접 호출하고 있다면, 그것은 통합(integration)의 문제가 아니라 거버넌스(governance)의 문제입니다. 바로 이 지점에서 LLM API 게이트웨이가 제 역할을 하게 되며, Node.js로 이를 설정하는 것은 다음번 깜짝 청구서를 디버깅하는 것보다 훨씬 적은 시간이 걸립니다.
게이트웨이 계층이 필요한 이유 (그리고 게이트웨이가 없을 때 발생하는 문제)
게이트웨이가 없을 때 실제로 어떤 일이 발생하는지 살펴보겠습니다. LLM을 호출하는 모든 서비스는 각자의 API 키, 각자의 재시도 로직(retry logic), 각자의 모델 이름을 하드코딩합니다. 그러다 어느 날 비용 문제로 GPT에서 Claude로 전환하고 싶어지면, 6개의 저장소(repo)를 뒤지며 검색(grepping)해야 합니다. 또는 주니어 개발자의 스크립트가 속도 제한(rate limited)이 걸린 엔드포인트에 대해 무한 재시도 루프에 빠져 하룻밤 사이에 비용이 급증할 수도 있습니다. 더 최악인 것은, 어떤 팀이나 기능이 실제로 비용을 발생시키고 있는지에 대한 가시성(visibility)이 전혀 없다는 점입니다.
게이트웨이는 애플리케이션 코드와 모델 제공자(model providers) 사이에 위치합니다. 모든 요청이 하나의 단일 지점(chokepoint)을 통해 흐르므로, 중앙 집중식 라우팅(routing), 중앙 집중식 비용 추적(cost tracking), 중앙 집중식 속도 제한(rate limiting)을 구현할 수 있으며, 애플리케이션 코드를 수정하지 않고도 제공자를 교체할 수 있는 단일 지점을 갖게 됩니다. 기업용 모델 API 지출은 이미 84억 달러를 넘어섰으며 계속 증가하고 있는데, 그 지출의 대부분은 중앙 집중식 제어 없이 이루어지고 있습니다. 이것은 나중에 해결해야 할 규모(scale)의 문제가 아니라, 여러분이 이미 처해 있는 규모의 문제입니다.
아무도 경고해주지 않는 함정: 프로젝트 후반부에 게이트웨이를 추가하는 것은 첫날에 추가하는 것보다 훨씬 고통스럽습니다. 왜냐하면 그때쯤이면 모든 서비스에 각자 맞춤형 호출 방식(bespoke calling convention)이 이미 박혀 있기 때문입니다. 만약 그린필드(greenfield, 신규 프로젝트)라면, 첫 번째 프롬프트 호출 코드를 작성하기 전에 이를 먼저 연결하세요.
LiteLLM vs Portkey vs Cloudflare AI Gateway: 빠른 비교
여기 세 가지 확실한 옵션이 있으며, 상황에 맞지 않는 잘못된 선택을 하는 것은 실수하기 매우 쉽습니다.
| 게이트웨이 (Gateway) | 적합한 대상 | 배포 (Deployment) | 주요 특징 |
|---|---|---|---|
| LiteLLM | 완전한 제어를 원하는 팀, 셀프 호스팅 (self hosted) 선호 | 자체 인프라 (Docker, VM, k8s) | 방대한 제공업체 지원, 즉시 사용 가능한 OpenAI 호환 API |
| ... |
모든 설정값(knob)을 직접 제어하고 싶고 별도의 서비스를 실행하는 것을 개의치 않는 팀이라면 LiteLLM을 선택하세요. 만약 로직을 직접 작성하지 않고도 가드레일(guardrails, PII 탐지, 프롬프트 인젝션 체크, 콘텐츠 모더레이션)을 갖추고 싶다면, 특히 이제 완전히 오픈 소스가 된 Portkey의 사전 구축된 세트는 따라올 자가 없습니다. 만약 트래픽이 이미 Cloudflare를 통해 흐르고 있다면, 새로 구축할 인프라가 없는 Cloudflare의 AI Gateway가 가장 저항이 적은(path of least resistance) 경로입니다.
이번 가이드에서는 LiteLLM을 사용하여 진행하겠습니다. LiteLLM은 내부에서 실제로 어떤 일이 일어나고 있는지 가장 명확하게 보여주며, 이러한 이해는 나중에 Portkey나 Cloudflare를 선택하게 되더라도 그대로 적용될 수 있기 때문입니다.
15분 만에 Node.js 프록시로 LiteLLM 설정하기
LiteLLM은 OpenAI 호환 API를 가진 프록시 서버 (proxy server)로 작동하므로, Node.js 코드는 거의 변경할 필요가 없으며 단순히 베이스 URL (base URL)만 변경하면 됩니다.
# litellm-config.yaml
model_list:
- model_name: gpt-4o
...
# 로컬에서 프록시 실행 (Docker를 사용하면 환경 간 재현성을 유지할 수 있습니다)
docker run -d \
-v $(pwd)/litellm-config.yaml:/app/config.yaml \
...
이제 Node.js 코드는 제공업체에 직접 호출하는 대신 프록시를 호출합니다. 이미 OpenAI SDK를 사용 중이라면, 베이스 URL을 변경하는 한 줄의 수정만으로 충분합니다:
// lib/llm-client.ts
import OpenAI from "openai";
...
이것으로 끝입니다. 애플리케이션 코드는 OpenAI와 직접 통신하는 대신 프록시와 통신하고 있다는 사실을 전혀 알지 못하며, 나중에 제공업체를 교체하는 것은 코드 변경이 아닌 설정 변경만으로 가능합니다.
시맨틱 캐싱 (Semantic caching): 놓치고 있는 비용 절감 기회
제가 초기에 겪었던 시행착오 중 하나를 소개하겠습니다. 만약 여러분의 애플리케이션이 "환불 정책이 어떻게 되나요?", "비밀번호를 어떻게 재설정하나요?"와 같은 흔한 질문에 답변한다면, 여러분은 거의 동일한 답변을 반복해서 생성하기 위해 매번 전체 비용을 지불하고 있는 셈입니다. 시맨틱 캐싱 (Semantic caching)은 정확한 문자열 일치 (exact string match)를 요구하는 대신, 의미적으로 유사한 프롬프트 (prompt)에 대해 이미 답변된 적이 있는지 확인함으로써 이 문제를 해결합니다.
시맨틱 캐싱만으로도 반복적인 워크로드 (workload)의 비용을 3050% 절감할 수 있으며, 캐싱과 결합된 라우팅 전략 (routing strategies)을 사용하면 전체 비용을 4070%까지 절감할 수 있습니다. 몇 가지 최적화 기술을 함께 쌓아 올린다면 프로덕션 워크로드에서 50~80%의 비용 절감을 기대할 수 있습니다. 이것은 단순한 미세 조정이 아니라, 지속 가능한 AI 기능이 될 것인지, 아니면 재무팀에서 계속해서 비용 정당성을 요구하는 기능이 될 것인지를 결정짓는 차이입니다. 상세한 분석이 필요하시다면 제 LLM 추론 비용 최적화 (LLM inference cost optimization) 글에서 이 비용 계산에 대해 더 자세히 다루고 있습니다.
// lib/semantic-cache.ts
import { createClient } from "redis";
import OpenAI from "openai";
...
선형 유사도 검사 (linear similarity check)를 통해 모든 캐시 키를 스캔하는 방식은 소규모 규모에서는 괜찮지만, 캐시된 항목이 수천 개를 넘어가면 벡터 데이터베이스 (vector database) (Pinecone, Qdrant 또는 pgvector)를 사용하십시오. 패턴은 동일하며, 조회 메커니즘만 바뀔 뿐입니다.
프로덕션에서의 서킷 브레이커 (Circuit breakers) 및 폴백 라우팅 (fallback routing)
서비스 제공업체는 다운될 수 있습니다. 속도 제한 (Rate limits)에 걸릴 수도 있습니다. 지연 시간 (Latency) 급증은 최악의 타이밍에 발생하곤 합니다. 만약 여러분의 게이트웨이가 이를 우아하게 처리하지 못한다면, 불안정한 제공업체 하나 때문에 전체 기능이 함께 마비될 수 있습니다.
서킷 브레이커 (Circuit Breaker)는 반복되는 실패를 감시하며, 임계값 (threshold)을 넘어서면 "개방 (opens)" 상태가 되어 일정 냉각 기간 (cooldown period) 동안 실패하는 제공업체로의 요청 전송을 중단하고, 대신 즉시 백업으로 페일오버 (failover) 합니다. 이는 LiteLLM의 폴백 (fallback) 설정이 프록시 레벨에서 처리하는 방식과 정확히 일치하지만, 이 패턴을 이해해 두는 것이 좋습니다. 그래야 이를 논리적으로 추론할 수 있고, 게이트웨이를 거치지 않는 모든 요소에 대해 애플리케이션 레이어 (application layer)에서도 동일한 보호 조치를 추가할 수 있기 때문입니다.
// lib/circuit-breaker.ts
import CircuitBreaker from "opossum";
import { gateway } from "./llm-client";
...
최신 게이트웨이 옵션 중 하나인 Bifrost는 초당 5,000개의 요청이 발생하는 상황에서 요청당 단 11마이크로초 (microseconds)의 오버헤드만을 추가합니다. Python 기반의 게이트웨이들이 대조적으로 수백 마이크로초를 추가하는 것과 비교하면, 순수 프록시 성능을 비교할 때 알아둘 만한 가치가 있습니다. Node 및 Go 기반의 프록시들은 대개 해당 범위의 낮은 쪽(low end)에 위치하는 경향이 있습니다.
미들웨어를 통한 비용 상한선 (Cost caps) 및 사용자별 할당량 (per user quotas)
라우팅 (Routing)과 캐싱 (Caching)은 모델 레이어 (model layer)에서 비용이 폭주하는 것을 막아줍니다. 하지만 단일 사용자, 테넌트 (tenant), 또는 버그가 있는 스크립트가 아무도 알아차리기 전에 월간 예산을 모두 써버리는 것을 방지하기 위한 강력한 상한선 (hard ceiling)도 필요합니다. 여기서 사용자별 할당량 (per user quotas)이 요청이 게이트웨이에 도달하기 전, 바로 미들웨어 레이어 (middleware layer)에서 제 역할을 하게 됩니다.
// middleware/cost-cap.ts
import { Request, Response, NextFunction } from "express";
import { createClient } from "redis";
...
이를 라우트 핸들러 (route handler) 이전에 연결하고, 핸들러가 모델 응답으로부터 토큰 수를 반환받으면 res.locals.recordUsage(tokensUsed)를 호출하도록 구성하십시오. 이를 게이트웨이 자체의 거버넌스 레이어 (governance layer)와 결합하면 (이 지점에서 Portkey의 가드레일 (guardrails)이나 LiteLLM의 예산 설정이 이중 역할을 수행합니다), 에지 (edge)와 미들웨어 양쪽 모두에서 보호를 받을 수 있습니다. 만약 할당량만으로 컴플라이언스 (compliance) 요구 사항을 충족할 수 없다면, AI governance in production에서 거버넌스 측면에 대해 더 자세히 다룹니다.
FAQ
LLM API 게이트웨이란 무엇인가요?
LLM API 게이트웨이는 애플리케이션과 LLM 제공업체(OpenAI, Anthropic 등) 사이에 위치하는 프록시 계층(proxy layer)입니다. 모델을 호출하는 모든 서비스에 로직을 분산시키는 대신, 라우팅(routing), 캐싱(caching), 속도 제한(rate limiting), 비용 추적(cost tracking)을 한 곳에서 중앙 집중적으로 처리합니다.
LLM API 비용을 어떻게 줄일 수 있나요?
시맨틱 캐싱(semantic caching, 반복적인 워크로드에서 3050% 절감), 작업 복잡도에 따라 저렴한 모델과 성능이 뛰어난 모델 사이를 오가는 스마트 라우팅(smart routing), 그리고 사용자별 엄격한 할당량(quotas) 설정을 결합하세요. 이러한 기술들을 함께 적용하면, 아무런 제어 장치 없이 제공업체를 직접 호출할 때보다 일반적으로 5080%의 비용 절감 효과를 거둘 수 있습니다.
Node.js를 위한 최고의 LLM 게이트웨이는 무엇인가요?
OpenAI와 호환되는 API를 갖춘, 직접 호스팅 가능하고 완전히 제어 가능한 프록시를 원한다면 LiteLLM을 추천합니다. 직접 구축하지 않고도 미리 만들어진 가드레일(guardrails)을 사용하고 싶다면 Portkey가 적합합니다. 트래픽이 이미 Cloudflare의 에지(edge)를 통해 흐르고 있으며 추가 지연 시간(latency)을 최소화하고 싶다면 Cloudflare AI Gateway를 사용하세요.
LLM 비용 최적화에 대해 더 깊이 있게 알고 싶다면, 제 사이트에서 더 자세히 다루고 있습니다.
이 과정을 귀하의 사이트에 엔드 투 엔드(end-to-end)로 구축하고 싶다면, 바로 제가 수행하는 업무입니다.
귀하의 설정 방식이 다르다면 댓글을 남겨주세요. 사람들이 실제로 프로덕션(production) 환경에서 어떤 라우팅이나 캐싱 전략을 실행하고 있는지 궁금합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기