LiteLLMを使ったLLMの集約 & 簡易的なKey管理 + langfuse添え
プライベートなLLM API、会社利用でのAPI、LocalLLMなど、LLMを使うだけでもいろいろなエンドポイントがあり管理が煩雑になる、あると思います。
そういったことへの対策として、いろいろなところでLiteLLMに関する記事はありますが、Keyの管理についてはあまり触れられていないようなので簡単にまとめておきます。
LiteLLMとは
LiteLLMは、LLMプロバイダーへのアクセスを統一的なインターフェースで提供するOSSです。LiteLLM Proxy Server (LLM Gateway) として起動することで、個々のLLMプロバイダーのAPI仕様の違いを意識することなく、OpenAI互換の形式でリクエストを送信し、様々なモデルを利用できるようになります。
加えてLiteLLM Proxyは、単なるAPIの抽象化に留まらず、認証、認可、使用状況の追跡、コスト管理、レート制限、キャッシュ、モデルルーティングといった、エンタープライズレベルの運用機能を提供しており、きちんと設定すればプライベート利用にとどまらない利用ができる気がします。
今回はあくまで個人利用の範囲で紹介します。
LiteLLMの起動 (コンテナ起動)
ここを読もう!呼んで、設定して、docker-compose up -d
、これでOKです。
…だけだと寂しいので、大雑把に実施した環境変数の設定とconfig.yamlを以下に書きます。なお、config.yamlを読み込むようにするにはdocker-compose.yamlでコメントアウトされているvolume設定を有効にする必要があります。
環境変数
設定できる一覧は上記にリストアップされています。私は以下のように設定しました。
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設定を行うことです。
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キー情報をマスクするための設定です。
登録したモデルはこんな感じで一覧で見れる
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を指定。
general_settings:
master_key: "sk-yourMasterKey12345"
- 環境変数での設定
環境変数 LITELLM_MASTER_KEY を設定することでもMaster Keyを指定。
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の作成画面
この画面を見るとわかるように、以下のような内容を個別に設定できます。社内で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のトレース画面
前述の通り、アプリケーション単位のトレースではなく、LiteLLMを経由したリクエスト単位のトレースになりますが、個人利用の範囲では十分な情報が得られます。
具体的にどんなリクエストが発生したんだっけ?、トークン数どのくらいだっけ?、なんか挙動おかしいけどちゃんとリクエスト通ってるの?、といった、見たいけどぱっと取るのがいまいち面倒な情報が確認できるので、雑にLLM使いたいだけ勢としてはちょうどいい塩梅だと思ってます。
もうちょっと設定したらいい感じでトレースの仕方も変えられたりするのかもしれないですが、個人的な需要がないので今回はここまで。
…まぁ、LangGraphとか使うときはそれはそれでトレース設定したりするんですが😛。
まとめ
LiteLLMを使うことで、複数のLLMプロバイダーへのアクセスを統一的に管理できるだけでなく、APIキーの管理も簡単に行えるようになります。ついでにLangfuseも連携させられます。
というお話でした。
Discussion