Skip to content

チュートリアル:本番対応コンテナのデプロイ

プレミアム機能

Workload APIはプレミアム機能です。 この機能を有効にする方法については、DataRobotの担当者または管理者にお問い合わせください。

完全なガバナンス(ロックされたアーティファクト、importance、共有、監視)を備えたコンテナ化されたAIサービスをデプロイします。ドラフトのワークロード(Hello, Workload を参照)とは異なり、これは長期にわたって実行される本番環境レベルのものです。

このチュートリアルでは、以下の機能を提供するFastAPIベースのエージェントサービス(otkachnlp/fastapi-server-example、DataRobotが公開したものではない一般に利用可能なサードパーティのイメージ)をデプロイします。

  • OpenAI互換の /chat/completions。DataRobot LLM Gatewayに接続されており、個別のLLMデプロイは必要ありません。
  • LangGraphの /agent エンドポイント:ArXiv検索を行うReActエージェント。
  • /healthz/readyz、および /health。それぞれ生存(liveness)、準備完了(readiness)、詳細なステータスを提供します。

作業方法に一致するタブを選択してください。cURLはREST APIを直接呼び出します。CLIは同じ呼び出しを dr workload / dr artifact コマンドでラップします(サブコマンドが存在しない場合は curl にフォールバックします)。Pulumiはロックされたアーティファクトとワークロードをコードとして宣言します。実行可能なノートブックを使用したい場合は、以下を選択してください。

 実行可能なノートブックとして表示

一目でわかるロックされたアーティファクトのワークロード

プロパティ
Lifetime 無期限。明示的に停止または削除されるまで持続します。
Artifact mutability ロックされると不変(Immutable)になります。
importance オプション。デフォルトは low です。本番環境用に明示的に設定します(criticalhighmoderate、または low)。
Workloads per artifact 無制限。1つのロックされたアーティファクトが複数のワークロードをバックアップできます。
置換 サポートされています。ロックされたものとロックされたもののみ置換します。

ドラフトとロックの完全な比較については、ワークロードの概念 を参照してください。

前提条件

  • curljq が使用可能なターミナル。
  • DataRobot APIのエンドポイントとトークン:
export DATAROBOT_ENDPOINT="[https://app.datarobot.com/api/v2](https://app.datarobot.com/api/v2)"
export DATAROBOT_API_TOKEN="<your-api-token>" 
  • 認証済みの DataRobot CLI (dr)。ワークロードコマンドが有効になっていること(export DATAROBOT_CLI_FEATURE_WORKLOAD=true)。
  • CLIに対応するものがない呼び出し(共有とメタデータの更新)用の curljq

次に、実行ごとに異なる値を設定します。

export MODEL="azure/gpt-5-nano-2025-08-07"
export RECIPIENT_USER_ID=""  # 共有するユーザー、グループ、または組織のID。スキップする場合は空白のままにします

ワークロードの作成

アーティファクトは常に draft として作成されるため、cURLおよびCLIを使用する場合は、最初に importance を設定してワークロードを作成し、次のステップでアーティファクトをロックします。ロックにより、その背後にあるワークロードはロックされた(本番)ライフサイクルに切り替わります:無期限のライフタイム、不変のspec、ロックからロックへの置換の対象。

アーティファクトの spec はコンテナのトポロジ(イメージ、ポート、エントリポイント、環境変数、プローブ)など、デプロイ間でアーティファクトとともに移動するあらゆるものを定義します。レプリカ数、CPU/メモリー、およびオートスケーリングはデプロイ時の懸念事項であり、 runtime.containerGroups[] に存在します。エントリは、グループとコンテナの name によってアーティファクトと一致させられます。コンテナは、プラットフォームが解決し {"source": "api-key"} を介して自動的に注入するワークロードごとのAPIトークンを使用して、DataRobot LLM Gatewayに対して認証を行います。specには値が設定されていないため、トークンが GET /artifacts/{id} の応答に表示されることはありません。また、 DATAROBOT_ENDPOINTプラットフォームマネージドであるため、設定する必要はありません。完全なリストについては、環境変数のタイプを参照してください。

readinessProbe.pathrunning 状態への移行を制御します。プラットフォームはこのパスをポーリングし、2xxが返された場合にのみワークロードを running に移行させます。このチュートリアルでは、プローブのポイントを /healthz に設定します。これは、FastAPIプロセスが立ち上がるとすぐに2xxを返します。コンテナは、LLM接続を実行するより深い /readyz エンドポイントも公開しますが、readiness probeは /healthz を指したままにしてください:外部依存関係で running を制御すると、その依存関係に問題が発生するたびにワークロードのステータスがばたつきます。起動をブロックするのではなく、ディープチェックを監視およびランブックのための明示的なエンドポイントとして到達可能に保ちます。

curl -s -X POST "${DATAROBOT_ENDPOINT}/workloads" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg model "$MODEL" \
    '{
      "name": "agent-service",
      "importance": "high",
      "artifact": {
        "name": "agent-service-artifact",
        "type": "service",
        "spec": {
          "containerGroups": [{
            "name": "default",
            "containers": [{
              "name": "agent",
              "imageUri": "otkachnlp/fastapi-server-example:latest",
              "port": 8080,
              "primary": true,
              "entrypoint": ["python", "server.py"],
              "environmentVars": [
                {"name": "MODEL", "value": $model},
                {"source": "api-key"}
              ],
              "readinessProbe": {"path": "/healthz", "port": 8080}
            }]
          }]
        }
      },
      "runtime": {
        "containerGroups": [{
          "name": "default",
          "replicaCount": 1,
          "containers": [{
            "name": "agent",
            "resourceAllocation": {"cpu": 1, "memory": "512MB"}
          }]
        }]
      }
    }'
  )" | tee /tmp/workload.json

export WORKLOAD_ID=$(jq -r '.id' /tmp/workload.json)
export ARTIFACT_ID=$(jq -r '.artifactId' /tmp/workload.json) 

specをファイルに保存し、$MODELを代入します。

Save the spec to a file, substituting $MODEL:

cat > workload.yaml <<EOF
name: agent-service
importance: high
artifact:
  name: agent-service-artifact
  type: service
  spec:
    containerGroups:
      - name: default
        containers:
          - name: agent
            imageUri: otkachnlp/fastapi-server-example:latest
            port: 8080
            primary: true
            entrypoint: ["python", "server.py"]
            environmentVars:
              - name: MODEL
                value: $MODEL
              - source: api-key
            readinessProbe:
              path: "/healthz"
              port: 8080
runtime:
  containerGroups:
    - name: default
      replicaCount: 1
      containers:
        - name: agent
          resourceAllocation:
            cpu: 1
            memory: "512MB"
EOF

dr workload create --spec-file workload.yaml --output-format json | tee /tmp/workload.json
export WORKLOAD_ID=$(jq -r '.id' /tmp/workload.json)
export ARTIFACT_ID=$(jq -r '.artifactId' /tmp/workload.json) 

datarobot.Artifactリソースは、 pulumi up の終了までに常に locked として解決されるため(Pulumiの使用時期を参照)、このフローには個別のロック手順はありません。 pulumi up はアーティファクトをすでにロックされた状態で作成します。

__main__.py
import pulumi
import pulumi_datarobot as datarobot

artifact = datarobot.Artifact(
    "agent-service-artifact",
    name="agent-service-artifact",
    type="service",
    spec={
        "container_groups": [{
            "name": "default",
            "containers": [{
                "name": "agent",
                "image_uri": "otkachnlp/fastapi-server-example:latest",
                "port": 8080,
                "primary": True,
                "entrypoint": ["python", "server.py"],
                "environment_vars": [
                    {"name": "MODEL", "value": pulumi.Config().require("model")},
                    {"source": "api-key"},
                ],
                "readiness_probe": {"path": "/healthz", "port": 8080},
            }],
        }],
    },
)

workload = datarobot.Workload(
    "agent-service",
    name="agent-service",
    importance="high",
    artifact_id=artifact.artifact_id,
    runtime={
        "container_groups": [{
            "name": "default",
            "replica_count": 1,
            "containers": [{
                "name": "agent",
                "resource_allocation": {"cpu": 1, "memory": "512MB"},
            }],
        }],
    },
    opts=pulumi.ResourceOptions(replace_on_changes=["artifact_id"]),
)

pulumi.export("artifactId", artifact.artifact_id)
pulumi.export("workloadId", workload.id)
pulumi.export("endpoint", workload.endpoint) 
pulumi config set model "azure/gpt-5-nano-2025-08-07"
pulumi up 

pulumi upはワークロードがrunningになるまでブロックするため、戻ってきたらサービスの呼び出しに進みます。

アーティファクトのロック

アーティファクトを draft から locked に移行させます。このワークロードはドラフトアーティファクトをバックアップする唯一のワークロードであるため、ワークロードのライフサイクルはそれと一緒にロック済みに移行します。ロックは一方向です:ロックされたアーティファクトをドラフトに戻すことはできません。

curl -X PATCH "${DATAROBOT_ENDPOINT}/artifacts/${ARTIFACT_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"status": "locked"}' 

PATCH /artifacts/{artifact_id}は、アーティファクトがまだdraftの状態である間のその他の更新の namedescription、およびspecも受け入れます。

dr artifact lock "$ARTIFACT_ID" 

ここで実行することはありません。アーティファクトは前の手順で既にロックされた状態で作成されています。

実行を待機する

runningに達するまで、ワークロードのステータスをポーリングします。想定される正常なパスの進行: submittedprovisioninglaunchingrunningerroredは最終的な状態であり、ポーリングしてやり過ごす一時的な異常ではありません。これを確認した場合は、待機を続けるのではなく、停止して調査(dr workload get "$WORKLOAD_ID"またはイベントエンドポイント)してください。

curl -s "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" | jq -r '.status' 

``` bash dr workload status "$WORKLOAD_ID"

ここで実行することはありません。 pulumi upはすでにrunningまでブロックしています。

サービスの起動

ワークロードから呼び出しURLを読み取り、それに対してアプリケーションルートを呼び出します。

ENDPOINT=$(curl -s "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" | jq -r '.endpoint')

curl -X POST "${ENDPOINT}/chat/completions" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"model": "'"${MODEL}"'", "messages": [{"role": "user", "content": "Hello!"}]}' 
ENDPOINT=$(dr workload endpoint "$WORKLOAD_ID")
curl -X POST "${ENDPOINT}/chat/completions" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"model": "'"${MODEL}"'", "messages": [{"role": "user", "content": "Hello!"}]}' 
ENDPOINT=$(pulumi stack output endpoint)
curl -X POST "${ENDPOINT}/chat/completions" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"model": "'"${MODEL}"'", "messages": [{"role": "user", "content": "Hello!"}]}' 

サーバーには、ArXivをツールで呼び出すエージェントもあります。これをテストするには、 {"query": "..."} 本文を使用して ${ENDPOINT}/agent に対して同じ方法で呼び出します。

ワークロードのガバナンス

これが本番環境のワークロードになったので、重要度と共有を設定します。

# Raise importance to critical
curl -X PATCH "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"importance": "critical"}'

# Share with another user, group, or organization (skip if RECIPIENT_USER_ID is blank)
if [ -n "$RECIPIENT_USER_ID" ]; then
  curl -X PATCH "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}/sharedRoles" \
    -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
      "operation": "updateRoles",
      "roles": [{"id": "'"${RECIPIENT_USER_ID}"'", "role": "USER", "shareRecipientType": "user"}]
    }'
fi 

重要度と共有の更新はREST APIを直接経由します。dr workloadは、作成、読み取り、ライフサイクル、およびログをカバーしており、メタデータや共有の更新はカバーしていません。

# Raise importance to critical
curl -X PATCH "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"importance": "critical"}'

# Share with another user, group, or organization (skip if RECIPIENT_USER_ID is blank)
if [ -n "$RECIPIENT_USER_ID" ]; then
  curl -X PATCH "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}/sharedRoles" \
    -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
      "operation": "updateRoles",
      "roles": [{"id": "'"${RECIPIENT_USER_ID}"'", "role": "USER", "shareRecipientType": "user"}]
    }'
fi 

importance は宣言的です。コード内で変更して再適用します。

workload = datarobot.Workload(
    "agent-service",
    name="agent-service",
    importance="critical",  # was "high"
    artifact_id=artifact.artifact_id,
    runtime={ ... },
    opts=pulumi.ResourceOptions(replace_on_changes=["artifact_id"]),
) 
pulumi up 

共有の設定はプロバイダー側では行われません。RESTまたはコンソールを使用して/sharedRolesを管理してください(Pulumiを使用するケースを参照してください)。

if [ -n "$RECIPIENT_USER_ID" ]; then
  curl -X PATCH "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}/sharedRoles" \
    -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
    -H "Content-Type: application/json" \
    -d '{
      "operation": "updateRoles",
      "roles": [{"id": "'"${RECIPIENT_USER_ID}"'", "role": "USER", "shareRecipientType": "user"}]
    }'
fi 

PATCHのスコープ

PATCH /workloads/{id} は、 namedescription、およびimportanceを受け入れます。ランタイムの変更(レプリカ、リソース)については、ローリング置換をトリガーするPATCH /workloads/{id}/settingsを使用します。ランタイム設定を参照してください。

観測

ロックされたワークロードは、組織で設定されたテレメトリ保持期間とともに、完全な監視基盤を公開します。監視の概念:保持期間の概要を参照してください。

機能 エンドポイント
サービスの正常性、レイテンシー、エラー率 GET /workloads/{id} (ワークロード上の計算フィールド)
ライフサイクルイベント(監査証跡) GET /workloads/{id}/events
集計リクエスト統計 GET /workloads/{id}/stats
指標ごとの時系列 GET /workloads/{id}/stats/{metric_name}
レプリカごとのステータス GET /workloads/{id}/protons/{proton_id}/statusDetails

これらはすべて、ワークロードを作成するために使用したインターフェイスに関係なく、REST APIから直接読み取られます。 dr workload logsはコンテナのstdout/stderrをカバーしますが、これはこの表のシグナルとは別のシグナルです。

curl -s "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}/events" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}"

curl -s "${DATAROBOT_ENDPOINT}/workloads/${WORKLOAD_ID}/stats" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" 

サマリー

このチュートリアルでは、以下を行いました:

  • ドラフトアーティファクトにバックアップされ、 importance が設定されたワークロードを作成し、アーティファクトをロックして、本番環境(無期限)パスに移動させました。
  • プラットフォームによって自動的に注入される、ワークロードごとのAPIトークンを使用して、DataRobot LLM Gatewayを呼び出すFastAPIエージェントサービスをデプロイしました。アーティファクトのspecに資格情報が表示されることはありませんでした。
  • OpenAI互換の /chat/completions ルートとLangGraphの /agent ルートの両方を呼び出しました。
  • importance を引き上げ、ワークロードを別のユーザー、グループ、または組織と共有しました。
  • 監視サーフェスからイベントを読み取り、統計を集計しました。

次のステップ

リソース 説明
Workload concepts オブジェクトモデル、ライフサイクルの状態、およびドラフトとロック済みの決定についての詳細。
Tutorial: Replace the artifact behind a running Workload エンドポイントを削除せずに新しいコンテナバージョンをシップします。
Deploy an open-weight model from Hugging Face GPUコンピュートバンドルのサイズを設定し、Hugging Face Hubモデルを提供します。
Instrument a Workload with OpenTelemetry (Python) 各リクエストの内部にトレース、指標、およびログを追加します。