ロード テストでは、パフォーマンスが低下する前に Databricks Apps エージェントが保持できる 1 秒あたりの最大クエリ数 (QPS) が検出されます。 このページでは、次の操作を行う方法を示します。
- エージェントのモック バージョンをデプロイして、インフラストラクチャのスループットを LLM 待機時間から分離します。
- Locustを使用して、負荷を段階的に増大させる彩度負荷テストを実行します。
- 対話型ダッシュボードを使用して結果を分析します。
Claude Code スキルを使用して AI 支援パスに従うか、各手順を手動で設定できます。
要件
- Databricks Apps が有効になっているAzure Databricks ワークスペース。
- OpenAI Agents SDK、LangGraph、またはカスタム フレームワークを使用して Databricks Apps にデプロイされた (またはデプロイする準備ができている) エージェント アプリ。 「AI エージェントを作成して Databricks Apps にデプロイする」を参照してください。
- Databricks CLI がインストールされ、認証されました。 「Databricks CLI のインストールまたは更新」を参照してください。
-
uvパッケージマネージャーと共に Python バージョン 3.10 以降が必要です。 - (AI 支援パスの場合) Claude Code がインストールされています。
- (最大 1 時間を超えるロード テストの場合)M2M OAuth 資格情報 (
client_idとclient_secret) を持つサービス プリンシパル。 Azure Databricks へのサービス プリンシパル アクセスを OAuth で承認する方法については、こちらを参照してください。- 短いロード テスト (最大 1 時間未満) の場合、既存のユーザー (U2M) の OAuth 資格情報
databricks auth login正常に動作します。 より長いテストの場合は、サービス プリンシパルで M2M OAuth を使用します。U2M トークンは、長時間の実行中に期限切れになり、テスト途中のエラーが発生します。 サービス プリンシパルを作成するには、ワークスペース管理者アクセスが必要です。
- 短いロード テスト (最大 1 時間未満) の場合、既存のユーザー (U2M) の OAuth 資格情報
AI 支援のセットアップ (推奨)
Claude Code を使用すると、 /load-testing スキルによってワークフローが自動化されます。 エージェント コードを読み取り、モックを生成し、ロード テスト スクリプトを作成し、デプロイの手順を説明します。
ヒント
Claude Code にこれを行うように指示します。
Clone https://github.com/databricks/app-templates and run the /load-testing skill against the {your-template} template.
または、次の手順に従います。
手順 1: エージェント テンプレートを複製する
/load-testing スキルは、最上位の スキルとして agent-load-testing リポジトリに含まれており、すべての個々のエージェント テンプレートに事前に同期されます。
app-templatesのプロジェクトが既にある場合は、既にスキルを持っています。
リポジトリを複製し、ロード テストするエージェントのテンプレート ディレクトリに変更します。
git clone https://github.com/databricks/app-templates.git
cd app-templates/{your-template}
手順 2: ロード テスト スキルを実行する
Claude Code で、次のコマンドを実行します。
/load-testing
このスキルでは、次の手順について対話形式で説明します。 モック作成をスキップして実際のエージェントをテストしたり、アプリが既に実行されている場合はデプロイをスキップしたりできます。
- パラメーターの収集: デプロイの状態、コンピューティング サイズ、worker 構成、OAuth 資格情報について質問します。
-
ロード テスト スクリプトの作成: プロジェクトに合わせた
locustfile.py、run_load_test.py、dashboard_template.pyを生成します。 - LLM のモック: 実際の LLM 呼び出しを構成可能なストリーミング遅延を使用して置き換えるために、SDK(OpenAI Agents SDK、LangGraph、またはカスタム)に特化したモック クライアントを作成します。
- テスト アプリのデプロイ: さまざまなコンピューティング サイズと worker 数で複数のアプリ構成をデプロイする手順について説明します。
- テストの実行: M2M OAuth 認証と飽和度の上昇を使用してロード テストを実行します。
- 結果の生成: QPS、待機時間、および失敗のメトリックを含む対話型 HTML ダッシュボードが生成されます。
手動セットアップ
AI 支援なしでロード テストを設定して実行するには、次の手順に従います。
手順 1: エージェントの LLM 呼び出しをモックする方法 (省略可能)
実際の LLM 待機時間を含むエンドツーエンドの結果が必要な場合は、この手順をスキップします。 Databricks Apps インフラストラクチャのスループットを分離して測定するには、LLM をモックして、要求ごとの待機時間 (通常は 1 ~ 30 秒) がボトルネックにならないようにします。
モックは、構成可能なストリーミング遅延を伴い既定の応答を返します。要求と応答の完全なパイプライン (SSE ストリーミング、ツールディスパッチ、SDK ランナー) を維持しつつ、LLM のみを置き換えます。 これにより、Databricks Apps プラットフォームが提供できる最大 QPS が表示され、ロード テスト中の Foundation Model API トークンコストが回避されます。
モック タイミングは、次の 2 つの環境変数によって制御されます。
| Variable | デフォルト | Description |
|---|---|---|
MOCK_CHUNK_DELAY_MS |
10 |
ストリーミングされたテキスト チャンク間の遅延 (ミリ秒単位) |
MOCK_CHUNK_COUNT |
80 |
応答ごとのテキストチャンク数 |
既定値では、各モック応答は約 800 ミリ秒 (10 ミリ秒 x 80 チャンク) で、実際の LLM 応答 (3 ~ 15 秒) よりも大幅に高速になります。 スループット番号は、モデルではなくプラットフォームを反映します。
実際の LLM クライアントを置き換えるモック クライアントを作成します。 残りのエージェント コードは変更されず、方法は SDK によって異なります。 OpenAI については、mock_openai_client.pyのdatabricks/app-templatesを参照してください。 同じパターンが他の SDK に適応します。
OpenAI Agents SDK
agent_server/mock_openai_client.pyを作成します。ストリーミングを使用してMockAsyncOpenAIを実装するchat.completions.create() クラスです。 使用するツールの呼び出しチャンクは即座に返され(ツールの呼び出しを決定するLLMをシミュレートします)、テキスト応答チャンクはMOCK_CHUNK_DELAY_MSおよびMOCK_CHUNK_COUNTに設定された環境変数からの設定可能な遅延で返されます。
エージェントにスワップします。
from agent_server.mock_openai_client import MockAsyncOpenAI
from agents import set_default_openai_client, set_default_openai_api
set_default_openai_client(MockAsyncOpenAI())
set_default_openai_api("chat_completions")
残りのエージェント コード (ハンドラー、ツール、ストリーミング ロジック) は変更されません。
LangGraph
ChatDatabricks モデルを、事前構築済みのAIMessage オブジェクトを返すモックに置き換えます。
# Before:
# model = ChatDatabricks(endpoint="databricks-claude-sonnet-4")
# After:
from agent_server.mock_llm import MockChatModel
model = MockChatModel()
モックは、最初の呼び出し時にツール呼び出しを含む AIMessage オブジェクトを返し、後続の呼び出しではテキスト コンテンツを返し、ストリーミング遅延を構成できます。
カスタム エージェント
エージェントが行う外部 API 呼び出し (LLM、ベクター検索、ツール API) を、構成可能な遅延を伴う現実的な応答図形を返すモック実装でラップします。
手順 2: ロード テスト スクリプトを設定する
プロジェクトに load-test-scripts/ ディレクトリを作成します。 ロード テスト フレームワークは、フレームワークに依存しない 3 つのスクリプトで構成され、Databricks Apps エージェントと連携します。
<project-root>/
agent_server/ # Your existing agent code
load-test-scripts/ # Load testing scripts (create this)
run_load_test.py # CLI orchestrator
locustfile.py # Locust test with SSE streaming + TTFT tracking
dashboard_template.py # Interactive HTML dashboard generator
load-test-runs/ # Results (auto-created per run)
<run-name>/
dashboard.html # Interactive dashboard
test_config.json # Test parameters for reproducibility
<label>/ # Per-config Locust CSV output
フレームワークには、次のファイルが含まれています。
-
locustfile.py:POST /invocations要求をstream: trueを使用して送信し、SSEストリームを解析します。カスタムメトリックとして最初のトークンまでの時間 (TTFT) を追跡し、自動更新機能を使ったM2M OAuthトークン交換を実施します。また、各レベルをstep_duration秒間維持しながら、ユーザー数をstep_sizeからmax_usersに徐々に増加させるStepRampShapeを実装するロードテスト。 -
run_load_test.py: 構成ごとに分離されたメトリックを使用して各アプリの URL を順番にテストする CLI オーケストレーター。 OAuth トークンの更新を処理し、各テストの前に正常性チェックとウォームアップを実行し、結果をload-test-runs/<run-name>/<label>/に保存します。 -
dashboard_template.py: KPI カード、棒グラフ (QPS、待機時間、構成別 TTFT)、QPS ランプ進行折れ線グラフ、および完全な結果テーブルを含む Chart.js を使用して自己完結型 HTML ダッシュボードを生成します。 スタンドアロンで実行できます:uv run dashboard_template.py ../load-test-runs/<run-name>/。
依存関係のインストール
ロード テスト スクリプトは、エージェントの運用環境の依存関係を汚染しないように、pyproject.toml内で独自のload-test-scripts/を使用します。
load-test-scripts/pyproject.tomlを作成します。
[project]
name = "load-test-scripts"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
"locust>=2.32,<2.40",
"urllib3<2.3",
"requests",
]
Note
locustを<2.40にピン留めします。 新しいバージョン (>=2.43) には、長いロード テストを中断する既知の RecursionError があります。
load-test-scripts/ ディレクトリ内からインストールします。
cd load-test-scripts/
uv sync
手順 3: さまざまな構成でテスト アプリをデプロイする
コンピューティング サイズとワーカー数が異なる複数の Databricks Apps をデプロイして、ワークロードに最適な構成を見つけます。
推奨されるテスト マトリックス
以下の構成では、前のテストで識別されたスイート スポットに焦点を当てています。 より広範なカバレッジが必要な場合は、どちらかの側に 1 つの構成 ( medium-w1 や large-w12など) を追加しますが、通常は次の 6 つで十分です。
| コンピューティング サイズ | 作業者 | 推奨されるアプリ名 |
|---|---|---|
| Medium | 2 | <your-app>-medium-w2 |
| Medium | 3 | <your-app>-medium-w3 |
| Medium | 4 | <your-app>-medium-w4 |
| 大 | 6 | <your-app>-large-w6 |
| 大 | 8 | <your-app>-large-w8 |
| 大 | 10 | <your-app>-large-w10 |
計算サイズの設定
Databricks CLI を使用して、アプリの作成時または更新時にコンピューティング サイズを設定します。
# Create a new app with Medium compute
databricks apps create <app-name> --compute-size MEDIUM
# Update an existing app to Large compute
databricks apps update <app-name> --compute-size LARGE
宣言型オートメーション バンドルを使用してワーカー数を構成する
start-server ( AgentServer.run()経由)は、 --workers フラグを直接受け入れます。 DAB 変数を使用して、 command 配列にワーカー数を渡します。
variables:
app_name:
default: 'my-agent-medium-w2'
workers:
default: '2'
resources:
apps:
load_test_app:
name: ${var.app_name}
source_code_path: .
config:
command: ['uv', 'run', 'start-server', '--workers', '${var.workers}']
env:
- name: MOCK_CHUNK_DELAY_MS
value: '10'
- name: MOCK_CHUNK_COUNT
value: '80'
targets:
medium-w2:
default: true
variables:
app_name: 'my-agent-medium-w2'
workers: '2'
large-w8:
variables:
app_name: 'my-agent-large-w8'
workers: '8'
デプロイと確認
Databricks CLI を使用して各ターゲットをデプロイします。
databricks bundle deploy --target medium-w2
databricks bundle run load_test_app --target medium-w2
ロード テストを実行する前に、アプリがアクティブであることを確認します。
databricks apps get <app-name> --output json | jq '{app_status, compute_status, url}'
Note
続行する前に、すべてのアプリが ACTIVE 状態になるまで待ちます。 まだ開始中のアプリは、誤解を招く結果を生み出します。
手順 4: ロード テストを実行する
認証の設定
実行する予定の期間に基づいて認証を選択します。
-
短いテスト (最大 1 時間未満):
databricks auth loginの既存のユーザー資格情報を使用します。 追加のセットアップは必要ありません。 - 長いテスト (夜間の実行など、最大 1 時間を超える): サービス プリンシパルで M2M OAuth を使用します。 U2M トークンの有効期限が切れ、テストの途中で中断します。 サービス プリンシパルを作成するには、ワークスペース管理者アクセスが必要です。
M2M OAuth の場合は、テストを実行する前にサービス プリンシパルの資格情報をエクスポートします。
export DATABRICKS_HOST=https://your-workspace.cloud.databricks.com
export DATABRICKS_CLIENT_ID=<your-client-id>
export DATABRICKS_CLIENT_SECRET=<your-client-secret>
パラメーターリファレンス
| パラメーター | 必須 | デフォルト | Description |
|---|---|---|---|
--app-url |
はい | — | テストするアプリの URL (繰り返し可能) |
--client-id |
長いテストの場合 |
DATABRICKS_CLIENT_ID Env |
サービス プリンシパル クライアント ID (M2M OAuth) |
--client-secret |
長いテストの場合 |
DATABRICKS_CLIENT_SECRET Env |
サービス プリンシパル クライアント シークレット (M2M OAuth) |
--label |
いいえ | URL から自動派生 | アプリごとの人間が判読できるラベル (繰り返し可能) |
--compute-size |
いいえ | 自動検出または medium |
アプリあたりのコンピューティング サイズ タグ: medium、 large (反復可能) |
--max-users |
いいえ | 300 |
シミュレートされた最大同時ユーザー数 |
--step-size |
いいえ | 20 |
ランプ ステップごとに追加されたユーザー |
--step-duration |
いいえ | 30 |
ランプステップあたりの秒 |
--spawn-rate |
いいえ | 20 |
ユーザーの生成率 (ユーザー/秒) |
--run-name |
いいえ | <timestamp> |
この実行の名前 — load-test-runs/<run-name>/ に保存された結果 |
--dashboard |
いいえ | オフ | テストの完了後に対話型 HTML ダッシュボードを生成する |
コマンドの例
クイック シングル アプリ テスト (短い実行 — databricks auth login セッションを使用):
cd load-test-scripts/
uv run run_load_test.py \
--app-url https://my-app.aws.databricksapps.com \
--dashboard --run-name quick-test
推奨される 6 つの構成全体の完全なマトリックス (長い実行 — M2M 資格情報を渡します)。
--compute-sizeと同じ順序で--app-urlフラグを渡します。
uv run run_load_test.py \
--app-url https://my-app-medium-w2.aws.databricksapps.com \
--app-url https://my-app-medium-w3.aws.databricksapps.com \
--app-url https://my-app-medium-w4.aws.databricksapps.com \
--app-url https://my-app-large-w6.aws.databricksapps.com \
--app-url https://my-app-large-w8.aws.databricksapps.com \
--app-url https://my-app-large-w10.aws.databricksapps.com \
--compute-size medium --compute-size medium --compute-size medium \
--compute-size large --compute-size large --compute-size large \
--client-id $DATABRICKS_CLIENT_ID \
--client-secret $DATABRICKS_CLIENT_SECRET \
--dashboard --run-name overnight-sweep
統計的一貫性のための複数の実行:
for RUN in r1 r2 r3 r4 r5; do
uv run run_load_test.py \
--app-url https://my-app.aws.databricksapps.com \
--client-id $DATABRICKS_CLIENT_ID \
--client-secret $DATABRICKS_CLIENT_SECRET \
--max-users 1000 --step-size 20 --step-duration 10 \
--run-name my_test_${RUN} --dashboard || break
done
実行中に何が起こるか
-
正常性チェック: アプリストリームを正しく検証します (
[DONE]を受け取ります)。 - ウォームアップ: アプリをウォームアップするための順次要求を送信します。
-
飽和への漸増:
step_duration秒ごとに同時ユーザーを増加させます。 - 飽和検出: ユーザー数が増えても QPS が頭打ちになると、スループットの上限に到達しました。
予測期間
テスト対象の各アプリは独自のランプを通じて実行されるため、合計実行時間はマトリックス内の構成の数に応じてスケーリングされます。 実行ウィンドウを計画するには、次の式を使用します。
アプリあたりの期間: (max_users / step_size) * step_duration 秒。
既定値 (--max-users 300 --step-size 20 --step-duration 30):
- 15 ステップ x 30 秒 = アプリあたり約 7.5 分
- 推奨される 6 構成マトリックスの場合: 実行あたり約 45 分
手順 5: 結果を表示して解釈する
ダッシュボードを開きます。
open load-test-runs/<run-name>/dashboard.html(省略可能)テンプレートを更新した後など、既存のデータからダッシュボードを再生成します。
cd load-test-scripts/ uv run dashboard_template.py ../load-test-runs/<run-name>/
ダッシュボード セクション
対話型ダッシュボードには、次のものが含まれます。
- KPI カード: 最適な構成 (ピーク成功 QPS 別)、全体のピーク QPS、最短待ち時間、および処理された総リクエスト数。
- 構成別 QPS: 中央値の QPS、障害を除くピーク QPS、および各構成のピーク QPS を並べて示すグループ化された横棒グラフ。
- 構成による待機時間: p50 と p95 の待機時間を示すグループ化されたバー。
- 構成による TTFT: 最初のトークンへの時間 (p50 と p95)。
- 提供された要求の合計数: 構成あたりの要求数。
- QPS ランプアップの進行: QPS、QPS (障害を除く)、レイテンシ、および失敗に関するタブ付き折れ線グラフ。 同時実行数の範囲を調整するための最大ユーザー数スライダーが含まれています。 グラフは、コンピューティング サイズ (中と大の横並び) でグループ化されます。
- 完全な結果テーブル: QPS のピーク時、ピーク時のユーザー、待機時間のパーセンタイル、および失敗率を持つすべての構成。
- テスト パラメーター: 再現性のための構成の概要。
結果を解釈する方法
- ピーク QPS: ランプ ステップで達成される最大 QPS。 これは、その構成のスループット上限です。
- ピーク時のユーザー: ピーク時の QPS が達成された同時ユーザーの数。 この時点を超えてユーザーを追加しても、スループットは向上しません。
- 失敗率: 0% または非常に低い値にする必要があります。 エラー率が高いということは、アプリがそのコンカレンシー レベルでオーバーロードされていることを意味します。
- QPS ランプ チャート: 線が平坦化する場所を探します。 これは飽和点です。ユーザーを追加してもスループットは向上しません。
トラブルシューティング
| 問題点 | 解決策 |
|---|---|
| 認証トークンのテスト中に期限切れになりました | 最大 1 時間を超えるテストの場合は、 --client-id を渡して U2M から M2M OAuth に切り替えます。 --client-secret |
| 健康診断が失敗しました | アプリがアクティブであることを確認します。 databricks apps get <name> --output json |
| 0 QPS または結果なし |
load-test-runs/<run-name>/<label>/locust_output.log のエラーをチェックする |
| ユーザー数が多いにもかかわらず、QPS が低い | アプリが飽和状態です。 より多くのワーカーまたは大規模なコンピューティングを試してみてください。 |
| 高い故障率 | アプリがオーバーロードされています。
--max-usersを減らすか、ワーカー数または計算リソースを増やします。 |
| ダッシュボードにランプ データが表示されない | 各結果サブディレクトリに results_stats_history.csv が存在するかどうかを確認する |
次のステップ
- 実際の LLM 呼び出しでテストする: モック作成手順をスキップし、実際のエージェントをデプロイして、LLM 応答時間を含むエンド ツー エンドの待機時間を測定します。
- ワーカー数を調整する: テスト マトリックスの結果を使用して、コンピューティング サイズに最適なワーカー数を見つけます。
- チュートリアル: GenAI アプリケーションを評価して改善し 、スループットと共に精度、関連性、安全性を測定します。