この記事では、Python SDK または REST API を使用して、コンテナー化されたエージェントを Foundry Agent Service にデプロイする方法について説明します。 独自のアプリケーションまたはサービスからエージェントのデプロイを直接管理する場合は、次の方法を使用します。
初めてデプロイする場合、または最速のパスが必要な場合は、「 クイック スタート: ホストされたエージェントを作成してデプロイ する」を使用してください。 このクイックスタートではAzure Developer CLI (azd) または VS Code 拡張機能 を使用します。これにより、ビルド、プッシュ、バージョン管理、RBAC の構成が自動的に処理されます。
ヒント
Docker レスの内部ループが好きですか?
ソース コード (プレビュー) から直接ホストされたエージェントをデプロイすることもできます。Pythonまたは.NETコードの.zipをアップロードし、プラットフォームがそれをビルドしてホストします。
デプロイのライフサイクル
すべてのホステッド エージェントの展開は、次の順序に従います。
- Build と push — エージェント コードをコンテナー イメージにパッケージ化し、Azure Container Registryにプッシュします。
- エージェント バージョンを作成する - Foundry Agent Service にイメージを登録します。 プラットフォームはインフラストラクチャをプロビジョニングし、専用の Entra エージェント ID を作成します。
-
状態確認、バージョンの状態が
activeに達するまで待ちます。 - Invoke — エージェントの専用エンドポイントに要求を送信します。
前提 条件
- Microsoft Foundry プロジェクト。
- サポートされているフレームワークを使用するエージェント コード。
- ローカル コンテナー開発用にインストールされた Docker Desktop。
- Azure CLI バージョン 2.80 以降。
必要なアクセス許可
ホスト型エージェントを作成して展開するには、projectスコープで Foundry Project Manager が必要です。 このロールには、エージェントを作成するためのデータ プレーンのアクセス許可と、プラットフォームで作成されたエージェント ID に Foundry User ロールを割り当てる機能の両方が含まれます。 エージェント ID は、実行時にモデルと成果物にアクセスするために、プロジェクトの Foundry User を必要とします。
重要
Foundry RBAC ロールの名前が最近変更されました。 Foundry User, Foundry Owner, Foundry Account Owner、および Foundry Project Manager は、以前は、AZURE AI ユーザー、Azure AI 所有者、Azure AI アカウント所有者、および AZURE AI Project Manager という名前でした。 名前の変更がロールアウトされている間、以前の名前が表示される場合があります。ロール ID とコア アクセス許可は、名前の変更によって変更されません。
azdまたは VS Code 拡張機能を使用する場合、ツールは、次のようなほとんどの RBAC 割り当てを自動的に処理します。
- プロジェクト マネージド ID のContainer Registry リポジトリ閲覧者 (イメージのプル)
- Foundry ユーザー (ランタイム モデルとツールへのアクセス) 用の、プラットフォームで作成されたエージェント ID
メモ
- プラットフォームは、デプロイ時に各ホストエージェントの専用の Entra エージェント ID を作成します。 この ID は、実行中のコンテナーがモデルとツールを呼び出すために使用するサービス プリンシパルです。 マネージド ID を手動で構成する必要はありません。 ただし、エージェントを作成するユーザーには、その ID に Foundry User を割り当てるアクセス許可が必要です。そのため、Foundry Project Manager は Foundry User 単独で使用することをお勧めします。
-
azdおよび VS Code 拡張機能では基本的な RBAC の割り当てが自動的に処理されますが、複雑なシナリオでは追加の手動構成が必要になる場合があります。 関連するすべてのアクセス許可とロールの割り当てに関する包括的な詳細については、 Hosted Agent のアクセス許可リファレンスを参照してください。
詳細については、「 認証と承認」を参照してください。
重要
ホステッド エージェントのコンテナー イメージを保持するAzure Container Registryは、現在、パブリック エンドポイント経由で到達可能である必要があります。 プライベート ネットワーク (パブリック ネットワーク アクセスが無効なプライベート エンドポイント) の背後にレジストリを配置することは、現在、ホストされているエージェントではサポートされていません。プラットフォームはイメージをプルできません。 ネットワーク制約の完全な一覧については、「 制限事項」を参照してください。
コンテナーの要件
ホストされるエージェント プラットフォームで実行するには、コンテナー イメージが次の要件を満たしている必要があります。
重要
ホスティング プラットフォームには、x86_64 (linux/amd64) コンテナー イメージが必要です。 Apple Silicon またはその他の ARM ベースのマシン上に構築する場合は、互換性のない ARM イメージが生成されないように、 docker build --platform linux/amd64 . を使用します。
プロトコル ライブラリ
ホストされるエージェントは、プロトコル ライブラリを介して Foundry ゲートウェイと通信します。 エージェントの対話パターンに一致するプロトコルを選択します。
| プロトコル | Python ライブラリ | .NET ライブラリ | エンドポイント | 〜に最適です |
|---|---|---|---|---|
| 応答 | azure-ai-agentserver-responses |
Azure.AI.AgentServer.Responses |
/responses |
会話型チャットボット、ストリーミング、プラットフォームで管理された履歴を含むマルチターン |
| 呼び出し | azure-ai-agentserver-invocations |
Azure.AI.AgentServer.Invocations |
/invocations |
Webhook レシーバー、非会話処理、カスタム非同期ワークフロー |
| 呼び出し (WebSocket) | azure-ai-agentserver-invocations |
Azure.AI.AgentServer.Invocations |
/invocations_ws |
双方向ストリーミング: リアルタイム音声エージェント、対話型メディア |
WebSocket プロトコルは、識別子invocations_wsを使用し、HTTP azure-ai-agentserver-invocations ルートと同じ/invocations パッケージに付属しているため、1 つのコンテナーで両方を処理できます。 永続的な全二重ストリーミング (たとえば、マイク PCM をエージェントに送信し、合成されたオーディオを受信する) が必要な場合に使用します。 音声シナリオについては、 ホストされたエージェントを使用した音声エージェントの構築に関するページを参照してください。
重要
invocations_ws WebSocket プロトコルはプレビュー段階であり、現在は米国中北部でのみ使用できます。
ファイル、SDK 呼び出し、または REST API 要求でエージェントを作成するときに複数のプロトコルを宣言し、必要なライブラリをインポートすることで、1 つのコンテナーでagent.yamlに公開できます。 Microsoft Agent Framework、LangChain、またはカスタム コードのいずれであっても、既存のフレームワーク内でプロトコル ライブラリを使用してください。
応答プロトコル ライブラリ
Responses プロトコルのPythonライブラリと.NET ライブラリは、Azure AI Responses API を実装します。 パッケージをインポートし、 IResponseHandler インターフェイスを実装します。 ライブラリは、ルーティング、サーバー送信イベント (SSE) によるストリーミング、バックグラウンド実行、キャンセル、キャッシュ、応答ライフサイクル管理を処理します。
IResponseHandler
IResponseHandler は、実装するコア抽象化です。 ライブラリは、受信要求ごとに CreateAsync を呼び出し、返された IAsyncEnumerable<ResponseStreamEvent> を SSE 経由でクライアントに配信します。
public class EchoHandler : ResponseHandler
{
public override IAsyncEnumerable<ResponseStreamEvent> CreateAsync(
CreateResponse request,
ResponseContext context,
CancellationToken cancellationToken)
{
return new TextResponse(context, request,
createText: async ct =>
{
var input = await context.GetInputTextAsync(cancellationToken: ct);
return $"Echo: {input}";
});
}
}
ResponseEventStream
ResponseEventStream は、 sequenceNumber、 outputIndex、 contentIndex、 itemId、および完全な Response ライフサイクルを自動的に管理します。 各 yield return は 1 対 1 を SSE イベントにマップするため、この状態を自分で追跡する必要はありません。
ストリーミング モードとバックグラウンド モード
- ストリーミング モード (既定): SSE イベントは、接続されているクライアントにリアルタイムで配信されます。
-
バックグラウンド モード: ハンドラーは、接続された SSE クライアントなしで完了まで実行されます。 イベントはバッファーに格納され、
GET /responses/{id}経由で再生できます。
応答のライフサイクル
ライブラリは、 created → in_progress → completed (または failed または cancelled) の完全な応答ライフサイクルを調整します。 ライブラリでは、取り消し、エラー処理、およびターミナル イベントの保証も自動的に管理されます。
スレッドセーフティ
AddResponsesServer()を介して登録されたすべてのサービス インスタンスはスレッド セーフです。 ハンドラー インスタンスは要求ごとにスコープ指定されます。
ハンドラー実装の詳細なガイダンスについては、handler 実装ガイドを参照してください。 実行可能な例については、Responses プロトコルのサンプルを参照してください。
ヘルスエンドポイント
プロトコル ライブラリは、プラットフォームの正常性チェック用の /readiness エンドポイントを自動的に公開します。 これを自分で実装する必要はありません。
ポート
コンテナーは、ポート 8088 のトラフィックをローカルで処理します。 運用環境では、Foundry ゲートウェイがルーティングを処理します。コンテナーでパブリック ポートを公開する必要はありません。
プラットフォームによって挿入された環境変数
ホストされるエージェント プラットフォームは、実行時に環境変数をコンテナーに自動的に挿入します。 コードでは、 agent.yaml または environment_variablesで宣言しなくても、これらを読み取ることができます。
FOUNDRY_* プレフィックスは、プラットフォームで使用するために予約されています。
| 変数 | 目的 |
|---|---|
FOUNDRY_PROJECT_ENDPOINT |
Foundry プロジェクト エンドポイント URL |
FOUNDRY_PROJECT_ARM_ID |
Foundry プロジェクトの ARM リソース ID |
FOUNDRY_AGENT_NAME |
実行中のエージェントの名前 |
FOUNDRY_AGENT_VERSION |
実行中のエージェントのバージョン |
FOUNDRY_AGENT_SESSION_ID |
現在の要求のセッション ID (ホストされているコンテナーのみ) |
APPLICATIONINSIGHTS_CONNECTION_STRING |
テレメトリ用の Application Insights 接続文字列 |
プラットフォームによって挿入された変数を agent.yamlで再宣言しないでください。これらは自動的に設定されます。
MODEL_DEPLOYMENT_NAMEやツールボックスの MCP エンドポイントなど、自分で宣言する変数は、environment_variablesまたは SDK agent.yaml呼び出しのcreate_versionセクションに移動します。
環境変数でのプロジェクト接続の参照
シークレット (API キー、トークン、エンドポイント) を agent.yaml またはイメージにハードコーディングする代わりに、サンドボックスの開始時に Foundry プロジェクト接続からシークレットをプルします。
environment_variables内の任意の値は、コンテナーの開始前にプラットフォームが解決するプレースホルダー式にすることができます。
プレースホルダー構文
プレースホルダーの形式は ${{connections.<name>.<path>}} で、<name> は接続のリソース名 (Project 詳細>接続されたリソース) で、<path>は次のいずれかになります。
| Path | 次に解決します。 |
|---|---|
credentials.<field> |
接続のシークレット フィールド |
target |
接続の target プロパティ (エンドポイント URL など) |
metadata.<field> |
接続の metadata の下にあるフィールド |
使用するフィールド名は、接続カテゴリによって異なります。
| 接続カテゴリ | プレースホルダーのフィールド名 |
|---|---|
ApiKey、AppInsights |
常に key。たとえば、 credentials.key |
CustomKeys |
接続の作成時に指定したキー名 (例: credentials.github_token |
例
まず、シークレットを保持する CustomKeys 接続をプロジェクトに作成します。
Microsoft Foundry で新しい接続を追加する を参照してください。 次に、 agent.yamlから参照します。
environment_variables:
- name: MODEL_DEPLOYMENT_NAME
value: gpt-5-mini
- name: GITHUB_TOKEN
value: ${{connections.agent-secrets.credentials.github_token}}
サンドボックスの開始時に、Foundry はプレースホルダーを解決し、解決された値をプレーン環境変数として挿入します。 コードは、それを他の環境変数と同じように読み取ります:
import os
token = os.environ["GITHUB_TOKEN"]
エージェント バージョンの GET はリテラル ${{...}} テキストを返します。解決されたシークレットは、管理 API を介してエコー バックされることはありません。
Considerations
- バージョンをデプロイする前に、接続を作成します。 サンドボックスの開始時に接続または参照先フィールドが見つからない場合、プレースホルダーは解決せず、変数は空になります。
- シークレットは書き込み専用です。 接続の GET は
credentials: nullを返します。 接続を検査することではなく、実行中のコンテナー内から env var を読み取って解決を確認します。 - フィールド名
CustomKeysは自分で記録してください。 管理 API では、作成後にエコーバックされることはありません。 後で推測せずにプレースホルダーを作成できるように、エージェント ソースの横 (IaC テンプレートやagent.yamlと共に) に保持します。 - Foundry は、基盤となるシークレットの名前を管理します。 接続を作成すると、Foundry は選択した名前の下に値をKey Vaultに格納します。既存のKey Vaultシークレットを名前で参照することはできません。 バッキング ストアとして独自のKey Vaultをアタッチするには、「Key Vault接続を設定するを参照してください。
エージェントをローカルでパッケージ化してテストする
Foundry にデプロイする前に、エージェントがプロトコル ライブラリを使用してローカルで動作することを検証します。 コンテナーは、運用環境と同じエンドポイントをローカルで処理します。
応答プロトコルをテストする
POST http://localhost:8088/responses
Content-Type: application/json
{
"input": "Where is Seattle?",
"stream": false
}
呼び出しプロトコルをテストする
POST http://localhost:8088/invocations
Content-Type: application/json
{
"message": "Hello!"
}
Azure Developer CLI または VS Code を使用してデプロイする
Azure Developer CLI (azd) と VS Code 拡張機能により、完全なデプロイ ライフサイクルが自動化されます。 詳細なチュートリアルについては、「 クイック スタート: ホスト型エージェントの作成とデプロイ」を参照してください。
Python SDK を使用してデプロイする
エージェントのデプロイをコードから直接管理する場合は、SDK Python使用します。
その他の前提条件
Azure Container Registry のコンテナー イメージ
コンテナー レジストリのリポジトリ ライター または AcrPush 役割 (イメージをプッシュするための役割)
Azure AI Projects SDK バージョン 2.1.0 以降
pip install "azure-ai-projects>=2.1.0"
コンテナー イメージをビルドしてプッシュする
Docker イメージをビルドします。
docker build --platform linux/amd64 -t myagent:v1 .Azure Container Registryにプッシュする:
az acr login --name myregistry docker tag myagent:v1 myregistry.azurecr.io/myagent:v1 docker push myregistry.azurecr.io/myagent:v1
ヒント
再現可能なデプロイには、 :latest の代わりに一意のイメージ タグを使用します。
コンテナー レジストリのアクセス許可を構成する
プロジェクトのマネージド ID にプル イメージへのアクセス権を付与します。
Azure ポータルで、Foundry プロジェクト リソースに移動します。
Identity を選択し、システム割り当て済み の下にあるオブジェクト (プリンシパル) ID をコピーします。
コンテナー レジストリのリポジトリ閲覧者ロールを、コンテナー レジストリのこの ID に割り当てます。 Azure Container Registryのロールとアクセス許可についてご参照ください。
ホストされるエージェントのバージョンを作成する
バージョンを作成すると、エージェントを自動的にプロビジョニングするプラットフォームがトリガーされます。 別の開始手順はありません。プラットフォームによってコンテナー スナップショットが作成され、エージェントが要求を処理する準備が整います。
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import HostedAgentDefinition, ProtocolVersionRecord, AgentProtocol
from azure.identity import DefaultAzureCredential
# Format: "https://resource_name.services.ai.azure.com/api/projects/project_name"
PROJECT_ENDPOINT = "your_project_endpoint"
# Create project client
credential = DefaultAzureCredential()
project = AIProjectClient(
endpoint=PROJECT_ENDPOINT,
credential=credential,
allow_preview=True,
)
# Create a hosted agent version
agent = project.agents.create_version(
agent_name="my-agent",
definition=HostedAgentDefinition(
container_protocol_versions=[
ProtocolVersionRecord(protocol=AgentProtocol.RESPONSES, version="1.0.0")
],
cpu="1",
memory="2Gi",
image="your-registry.azurecr.io/your-image:tag",
environment_variables={
"MODEL_DEPLOYMENT_NAME": "gpt-5-mini"
}
)
)
print(f"Agent created: {agent.name}, version: {agent.version}")
複数のプロトコルを公開するには、それぞれを container_protocol_versions渡します。
container_protocol_versions=[
ProtocolVersionRecord(protocol=AgentProtocol.RESPONSES, version="1.0.0"),
ProtocolVersionRecord(protocol=AgentProtocol.INVOCATIONS, version="1.0.0"),
ProtocolVersionRecord(protocol=AgentProtocol.INVOCATIONS_WS, version="1.0.0"),
],
キー パラメーター:
| パラメーター | 説明 |
|---|---|
agent_name |
一意の名前 (ハイフン付きの英数字、最大 63 文字) |
image |
完全な Azure Container Registry イメージのURLとタグ |
cpu |
CPU の割り当て (たとえば、 "1") |
memory |
メモリの割り当て (たとえば、 "2Gi") |
container_protocol_versions |
コンテナーが公開するプロトコル (responses、 invocations、 invocations_ws、または任意の組み合わせ) |
バージョンのステータスを確認する
バージョンを作成した後、エージェントを呼び出す前に状態が active されるまでポーリングします。 通常、プロビジョニングにはイメージ サイズに応じて 1 分未満かかります。
import time
# Poll until the agent version is active
while True:
version_info = project.agents.get_version(
agent_name="my-agent",
agent_version=agent.version
)
status = version_info["status"]
print(f"Status: {status}")
if status == "active":
print("Agent is ready!")
break
elif status == "failed":
print(f"Provisioning failed: {version_info['error']}")
break
time.sleep(5)
バージョンの状態の値:
| ステータス | 説明 |
|---|---|
creating |
インフラストラクチャのプロビジョニングが進行中 |
active |
エージェントは要求を処理する準備ができています |
failed |
プロビジョニングに失敗しました - 詳細については、 error フィールドを確認してください |
deleting |
バージョンがクリーンアップされています |
deleted |
バージョンが完全に削除されました |
エージェントを呼び出す
バージョンが active 状態になったら、 get_openai_client を使用して、エージェントのエンドポイントにバインドされた OpenAI クライアントを作成します。
応答プロトコルについて
# Create an OpenAI client bound to the agent endpoint
openai_client = project.get_openai_client(agent_name="my-agent")
response = openai_client.responses.create(
input="Hello! What can you do?",
)
print(response.output_text)
呼び出しプロトコルの場合は、呼び出しエンドポイントを直接呼び出します。
import requests
token = credential.get_token("https://ai.azure.com/.default").token
url = f"{PROJECT_ENDPOINT}/agents/my-agent/endpoint/protocols/invocations"
response = requests.post(url, headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Foundry-Features": "HostedAgents=V1Preview"
}, params={"api-version": "v1"}, json={
"message": "Process this task"
})
print(response.json())
詳細な例については、 ホストされるエージェントのサンプルを参照してください。
REST API を使用してデプロイする
HTTP ベースの直接デプロイやカスタム ツールとの統合に REST API を使用します。
開始する前に、 コンテナー イメージをビルドしてプッシュし 、 コンテナー レジストリのアクセス許可を構成します。
変数を設定する
BASE_URL="https://{account}.services.ai.azure.com/api/projects/{project}"
API_VERSION="v1"
TOKEN=$(az account get-access-token --resource https://ai.azure.com --query accessToken -o tsv)
エージェントを作成する
curl -X POST "$BASE_URL/agents?api-version=$API_VERSION" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "my-agent",
"definition": {
"kind": "hosted",
"image": "myacr.azurecr.io/my-agent:v1",
"cpu": "1",
"memory": "2Gi",
"container_protocol_versions": [
{"protocol": "responses", "version": "1.0.0"}
],
"environment_variables": {
"MODEL_DEPLOYMENT_NAME": "gpt-5-mini"
}
}
}'
エージェントを作成すると、バージョン 1 も作成され、プロビジョニングがトリガーされます。
バージョンのステータスを確認する
statusがactiveされるまで、バージョン エンドポイントをポーリングします。
while true; do
STATUS=$(curl -s -X GET "$BASE_URL/agents/my-agent/versions/1?api-version=$API_VERSION" \
-H "Authorization: Bearer $TOKEN" | jq -r '.status')
echo "Status: $STATUS"
[ "$STATUS" = "active" ] && echo "Ready!" && break
[ "$STATUS" = "failed" ] && echo "Provisioning failed." && exit 1
sleep 5
done
エージェントを呼び出す
エージェントの専用エンドポイントを使用して要求を送信します。 サーバー送信イベントを受信するように "stream": true を設定します。
応答プロトコル:
curl -X POST "$BASE_URL/agents/my-agent/endpoint/protocols/openai/responses?api-version=$API_VERSION" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"input": "Hello! What can you do?",
"store": true
}'
呼び出しプロトコル:
curl -X POST "$BASE_URL/agents/my-agent/endpoint/protocols/invocations?api-version=$API_VERSION" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Foundry-Features: HostedAgents=V1Preview" \
-d '{
"message": "Process this task"
}'
新しいバージョンを作成する
新しいバージョンを作成して、更新されたコードまたは構成をデプロイします。
curl -X POST "$BASE_URL/agents/my-agent/versions?api-version=$API_VERSION" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"definition": {
"kind": "hosted",
"image": "myacr.azurecr.io/my-agent:v2",
"cpu": "1",
"memory": "2Gi",
"container_protocol_versions": [
{"protocol": "responses", "version": "1.0.0"}
],
"environment_variables": {
"MODEL_DEPLOYMENT_NAME": "gpt-5-mini"
}
}
}'
リソースのクリーンアップ
料金の発生を防ぐために、処理が完了したらリソースをクリーンアップします。 エージェント コンピューティングは、非アクティブ状態が 15 分続くとプロビジョニングが解除されるため、エージェントが要求を処理していない場合はコストはかからなくなります。
Azure Developer CLI のクリーンアップ
azd down
SDK のクリーンアップ
1 つのバージョンを削除します。
project.agents.delete_version(agent_name="my-agent", agent_version=agent.version)
または、エージェント全体とそのすべてのバージョンを削除します。
project.agents.delete(agent_name="my-agent")
REST API のクリーンアップ
1 つのバージョンを削除します。
curl -X DELETE "$BASE_URL/agents/my-agent/versions/1?api-version=$API_VERSION" \
-H "Authorization: Bearer $TOKEN"
または、エージェント全体を削除します。
curl -X DELETE "$BASE_URL/agents/my-agent?api-version=$API_VERSION" \
-H "Authorization: Bearer $TOKEN"
警告
エージェントを削除すると、そのバージョンがすべて削除され、アクティブなセッションが終了します。 この操作を元に戻すことはできません。
トラブルシューティング
プロビジョニング エラーは、バージョン オブジェクトの error.code フィールドと error.message フィールドに表示されます。 作成後にバージョンの状態を確認して、問題を特定します。
| エラー コード | HTTP コード | ソリューション |
|---|---|---|
image_pull_failed |
400 | イメージ URI が正しく、プロジェクトマネージド ID に ACR の Container Registry Repository Reader があることを確認します |
SubscriptionIsNotRegistered |
400 | サブスクリプション プロバイダーを登録する |
InvalidAcrPullCredentials |
401 | マネージド ID またはレジストリ RBAC を修正する |
UnauthorizedAcrPull |
403 | 正しい資格情報または ID を指定する |
AcrImageNotFound |
404 | イメージ名/タグを修正するか、イメージを発行する |
RegistryNotFound |
400/404 | レジストリ DNS またはネットワークの到達可能性を修正する |
5xx エラーについては、Microsoftサポートにお問い合わせください。
RBAC の要件とアクセス許可のトラブルシューティングの詳細については、 ホストされるエージェントのアクセス許可のリファレンスを参照してください。