top of page

TerraformでLiteLLM ProxyをGoogle Cloud上に構築する

  • Shogo Umeda
  • 20 時間前
  • 読了時間: 14分

はじめに


近年、LLMアプリケーションの開発において、複数のLLMプロバイダーを使い分ける必要性が高まっています。 OpenAIのGPT、AnthropicのClaude、GoogleのGeminiなど、それぞれ異なる特徴を持っており、それぞれの特徴に合わせてLLMを使い分けるケースも多くあります。 また、コスト最適化の観点から、簡単なタスクには安価なモデルを、複雑なタスクには高性能なモデルを使い分けることも重要です。 しかし、従来のアプローチでは各LLMプロバイダーごとに異なるAPI仕様に対応する必要があり、APIキーの分散管理、使用量・コストの把握困難、アプリケーション側での複雑な実装といった課題がありました。 LiteLLM Proxyは、複数のLLMプロバイダー利用に伴うAPI仕様の違いや管理の煩雑さといった課題を解決するLLM Gatewayソリューションです。

統一されたAPIインターフェースを提供することで、開発者は一つのエンドポイントからOpenAIやGoogle Geminiなど様々なLLMプロバイダーへシームレスにアクセスできます。

また、自動的な負荷分散やフェイルオーバー機能により高い可用性を確保し、詳細な使用量・コストの監視機能によって効率的なリソース管理も実現します。


さらに、LiteLLM ProxyはLangfuseとの連携によるトレース送信機能も標準で備えています。

簡単な設定を行うだけで、各LLMリクエストのトレースログを自動的にLangfuseへ送信し、可観測性や運用分析を強化できます。


LiteLLM Proxyの主要な特徴


LiteLLM Proxyは、複数のLLMプロバイダーを統一的に管理できるプロキシサーバーです。主な特徴は以下の通りです:


  • 複数プロバイダー統合: OpenAI、Anthropic、Google、Azure OpenAIなど、様々なLLMプロバイダーを統一APIで利用可能

  • コスト・使用量管理: リクエスト数、トークン使用量、コストの追跡と制限設定

  • APIキー管理: 複数のAPIキーを一元管理し、セキュアに配布

  • 負荷分散・フェイルオーバー: 複数のエンドポイント間でのリクエスト分散と自動フェイルオーバー

  • ログ・監視: 詳細なリクエストログとメトリクスの収集

    • Langufseへのログ送信も可能


本記事の全体像


本記事では以下について解説します。

  • Terraformを使用して、Google Cloud上にLiteLLM Proxyを構築する手順を解説する

  • LiteLLM Proxyを使用して複数のLLMプロバイダーへのアクセスを試す

  • LiteLLM ProxyのWeb UIでの管理画面を確認する

  • LiteLLM Proxyを利用した LLMプロバイダーアクセスのTrace情報がLangfuseへ送信されていることの確認する


構築する全体構成


以下の構成図に示すとおり、Google Cloud上にLiteLLM Proxy環境を構築します。

※本構成は必要最小限の構成になっております。セキュリティ強度を高める場合はCloud Runサービスの前段に外部アプリケーションロードバランサーを構成し、IAPやCloud Armorを利用ください。


LiteLLM Proxy構成図
LiteLLM Proxy構成図


この構成では以下の要素を組み合わせています:


  • LiteLLM Proxy Cloud Run上でコンテナとして稼働する中核コンポーネント

  • Secret Manager: APIキーの安全な管理

  • Cloud SQL: プロキシの設定データとメタデータの保存


※以下のコンポーネントの構築・準備手順はこの記事では割愛します。

  • Langfuse : LLMリクエストの可観測性とパフォーマンス監視 

  • 複数LLMプロバイダー: OpenAI、Googleへの統一アクセス



次のセクションから、実際の構築手順を解説していきます。

※ 本記事ではTerraformのインストールやGoogle Cloud プロジェクトの作成等は割愛いたします。


Terraformによるインフラ構築


TerraformによりGoogle Cloud上にLiteLLM Proxy環境を構築します。


Terraformファイル構成


LiteLLM Proxy環境の構築に必要な主要ファイルを以下のように構成します


.
├── main.tf          # メインの設定ファイル(プロバイダー設定、リソース定義)
├── variables.tf     # 変数定義(カスタマイズ可能な値)
├── outputs.tf       # 出力値(デプロイ後に必要な情報)
└── terraform.tfvars # 変数の実際の値(プロジェクト名や環境変数値を設定)


下記のとおり、`main.tf` `variables.tf` `outputs.tf` `terraform.tfvars` ファイルを作成します。

コードブロックは展開して確認ください。


メインリソース(`main.tf`)

# Googleプロバイダー、プロジェクト設定

terraform {
  required_version = ">= 0.14"
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 6.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "~> 3.1"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
  zone    = var.zone
}

# 変数とランダム値生成(セキュリティ関連)

# Random password for database
resource "random_password" "db_password" {
  length  = 16
  special = false
  upper   = true
  lower   = true
  numeric = true
}

# Random master key for LiteLLM
resource "random_password" "master_key" {
  length  = 32
  special = true
  upper   = true
  lower   = true
  numeric = true
}

# Random password for LiteLLM UI
resource "random_password" "ui_password" {
  length  = 16
  special = true
  upper   = true
  lower   = true
  numeric = true
}

# Random salt key for LiteLLM
resource "random_string" "salt_key" {
  length  = 16
  special = false
  upper   = true
  lower   = true
  numeric = true
}

# Random prefix for database name
resource "random_id" "db_prefix" {
  byte_length = 4
}

# Local values - 条件分岐により変数またはランダム値を使用
locals {
  db_password       = var.db_password != null ? var.db_password : random_password.db_password.result
  master_key        = var.master_key != null ? var.master_key : random_password.master_key.result
  ui_password       = var.ui_password != null ? var.ui_password : random_password.ui_password.result
  salt_key          = var.salt_key != null ? var.salt_key : random_string.salt_key.result
  vertex_project_id = var.vertex_project_id != null ? var.vertex_project_id : var.project_id
}

# Google Project Servicesの有効化
resource "google_project_service" "required_apis" {
  for_each = toset([
    "compute.googleapis.com",
    "run.googleapis.com",
    "sqladmin.googleapis.com",
    "secretmanager.googleapis.com",
    "vpcaccess.googleapis.com",
    "aiplatform.googleapis.com",
  ])

  project = var.project_id
  service = each.value

  disable_dependent_services = false
  disable_on_destroy         = false
}

# ネットワーク(VPC/サブネット/プライベート接続)

resource "google_compute_network" "litellm_vpc" {
  name                    = "litellm-vpc"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "cloudrun_egress" {
  name                     = "cloudrun-egress"
  ip_cidr_range            = "10.0.2.0/24"
  network                  = google_compute_network.litellm_vpc.id
  region                   = var.region
  private_ip_google_access = true
}

resource "google_compute_global_address" "psa_subnet" {
  name          = "psa-subnet"
  purpose       = "VPC_PEERING"
  address_type  = "INTERNAL"
  prefix_length = 16
  network       = google_compute_network.litellm_vpc.id
}

resource "google_service_networking_connection" "private_service_connection" {
  network                 = google_compute_network.litellm_vpc.id
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.psa_subnet.name]
}


# Cloud SQL(PostgreSQLデータベース)

resource "google_sql_database_instance" "litellm_db_01" {
  database_version = "POSTGRES_16"
  name             = "litellm-db-${random_id.db_prefix.hex}-1"
  region           = var.region
  project          = var.project_id

  settings {
    activation_policy = "ALWAYS"
    availability_type = "ZONAL"
    disk_autoresize   = false
    disk_size         = 10
    disk_type         = "PD_SSD"
    edition           = "ENTERPRISE"
    pricing_plan      = "PER_USE"
    tier              = "db-f1-micro"

    ip_configuration {
      ipv4_enabled                                  = false
      private_network                               = google_compute_network.litellm_vpc.id
      enable_private_path_for_google_cloud_services = true
    }

    location_preference { zone = var.zone }
  }

  deletion_protection = false
  depends_on          = [google_service_networking_connection.private_service_connection]
}

resource "google_sql_database" "litellm_db" {
  name     = "litellm_db"
  instance = google_sql_database_instance.litellm_db_01.name
  project  = var.project_id
}

resource "google_sql_user" "litellm_user" {
  name     = "litellm_user"
  instance = google_sql_database_instance.litellm_db_01.name
  password = local.db_password
  project  = var.project_id
}


# Secret Manager(機密情報管理)

resource "google_secret_manager_secret" "litellm_master_key" {
  secret_id = "litellm-master-key"
  project   = var.project_id
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "litellm_master_key" {
  secret      = google_secret_manager_secret.litellm_master_key.id
  secret_data = local.master_key
}

resource "google_secret_manager_secret" "litellm_database_url" {
  secret_id = "litellm-database-url"
  project   = var.project_id
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "litellm_database_url" {
  secret      = google_secret_manager_secret.litellm_database_url.id
  secret_data = "postgresql://${google_sql_user.litellm_user.name}:${local.db_password}@${google_sql_database_instance.litellm_db_01.private_ip_address}:5432/${google_sql_database.litellm_db.name}"
}

resource "google_secret_manager_secret" "litellm_ui_username" {
  secret_id = "litellm-ui-username"
  project   = var.project_id
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "litellm_ui_username" {
  secret      = google_secret_manager_secret.litellm_ui_username.id
  secret_data = var.ui_username
}

resource "google_secret_manager_secret" "litellm_ui_password" {
  secret_id = "litellm-ui-password"
  project   = var.project_id
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "litellm_ui_password" {
  secret      = google_secret_manager_secret.litellm_ui_password.id
  secret_data = local.ui_password
}

resource "google_secret_manager_secret" "litellm_salt_key" {
  secret_id = "litellm-salt-key"
  project   = var.project_id
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "litellm_salt_key" {
  secret      = google_secret_manager_secret.litellm_salt_key.id
  secret_data = local.salt_key
}

resource "google_secret_manager_secret" "litellm_proxy_admin_id" {
  secret_id = "litellm-proxy-admin-id"
  project   = var.project_id
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "litellm_proxy_admin_id" {
  secret      = google_secret_manager_secret.litellm_proxy_admin_id.id
  secret_data = var.proxy_admin_id
}

resource "google_secret_manager_secret" "langfuse_public_key" {
  secret_id = "langfuse-public-key"
  project   = var.project_id
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "langfuse_public_key" {
  secret      = google_secret_manager_secret.langfuse_public_key.id
  secret_data = var.langfuse_public_key
}

resource "google_secret_manager_secret" "langfuse_secret_key" {
  secret_id = "langfuse-secret-key"
  project   = var.project_id
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "langfuse_secret_key" {
  secret      = google_secret_manager_secret.langfuse_secret_key.id
  secret_data = var.langfuse_secret_key
}

resource "google_secret_manager_secret" "litellm_config_yaml" {
  secret_id = "litellm-config-yaml"
  project   = var.project_id
  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "litellm_config_yaml" {
  secret      = google_secret_manager_secret.litellm_config_yaml.id
  secret_data = var.litellm_config_yaml
}

# OpenAI API Key Secret
resource "google_secret_manager_secret" "openai_api_key" {
  secret_id = "openai-api-key"
  project   = var.project_id

  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "openai_api_key" {
  secret      = google_secret_manager_secret.openai_api_key.id
  secret_data = var.openai_api_key
}

# Cloud Run Service

resource "google_cloud_run_v2_service" "litellm_proxy" {
  name                 = "litellm-proxy"
  location             = var.region
  project              = var.project_id
  ingress              = "INGRESS_TRAFFIC_ALL"
  invoker_iam_disabled = true

  template {
    execution_environment = "EXECUTION_ENVIRONMENT_GEN2"

    dynamic "volumes" {
      for_each = var.litellm_config_yaml != null ? [1] : []
      content {
        name = "litellm-config"
        secret {
          secret = google_secret_manager_secret.litellm_config_yaml.secret_id
          items {
            path    = "litellm_config.yaml"
            version = "latest"
          }
        }
      }
    }

    containers {
      # LiteLLM Proxy image from Docker Hub
      image = "docker.io/litellm/litellm:${var.litellm_version}"
      name  = "litellm-proxy"

      args = var.litellm_config_yaml != null ? [
        "--config", "/etc/litellm/litellm_config.yaml"
      ] : []

      ports {
        container_port = 4000
        name           = "http1"
      }

      # Environment variables
      env {
        name  = "LITELLM_LOG_LEVEL"
        value = "INFO"
      }

      env {
        name  = "STORE_MODEL_IN_DB"
        value = "True"
      }

      env {
        name = "LANGFUSE_PUBLIC_KEY"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.langfuse_public_key.secret_id
            version = "latest"
          }
        }
      }

      env {
        name = "LANGFUSE_SECRET_KEY"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.langfuse_secret_key.secret_id
            version = "latest"
          }
        }
      }

      env {
        name  = "LANGFUSE_HOST"
        value = var.langfuse_host
      }

      # Secret Manager references
      env {
        name = "DATABASE_URL"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.litellm_database_url.secret_id
            version = "latest"
          }
        }
      }

      env {
        name = "LITELLM_MASTER_KEY"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.litellm_master_key.secret_id
            version = "latest"
          }
        }
      }

      env {
        name = "UI_PASSWORD"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.litellm_ui_password.secret_id
            version = "latest"
          }
        }
      }

      env {
        name = "UI_USERNAME"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.litellm_ui_username.secret_id
            version = "latest"
          }
        }
      }

      env {
        name = "LITELLM_SALT_KEY"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.litellm_salt_key.secret_id
            version = "latest"
          }
        }
      }

      env {
        name = "PROXY_ADMIN_ID"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.litellm_proxy_admin_id.secret_id
            version = "latest"
          }
        }
      }

      # OpenAI API Key (conditional)
      dynamic "env" {
        for_each = var.openai_api_key != null ? [1] : []
        content {
          name = "OPENAI_API_KEY"
          value_source {
            secret_key_ref {
              secret  = google_secret_manager_secret.openai_api_key.secret_id
              version = "latest"
            }
          }
        }
      }

      # Resource limits
      resources {
        limits = {
          cpu    = "1000m"
          memory = "1Gi"
        }
        startup_cpu_boost = true
        cpu_idle          = true
      }

      dynamic "volume_mounts" {
        for_each = var.litellm_config_yaml != null ? [1] : []
        content {
          name       = "litellm-config"
          mount_path = "/etc/litellm"
        }
      }

      # Health check
      startup_probe {
        failure_threshold = 6
        http_get {
          path = "/"
          port = 4000
        }
        initial_delay_seconds = 60
        period_seconds        = 10
        timeout_seconds       = 10
      }
    }

    # Scaling configuration
    scaling {
      max_instance_count = 1
      min_instance_count = 0
    }

    max_instance_request_concurrency = 80
    service_account                  = google_service_account.lite_llm_proxy.email
    timeout                          = "300s"


    vpc_access {
      network_interfaces {
        network    = google_compute_network.litellm_vpc.id
        subnetwork = google_compute_subnetwork.cloudrun_egress.id
      }
      egress = "PRIVATE_RANGES_ONLY"
    }
  }

  traffic {
    percent = 100
    type    = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
  }

  deletion_protection = false


  depends_on = [
    google_project_service.required_apis,
    google_sql_user.litellm_user,
    google_service_account.lite_llm_proxy,
    google_project_iam_member.litellm_proxy_cloudsql_client,
    google_project_iam_member.litellm_proxy_secret_accessor,
  ]
}
# IAM for Cloud Run service
# Cloud Run IAM for load balancer access
resource "google_cloud_run_service_iam_member" "litellm_proxy_public" {
  service  = google_cloud_run_v2_service.litellm_proxy.name
  location = google_cloud_run_v2_service.litellm_proxy.location
  project  = google_cloud_run_v2_service.litellm_proxy.project
  role     = "roles/run.invoker"
  member   = "allUsers"
}

# Vertex AI permission for Cloud Run service account
resource "google_project_iam_member" "litellm_proxy_vertex_user" {
  project = local.vertex_project_id
  role    = "roles/aiplatform.user"
  member  = "serviceAccount:${google_service_account.lite_llm_proxy.email}"
}

resource "google_service_account" "lite_llm_proxy" {
  account_id   = "lite-llm-proxy"
  description  = "LiteLLM Proxy Service Account"
  display_name = "LiteLLM Proxy"
  project      = var.project_id
}

# IAM binding for service account
resource "google_project_iam_member" "litellm_proxy_cloudsql_client" {
  project = var.project_id
  role    = "roles/cloudsql.client"
  member  = "serviceAccount:${google_service_account.lite_llm_proxy.email}"
}

resource "google_project_iam_member" "litellm_proxy_secret_accessor" {
  project = var.project_id
  role    = "roles/secretmanager.secretAccessor"
  member  = "serviceAccount:${google_service_account.lite_llm_proxy.email}"
}


変数定義(`variables.tf`)

variable "project_id" {
  description = "GCP Project ID"
  type        = string
}

variable "region" {
  description = "GCP Region"
  type        = string
  default     = "asia-northeast1"
}

variable "zone" {
  description = "GCP Zone"
  type        = string
  default     = "asia-northeast1-a"
}


variable "db_password" {
  description = "Database password for LiteLLM user (optional)"
  type        = string
  default     = null
  sensitive   = true
}

variable "master_key" {
  description = "LiteLLM master key (optional)"
  type        = string
  default     = null
  sensitive   = true
}

variable "ui_username" {
  description = "UI username for LiteLLM admin"
  type        = string
  default     = "admin"
}

variable "ui_password" {
  description = "UI password for LiteLLM admin (optional)"
  type        = string
  default     = null
  sensitive   = true
}

variable "salt_key" {
  description = "Salt key for LiteLLM (optional)"
  type        = string
  default     = null
  sensitive   = true
}

variable "proxy_admin_id" {
  description = "Proxy admin ID"
  type        = string
  default     = "admin"
}

variable "langfuse_public_key" {
  description = "Langfuse public key"
  type        = string
  default     = null
  sensitive   = true
}

variable "langfuse_secret_key" {
  description = "Langfuse secret key"
  type        = string
  default     = null
  sensitive   = true
}

variable "langfuse_host" {
  description = "Langfuse host URL"
  type        = string
  default     = null
}

variable "vertex_project_id" {
  description = "Project ID where Vertex AI is used"
  type        = string
  default     = null
}

variable "litellm_config_yaml" {
  description = "Contents of litellm_config.yaml (optional)"
  type        = string
  default     = null
  sensitive   = true
}

variable "litellm_version" {
  description = "LiteLLM container image version"
  type        = string
  default     = "v1.75.8-stable"
}
variable "openai_api_key" {
  description = "OpenAI API key (optional)"
  type        = string
  default     = null
  sensitive   = true
}

出力値定義(`outputs.tf`)

output "cloud_run_url" {
  description = "Cloud Run service URL"
  value       = google_cloud_run_v2_service.litellm_proxy.uri
}

output "database_private_ip" {
  description = "Cloud SQL instance private IP"
  value       = google_sql_database_instance.litellm_db_01.private_ip_address
}

output "database_connection_name" {
  description = "Cloud SQL instance connection name"
  value       = google_sql_database_instance.litellm_db_01.connection_name
}

output "database_name" {
  description = "LiteLLM database name"
  value       = google_sql_database.litellm_db.name
}

output "service_account_email" {
  description = "LiteLLM Proxy service account email"
  value       = google_service_account.lite_llm_proxy.email
}

変数入力ファイル(`terraform.tfvars`)

# Google CloudのプロジェクトID、リージョン、ゾーンを入力してください
project_id = "your-project-id"
region     = "asia-northeast1"
zone       = "asia-northeast1-a"

# Langfuse settings(LLM可観測性プラットフォーム)
# Langfuse のパブリックキーとシークレットキー、ホストURLを入力してください
langfuse_public_key = "pk-lf-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
langfuse_secret_key = "sk-lf-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
langfuse_host       = "https://your-langfuse-instance.com"

# LiteLLM Container version
litellm_version = "v1.75.8-stable"

# OpenAI API Key
# OpenAI を利用する場合はOpenAI API Keyを設定してください。
openai_api_key = "sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# LiteLLM設定ファイル
# LiteLLM設定は litellm_config.yaml に設定します。以下を参考に設定してください。
# Vertex AIでGeminiを利用する場合はproject_id,locationの設定、OpenAIを利用する場合はOpenAI API Keyの設定が必要な点を注意ください。
# サンプル設定を以下に示します。
litellm_config_yaml = <<EOT
model_list:
  # Vertex AI Geminiモデル
  # Vertex AI を利用する場合はVertex AI Project ID,Locationを設定してください。
  - model_name: "gemini-pro"
    litellm_params:
      model: "vertex_ai/gemini-1.5-pro-002"
      vertex_project: "your-project-id"
      vertex_location: "asia-northeast1"
  - model_name: "gemini-flash"
    litellm_params:
      model: "vertex_ai/gemini-1.5-flash-002"
      vertex_project: "your-project-id"
      vertex_location: "asia-northeast1"
  # OpenAIモデル(API Key設定時のみ)
  # OpenAI を利用する場合はOpenAI API Keyを設定してください。
  - model_name: "gpt-4.1"
    litellm_params:
      model: "openai/gpt-4.1"
      api_key: os.environ/OPENAI_API_KEY
  - model_name: "gpt-4.1-mini"
    litellm_params:
      model: "openai/gpt-4.1-mini"
      api_key: os.environ/OPENAI_API_KEY
litellm_settings:
  success_callback: ["langfuse"]
  failure_callback: ["langfuse"]
EOT


Terraformの実行手順


下記の手順に従って、Terraformを実行LiteLLM Proxy環境を構築します。


1. Terraform 初期化

# 作業ディレクトリに移動
cd /path/to/your/terraform

# Terraform初期化
terraform init


2. 実行計画の確認

# 実行計画を確認
terraform plan


3. リソースの作成

# リソース作成実行
terraform apply

# 確認プロンプトで "yes" を入力


4. デプロイの確認

# 出力値の確認
terraform output

次のセクションでは、デプロイされたLiteLLM ProxyのLLM Gateway機能を実際に試行してみます。


LLM Gateway機能の試行


LiteLLM Proxyがデプロイされたら、実際にLLM Gateway機能をテストしてみましょう。


基本的な動作確認


1. ヘルスチェック

# Cloud RunのURL(outputsのcloud_run_urlで確認)
CUSTOM_DOMAIN=$(terraform output -raw cloud_run_url)

# ヘルスチェック
curl -sS -X GET "${CUSTOM_DOMAIN}/" -o /dev/null -w "%{http_code}\n"

# 200 が返ってくれば正常


2. 利用可能なモデル一覧の取得

# マスターキーを取得(実際の運用では環境変数に設定)
MASTER_KEY=$(gcloud secrets versions access latest --secret="litellm-master-key")

# モデル一覧を取得(ALB経由)
curl -X GET "${CUSTOM_DOMAIN}/v1/models" \
  -H "Authorization: Bearer ${MASTER_KEY}" \
  -H "Content-Type: application/json"

# モデル一覧が返ってくれば正常

OpenAI互換APIでのテスト


LiteLLM ProxyはOpenAI APIと互換性があるため、OpenAIクライアントと同様に使用できます。


1. Chat Completions API(GPT-4.1-mini)

# GPT-4.1-miniを使用したチャット
curl -X POST "${CUSTOM_DOMAIN}/v1/chat/completions" \
  -H "Authorization: Bearer ${MASTER_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4.1-mini",
    "messages": [
      {
        "role": "user",
        "content": "Hello! Please introduce yourself."
      }
    ],
    "max_tokens": 200,
    "temperature": 0.7
  }'

2. Chat Completions API(Google Gemini Flash)

# Gemini Flashを使用したチャット
curl -X POST "${CUSTOM_DOMAIN}/v1/chat/completions" \
  -H "Authorization: Bearer ${MASTER_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-flash",
    "messages": [
      {
        "role": "user",
        "content": "What are the advantages of using Google Cloud Run for hosting AI services?"
      }
    ],
    "max_tokens": 200,
    "temperature": 0.3
  }'

Web UIでの管理機能確認


LiteLLM ProxyにはWeb UIでの管理画面が用意されており、ブラウザで管理できます。


1. UIへのアクセス

以下のコマンドでUIへのアクセス情報が確認できます。

# UI認証情報を取得
UI_USERNAME=$(gcloud secrets versions access latest --secret="litellm-ui-username")
UI_PASSWORD=$(gcloud secrets versions access latest --secret="litellm-ui-password")

echo "UI URL: $(terraform output -raw cloud_run_url)/ui"
echo "Username: ${UI_USERNAME}"
echo "Password: ${UI_PASSWORD}"

# 以下のように出力される
UI URL: https://litellm-proxy-xxxxxxxx.a.run.app/ui
Username: xxxxx
Password: xxxxx


出力された情報をもとにWeb UIへログインします。


    LiteLLM ログイン画面
LiteLLM ログイン画面

2. UIで確認できる機能

LiteLLM のWeb UIからは以下のような情報が確認できます。

詳しくは公式ドキュメントを参照ください。(LiteLLM公式ドキュメントリンク


  • リクエスト統計: 各モデルの使用回数、成功/失敗率

  • コスト追跡 : プロバイダー別のコスト情報

  • 使用量制限 : ユーザーやAPIキー別の制限設定

  • ログ表示 : リアルタイムのリクエストログ

  • モデル管理 : 利用可能モデルの一覧と設定


LiteLLM Web UI画面
LiteLLM Web UI画面



LangfuseでのTrace確認


Langfuseでは、LiteLLM Proxyを利用した各種トレース情報が確認できます。

本手順で設定したLangfuseホストにアクセスし、Traceを確認します。



OpenAIのTrace確認


上記のCurlコマンドで確認したOpenAI/GTP へのアクセスのTraceを確認します。


    Langfuse - OpenAI Trace確認
Langfuse - OpenAI Trace確認

GeminiのTrace確認


上記のCurlコマンドで確認したVertexAI/Gemini へのアクセスのTraceを確認します。


Langfuse - Gemini Trace確認
Langfuse - Gemini Trace確認




まとめ


構築の利点の再確認


今回のTerraformとGoogle Cloud Runを使用したLiteLLM Proxy構築により、以下の利点が実現できました


1. 運用・管理面での利点


  • コスト一元管理: 複数のLLMプロバイダーのコストを統合して追跡・制御

  • APIキー管理: Secret Managerによる安全な機密情報管理

  • 統一API: OpenAI互換APIによる既存コードの再利用性


2. インフラ面での利点


  • サーバーレス: インフラ管理不要で自動スケーリング

  • 高可用性: Cloud Runのマネージドサービス利用

  • 監視: Cloud Loggingによる包括的なログ管理



おわりに


本記事では、TerraformとGoogle Cloud Runを用いて、Google Cloud上にLiteLLM Proxyを構築する手順を解説しました。


構築したLiteLLM Proxyは、複数のLLMプロバイダーを一元的に管理し、コストや使用量を効率的に制御できる強力なLLMゲートウェイとして機能します。また、Cloud Runのサーバーレスな特性により、運用負荷を最小限に抑えつつ高い可用性を実現できます。


本記事では触れませんでしたが、LiteLLM Proxyにはコスト管理やLLMプロバイダーのフォールバック機能など、LLMアプリケーションの開発・運用に役立つ機能が他にも備わっています。


ぜひ、LiteLLM Proxyを活用して、効率的で柔軟なLLMアプリケーション開発環境を構築してみてください!


コメント


bottom of page