지출 추적 (Spend Tracking)

지출 추적 (Spend Tracking)

LLM 게이트웨이를 운영할 때 어느 키·어느 사용자·어느 팀이 얼마를 썼는지 아는 것은 곧 비용 통제의 핵심이에요. LiteLLM 프록시는 100개 이상의 LLM에 대해 지출을 자동으로 추적해서, 키·사용자·팀 단위로 비용을 분석하고 리포트로 뽑을 수 있게 도와줍니다. 이 장은 지출이 어떻게 쌓이고, 어디에서 확인하며, 리포트로 어떻게 뽑는지를 다룹니다.

출처: 공식문서

지출 추적의 원리

LiteLLM은 알려진 모델 전부에 대해 지출을 자동으로 추적해요. 모델별 가격은 모델 비용 맵을 참고하고, 일부 프로바이더(Vertex AI PayGo/우선순위 가격, Bedrock 서비스 티어, Azure base model 매핑 등)의 비용 추적은 응답에 티어 메타데이터가 포함되면 자동으로 적용돼요.

:::tip 가격 데이터 최신화 정확한 비용 추적을 위해 GitHub에서 모델 가격 데이터 동기화를 권장해요. :::

:::info 비용이 프로바이더 청구서와 안 맞나요? 비용 불일치 디버깅의 단계별 워크플로(시간 범위 정렬 → 토큰 범주 비교(캐시 포함) → 차이가 수집/수식/모델맵 가격 중 어느 쪽인지 판단)를 따라가 보세요. :::

지출 추적 시작하기

Step 1LiteLLM을 데이터베이스와 함께 설정해요. 지출 로그는 DB에 저장되므로 이 설정이 먼저 필요해요.

Step 2/chat/completions 요청을 보내요. 지출을 사용자별로 추적하고 싶으면 user를, 태그별로 추적하고 싶으면(엔터프라이즈) metadata.tags를 넘겨요.

import openai
client = openai.OpenAI(
    api_key="sk-1234",
    base_url="http://0.0.0.0:4000"
)

response = client.chat.completions.create(
    model="llama3",
    messages = [
        {
            "role": "user",
            "content": "this is a test request, write a short poem"
        }
    ],
    user="palantir", # OPTIONAL: pass user to track spend by user
    extra_body={
        "metadata": {
            "tags": ["jobID:214590dsff09fds", "taskName:run_page_classification"] # ENTERPRISE: pass tags to track spend by tags
        }
    }
)

print(response)

Curl로는 metadata를 요청 본문에 포함하면 돼요.

curl --location 'http://0.0.0.0:4000/chat/completions' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer ***' \
    --data '{
    "model": "llama3",
    "messages": [
        {
        "role": "user",
        "content": "what llm are you"
        }
    ],
    "user": "palantir", # OPTIONAL: pass user to track spend by user
    "metadata": {
        "tags": ["jobID:214590dsff09fds", "taskName:run_page_classification"] # ENTERPRISE: pass tags to track spend by tags
    }
}'

Step 3 — 지출이 추적됐는지 확인해요. 간단한 방법은 응답 헤더에서 x-litellm-response-cost를 확인하는 거예요. 계산된 비용이 담겨 있어요. DB로는 LiteLLM_SpendLogs 테이블에 지출이 기록되고, UI(https://your-proxy-endpoint/ui)의 Usage 탭에서 확인할 수 있어요.

{
  "api_key": "fe6b0cab4ff5a5a8df823196cc8a450*****",                            # Hash of API Key used
  "user": "default_user",                                                       # Internal User (LiteLLM_UserTable) that owns `api_key=sk-1234`.
  "team_id": "e8d1460f-846c-45d7-9b43-55f3cc52ac32",                            # Team (LiteLLM_TeamTable) that owns `api_key=sk-1234`
  "request_tags": ["jobID:214590dsff09fds", "taskName:run_page_classification"],# Tags sent in request
  "end_user": "palantir",                                                       # Customer - the `user` sent in the request
  "model_group": "llama3",                                                      # "model" passed to LiteLLM
  "api_base": "https://api.groq.com/openai/v1/",                                # "api_base" of model used by LiteLLM
  "spend": 0.000002,                                                            # Spend in $
  "total_tokens": 100,
  "completion_tokens": 80,
  "prompt_tokens": 20,
  "metadata": {
    "attempted_fallbacks": 0,                                                    # 0 = requested model group served the request
    "original_model_group": "llama3"                                             # Model group originally requested
  }
}

사용자별 총 지출 확인

엔드 유저에게 키를 발급하고 키에 user_id를 설정해 뒀다면, 그 사용자의 사용량을 확인할 수 있어요.

curl -L -X GET 'http://localhost:4000/user/info?user_id=jane_smith' \
-H 'Authorization: Bearer ***'

응답의 user_info.spend에 사용자 총 지출이 담겨요.

:::warning 엔드 유저는 요청 본문에 user 파라미터를 넣을 수 있는데, 이러면 /customer/info?end_user_id=self-declared-user로 비용이 집계되고 키 소유자로 집계되지 않아요. 즉 사용자가 이 방법으로 지출 추적을 "회피"할 수 있어요. 사용자별 지출을 추적해야 하고 엔드 유저에게 API 키를 준다면, 키 생성 시 반드시 user_id를 설정하고 백엔드 서비스에서 그 사용자를 대신해 호출할 때 항상 그 사용자 전용 키를 쓰세요. :::

일일 지출 브레이크다운 API

/user/daily/activity 엔드포인트 하나로 사용자의 일별 상세 사용량(모델·프로바이더·API 키별)을 얻을 수 있어요.

curl -L -X GET 'http://localhost:4000/user/daily/activity?start_date=2025-03-20&end_date=2025-03-27' \
-H 'Authorization: Bearer ***'
{
    "results": [
        {
            "date": "2025-03-27",
            "metrics": {
                "spend": 0.0177072,
                "prompt_tokens": 111,
                "completion_tokens": 1711,
                "total_tokens": 1822,
                "api_requests": 11
            },
            "breakdown": {
                "models": {
                    "{{openai_small}}": {
                        "spend": 1.82e-05,
                        "prompt_tokens": 37,
                        "completion_tokens": 9,
                        "total_tokens": 46,
                        "api_requests": 1
                    }
                },
                "providers": { "openai": { ... }, "azure_ai": { ... } },
                "api_keys": { "3126b6eaf1...": { ... } }
            }
        }
    ],
    "metadata": {
        "total_spend": 0.7274667,
        "total_prompt_tokens": 280990,
        "total_completion_tokens": 376674,
        "total_api_requests": 14
    }
}

:::info 이 엔드포인트의 요청 수는 지출 로그에서 파생되므로 기록된 요청만 포함하고, 업스트림 시도마다 별도로 집계해요. 게이트웨이가 실제로 응답한 횟수(키나 모델이 해석되기 전에 거부된 요청 포함)가 필요하면 /gateway/daily/activity를 쓰세요. 둘은 일치할 거라 기대하지 않아요. :::

커스텀 태그로 비용 배분

요청에 태그를 달면 지출을 태그별로 나눠 볼 수 있어요. 기본적으로 LiteLLM은 User-Agent를 커스텀 태그로 기록해서 Claude Code·Gemini CLI 같은 도구별 사용량을 볼 수 있어요.

키 생성 시, 팀 생성 시, 또는 요청의 metadata.tags를 통해 태그를 지정합니다.

curl -L -X POST 'http://0.0.0.0:4000/key/generate' \
-H 'Authorization: Bearer ***' \
-H 'Content-Type: application/json' \
-d '{
    "metadata": {
        "tags": ["tag1", "tag2", "tag3"]
    }
}
'

지출 추적에 커스텀 헤더를 추가하려면 litellm_settings.extra_spend_tag_headers에 헤더를 나열하고, user-agent 추적을 끄려면 disable_add_user_agent_to_request_tags: true를 설정해요.

litellm_settings:
  extra_spend_tag_headers:
    - "x-custom-header"

지출 리포트 생성 (엔터프라이즈)

다른 팀·고객·사용자에게 비용을 청구할 때는 /global/spend/report 엔드포인트로 지출 리포트를 뽑아요. group_by 파라미터로 팀(team), 고객(customer) 단위로 나눌 수 있고, 특정 키(api_key=sk-1234)나 내부 사용자(internal_user_id=ishaan)를 지정할 수도 있어요.

curl -X GET 'http://localhost:4000/global/spend/report?start_date=2024-04-01&end_date=2024-06-30&group_by=team' \
  -H 'Authorization: Bearer ***'

group_by=team 응답은 날짜별로 팀 이름, 팀별 총 지출, 그리고 키+모델 단위의 상세 메타데이터를 돌려줘요.

지출 로그 API — 개별 트랜잭션 로그

/spend/logs 엔드포인트는 날짜 필터를 쓸 때 summarize 파라미터로 데이터 형식을 제어해요.

Parameter Description
summarize New parameter: true (default) = aggregated data, false = individual transaction logs
  • summarize=false — 분석 대시보드, ETL, 상세 감사(audit) 추적 용도
  • summarize=true — 일일 지출 리포트, 상위 수준 비용 추적(레거시 동작)
curl -X GET "http://localhost:4000/spend/logs?start_date=2024-01-01&end_date=2024-01-02&summarize=false" \
-H "Authorization: Bearer ***"

커스텀 지출 로그 메타데이터 (엔터프라이즈)

지출 로그의 메타데이터에 특정 key-value 쌍을 기록하고 싶다면 spend_logs_metadata를 사용해요. 키·팀 생성 시, 요청 본문 metadata.spend_logs_metadata, 또는 x-litellm-spend-logs-metadata 헤더로 전달할 수 있어요.

import openai
client = openai.OpenAI(
    api_key="sk-1234",
    base_url="http://0.0.0.0:4000"
)

# Pass spend logs metadata via headers
response = client.chat.completions.create(
    model="{{openai_small}}",
    messages = [
        {
            "role": "user",
            "content": "this is a test request, write a short poem"
        }
    ],
    extra_headers={
        "x-litellm-spend-logs-metadata": '{"user_id": "12345", "project_id": "proj_abc", "request_type": "chat_completion"}'
    }
)

print(response)

/spend/logs 응답의 metadata.spend_logs_metadata에서 기록된 커스텀 메타데이터를 확인할 수 있어요.

더 알아보기