LM Warden

アプリごとに一つのキー、キーごとに一つのページ。

同僚、ノート PC、CI ジョブ、エージェントのそれぞれに専用のキーを渡しましょう。キーのページには、使用量と、リクエストがキューで待った時間 (中央値と p95) が、ドラッグや入力で指定した任意の期間について表示されます。キーは猶予期間付きでローテーションでき、優先度を P0 ~ P9 で設定できます。待機中の P9 リクエストは常に P8 リクエストより先に処理されます。

一時停止すると、新しいリクエストは拒否され、すでに実行中のリクエストは最後まで処理されます。

$ curl -i http://gpu-box:8080/v1/chat/completions \
    -H "Authorization: Bearer vw_…" -d '{…}'
HTTP/1.1 403 Forbidden
content-type: application/json

{"detail":"token paused"}

2026 年 9 月 23 日のローカル インスタンスより。ホストとキーは置き換え、その他のヘッダーは省略しています。

図 13demo-agent のページ。図 1 の負荷を発生させたキーです。画面上の一時間で 37 リクエスト、生成トークン 43k。続いて God mode のドック (一つのキーのプロンプトと応答を表示するオプトインのライブ ビュー。既定ではオフ) が開き、応答が書き出されるそばからストリーミングされます。プロンプトは自社で用意したものです。
Stats ページの直近 7 日間 (9 月 16 日~23 日) の Requests グラフ:リクエストごとに一つのマーク。色は API キー、大きさは生成トークン数、形は終了理由を表し、縦軸は 100 ms から 10,000 s までの対数目盛の所要時間。ほとんどのマークは 3~100 秒の間にあり、あるキーは一秒未満から数百秒まで伸びる密な列を二本示している。
図 14すべてのキーのリクエストを一つのグラフに。同じ Stats ページより:直近 7 日間、28,906 リクエスト、十五件に一件の割合で描画。マーク一つがリクエスト一件で、色はキー、大きさは生成したトークン数、形は終わり方を表し、高さは対数目盛での所要時間です。安定した琥珀色が opencode-laptop、二本の密なピンクの列が research-notebook です。2026 年 9 月 23 日に記録。キー名は置き換えています。画像を横にスクロールすると一週間全体が見られます。

乗り換えは base_url の変更だけ。

/v1/chat/completions と /v1/models に対応し、/v1/models は各モデルの max_model_len を報告します。また /v1/messages で Anthropic Messages API にも対応しているので、Claude Code は ANTHROPIC_BASE_URL を warden のルート URL に向けるだけです (/v1/messages パスは Claude Code が自分で付けます)。さらに /v1/responses で OpenAI Responses API にも対応しているので、Codex CLI も読み込んだモデルを使えます。重みは通常の HuggingFace キャッシュにあり、make export-hf-cache で tarball として受け取れます。各エンジンを起動したときの正確な argv も GET 一回で取得できるので、動いている構成を私たちに頼らずに再構築できます。下の diff を逆にたどれば、それがそのまま乗り換えの手順になります。

  import os
  from openai import OpenAI

  client = OpenAI(
-     base_url="https://api.openai.com/v1",
-     api_key=os.environ["OPENAI_API_KEY"],
+     base_url="http://gpu-box:8080/v1",
+     api_key=os.environ["LM_WARDEN_KEY"],   # a vw_ key from API tokens
  )

  reply = client.chat.completions.create(
-     model="gpt-4o-mini",
+     model="gpt-oss-20b",   # the served name of a model you loaded
      messages=[{"role": "user", "content": "What is a KV cache?"}],
  )