TuBrief
구독 채널
비디오
커뮤니티

AI 에이전트 비용 폭증을 막는 하이브리드 라우팅 설계법

TuBrief 편집팀
2026년 7월 6일
0
컴퓨터/소프트웨어

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

한국어EnglishEspañol中文العربيةहिन्दीDeutschFrançaisPortuguêsРусскийBahasa Indonesia日本語

관련 영상

Claude Sonnet 3.5은 실망스러웠습니다... (그래도 Fable은 돌아왔네요!)5:33

Claude Sonnet 3.5은 실망스러웠습니다... (그래도 Fable은 돌아왔네요!)

Better Stack

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

AI 에이전트 비용 폭증을 막는 하이브리드 라우팅 설계법

최신 AI 에이전트 기능을 가져다 쓰다 보면 지갑이 먼저 털립니다. 단순히 질문을 던지고 답을 받는 구조와 다릅니다. 스스로 생각하고 판단하는 에이전틱 워크플로우는 혼자서 내부 루프를 돌며 토큰을 최소 5배에서 최대 30배까지 더 씁니다. 멋진 자동화 프로그램을 만들었는데 막상 운영해 보니 API 비용이 번 돈보다 더 많이 나오는 배보다 배꼽이 큰 상황이 벌어집니다.

리우 연구진(2026)이 발표한 에이전틱 ROI 공식에 따르면, 시스템의 가치는 향상된 품질과 절감한 시간을 누적 API 요금으로 나누어 결정됩니다. 결국 아무리 똑똑한 에이전트라도 유지비가 더 들면 비즈니스로서 가치가 제로라는 뜻입니다. 지출을 통제하려면 각 작업의 API 비용이 단일 매출 마진의 10% 밑으로 떨어지도록 구조를 짜야 합니다. 무턱대고 가장 비싼 모델만 쓰지 말고, 작업 난이도에 따라 모델을 쪼개서 배치하는 기준이 필요합니다.

모델 등급 대표 API 식별자 1M 입력 단가 1M 출력 단가 SWE-bench Pro 점수 주요 적합 태스크 범위 최저 수익 한계선 ($)
Frontier Tier claude-fable-5 10.00 50.00 80.3% 복잡한 다중 파일 리팩토링, 추론 루프 1.00 이상
Mid-Tier claude-sonnet-5 3.00 15.00 63.2% API 로직 연동, 디버깅, 전문 작문 0.15 ~ 0.30
Lightweight Tier gpt-4o-mini 0.15 0.60 미측정 단순 텍스트 분류, 정규식, 전처리 0.015 미만

하이브리드 모델 라우팅 시스템 구현

비용을 아끼는 핵심은 코드가 실행되는 시점에 쿼리의 난이도를 파악하고 모델을 동적으로 분산하는 로직입니다. RouteLLM이나 Not Diamond 같은 라우팅 제어기를 사용해 예산 감시망을 만듭니다. 평소에는 가성비가 좋은 Sonnet 5를 기본 모드로 지정해 전체 트래픽의 80% 이상을 처리하게 만들고, 여기서 해결하지 못한 실패 건만 Fable 5로 올리는 방식이 안전합니다. Sonnet 5가 답을 못 맞춘다고 프롬프트로 추론 수준을 최고조로 높여 재시도하는 짓은 하지 마십시오. 내부 추론 토큰이 폭발하면서 비용은 Fable 5만큼 나오는데 정답률은 떨어지는 최악의 결과를 마주합니다.

아래 파이썬 코드는 무한 루프나 악의적인 대량 요청으로 인한 요금 폭탄을 막고 월간 AI 운영 비용을 40% 줄여주는 예산 방어막 아키텍처입니다.

import os
import tiktoken
from anthropic import Anthropic
from notdiamond import NotDiamond
from notdiamond.exceptions import APIStatusError, APIConnectionError

SONNET_INPUT_PRICE_PER_M = 3.00
SONNET_OUTPUT_PRICE_PER_M = 15.00
MAX_PER_CALL_BUDGET_DOLLARS = 0.045000

class HybridAIOrchestrator:
    def __init__(self):
        self.anthropic_key = os.environ.get("ANTHROPIC_API_KEY")
        self.notdiamond_key = os.environ.get("NOT_DIAMOND_API_KEY")
        self.anthropic_client = Anthropic(api_key=self.anthropic_key)
        self.nd_client = NotDiamond(api_key=self.notdiamond_key)
        self.local_tokenizer = tiktoken.encoding_for_model("gpt-4o-mini")

    def evaluate_preflight_input_cost(self, system_text: str, user_text: str) -> float:
        aggregated_payload = f"System: {system_text}\nUser: {user_text}"
        tokens_measured = len(self.local_tokenizer.encode(aggregated_payload))
        calculated_cost = (tokens_measured / 1_000_000) * SONNET_INPUT_PRICE_PER_M
        return calculated_cost

    def execute_optimized_inference(self, system_prompt: str, user_prompt: str) -> dict:
        estimated_input_cost = self.evaluate_preflight_input_cost(system_prompt, user_prompt)
        if estimated_input_cost > MAX_PER_CALL_BUDGET_DOLLARS:
            return {
                "success": False,
                "error_code": "BUDGET_EXCEEDED",
                "message": f"작업 요청이 한도 초과 차단되었습니다. 예상 입력 비용: ${estimated_input_cost:.6f}"
            }

        try:
            routing_decision = self.nd_client.model_router.select_model(
                messages=[
                    {"role": "system", "content": system_prompt},
                    {"role": "user", "content": user_prompt}
                ],
                llm_providers=[
                    {"provider": "openai", "model": "gpt-4o-mini"},
                    {"provider": "anthropic", "model": "claude-sonnet-5"},
                    {"provider": "anthropic", "model": "claude-fable-5"}
                ],
                tradeoff="cost"
            )
            targeted_model = routing_decision.provider.model
            session_tracker_id = routing_decision.sessionId
        except (APIStatusError, APIConnectionError, Exception):
            targeted_model = "claude-sonnet-5"
            session_tracker_id = "LOCAL_FALLBACK_VAL"

        try:
            if "sonnet" in targeted_model:
                api_response = self.anthropic_client.messages.create(
                    model="claude-sonnet-5",
                    max_tokens=2048,
                    system=system_prompt,
                    messages=[{"role": "user", "content": user_prompt}]
                )
                output_payload = api_response.content[0].text
            elif "fable" in targeted_model:
                api_response = self.anthropic_client.messages.create(
                    model="claude-fable-5",
                    max_tokens=4096,
                    system=system_prompt,
                    messages=[{"role": "user", "content": user_prompt}]
                )
                output_payload = api_response.content[0].text
            else:
                output_payload = "경량 에이전트 분류 작업 완료 데이터"

            return {
                "success": True,
                "model_invoked": targeted_model,
                "session_id": session_tracker_id,
                "response_text": output_payload
            }
        except Exception as execution_err:
            return {
                "success": False,
                "error_code": "EXECUTION_FAILED",
                "message": f"최종 LLM 구동 실패 사유: {str(execution_err)}"
            }

API 비용 관리를 위한 시스템 프롬프트 최적화

라우팅 로직을 아무리 잘 짜도 매번 수천 토큰짜리 지시문을 통째로 전송하면 밑 빠진 독에 물 붓기입니다. 뼈대를 깎아내는 프롬프트 다이어트가 필요합니다. LLMLingua-2 압축 방법론을 참고하면 소형 모델을 사용해 문맥에 불필요한 단어를 쳐내고 핵심 엔티티만 남길 수 있습니다. 특히 프롬프트에 들어가는 예시 데이터(Few-shot)는 지시문에 비해 조금 잘려 나가도 모델이 알아먹습니다. 예시 데이터의 소거 비율을 70% 이상으로 잡고 필터를 먹이십시오. 프롬프트 크기가 줄어들면서 최종 모델의 응답 속도가 20% 이상 빨라집니다.

여기에 청구 비용을 90%까지 즉각 깎아주는 장치가 바로 프롬프트 캐싱입니다. 각 공급사마다 캐시를 다루는 규칙이 다르니 기준을 정확히 알아야 손해를 안 봅니다.

모델 패밀리 최소 구동 기준 캐시 쓰기 가산 배수 캐시 리드 할인 배수 TTL 소멸 지속 시간 캐시 무효 방지 주의사항
Claude Sonnet 5 1,024 토큰 5분 TTL: 1.25x / 1시간 TTL: 2x 0.10x ($3.00 -> $0.30) 디폴트 5분 (요청 시 연장) 도구 스키마 및 규칙 선언 정적 일관성 유지
Claude Fable 5 1,024 토큰 5분 TTL: 1.25x / 1시간 TTL: 2x 0.10x ($10.00 -> $1.00) 디폴트 5분 동일 적용 세션 타임스탬프를 캐시 영역 내에 이식 금지
GPT-4o / Mini 1,024 토큰 가산 요금 없음 0.20x ~ 0.50x 자동 감면 변동형 소멸 (5~10분 미활동) OpenAI 게이트는 무상태형 자동 탐지 기준 작동

캐시 적중률을 높이려면 프롬프트 구조에 위생 개념을 도입해야 합니다. 매번 바뀌는 사용자의 입력 텍스트, 고유 세션 ID, 현재 시간 같은 변동 데이터는 고정된 시스템 프롬프트 맨 뒤로 밀어내십시오. 앞에 배치하면 뒤에 오는 모든 정적 지문까지 캐시가 깨집니다. 서비스가 켜질 때 아주 짧은 더미 쿼리를 한 번 선제 발송해 캐시를 미리 구워두는 웜 가동 프로세스도 쓸만합니다. 변하지 않는 규칙과 툴 정의를 Anthropic의 캐시 브레이크포인트 지점 바로 앞에 집적시켜 두면 캐시 미스로 인한 중복 쓰기 요금을 막을 수 있습니다.


실전 운영: 개발 단계별 비용 예측 및 추적 시스템

서비스가 크는 단계에 따라 비용을 바라보는 눈도 달라져야 합니다. 처음 만드는 MVP 단계에서는 트래픽이 적습니다. 대신 에이전트가 헛소리를 하거나 자기 혼자 무한 루프를 돌며 예외를 뿜어내는 일이 잦습니다. 이때는 비용을 좀 쓰더라도 안정적으로 작업을 끝내도록 미드티어 모델에 여유를 둬야 합니다. 하지만 유저가 몰리는 스케일업 단계로 넘어가면 이야기가 다릅니다. 이때는 단순 포맷 검증이나 분류 같은 뻔한 작업을 최대한 gpt-4o-mini 같은 저비용 모델로 빼주고, 캐시 적중률을 80% 선으로 묶어두어야만 지출 곡선이 꺾입니다.

사용자별로 비용을 추적하고 일일 마진 균열을 감시할 수 있는 PostgreSQL 스키마를 공유합니다. 무작위 UUID를 기본키로 쓰면 인덱스 페이지가 쪼개지면서 DB 성능이 인프라 레벨에서 박살 나므로, 여기서는 시간 순서대로 정렬되는 UUIDv7 규격을 애플리케이션 단계에서 만들어 넣는 구조를 씁니다.

CREATE EXTENSION IF NOT EXISTS "pgcrypto";

CREATE TABLE clients (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_name VARCHAR(255) NOT NULL,
    hashed_auth_token VARCHAR(64) UNIQUE NOT NULL,
    daily_budget_limit NUMERIC(12, 6) NOT NULL DEFAULT 5.000000,
    cumulative_spend_dollars NUMERIC(14, 6) DEFAULT 0.000000,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE interactive_sessions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    client_id UUID REFERENCES clients(id) ON DELETE CASCADE,
    session_title VARCHAR(500) NOT NULL,
    total_session_spend NUMERIC(12, 6) DEFAULT 0.000000,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE telemetry_llm_messages (
    id UUID PRIMARY KEY,
    session_id UUID REFERENCES interactive_sessions(id) ON DELETE CASCADE,
    role VARCHAR(50) NOT NULL CHECK (role IN ('system', 'user', 'assistant')),
    routed_model_identifier VARCHAR(150) NOT NULL,
    raw_prompt_tokens INT DEFAULT 0,
    raw_completion_tokens INT DEFAULT 0,
    cached_read_input_tokens INT DEFAULT 0,
    cached_write_input_tokens INT DEFAULT 0,
    session_latency_ms INT,
    transaction_cost_dollars NUMERIC(14, 8) DEFAULT 0.00000000,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_telemetry_client_billing ON clients(hashed_auth_token) WHERE is_active = TRUE;
CREATE INDEX idx_telemetry_messages_sessions ON telemetry_llm_messages(session_id);
CREATE INDEX idx_telemetry_latency_performance ON telemetry_llm_messages(routed_model_identifier, session_latency_ms);

이 스키마를 유저 API 게이트웨이에 연결해 두면 복잡한 툴 없이 단순 집계 쿼리만으로도 특정 유저가 하루 제한선인 5달러를 넘겼는지 실시간으로 잡아낼 수 있습니다. 시스템이 알아서 한도를 통제하므로 API 요금이 전체 프로젝트 수익의 10% 선을 넘지 않도록 안전하게 묶어둘 수 있습니다.