📌

LiteLLMを使ったLLMの集約 & 簡易的なKey管理 + langfuse添え

に公開

プライベートな LLM API、会社利用での API、LocalLLM など、LLM を使うだけでもいろいろなエンドポイントがあり、管理が煩雑になることがあると思います。
そういったことへの対策として、いろいろなところで LiteLLM に関する記事はありますが、Key の管理についてはあまり触れられていないようなので簡単にまとめておきます。

LiteLLMとは

https://docs.litellm.ai/

LiteLLM は、LLM プロバイダーへのアクセスを統一的なインタフェースで提供する OSS です。LiteLLM Proxy Server (LLM Gateway) として起動することで、個々の LLM プロバイダーの API 仕様の違いを意識することなく、OpenAI 互換の形式でリクエストを送信し、様々なモデルを利用できるようになります。
加えて LiteLLM Proxy は、単なる API の抽象化に留まらず、エンタープライズレベルの運用機能を提供している。具体的には認証・認可・使用状況の追跡・コスト管理・レート制限・キャッシュ・モデルルーティング等です。きちんと設定すればプライベート利用にとどまらない利用ができると考えられます。

今回はあくまで個人利用の範囲で紹介します。

LiteLLMの起動 (コンテナ起動)

https://docs.litellm.ai/docs/proxy/deploy

ここを読もう! 呼んで、設定して、docker-compose up -d、これで OK です。

…だけだと寂しいので、大雑把に実施した環境変数の設定と config.yaml を以下に書きます。なお、config.yaml を読み込むようにするには docker-compose.yaml でコメントアウトされている volume 設定を有効にしてください。

環境変数

https://docs.litellm.ai/docs/proxy/config_settings#environment-variables---reference

設定できる一覧は上記にリストアップされています。私は以下のように設定しました。

.env
LITELLM_MASTER_KEY="sk-1234"
LITELLM_SALT_KEY="sk-1234"
DATABASE_URL = "postgresql://llmproxy:dbpassword9090@db:5432/litellm"
STORE_MODEL_IN_DB = "True"

LANGFUSE_PUBLIC_KEY="pk-lf-XXXX"
LANGFUSE_SECRET_KEY="sk-lf-XXXX"
LANGFUSE_HOST="http://localhost:8000"

上4つは公式リポジトリの記載ママです。Master Key を変更したい場合はここで設定します。SALT Key は、LiteLLM が API キーを暗号化するために使用されます。これも適宜変更してください。公式では1password のパスワードジェネレータ使えという推奨があります。

今回追加で設定したのはしたの3つです。これを設定すると、Langfuse が LiteLLM と連携できるようになります。個別にトレース設定をしなくても、LiteLLM を経由したリクエストは自動的に Langfuse に記録されます。基本的にはリクエスト単位の記録になるのでアプリケーションレベルでのトレース構造にはなりませんが、個人利用の範囲では十分なので設定しています。

config.yaml

やるべきことは、集約するモデルの設定と、その他のグローバルな LiteLLM 設定をすることです。

config.yaml
model_list:
  - model_name: claude-3-haiku
    litellm_params:
      model: bedrock/anthropic.claude-3-haiku-20240307-v1:0
      aws_region_name: ap-northeast-1
  - model_name: gpt-4o
    litellm_params:
      model: azure/gpt-4o
      api_base: https://****.openai.azure.com/
      api_version: "2025-01-01-preview"
      api_key: XXXX
  - model_name: deepseek-R1
    litellm_params:
      model: openrouter/deepseek/deepseek-r1
      api_key: sk-or-XXXX
  - model_name: ollama_chat/qwen3:4b
    litellm_params:
      model: ollama_chat/qwen3:4b
      api_base: "http://host.docker.internal:11434"

litellm_settings:
  drop_params: True
  success_callback: ["langfuse"]
  redact_user_api_key_info: true

私は、Bedrock、Azure OpenAI、OpenRouter、Ollama のモデルを集約しています。各モデルの設定は、litellm_params で指定します。
Bedrock は aws configure で設定したプロファイルを利用可能な状態にすれば (例えばホストの .aws を volume にマウントするなど)、モデル名とリージョンの設定のみで利用可能です。
Ollama は別のコンテナで起動している Langfuse と接続することにしたため、コンテナからホストへアクセスするように指定しています。この設定で Ollama が起動していれば、LiteLLM 経由で Ollama のモデルを利用できました。

litellm_settings では、LiteLLM の動作に関する設定をします。drop_params はリクエストパラメータを削除するかどうか、success_callback は成功したリクエストのコールバック先を指定します。ここでは Langfuse を指定することで、リクエストのトレース情報を Langfuse に送信しています。redact_user_api_key_info は、ユーザーの API キー情報をマスクするための設定です。

models
登録したモデルはこんな感じの一覧で見れる

Keyの管理

LiteLLM では、API キーの管理を簡単に行うことができます。

認証方法自体は OAuth2.0での認証やカスタム設定もできるようです。様々な認証方式をサポートするということは、LiteLLM が単なる API ゲートウェイではなく認証・認可の機能も持っていることを意味します。認証された主体がどのモデルにアクセスできるか、どれだけの量をどの程度の頻度で利用できるかといったポリシーを適用できます。組織的な ID 管理やセキュリティポリシーと深く統合できるということですね。

一方で、個人利用の範囲ではそこまでの重量級の機能は必要なく、API キーを直接管理するのが簡単でリーズナブルと考えています。特に Master Key と Virtual Key による階層的なキー管理は、セキュリティと運用効率のバランスが取れた方法ではないでしょうか。

Master Key

Master Key は、LiteLLM の管理者が持つキーで、全ての管理権限を持ちます。
これを指定すればあらゆるリクエストを実行できるため、よく注意して管理する必要があると思います。

設定方法

Master Key は、主に以下の方法で設定できました。

  • config.yaml での設定

前述の通り、config.yaml に以下のように設定することで Master Key を指定。

config.yaml
general_settings:
  master_key: "sk-yourMasterKey12345"
  • 環境変数での設定

環境変数 LITELLM_MASTER_KEY を設定することでも Master Key を指定。

.env
LITELLM_MASTER_KEY="sk-yourMasterKey12345"

できること

基本的にはすべてのコントロール権を持つキーです。具体的には以下のような操作が可能です。

  • Virtual Key の管理
    • 新規 Virtual Key の発行 (/key/generate エンドポイント)
    • 既存 Virtual Key の情報照会 (/key/info エンドポイント)
    • Virtual Key の更新 (/key/update エンドポイント、例: 予算増額、ガードレール設定)
    • Virtual Key の無効化/ブロック (/key/block エンドポイント)
    • Virtual Key の削除
  • ユーザー管理
    • 新規ユーザーの作成 (/user/new エンドポイント)
    • ユーザー情報の照会 (/user/info エンドポイント)
    • ユーザーの削除 (/user/delete エンドポイント)
  • チーム管理
    • 新規チームの作成 (/team/new エンドポイント)
    • チーム情報の照会 (/team/info エンドポイント)
    • チームへのコールバック設定(ロギングなど)(/team/callback エンドポイント)
  • モデル管理
    • プロキシで利用可能なモデルの追加、更新、削除(CLI 経由など)
  • 認証情報管理
    • LLM プロバイダーの認証情報(API キーなど)の管理(CLI 経由など)
  • 管理 UI および CLI からの操作
    • LiteLLM Proxy UI を介した各種管理操作のバックエンド認証
    • litellm-proxy CLI を用いた管理コマンド実行時の認証
  • Master Key 自体の管理
    • Master Key のローテーション (/key/regenerate エンドポイント)

Master Keyのローテーション

ベストプラクティスとして、Master Key は定期的にローテーションすることが推奨されているようです (私はそもそも外部公開していないし、面倒なのでやっていませんが)。
万が一の漏洩時にも被害を最小限に抑えることができるので良い設計ですね。こんな感じで利用できるようです。

curl -L -X POST 'http://localhost:4000/key/regenerate' \
-H 'Authorization: Bearer <current-master-key>' \
-H 'Content-Type: application/json' \
-d '{
    "key": "<current-master-key>",
    "new_master_key": "<new-master-key>"
}'

Virtual Key

Virtual Key は、LiteLLM Proxy を利用するクライアントアプリケーションやエンドユーザに発行されます。 API キーであり、実際の LLM リクエストの認証と認可を担います。
Master Key がプロキシ全体の管理を司るのに対し、Virtual Key はより限定的な権限を設定できます。こういったあたりを作り込まなくても、compose でぱぱっと起動して使い始められるのが LiteLLM の良いところですね。

作成方法

API (/key/generate)、CLI、Web UI のいずれかから Virtual Key を作成できます。Web UI からの作成は、LiteLLM Proxy の管理 UI にアクセスし Virtual Keys → Create New Key を選択します。

Virtual Key作成
Virtual Keyの作成画面

この画面を見るとわかるように、以下のような内容を個別に設定できます。社内で LLM の API 基盤を作ったり、部署ごとにバジェットコントロール、クォータコントロールをしたりする場合には変にスクラッチで作るより LiteLLM を使ったほうが多分セキュアで楽ですね。

設定値 設定例 説明
Models ["gpt-3.5-turbo", "gpt-4"] アクセスを許可するモデルのリスト
Aliases {"gpt-4-alias": "gpt-4"} モデル名のエイリアス
Duration 30d 有効期間
Max Budget 100.0 最大利用予算 (USD)
TPM Limit 10000 1分あたりの最大トークン数
RPM Limit 100 1分あたりの最大リクエスト数
User ID user-123 関連付けるユーザーID
Team ID team-abc 関連付けるチームID
Metadata {"project": "alpha"} カスタムメタデータ
Key Alias my-project-key キーのエイリアス(管理用の表示名)
Guardrails ["pii-masking"] 適用するガードレールのリスト

利用方法

OpenAI API 互換の形式でリクエストを送信することで、LiteLLM Proxy は Virtual Key を使用するだけです。

認証が通ってかつ、許可されたモデルに対してはリクエストが通ります。

認証が通るとき
$ curl -X POST http://localhost:8000/chat/completions \
  -H "Authorization: Bearer sk-****" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "messages": [
      {
        "role": "user",
        "content": "こんにちは、調子はどうですか?"
      }
    ]
  }'

{
  "id": "chatcmpl-BhYvissWugcPiamCNtaVTVdEAbkrY",
  (...中略...)
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "こんにちは!私はAIなので体調の概念はありませんが、きちんと動作しています。何かお手伝いできることはありますか?",
        "role": "assistant",
        "tool_calls": null,
        "function_call": null,
        "annotations": []
      }
    }
  ],
  (...中略...)
}

一方で、Virtual Key で許可されていないモデルに対してリクエストを送信すると、認証は通ってもリクエストは拒否されます。

認証が失敗したとき
$ curl -X POST http://localhost:8000/chat/completions \
  -H "Authorization: Bearer sk-****" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-3-7-sonnet",
    "messages": [
      {
        "role": "user",
        "content": "こんにちは、調子はどうですか?"
      }
    ]
  }'

{
  "error": {
    "message": "key not allowed to access model. This key can only access models=['gpt-4o']. Tried to access claude-3-7-sonnet",
    "type": "key_model_access_denied",
    "param": "model",
    "code": "401"
  }
}

ちなみに、ここで Authorization ヘッダに Master Key を指定すると全部通ります。

Langfuseとの連携

LiteLLM と Langfuse を連携させると、LiteLLM を経由したリクエストのトレース情報を Langfuse に自動的に記録されます。こんな感じ。

Langfuseとの連携
Langfuseのトレース画面

前述の通り、アプリケーション単位のトレースではなく、LiteLLM を経由したリクエスト単位のトレースになりますが、個人利用の範囲では十分な情報が得られます。

具体的にどんなリクエストが発生したんだっけ? トークン数どのくらいだっけ? なんか挙動おかしいけどちゃんとリクエスト通ってるの? といった、見たいけどぱっと取るのがいまいち面倒な情報を確認できるので、雑に LLM 使いたいだけ勢としてはちょうどいい塩梅だと思ってます。

もうちょっと設定したらいい感じでトレースの仕方も変えられたりするのかもしれないですが、個人的な需要がないので今回はここまで。

…まぁ、LangGraph とか使うときは LangGraph でトレース設定したりするんですが😛。

まとめ

LiteLLM を使うことで、複数の LLM プロバイダーへのアクセスを統一的に管理できるだけでなく、API キーの管理も簡単に行えるようになります。ついでに Langfuse も連携させられます。

というお話でした。

とある通信会社の有志

Discussion