본문 바로가기
서버구축 (WEB,DB)

API Gateway와 AI Gateway & Routing: 멀티 모델 시대의 인프라 전략

by 날으는물고기 2025. 8. 29.

API Gateway와 AI Gateway & Routing: 멀티 모델 시대의 인프라 전략

728x90

핵심 정의와 스코프

  1. Route Gateway(라우트 게이트웨이)
    • 광의의 개념. L7(HTTP) 기준으로 호스트/경로/헤더/메서드/쿠키/Geo/IP 등 조건에 따라 백엔드 서비스로 트래픽을 분기하는 컴포넌트.
    • 예: NGINX/Envoy/Kong/APISIX, Kubernetes Ingress/Gateway API, 클라우드 API 게이트웨이 등.
  2. API Gateway
    • “비즈니스 API”를 외부/내부에 제공하기 위한 전면 게이트웨이.
    • 인증/인가, 레이트리밋, WAF, 로깅, 버저닝, 라우팅, 재시도/타임아웃/회로차단, 트랜스폼(헤더/본문)API 관리 기능을 제공.
  3. AI Gateway
    • LLM/멀티 모델 호출을 표준화·프록시화.
    • 프로바이더(예: OpenAI, Gemini, Bedrock, OpenRouter, DeepSeek, Ollama 등)와 모델단일 API로 통일하고, 모델 선택/폴백/비용·지연 최적화/콘텐츠 필터/프롬프트 가드/토큰 집계/로그·과금 등을 중앙화.
  4. AI Routing
    • 요청의 특성(길이/난이도/도구 필요/보안 등)운영 목표(비용/지연/SLA/정확도)를 바탕으로 가장 적합한 모델·프로바이더를 자동 선택하는 전략(룰/휴리스틱/정책/학습 기반).
    • 예: 일반 대화 → 저비용 모델, 추론/코딩 → reasoning 모델, 장문 컨텍스트 → 장문 모델, 기밀 데이터 → 로컬 모델(Ollama/vLLM).

공통 아키텍처(제어면/데이터면)

  • 데이터 플레인: 실제 요청이 흐르는 게이트웨이(프록시).
  • 컨트롤 플레인: 선언형 설정(GitOps), 관리 API, 정책 엔진(OPA/Cedar), 시크릿, 플러그인/필터 관리.
  • 배치 위치
    • 에지(Edge): 인터넷 경계. WAF·DDoS·TLS 종료·봇 방어.
    • 코어(Core): 내부 서비스 간. 서비스 메시/내부 API/AI 게이트웨이.
    • 사이드카: 애플리케이션마다 주입(서비스 메시).

API Gateway의 핵심 기능 맵

  1. 라우팅: 호스트/경로/헤더/메서드/가중치/AB/카나리/미러링.
  2. 보안: TLS/mTLS, OAuth2/OIDC, Key/Auth, ACL, IP 제한, WAF, DLP(간단 필터).
  3. 정책/제한: 레이트리밋, 버스트, QoS, 크기 제한, 스로틀.
  4. 안정성: 타임아웃/재시도, 회로차단, 헬스체크, 폴백 서비스.
  5. 변환: 헤더/쿼리/경로 재작성, 본문 변환(JSON/XML), gRPC↔HTTP 변환.
  6. 가시성: 구조화 로그, 메트릭, 트레이싱(Trace ID 전파, OpenTelemetry).
  7. 거버넌스: 버저닝, 수명주기, 문서화, 개발자 포털(선택).

도구 예: Kong(DecK/KIC), NGINX(+NJS/Plus), Apache APISIX, Envoy 기반 게이트웨이, AWS/GCP/Cloudflare API Gateway 등.

AI Gateway의 추가 기능 맵

  1. 멀티프로바이더/멀티모델 표준화: OpenAI 호환 /v1/chat/completions 단일로 묶기.
  2. AI 라우팅
    • 룰 기반: profile=general/reasoning/longform/background 매핑.
    • 휴리스틱: 토큰 길이, 키워드(“explain why”, “step by step”), 첨부/툴콜 유무.
    • 학습/정책 엔진: 모델 선택을 비용/지연/성공률 기반으로 A/B·밴딧 최적화.
    • 수동 명령 전환: /model 공급자,모델명 프롬프트 첫 줄 트리거.
  3. 보안/프라이버시: 전처리 PII 마스킹, 안전 가드레일(금칙어·데이터 유출 방지), 함수 호출 화이트리스트, 데이터 지역성.
  4. 관찰성/과금: 토큰/비용/지연/성공률 집계, 사업부/프로젝트별 할당/쿼터.
  5. 캐시/요약/리듀서: 장문 입력을 비용 절감 위해 전처리(샤딩/요약) 후 재요청.
  6. RAG 연동: 게이트웨이 단계에서 사내 벡터/RAG 호출 우선(내부 데이터 우선 정책).

도구 예: LiteLLM/OpenRouter/Helicone/Portkey 같은 LLM 프록시/게이트웨이, vLLM/TGI/Ollama 같은 모델 서버, 자체 Node.js/FastAPI 프록시(조합 가능).

대표 아키텍처 패턴

  1. Edge(API GW) → Core(AI GW)
    • 외부는 API GW에서 인증/레이트리밋/WAF, 내부로 AI GW에 전달하여 모델 라우팅/보안 필터 수행.
    • 장점: 외부 노출 최소화, 역할 분리 명확.
  2. 단일 게이트웨이 통합
    • API GW에 AI 라우팅 플러그인/업스트림 통합. 간단하지만 정책 분리/확장성이 낮을 수 있음.
  3. Kubernetes 네이티브
    • Gateway API/Ingress로 대외 라우팅, 내부에는 AI GW(Deployment).
    • 선언형(CRD) + GitOps(ArgoCD/Flux) + 시크릿/네임스페이스 분리.
  4. 로컬 모델 분리(보안·비용)
    • 기밀/규정 대상 요청은 로컬 모델(Ollama/vLLM) 우선, 외부 모델은 비기밀/저비용 구간만.

보안 필수 체크리스트

  1. 인증/인가
    • 외부→API GW: OIDC/OAuth2, API Key/MTLS.
    • API GW→AI GW: mTLS + 서비스 계정(RBAC).
    • AI GW→프로바이더: 프로바이더 키는 서버사이드 보관, 프로젝트·환경 분리.
  2. 데이터 보호
    • 전처리 PII 마스킹(전화/이메일/주민번호/키), 프롬프트 가드(내부 시스템 정보·시크릿 유출 방지).
    • 함수/툴콜 허용 목록만 실행, 외부 호출 도메인 허용 리스트.
    • 데이터 지역성/로깅 정책: 로그에 민감 원문 저장 금지, 해시/샘플·비식별화.
  3. 네트워크/경계
    • Admin/API 포트 내부망 한정, 방화벽/IP allowlist, 라우터/게이트웨이 분리 배치.
    • egress 제어(외부 LLM 호출 도메인 제한).
  4. 정책/컴플라이언스
    • OPA/Rego 또는 Cedar로 모델 선택·툴 사용·데이터 전송 정책 선언화.
    • 변경은 PR 승인·감사로그 남기고 GitOps로 반영.
  5. 안정성
    • 회로차단/재시도/백오프, 폴백 체인(주→보조 모델), 타임아웃 일관화.
    • 과도한 정규식/거대 본문 제한, 스트리밍 백프레셔.

관찰성/비용/품질 운영

  • 메트릭: p50/p95 지연, 성공률, 폴백률, 토큰/비용(월·부서·사용자), 프롬프트 길이 분포.
  • 로그/트레이스: 요청ID/사용자/정책ID/선택 모델/비용/결정 근거(간단 요약).
  • 예산/쿼터: 부서/프로젝트 단위 월간 한도·속도 제한, 초과 시 자동 모델 다운그레이드.
  • 품질: 태스크별 평가셋(A/B), 수동/자동 라우팅 비교 리포트.
300x250

구성 예시 — Kong(API GW) + 내부 AI Gateway

1) Kong(DecK) 선언형 예시

# kong.yaml
_format_version: "3.0"
services:
  - name: ai-gateway
    url: http://ai-gateway.default.svc.cluster.local:8080
    routes:
      - name: ai-openai-compatible
        paths: ["/v1/chat/completions"]
        strip_path: false
    plugins:
      - name: rate-limiting
        config: { second: 30, policy: local }
      - name: key-auth
      - name: request-transformer
        config:
          add: { headers: ["x-request-id:$(request_id)"] }
consumers:
  - username: team-ml
keyauth_credentials:
  - key: REPLACE_ME_SECURE_KEY_FOR_TEAM_ML

적용

deck diff --state kong.yaml
deck sync --state kong.yaml

2) K8s Gateway API(HTTPRoute)로 외부→Kong 라우팅

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: ai-route
spec:
  parentRefs: [{ name: kong }]
  rules:
  - matches:
    - path: { type: PathPrefix, value: /v1 }
    backendRefs:
    - name: kong-proxy
      port: 80

AI Gateway(커스텀) 라우팅 서버 예시(Node.js)

목표: OpenAI 호환 /v1/chat/completions를 받아 프로필/휴리스틱/명령형 기준으로 모델을 선택하고, 응답을 OpenAI 호환 형식으로 반환.

// server.ts
import express from "express";
import bodyParser from "body-parser";
import fetch from "node-fetch";

const app = express();
app.use(bodyParser.json({ limit: "2mb" }));

type Msg = { role: "system"|"user"|"assistant"|"tool"; content: string };
type Req = { model?: string; messages: Msg[]; stream?: boolean; temperature?: number; _profileHint?: string };

function pickProfile(req: Req) {
  // 1) 명령형 전환
  const first = req.messages[0]?.content || "";
  const m = first.match(/^\/model\s+([a-z0-9_-]+)\s*,\s*([a-z0-9._:-]+)/i);
  if (m) return { provider: m[1], model: m[2], stripCmd: true };

  // 2) 힌트/휴리스틱
  const text = req.messages.at(-1)?.content ?? "";
  const tokens = text.length/4;
  if (req._profileHint === "longform" || tokens > 12000) return { provider: "gemini", model: "gemini-1.5-pro" };
  if (/explain reasoning|why|prove|chain of thought/i.test(text)) return { provider: "deepseek", model: "deepseek-reasoner" };
  return { provider: "openrouter", model: "gpt-4o-mini" };
}

function redactPII(s: string) {
  return s.replace(/\b\d{3}-\d{2}-\d{4}\b/g, "***-**-****"); // 예: 미국 SSN 패턴
}

app.post("/v1/chat/completions", async (req, res) => {
  const body: Req = req.body;

  // 전처리(PII 마스킹 + 시스템 프롬프트 주입)
  body.messages = [
    { role: "system", content: "Follow org policy. Output in Korean. Do not reveal secrets." },
    ...body.messages.map(m => ({ ...m, content: redactPII(m.content) }))
  ];

  // 라우팅 결정
  const sel = pickProfile(body);
  if (sel.stripCmd) body.messages[0].content = body.messages[0].content.replace(/^\/model[^\n]*\n?/, "").trim();

  // 공급자 호출(간략: OpenRouter 예시)
  let providerResp: any = {};
  if (sel.provider === "openrouter") {
    const resp = await fetch("https://openrouter.ai/api/v1/chat/completions", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${process.env.OPENROUTER_API_KEY}`
      },
      body: JSON.stringify({ model: sel.model, messages: body.messages, stream: body.stream, temperature: body.temperature })
    });
    providerResp = await resp.json();
  }
  // deepseek/gemini/ollama 등은 어댑터 함수로 분기…

  // 표준화 + 후처리(민감정보 마스킹)
  const text =
    providerResp?.choices?.[0]?.message?.content ||
    providerResp?.output_text || providerResp?.message?.content || providerResp?.response || "";
  const safeText = text.replace(/(API_KEY|PASSWORD)=\S+/g, "$1=******");

  return res.json({
    id: `ai-gw_${Date.now()}`,
    object: "chat.completion",
    created: Math.floor(Date.now()/1000),
    model: providerResp?.model || sel.model,
    choices: [{ index: 0, finish_reason: "stop", message: { role: "assistant", content: safeText } }],
    usage: providerResp?.usage
  });
});

app.listen(8080, () => console.log("AI Gateway listening on :8080"));

운영 시: mTLS/RBAC/레이트리밋은 API GW(Kong/NGINX)에서, 모델 라우팅/PII 마스킹/규정 필터는 AI GW에서.

NGINX(혹은 NGINX Plus) 프런트 예시

# 외부 → /v1/* 은 내부 AI GW로 역프록시
server {
  listen 443 ssl http2;
  server_name ai.example.com;

  ssl_certificate     /etc/nginx/tls/fullchain.pem;
  ssl_certificate_key /etc/nginx/tls/privkey.pem;

  # JWT 인증(예: OIDC 후단)
  auth_jwt "AI Gateway";
  auth_jwt_key_file /etc/nginx/jwt_pub.jwk;

  location /v1/ {
    proxy_set_header X-Request-ID $request_id;
    proxy_set_header Authorization $http_authorization;
    proxy_pass http://ai-gateway.default.svc.cluster.local:8080;
    proxy_connect_timeout 5s;
    proxy_read_timeout 120s;
  }

  # 헬스체크/상태
  location = /healthz { return 200 'ok'; }
}

테스트/검증(보안·기능·성능)

  1. 스모크
    • /v1/chat/completions 200, /healthz 200, 인증 없는 요청 401/403, 레이트리밋 시 429.
  2. 보안
    • 시크릿 미포함 응답 보장, 프롬프트 인젝션 시 툴콜·외부요청 차단 검증, PII 마스킹 동작.
    • Admin/API 포트 외부 노출 금지 확인, egress 제한 동작(허용 도메인 외 차단).
  3. 라우팅
    • /model 명령 전환, longform/think 프로필 휴리스틱 테스트, 폴백 체인(장애 시 대체 모델) 검증.
  4. 성능
    • 동시성/스트리밍 백프레셔, p95<목표, 타임아웃/재시도/회로차단 정상.

예시(Pytest-HTTPX)

@pytest.mark.asyncio
async def test_requires_auth(ac):
    r = await ac.post("/v1/chat/completions", json={"messages":[{"role":"user","content":"hi"}]})
    assert r.status_code in (401,403)

@pytest.mark.asyncio
async def test_model_switch(ac, token):
    r = await ac.post("/v1/chat/completions",
      headers={"Authorization": f"Bearer {token}"},
      json={"messages":[{"role":"user","content":"/model openrouter,gpt-4o-mini\n코드 리뷰"}]})
    assert r.status_code == 200

도입 체크리스트

  1. 구조: Edge(API GW)와 Core(AI GW) 분리, mTLS/RBAC/율제한.
  2. 정책: AI 라우팅(프로필·휴리스틱·명령형), OPA/Cedar로 선언화.
  3. 보안: PII 마스킹, 툴콜 화이트리스트, 시크릿·키 서버사이드, egress 제한.
  4. 가시성: 토큰/비용/지연/폴백률/정책ID 로그, OTEL 트레이스.
  5. GitOps: Kong decK/Ingress/Gateway API 선언형, PR 승인·감사·롤백.
  6. 테스트: 보안/라우팅/성능 스위트 자동화, 카나리/AB로 점진 배포.
  7. 비용 최적화: 장문 전처리(요약/샤딩), 백그라운드/야간은 저비용 모델, 한도 초과 시 모델 다운그레이드.
728x90
그리드형(광고전용)

댓글