0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Microsoft Foundry Hosted Agent をゼロからデプロイして分かったこと

0
Posted at

はじめに

本記事記述および実装内容は、多くの部分をAIで処理しており、人間チェックは甘いです

Microsoft Foundry の Hosted Agent(Public Preview)を実際にゼロから IaC 構築 → デプロイ → 呼び出し → 監視確認まで一通り検証しました。

公式ドキュメントだけでは分かりにくいハマりポイントが多く、特に API バージョンの互換性問題RBAC の複雑さ には苦労しました。この記事では、検証で得た知見を実践ベースで共有します。

この記事で分かること

  • Hosted Agent の仕組みとデプロイ方法(4パターン)
  • 最小構成のコードとインフラ要件
  • API バージョン互換性の落とし穴と対処法
  • RBAC で必要なロール一覧
  • トレース・監視が自動で動く仕組み
  • 価格体系と注意点
  • 構築時のハマりポイント集

検証環境

項目 内容
検証日 2026-04-28
ホスティングリージョン Canada Central
モデル推論リージョン West US
SDK agent-framework 1.2.0, agent-framework-foundry-hosting 1.0.0a260424
API バージョン 2025-05-15-preview (Agent API), 2025-10-01-preview (Capability Host)

Hosted Agent とは

Hosted Agent は、自分で書いたコンテナ化された AI エージェントを Foundry Agent Service 上で実行できるサービスです。

Prompt Agent(LLM の設定だけで作るエージェント)とは異なり、任意の Python/C# コードをコンテナに入れてデプロイでき、カスタムツールや外部 API 連携が自由にできます。

アーキテクチャ概要
┌──────────────────────────────────────────────────────┐
│  Foundry Agent Service                                │
│  ┌────────────────────────────────────────────────┐  │
│  │  Hypervisor Sandbox (セッションごとに分離)       │  │
│  │  ┌─────────────────────────────────────────┐   │  │
│  │  │  Your Container (main.py)               │   │  │
│  │  │  → OpenAI Responses API で通信          │   │  │
│  │  └─────────────────────────────────────────┘   │  │
│  └────────────────────────────────────────────────┘  │
│                                                       │
│  Auto: OTel → Application Insights                   │
│  Auto: Managed Identity (instance_identity)          │
│  Auto: Scale-to-zero (15分アイドルで停止)             │
└──────────────────────────────────────────────────────┘

主な特徴:

  • スケールトゼロ(アイドル15分で停止、コンピュート課金停止)
  • Hypervisor レベルのサンドボックス分離
  • エージェントごとに自動で Managed Identity 発行
  • Application Insights へのトレース自動送信
  • OpenAI 互換 Responses API プロトコル

最小構成のエージェントコード

必要なファイルは 3 つだけ:

main.py
import os
from agent_framework import Agent
from agent_framework.openai import OpenAIChatClient
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.identity import DefaultAzureCredential

def main():
    credential = DefaultAzureCredential()

    # ⚠️ api_version の明示指定が必須(後述)
    client = OpenAIChatClient(
        model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
        azure_endpoint=os.environ["MODEL_ENDPOINT"],
        credential=credential,
        api_version="2025-05-15-preview",
    )

    agent = Agent(
        client=client,
        instructions="You are a friendly assistant.",
        default_options={"store": False},
    )

    server = ResponsesHostServer(agent)
    server.run()

if __name__ == "__main__":
    main()
requirements.txt
agent-framework>=1.1.1
agent-framework-foundry-hosting
azure-identity
python-dotenv
Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . /app/user_agent/
EXPOSE 8088
CMD ["python", "/app/user_agent/main.py"]

デプロイ方法(4パターン)

方法A: REST API で直接デプロイ

最もプリミティブだが、仕組みの理解に最適。YAML ファイル不要。

REST-APIでデプロイ
# 1. ACR にイメージをビルド・プッシュ
az acr build --registry myacr --image my-agent:v1 --file Dockerfile .

# 2. REST API でエージェント作成
TOKEN=$(az account get-access-token --query accessToken -o tsv)
curl -X POST "${PROJECT_ENDPOINT}/agents?api-version=2025-05-15-preview" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-agent",
    "definition": {
      "kind": "hosted",
      "container_protocol_versions": [{"protocol": "responses", "version": "1.0.0"}],
      "cpu": "0.25",
      "memory": "0.5Gi",
      "image": "myacr.azurecr.io/my-agent:v1",
      "environment_variables": {
        "MODEL_ENDPOINT": "https://...",
        "AZURE_AI_MODEL_DEPLOYMENT_NAME": "gpt-4-1-mini"
      }
    }
  }'

方法B: azd CLI でデプロイ(推奨)

azd ai agent 拡張機能を使うとビルド・プッシュ・RBAC まで自動。

azdでデプロイ
azd ext install azure.ai.agents    # 拡張機能インストール
azd ai agent init                   # テンプレート生成
azd provision                       # インフラ構築
azd deploy                          # ビルド→プッシュ→エージェント作成→RBAC 割当

追加で agent.yaml(ランタイムスペック)と azure-agent.yaml(azd サービス定義)が必要。

agent.yaml の例
agent.yaml
kind: hosted
name: my-hosted-agent
protocols:
  - protocol: responses
    version: 1.0.0
resources:
  cpu: '0.25'
  memory: '0.5Gi'
azure-agent.yaml の例
azure-agent.yaml
services:
  hosted-agent:
    project: ./hosted-agent
    language: py
    host: containerapp
    agent:
      kind: hosted
      protocols:
        - protocol: responses
          version: 1.0.0
      resources:
        cpu: '0.25'
        memory: '0.5Gi'

方法C: Foundry Portal

GUI だけでのデプロイは未提供(2026-05 現在)。Portal は管理・テスト用 UI:

  • デプロイ済みエージェントの状態確認
  • Playground でのテスト
  • コンテナログ・セッションファイルの閲覧

公式ドキュメントの「Foundry Portal」ピボットも実際には azd deploy を前提としています。Portal 単体でのデプロイ機能はありません。

方法D: VS Code 拡張機能(Microsoft Foundry Toolkit)

コマンドパレットから GUI 操作でデプロイまで完結:

  1. Microsoft Foundry: Create Project — プロジェクト作成
  2. Microsoft Foundry: Open Model Catalog — モデルデプロイ
  3. Microsoft Foundry: Create new Hosted Agent — スキャフォールド
  4. F5 — ローカルテスト
  5. Microsoft Foundry: Deploy Hosted Agent — デプロイ(RBAC 自動割当)

Docker Desktop 不要(リモートビルド)。プレリリース版の Microsoft Foundry Toolkit 拡張機能が必要です。

⚠️ 最大のハマりポイント: API バージョン互換性

問題

agent-framework の SDK(OpenAIChatClient, FoundryChatClient)は内部で /openai/v1/responses パスを使います。しかし、Azure AI Services のゲートウェイはこのパスを特定の API バージョンでしか受け付けません

検証結果

API バージョン /openai/v1/responses /openai/responses
2024-10-21
2025-03-01-preview
2025-04-01-preview
2025-05-15-preview

結論

api_version="2025-05-15-preview" の明示指定が必須。

SDK のデフォルト api_version では動作しません。指定しないと以下のエラーが返ります:

エラーレスポンス例
{
  "error": {
    "code": "BadRequest",
    "message": "Unsupported API version: The request URL path is not recognized."
  }
}

なぜこうなるのか

  • Responses API 自体は 2025-03-01-preview で追加された
  • しかし /v1/ プレフィックス付きパスのルーティングは 2025-05-15-preview で初めて対応
  • SDK は OpenAI 互換のため /v1/ パスを使う → 古い API バージョンだと 400 エラー

2026-05 時点で /v1/responses に対応する GA バージョンは存在しない。Preview API への依存が必須です。

検証に使用したスクリプト
api-version-test.sh
for ver in "2024-10-21" "2025-03-01-preview" "2025-04-01-preview" "2025-05-15-preview"; do
  for path in "/openai/v1/responses" "/openai/responses"; do
    status=$(curl -s -o /dev/null -w "%{http_code}" \
      -X POST "${ENDPOINT}${path}?api-version=${ver}" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"model":"gpt-4.1-mini","input":"hello"}')
    echo "$ver | $path | $status"
  done
done

RBAC 設定(3 ロール必要)

Hosted Agent のデプロイ後、自動生成される instance_identity に以下のロール割り当てが必要です:

# 対象リソース ロール 目的
1 モデルデプロイメントのある AI Services Cognitive Services User モデル推論
2 ホスティング先 AI Account Cognitive Services User ストレージ読み取り(Playground 対応)
3 ホスティング先 AI Account Azure AI Developer ストレージ書き込み(store:true, マルチターン)

よくあるエラーと対応

エラー 1:

PermissionDeniedエラー(ストレージ読み取り)
PermissionDenied: lacks the required data action 
Microsoft.CognitiveServices/accounts/AIServices/agents/read

原因: ロール #2(ホスティング先への Cognitive Services User)が未割当
対処: az role assignment create で割り当て

エラー 2:

PermissionDeniedエラー(モデルアクセス)
PermissionDenied: Principal does not have access to API/Operation.

原因: ロール #1(モデル側への Cognitive Services User)が未割当、またはモデルエンドポイントが到達不能
対処: モデルのある AI Services にロール割り当て、またはエンドポイント URL 確認

エージェントを削除→再作成するたびに新しい instance_identity が発行されます。 つまり RBAC も毎回再割り当てが必要です。CI/CD パイプラインでは自動化を組み込んでください。

トレース・監視(自動で動く)

configure_azure_monitor() は不要

Hosted Agent では コードに計装を書く必要がありませんResponsesHostServer が起動時に自動で OTel SDK を初期化し、プラットフォームから注入された APPLICATIONINSIGHTS_CONNECTION_STRING を使って Application Insights にトレースを送信します。

トレース設定(Hosted-Agentの場合)
# ❌ Hosted Agent ではこれは不要
# from azure.monitor.opentelemetry import configure_azure_monitor
# configure_azure_monitor()

# ✅ ResponsesHostServer が内部で自動構成
server = ResponsesHostServer(agent)
server.run()
デプロイ形態 configure_azure_monitor
Hosted Agent(Foundry Agent Service) 不要(自動)
ローカル開発でトレース確認 必要
Container Apps 等に自前デプロイ 必要

APPLICATIONINSIGHTS_CONNECTION_STRING はプラットフォームがコンテナに自動注入します。appi-connection が正しく設定されていれば、コード側での対応は一切不要です。

確認できたテレメトリ

コンテナ起動時にログが出ます:

起動ログ
Application Insights trace exporter configured.
Application Insights log exporter configured.

Application Insights で確認できるデータ:

テーブル 内容
requests エージェント呼び出し(レイテンシ、ステータス)
traces アプリケーションログ
exceptions エラースタックトレース
KQLクエリ例(レイテンシ確認)
requests
| where name startswith "invoke_agent"
| project timestamp, name, duration
| order by timestamp desc

観測されたレイテンシ

状態 レイテンシ
コールドスタート(初回セッション作成) 20〜30秒
ウォームスタート 1.2〜3.0秒
モデル推論のみ 1.0〜1.5秒

価格体系

コンピュート課金(スケールトゼロ)

課金項目 単価
vCPU $0.0994/時
メモリ $0.0118/GiB-時

月額見積もり:

サイズ スペック 24時間稼働 1日8時間
最小 0.25 vCPU / 0.5 GiB 約 $22/月 約 $7/月
1 vCPU / 2 GiB 約 $89/月 約 $30/月
最大 2 vCPU / 4 GiB 約 $178/月 約 $59/月

注意点

以下の課金はコンピュート料金に含まれません。別途発生します。

  1. 15分アイドルで課金停止 — スケールトゼロ対応で、使わなければコンピュート費用はかからない
  2. モデル推論は別課金 — GPT-4.1-mini 等のトークン課金が別途発生
  3. ACR 課金 — コンテナイメージ格納(Basic: ~$5/月)
  4. Application Insights 課金 — トレースデータ量に応じて課金(5GB/月まで無料)
  5. 状態保持中のストレージ — セッション停止後も最大30日間状態が残り、ストレージ課金が継続

インフラ構築時のハマりポイント集

1. Capability Host の設定

enablePublicHostingEnvironmentAccount レベルと Project レベルの両方true にする必要があります。片方だけだとエージェント作成時に 500 エラー。

CapabilityHost作成(Accountレベル)
az rest --method PUT \
  --url "https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.CognitiveServices/accounts/{account}/capabilityHosts/default?api-version=2025-10-01-preview" \
  --body '{"properties": {"enablePublicHostingEnvironment": true}}'

一度作成した Capability Host の更新(PUT)が反映されない場合があります。その場合は全エージェント削除 → Capability Host 再作成が必要です。

2. ACR 接続

  • 認証タイプ: ManagedIdentity(RegistryIdentity)
  • isSharedToAll: true が必要
  • プロジェクト Managed Identity に AcrPull ロール割り当て

3. Application Insights 接続

  • 認証タイプ: ApiKey
  • credentials.key には 完全な ConnectionString を設定(InstrumentationKey=xxx;IngestionEndpoint=xxx;LiveEndpoint=xxx 形式)
  • 接続が不正だとコンテナ起動時にクラッシュ

4. 予約済み環境変数

FOUNDRY_*AGENT_* プレフィックスはプラットフォームが自動注入するため使用不可。カスタム変数は MODEL_ENDPOINT のように自由に命名してください。

5. エージェント更新は削除→再作成のみ

PUT/PATCH は 405。イメージ更新にはエージェント削除 → 再作成が必要で、毎回新しい identity が発行されるため RBAC も再設定が必要。

6. リージョン制約

サポートリージョン(2026-04): Australia East, Canada Central, North Central US, Sweden Central のみ。

モデルの SKU 可用性はリージョン × サブスクリプションに依存します。az cognitiveservices model list で表示されても実際にデプロイできない場合があるため注意。

マルチターン会話

方式1: input 配列で履歴を渡す ✅

input配列方式
{
  "input": [
    {"role": "user", "content": "My name is Taro."},
    {"role": "assistant", "content": "了解しました、太郎さん。"},
    {"role": "user", "content": "What is my name?"}
  ]
}

→ 問題なく動作。クライアント側で履歴管理が必要。

方式2: previous_response_id ⚠️

previous_response_id方式
{
  "input": "What is my name?",
  "previous_response_id": "resp_abc123..."
}

store: true + Azure AI Developer ロールが必要。RBAC が不足すると PermissionDenied。

総合評価

👍 長所

  • スケールトゼロ — 使わなければコンピュート無料
  • Hypervisor 分離 — セキュリティが高い
  • 自動 Managed Identity — エージェントごとに発行
  • OTel 自動統合 — コード変更なしで監視可能
  • OpenAI 互換 API — 標準的なインターフェース

👎 課題(Public Preview 段階)

  • リージョン制限 — 4リージョンのみ
  • 削除→再作成 — エージェント更新のたびに RBAC 再設定
  • API バージョン問題 — GA 対応なし、Preview 必須
  • Capability Host 更新不可 — 初回構築を正確に
  • RBAC の複雑さ — 3リソース × 3ロールの理解が必要
  • ドキュメントと実際の差異 — API パスやエラーメッセージ

本番利用に向けた推奨事項

  1. モデルとホスティングを同一リージョンに配置
  2. store: false を基本とし、必要時のみ有効化
  3. CI/CD で RBAC 再割り当ての自動化を組み込む
  4. Capability Host は初回構築時に正確に設定
  5. Application Insights でコールドスタートのレイテンシを監視
  6. コンテナイメージサイズを最小化

まとめ

Microsoft Foundry Hosted Agent は、カスタムコードの AI エージェントをサーバーレスに動かせる有望なサービスです。スケールトゼロ課金と分離は大きな魅力。

一方で Public Preview 段階のため、API バージョン互換性、RBAC の複雑さ、エージェント更新の手間など、プロダクション利用にはまだ工夫が必要です。特に api_version="2025-05-15-preview" の明示指定 を忘れると何も動かないので、最初にこの記事を読んでから着手することをお勧めします。

GA に向けて改善が進むことを期待しています。

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?