Azure Container Apps でのサーバーレス コード インタープリター セッション (プレビュー)
Azure Container Apps の動的セッションでは、コード インタープリターへの高速でスケーラブルなアクセスが提供されます。 各コード インタープリター セッションは、Hyper-V 境界によって完全に分離され、信頼されていないコードを実行するように設計されています。
Note
Azure Container Apps の動的セッション機能は現在プレビューの段階です。 詳細については、「プレビューの制限事項」を参照してください。
コード インタープリター セッション用に使用する
コード インタープリター セッションは、悪意のある可能性がある、またはホスト システムや他のユーザーに損害を与える可能性があるコードを実行する必要がある、次のようなシナリオに最適です。
- 大規模言語モデル (LLM) によって生成されたコード。
- エンド ユーザーが Web または SaaS アプリケーションで送信したコード。
LangChain、LlamaIndex、セマンティック カーネルなどの一般的な LLM フレームワークの場合、ツールとプラグインを使用して AI アプリをコード インタープリター セッションと統合できます。
作成中のアプリケーションは、REST API を使用してコード インタープリター セッションと統合することもできます。 この API を使用すると、セッションでコードを実行し、結果を取得できます。 セッションとの間でファイルをアップロードおよびダウンロードすることもできます。 実行可能なコード ファイル、またはコードで処理できるデータ ファイルをアップロードおよびダウンロードできます。
組み込みのコード インタープリター セッションは、インフラストラクチャまたはコンテナーを管理する必要なく、最も一般的なコード実行シナリオをサポートします。 コード実行環境を完全に制御する必要がある場合、または分離されたサンドボックスを必要とする別のシナリオがある場合は、カスタム コード インタープリター セッションを使用できます。
コード インタープリター セッション プール
コード インタープリター セッションを使用するには、コード インタープリター セッションの構成を定義するセッション プールと呼ばれる Azure リソースが必要です。 セッション プールでは、同時セッションの最大数や、セッションが終了するまでのセッションのアイドル時間などの設定を指定できます。
セッション プールは、Azure portal、Azure CLI、または Azure Resource Manager テンプレートを使用して作成できます。 セッション プールを作成したら、プールの管理 API エンドポイントを使用して、セッション内でコードを管理および実行できます。
Azure CLI を使用してセッション プールを作成する
Azure CLI を使用してコード インタープリター セッション プールを作成するには、次のコマンドを使用して、最新バージョンの Azure CLI と Azure Container Apps 拡張機能があることを確認します。
# Upgrade the Azure CLI
az upgrade
# Install or upgrade the Azure Container Apps extension
az extension add --name containerapp --upgrade --allow-preview true -y
az containerapps sessionpool create
コマンドを使用して、プールを作成します。 次の例では、my-session-pool
という名前の Python コード インタープリター セッション プールを作成します。 コマンドを実行する前に、<RESOURCE_GROUP>
をリソース グループ名に置き換えてください。
az containerapp sessionpool create \
--name my-session-pool \
--resource-group <RESOURCE_GROUP> \
--location westus2 \
--container-type PythonLTS \
--max-sessions 100 \
--cooldown-period 300 \
--network-status EgressDisabled
セッション プールを作成するときに、次の設定を定義できます。
設定 | 説明 |
---|---|
--container-type |
使用するコード インタープリターの種類。 値 PythonLTS のみがサポートされています。 |
--max-sessions |
同時に許可される割り当て済みセッションの最大数。 最大値は 600 です。 |
--cooldown-period |
終了するまでに許可されるアイドル状態の秒数。 アイドル期間は、セッションの API が呼び出されるたびにリセットされます。 使用できる範囲は、300 と 3600 の間です。 |
--network-status |
送信ネットワーク トラフィックをセッションから許可するかどうかを指定します。 有効な値は、EgressDisabled (既定値) および EgressEnabled です。 |
重要
エグレスを有効にすると、セッションで実行されているコードがインターネットにアクセスできます。 サービス拒否攻撃などの悪意のあるアクティビティの実行に使用される可能性があるため、コードが信頼されていない場合は注意が必要です。
Azure CLI を使用してプール管理 API エンドポイントを取得する
LLM フレームワーク統合でコード インタープリター セッションを使用するか、管理 API エンドポイントを直接呼び出すには、プールの管理 API エンドポイントが必要です。 エンドポイントの形式は https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>
です。
セッション プールの管理 API エンドポイントを取得するには、az containerapps sessionpool show
コマンドを使用します。 コマンドを実行する前に、<RESOURCE_GROUP>
をリソース グループ名に置き換えてください。
az containerapp sessionpool show \
--name my-session-pool \
--resource-group <RESOURCE_GROUP> \
--query 'properties.poolManagementEndpoint' -o tsv
セッションでのコード実行
セッション プールを作成したら、作成中のアプリケーションは、LLM フレームワークとの統合を使用するか、プールの管理 API エンドポイントを直接使用して、プール内のセッションと対話できます。
セッション識別子
重要
セッション識別子は機密情報であり、セキュリティで保護されたプロセスを使ってその値を管理する必要があります。 このプロセスの一部として、アプリケーションで確実に、各ユーザーまたはテナントがそれ自身のセッションにしかアクセスできないようにする必要があります。 セッションへのアクセスをセキュリティで保護しないと、ユーザーのセッション内に保存されているデータの誤用または未承認のアクセスが発生する可能性があります。 詳細については、「セッション識別子」を参照してください
プール内のセッションと対話するときは、セッション識別子を使用して各セッションを参照します。セッション識別子は、セッション プール内で一意である定義した文字列です。 Web アプリケーションを構築している場合は、ユーザーの ID を使用できます。 チャットボットを構築している場合は、会話 ID を使用できます。
識別子を持つ実行中のセッションがある場合は、セッションが再利用されます。 識別子を持つ実行中のセッションがない場合は、新しいセッションが自動的に作成されます。
セッション識別子の詳細については、「セッションの概要」を参照してください。
認証
認証は、Microsoft Entra (旧称 Azure Active Directory) トークンを使用して処理されます。 有効な Microsoft Entra トークンは、セッション プール上の Azure ContainerApps Session Executor および "共同作成者" ロールに属する ID によって生成されます。
LLM フレームワーク統合を使用している場合、フレームワークはトークンの生成と管理を自動的に処理します。 アプリケーションが、セッション プールで必要なロールの割り当てを持つマネージド ID で構成されていることを確認します。
プールの管理 API エンドポイントを直接使用している場合は、トークンを生成し、それを HTTP 要求の Authorization
ヘッダーに含める必要があります。 前述のロールの割り当てに加えて、トークンには、値 https://dynamicsessions.io
を持つ対象者 (aud
) クレームが含まれている必要があります。
詳細については、「認証」を参照してください。
LLM フレームワークの統合
次の LLM フレームワークは、セッション プール管理 API を直接使用する代わりに、コード インタープリター セッションとの統合を提供します。
フレームワーク | Package | チュートリアル |
---|---|---|
LangChain | Python: langchain-azure-dynamic-sessions |
チュートリアル |
LlamaIndex | Python: llama-index-tools-azure-code-interpreter |
チュートリアル |
セマンティック カーネル | Python: semantic-kernel (バージョン 0.9.8-b1 以降) |
チュートリアル |
管理 API エンドポイント
LLM フレームワーク統合を使用していない場合は、管理 API エンドポイントを使用してセッション プールを直接操作できます。
プール内のセッションを管理するために、次のエンドポイントを使用できます。
エンドポイント パス | Method | 説明 |
---|---|---|
code/execute |
POST |
セッションでコードを実行します。 |
files/upload |
POST |
セッションにファイルをアップロードします。 |
files/content/{filename} |
GET |
セッションからファイルをダウンロードします。 |
files |
GET |
セッション内のファイルを一覧表示します。 |
プールの管理 API エンドポイントとエンドポイント パスを連結して、各エンドポイントの完全な URL を構築します。 クエリ文字列には、セッション識別子を含む identifier
パラメーターと、2024-02-02-preview
値を持つ api-version
パラメーターを含める必要があります。
例: https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/code/execute?api-version=2024-02-02-preview&identifier=<IDENTIFIER>
セッションでコードを実行する
セッションでコードを実行するには、要求本文で実行するコードを持つ POST
要求を code/execute
エンドポイントに送信します。 この例では、Python で "Hello, world!" を出力します。
要求を送信する前に、<>
角かっこの間のプレースホルダーを、セッション プールとセッション識別子の適切な値に置き換えます。
POST https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/code/execute?api-version=2024-02-02-preview&identifier=<SESSION_ID>
Content-Type: application/json
Authorization: Bearer <token>
{
"properties": {
"codeInputType": "inline",
"executionType": "synchronous",
"code": "print('Hello, world!')"
}
}
セッションを再利用するには、後続の要求で同じセッション識別子を指定します。
セッションにファイルをアップロードする
ファイルをセッションにアップロードするには、マルチパート フォーム データ要求内で uploadFile
エンドポイントに POST
要求を送信します。 要求本文にファイル データを含めます。 ファイルにはファイル名を含める必要があります。
アップロードされたファイルは、セッションのファイル システムの /mnt/data
ディレクトリに格納されます。
要求を送信する前に、<>
角かっこの間のプレースホルダーを、要求に固有の値に置き換えます。
POST https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/files/upload?api-version=2024-02-02-preview&identifier=<SESSION_ID>
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Authorization: Bearer <token>
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="<FILE_NAME_AND_EXTENSION>"
Content-Type: application/octet-stream
(data)
------WebKitFormBoundary7MA4YWxkTrZu0gW--
セッションからファイルをダウンロードする
セッションの /mnt/data
ディレクトリからファイルをダウンロードするには、file/content/{filename}
エンドポイントに GET
要求を送信します。 応答にファイル データが含まれます。
要求を送信する前に、<>
角かっこの間のプレースホルダーを、要求に固有の値に置き換えます。
GET https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/files/content/<FILE_NAME_AND_EXTENSION>?api-version=2024-02-02-preview&identifier=<SESSION_ID>
Authorization: Bearer <TOKEN>
セッション内のファイルを一覧表示する
セッションの /mnt/data
ディレクトリ内のファイルを一覧表示するには、files
エンドポイントに GET
要求を送信します。
要求を送信する前に、<>
角かっこの間のプレースホルダーを、要求に固有の値に置き換えます。
GET https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/files?api-version=2024-02-02-preview&identifier=<SESSION_ID>
Authorization: Bearer <TOKEN>
応答にセッション内のファイルの一覧が含まれます。
次の一覧は、セッション コンテンツの要求から予想される応答の種類のサンプルを示しています。
{
"$id": "1",
"value": [
{
"$id": "2",
"properties": {
"$id": "3",
"filename": "test1.txt",
"size": 16,
"lastModifiedTime": "2024-05-02T07:21:07.9922617Z"
}
},
{
"$id": "4",
"properties": {
"$id": "5",
"filename": "test2.txt",
"size": 17,
"lastModifiedTime": "2024-05-02T07:21:08.8802793Z"
}
}
]
}
プレインストール済みのパッケージ
Python コード インタープリター セッションには、NumPy、pandas、scikit-learn などの一般的な Python パッケージが含まれます。
プレインストール済みのパッケージの一覧を出力するには、次のコードを使用して code/execute
エンドポイントを呼び出します。
要求を送信する前に、<>
角かっこの間のプレースホルダーを、要求に固有の値に置き換えます。
POST https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/identifier/<SESSION_ID>/code/execute?api-version=2024-02-02-preview&identifier=<SESSION_ID>
Content-Type: application/json
Authorization: Bearer <TOKEN>
{
"properties": {
"codeInputType": "inline",
"executionType": "synchronous",
"code": "import pkg_resources\n[(d.project_name, d.version) for d in pkg_resources.working_set]"
}
}