Databricks Appsエージェントの負荷テストを実行する
負荷テストにより、パフォーマンスが低下する前にDatabricks Appsエージェントが維持できる1秒あたりの最大クエリー数 (QPS) が判明します。このページでは、次の操作を行う方法を説明します:
- エージェントのモックバージョンをデプロイし、インフラストラクチャのthroughputをLLMのレイテンシーから分離します。
- Locust を使用して、ランプアップ飽和負荷テストを実行します。
- インタラクティブダッシュボードで結果を分析します。
Claude Codeスキルを使用してAIアシストパスに従うか、各ステップを手動で設定できます。

要件
- Databricks Appsが有効化されたDatabricksワークスペース。
- OpenAI Agents SDK、LangGraph、またはカスタムフレームワークを使用してDatabricks Appsにデプロイされた(またはデプロイ準備が整った)エージェントアプリ。AI エージェントを作成してDatabricks Appsにデプロイするを参照してください。
- Databricks CLI がインストールされ、認証されました。Databricks CLI のインストールまたは更新を参照してください。
- Python 3.10 以降と
uvパッケージマネージャー。 - (AI支援パスの場合) Claude Codeがインストールされていること。
- (ロードテストが約1時間を超える場合)M2M OAuth 資格情報(
client_idおよびclient_secret)を持つService Principal。OAuthを使用したDatabricksへのService Principal アクセスの承認を参照してください。- 短いロードテスト(1時間未満)の場合、
databricks auth loginからの既存のユーザー(U2M)OAuth資格情報は問題なく機能します。より長いテストには、Databricks Service PrincipalでM2M OAuthを使用してください。U2Mトークンは長時間のラン中に期限切れとなり、テスト途中で失敗の原因となるためです。Databricks Service Principalの作成には、ワークスペース管理者のアクセスが必要です。
- 短いロードテスト(1時間未満)の場合、
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: エージェントTemplateのクローンを作成する
/load-testing スキルは、トップレベルの agent-load-testing スキルとして、また個々のエージェント Template に事前に同期されて、databricks/app-templates リポジトリに含まれています。app-templates から既にプロジェクトがある場合は、スキルは既にあります。
ロードテストしたいエージェントのTemplateディレクトリに移動し、リポジトリをクローンします。
git clone https://github.com/databricks/app-templates.git
cd app-templates/{your-template}
ステップ2:ロードテストスキルを実行します
Claude Code で、実行します:
/load-testing
このスキルは、以下のステップをインタラクティブに案内します。実際のGenieをテストするためにモックをスキップしたり、アプリがすでに実行されている場合はデプロイをスキップしたりできます。
- パラメーターの収集 : デプロイ状況、コンピュートサイズ、ワーカー設定、およびOAuth認証情報について尋ねます。
- ロードテストスクリプトの作成 :プロジェクトに合わせて調整された
locustfile.py、run_load_test.py、およびdashboard_template.pyが生成されます。 - LLMのモック :構成可能なストリーミング遅延で実際のLLM呼び出しを置き換える、SDK(OpenAI Agents SDK、LangGraph、またはカスタム)固有のモッククライアントを作成します。
- **テストアプリのデプロイ**:これにより、異なるコンピュートサイズとワーカー数を持つ複数のアプリ構成をデプロイする手順を説明します。
- **テストの実行**: M2M OAuth認証と飽和までランプアップを使用してロードテストを実行します。
- 結果の生成 :QPS、レイテンシー、障害メトリクスを含むインタラクティブなHTMLダッシュボードを生成します。
手動セットアップ
AIアシスタンスなしで負荷テストをセットアップして実行するには、これらのステップに従ってください。
ステップ1:エージェントのLLM呼び出しをモックする(オプション)
実際のLLMレイテンシーを含むエンドツーエンドの結果が必要な場合は、このステップをスキップしてください。Databricks Apps インフラストラクチャの throughput を単独で測定するには、LLM をモックして、リクエストごとのレイテンシー (通常1~30秒) がボトルネックにならないようにしてください。
モックは、設定可能なストリーミング遅延で定型応答を返し、完全なリクエスト/レスポンスパイプライン (SSE ストリーミング、ツールディスパッチ、SDK ランナー) を維持しながら、LLMのみを入れ替えます。これにより、Databricks Apps プラットフォームが提供できる最大 QPS が明らかになり、ロードテスト中の基盤モデル API トークンコストを回避できます。
モックのタイミングは、2つの環境変数によって制御されます:
変数 | デフォルト | 説明 |
|---|---|---|
|
| ストリーム化されたテキストチャンク間のミリ秒単位の遅延 |
|
| 応答あたりのテキストチャンク数 |
デフォルトでは、各モック応答には約 800 ms (10 ms x 80 チャンク) かかり、実際の LLM 応答 (3~15 秒) よりも大幅に高速です。throughput 数値はプラットフォームを反映したものであり、モデルを反映したものではありません。
実際のLLMクライアントを置き換えるモッククライアントを作成します。エージェントコードの残りの部分は変更されず、アプローチはSDKによって異なります。OpenAIについては、databricks/app-templatesでmock_openai_client.py参照実装を参照してください。同じパターンは他のSDKにも対応しています。
- OpenAI Agents SDK
- LangGraph
- Custom agents
ストリーミングで chat.completions.create() を実装する MockAsyncOpenAI クラスである agent_server/mock_openai_client.py を作成します。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")
エージェントコードの残りの部分(ハンドラー、ツール、ストリーミングロジック)は変更されません。
ChatDatabricksモデルを、事前に構築されたAIMessageオブジェクトを返すモックに置き換えてください:
# Before:
# model = ChatDatabricks(endpoint="databricks-claude-sonnet-4")
# After:
from agent_server.mock_llm import MockChatModel
model = MockChatModel()
モックは、最初の呼び出しでツール呼び出しを含むAIMessageオブジェクトを返し、後続の呼び出しでテキストコンテンツを返し、構成可能なストリーミング遅延を伴う必要があります。
エージェントが行う外部API呼び出し(LLM、AI Search、ツールAPIs)を、構成可能な遅延を伴う現実的な応答形式を返すモック実装でラップします。
ステップ 2: ロードテストスクリプトを設定する
プロジェクト内にload-test-scripts/ディレクトリを作成します。この負荷テストフレームワークは、フレームワークに依存せず、あらゆるDatabricks Appsエージェントで動作する3つのスクリプトで構成されています。
<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:stream: trueでPOST /invocations個のリクエストを送信し、SSEストリームを解析し、カスタムメトリクスとしてTime to First Token(TTFT)を追跡し、自動更新付きのM2M OAuthトークン交換を使用し、各レベルをstep_duration秒間保持しながらユーザーをstep_sizeからmax_usersまで増加させるStepRampShapeを実装するLocust負荷テストです。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>/。
依存関係をインストール
ロード テスト スクリプトは、エージェントの本番運用の依存関係を汚染しないように、load-test-scripts/ 内で独自の pyproject.toml を使用します。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",
]
locustを<2.40にピン留めします。新しいバージョン (>=2.43) には、長いロードテストを中断する既知の RecursionError があります。
load-test-scripts/ディレクトリ内からインストールします:
cd load-test-scripts/
uv sync
ステップ 3:さまざまな構成のテストアプリをデプロイします
複数のDatabricks Appsを異なるコンピュートサイズとワーカー数でデプロイして、ワークロードに最適な構成を見つけます。
推奨テスト マトリックス
以下の構成は、以前のテストで特定された最適な箇所に焦点を当てています。より広いカバレッジが必要な場合は、いずれかの側に構成を追加します(例:medium-w1またはlarge-w12)。ただし、以下の6つで通常は十分です。
コンピュートサイズ | ワーカー | 推奨されるアプリ名 |
|---|---|---|
M | 2 |
|
M | 3 |
|
M | 4 |
|
Large | 6 |
|
Large | 8 |
|
Large | 10 |
|
コンピュートサイズを構成する
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}'
続行する前に、すべてのアプリが ACTIVE ステータスに達するまで待機してください。まだ起動中のアプリは、誤解を招く結果を生成します。
ステップ 4: ラン ロード テスト
認証を設定する
利用期間に応じて認証方法を選択してください。
- 短期テスト (約1時間未満) :
databricks auth loginから既存のユーザー認証情報を使用してください。追加のセットアップは不要です。 - **長時間テスト (約1時間~、夜間のランなど)**:Databricks Service Principalを使用したM2M OAuthを使用します。U2Mトークンは期限切れになり、テストの実行中に中断します。Databricks Service Principalの作成にはワークスペース管理者アクセスが必要です。
M2M OAuth の場合、テストを実行する前に Databricks の Service Principal の資格情報をエクスポートします。
export DATABRICKS_HOST=https://your-workspace.cloud.databricks.com
export DATABRICKS_CLIENT_ID=<your-client-id>
export DATABRICKS_CLIENT_SECRET=<your-client-secret>
パラメーターリファレンス
パラメーター | 必須 | デフォルト | 説明 |
|---|---|---|---|
| はい | — | テストするアプリの URL(s) (繰り返し可能) |
| 長時間のテストの場合。 |
| Service PrincipalクライアントID (M2M OAuth) |
| 長時間のテストの場合。 |
| Service Principalクライアントシークレット (M2M OAuth) |
| No | URL から自動的に派生しました。 | アプリごとに人間が判読できるラベル(繰り返し可能) |
| No | 自動検出された、または | アプリごとのコンピュートサイズタグ: |
| No |
| 最大並列シミュレート ユーザー数 |
| No |
| ランプステップごとに追加されたユーザー |
| No |
| ランプステップあたりの秒数 |
| No |
| ユーザー spawn rate(users/sec) |
| No |
| このランの名前 — 結果の保存先 |
| No | オフ | テスト完了後にインタラクティブな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]を受信)。 - ウォームアップ : アプリをウォームアップするためにシーケンシャルリクエストを送信します。
- Ramp-to-saturation :
step_duration秒ごとに並列ユーザーを増やします。 - 飽和検出 :ユーザーを追加してもQPSが頭打ちになる場合、throughputの限界に達しています。
推定される期間
テスト対象の各アプリは独自のランプを通してランされるため、総ラン時間はマトリックス内の構成数に比例します。以下の式を使用して、ランウィンドウを計画してください。
アプリあたりの期間: (max_users / step_size) * step_duration秒。
デフォルト (--max-users 300 --step-size 20 --step-duration 30)の場合:
- 15ステップ × 30秒 = アプリあたり約7.5分。
- 推奨される6構成マトリックスの場合、1ランあたり約45分です。
ステップ 5:結果を表示して解釈する
-
ダッシュボードを開く:
Bashopen load-test-runs/<run-name>/dashboard.html -
(オプション) 既存のデータからダッシュボードを再生成します (例: Templateの更新後):
Bashcd load-test-scripts/
uv run dashboard_template.py ../load-test-runs/<run-name>/
ダッシュボードのセクション
対話型ダッシュボードには以下が含まれます:
- **KPIカード**: 最適な構成(ピーク時の成功QPS別)、全体的なピークQPS、最小レイテンシー、および処理されたリクエストの総数。
- QPS by Config :中央QPS、失敗を除外したピークQPS、およびピークQPSを各構成について並べて表示するグループ化された棒グラフ。
- 構成別のレイテンシ :p50およびp95レイテンシを示すグループ化されたバー。
- **構成別のTTFT**:最初のトークンまでの時間(p50およびp95)。
- 合計処理リクエスト数 :構成ごとのリクエスト数。
- QPS Ramp Progression :QPS、QPS(失敗を除く)、レイテンシー、および失敗のtab付き折れ線グラフ。より低い並列範囲にズームインするための最大ユーザー数スライダーが含まれています。グラフはコンピュートサイズ(中および大を並べて)別にグループ化されています。
- すべての結果の表 :ピークQPS、ピーク時のユーザー数、レイテンシーのパーセンタイル、および失敗率を含むすべての構成。
- **テストパラメーター**:再現性のための構成の概要。
結果を解釈する方法
- ピーク QPS :どのランプステップでも達成された最大 QPS。これは、その構成のthroughputの上限です。
- **ピーク時のユーザー数**:ピークQPSが達成されたときの並列ユーザー数。この点を超えてユーザーを追加しても、throughputは増加しません。
- 失敗率 :0%にするか、非常に低い値にする必要があります。高い失敗率は、その同時実行レベルでアプリに過負荷がかかっていることを意味します。
- QPS ランプチャート :ラインが平坦になる場所を探してください。それが飽和点です。ユーザーを増やしてもthroughputは増加しません。
合成データでのベンチマークのリファレンスラン
このセクションでは、すべてのLLM呼び出しがモックされた状況で、Databricksの社内ベンチマークランが合成エージェントアプリに対して測定した内容を報告しています。これは、独自のエージェントのロードテストとは別の作業です。期待できる結果の形を確認し、サイジングの大まかな出発点を得るために使用してください。
このランが示したもの
- 推奨される開始点 :Medium コンピュート では 2 workers、Large では 8 workers。
- ワーカーが多いほど常に良いとは限りません。 Medium では、2 ワーカー (155.1 QPS) は 4 ワーカー (116.5 QPS) を約 33% 上回りました。モックワークロードは CPU バウンドであるため、2 ワーカーを超えると、追加の並列処理を打ち消す CPU/メモリ競合が発生します。ほとんどモデル Endpoint で待機する実際の IO バウンドのエージェントは、このモックよりもさらにスケーリングする可能性があるため、必ず自身のエージェントをテストしてください。
- コンピュートサイズ:Largeは、Mediumの約2.2倍のthroughputを実現しました (278.0対123.5の平均ピークQPS)。
- レイテンシー : LargeはMediumよりも約20%低く(p50で906 ms 対 1,180 ms)、TTFTはLargeで約1,100 msに対し、Mediumでは1,720~1,820 msでした。
- 信頼性 : すべての構成で、1,000の並列ユーザーの場合でも、障害発生率は0%またはその付近に留まりました。
LLM はモックされたため(ストリーミングはチャンクごとの固定遅延でシミュレート)、これらはエンドツーエンドのエージェント数値ではなく、インフラストラクチャの throughput 数値です。これらは、Databricks Apps FastAPI AgentServer が並行して処理できるリクエスト数を測定するものであり、実際のモデルのレイテンシーではありません。ライブ LLM Endpoint を呼び出す本番運用エージェントは、QPS が低く、レイテンシーが高くなります。これはモデルの応答時間が主な原因です。エージェントの複雑さ、ペイロードサイズ、ツール呼び出し、リージョン、および呼び出すモデル Endpoint によって、数値は異なります。正確なサイジングのために、自身のエージェントに対して負荷テストを実行します。
以下の表に示された結果は、構成ごとの完全な内訳を示しています。
テスト条件
- 参照ラン :8つのアプリ構成(Mediumが4つ、Largeコンピュートが4つ)に対して5回の同一のラウンドを実行し、それぞれ異なるuvicornワーカー数を使用します。
- Ramp :20人から1,000人の並列ユーザー、20人ずつのユーザーをそれぞれ10秒間保持するステップで(構成ごとに50ステップ)。
- モックエージェント : LLM トークン ストリーミングをシミュレートし、リクエストあたり約95チャンクのストリーミング応答を返します。
- ボリューム : すべてのランにおける約146万件の合計リクエスト数。
構成ごとのピーク QPS
ピーク QPS は 5 ランで平均されます。
コンピュートサイズ | ワーカー | 平均ピークQPS | ピーク範囲 | 失敗率 |
|---|---|---|---|---|
M | 2 | 155.1 | 137.0–166.6 | 0.0% |
M | 4 | 116.5 | 112.6~121.8 | 0.1% |
M | 6 | 111.9 | 102.6-117.5 | 0.0% |
M | 8 | 110.3 | 108.3-112.1 | 0.0% |
Large | 6 | 281.6 | 268.2~292.4 | 0.0% |
Large | 8 | 268.2 | 265.8-271.0 | 0.0% |
Large | 10 | 288.1 | 280.3-299.4 | 0.0% |
Large | 12 | 274.2 | 269.4-278.8 | 0.0% |
コンピュートサイズによる平均値:
コンピュートサイズ | 平均ピークQPS | 平均QPS |
|---|---|---|
M | 123.5 | 45.5 |
Large | 278.0 | 100.1 |
このランでは、ラージ コンピュートは、ミディアム コンピュートのおよそ2.2倍の throughput を提供しました。
トラブルシューティング
問題 | ソリューション |
|---|---|
認証トークンはテスト中に有効期限が切れました | ~1 時間を超えるテストの場合、 |
ヘルスチェックに失敗しました | アプリがアクティブであることを確認: |
0 QPS または結果なし |
|
ユーザー数が多いにもかかわらず QPS が低い | アプリは飽和しています。ワーカーを増やすか、より大きなコンピュートをお試しください。 |
高い失敗率 | アプリは過負荷状態です。 |
ダッシュボードにランプデータが表示されていません。 | 各結果サブディレクトリに |
その他のリソース
- 実際のLLM呼び出しでテスト : モックのステップをスキップし、実際のAgentをデプロイして、LLMの応答時間を含むエンドツーエンドのレイテンシーを測定します。
- ワーカー数の調整 :テストマトリックスの結果を使用して、コンピュートサイズに最適なワーカー数を見つけます。
- 精度、関連性、安全性、throughputを測定するには、チュートリアル: GenAIアプリケーションの評価と改善を参照してください。
- AI Gatewayを含む完全な本番運用準備シーケンスについては、Databricks Appsエージェントを本番運用に対応させるを参照してください。