Azure AI Agent Server SDK for Python beta wave解説:実装・移行・自動化で楽になる点

Azure AI Agent Server SDK for Python を使って Hosted Agent を実装している開発者にとって、2026年4月20日時点で注目すべき更新は、coreinvocationsresponses の beta wave が足並みをそろえて診断性と運用性を強化した点です。結論から言うと、今回の更新で楽になるのは「ログを自前で仕込む作業」「リクエスト単位の障害追跡」「Responses API の状態管理・SSE・チャット分離まわりの実装確認」「旧プレビューからの移行判断」です。

特に azure-ai-agentserver-core_2.0.0b2 では起動時設定ログと受信リクエストログが強化され、azure-ai-agentserver-invocations_1.0.0b2azure-ai-agentserver-responses_1.0.0b2 ではその共通基盤を使って、各プロトコルホストの見通しが良くなりました。Developers、platform engineers、DevOps teams が「PoC のエージェントを運用に近づける」段階で、かなり効いてくる更新です。(GitHub)

目次

Azure AI Agent Server SDK for Python の beta wave は何を変えるのか

Azure AI Agent Server SDK for Python は、Azure AI Hosted Agent コンテナーを Python で実装するための SDK 群です。azure-ai-agentserver-core がホスト基盤を担い、azure-ai-agentserver-invocationsazure-ai-agentserver-responses がそれぞれ Invocation protocol、Responses protocol のエンドポイントを追加します。Microsoft Learn では、core パッケージが health probe、graceful shutdown、OpenTelemetry tracing、ASGI serving などのプロトコル非依存の基盤を提供すると説明されています。(Microsoft Learn)

今回の coordinated beta wave のポイントは、単なる機能追加ではなく、実装後に「なぜ動かないのか」「どのリクエストが遅いのか」「どの response ID が問題なのか」を追いやすくしたことです。

パッケージ主な役割今回の開発者メリット
azure-ai-agentserver-coreHosted Agent の共通ホスト基盤起動設定、受信HTTPリクエスト、trace ID、相関ヘッダーを見やすくする
azure-ai-agentserver-invocations任意JSONの実行API、Webhook型処理、非会話型処理OpenAPI spec の設定有無や受信リクエストを確認しやすくする
azure-ai-agentserver-responsesResponses API、SSE、background、cancel、delete、input itemsresponse lifecycle、チャット分離、SSE replay、Foundry storage 呼び出しの診断を強化する

注意したいのは、これらは beta / preview 系の更新であり、短い期間で後続バージョンが出る可能性があることです。本番導入では、対象バージョンの Release notes と Microsoft Learn の該当バージョンを確認してから固定するのが安全です。

core 2.0.0b2:ログとトレースの共通基盤が実装負担を減らす

azure-ai-agentserver-core_2.0.0b2 の中心は、AgentServerHost による運用ログの強化です。Release notes では、起動時に platform environment、connectivity、host options の3系統の INFO ログを出力すること、また InboundRequestLoggingMiddleware が自動で組み込まれ、HTTP method、path、status code、duration、x-request-idx-ms-client-request-id などを記録することが示されています。(GitHub)

これにより、これまでアプリ側で書きがちだった次のようなログを、SDK 側の標準的な形式に寄せやすくなります。

# 以前はアプリ側でこのようなログを個別に入れがちだった
logger.info("request started: path=%s", request.url.path)
logger.info("request completed: status=%s duration_ms=%s", status, duration_ms)

今回の更新後は、最低限のアプリ固有ログに絞れます。

import logging
from azure.ai.agentserver.invocations import InvocationAgentServerHost
from starlette.requests import Request
from starlette.responses import JSONResponse, Response

logger = logging.getLogger(__name__)

app = InvocationAgentServerHost(log_level="INFO")

@app.invoke_handler
async def handle(request: Request) -> Response:
    body = await request.json()

    # SDK側でHTTPリクエストの共通情報は記録されるため、
    # ここでは業務上意味のあるイベントだけを残す
    logger.info("business_event=customer_lookup_requested")

    return JSONResponse({"ok": True, "input": body})

app.run()

起動時ログで見るべき項目

起動時ログは、開発者だけでなく platform engineers にも役立ちます。たとえばコンテナーが起動しているのに Hosted Agent として呼び出せない場合、アプリコードより先に起動設定を確認すべきです。

確認項目見るべき内容よくある切り分け
agent name / version期待したエージェント名とバージョンか古いイメージをデプロイしていないか
portPORT 環境変数または既定ポートルーティング先ポートの不一致
project endpointAzure AI Foundry project endpoint環境変数の設定漏れ
OTLP endpointOpenTelemetry collector の宛先trace が外部基盤に出ない原因
registered protocolsResponses / Invocations の登録状況期待した protocol host が起動していない

AgentServerHostPORT 環境変数、FOUNDRY_AGENT_NAMEFOUNDRY_AGENT_VERSIONFOUNDRY_PROJECT_ENDPOINT、Application Insights connection string、OTLP endpoint などを扱います。Microsoft Learn では、既定の listen port は 8088、Python 3.10 以降が前提と説明されています。(Microsoft Learn)

InboundRequestLoggingMiddleware で障害調査がどう楽になるか

今回の更新で実務上大きいのは、InboundRequestLoggingMiddleware が core に入り、各 protocol host で一貫した受信リクエストログを使いやすくなったことです。core_2.0.0b2 では、ステータスコードが400以上の場合は WARNING、未処理例外は500として WARNING に記録され、OpenTelemetry span がない場合でも W3C traceparent ヘッダーから trace ID を抽出できるようになったとされています。(GitHub)

実装者の視点では、次のようなトラブルシュートがしやすくなります。

症状ログで見るポイント次のアクション
クライアントから400が返るpath、status code、correlation headerrequest body validation、response ID、必須ヘッダーを確認
特定APIだけ遅いduration_ms、pathhandler 内の処理、外部LLM、storage呼び出しを分けて見る
クライアント側ログと突合できないx-request-idx-ms-client-request-idクライアント側でも同じIDを記録
分散トレースに載らないtrace ID、OTLP / Application Insights 設定connection string、OTLP endpoint、collector 側設定を確認
例外発生時に原因が分からないWARNING ログ、500記録handler で握りつぶしていないか確認

重要なのは、ログの粒度を「全部 DEBUG にする」ではなく、共通ログは SDK、業務イベントはアプリ、外部依存は span / correlation ID という役割分担にすることです。これにより、ログ量を増やしすぎずに調査できます。

invocations 1.0.0b2:任意JSON APIを業務処理に組み込みやすくなる

azure-ai-agentserver-invocations_1.0.0b2 では、InvocationAgentServerHost が OpenAPI spec の設定有無を INFO レベルでログ出力し、受信リクエストログも AgentServerHost によって自動的に組み込まれるようになりました。(GitHub)

Invocations protocol は、会話型の Responses API よりもシンプルに「入力JSONを受け取り、処理結果を返す」用途に向いています。Microsoft Learn では、POST /invocationsGET /invocations/{id}POST /invocations/{id}/cancelGET /invocations/docs/openapi.json が invocation lifecycle として説明されています。(Microsoft Learn)

Invocations が向いている実装パターン

Invocations は、次のようなケースで使いやすい選択肢です。

用途判断基準
Webhook型処理外部サービスからJSONを受けて分類・要約する会話履歴よりも単発処理が中心
業務API化顧客IDを受け取り、社内データを参照して回答する入出力スキーマを明確にしたい
非同期処理長時間の分析ジョブを起動し、後から取得するpolling / cancel が必要
OpenAPI連携エージェントのAPI仕様を公開するGET /invocations/docs/openapi.json を使いたい

最小構成は次のように書けます。

from azure.ai.agentserver.invocations import InvocationAgentServerHost
from starlette.requests import Request
from starlette.responses import JSONResponse, Response

app = InvocationAgentServerHost()

@app.invoke_handler
async def handle(request: Request) -> Response:
    data = await request.json()

    # 例:業務処理に渡しやすいように入力を検証する
    name = data.get("name")
    if not name:
        return JSONResponse(
            {"error": "name is required"},
            status_code=400,
        )

    return JSONResponse({"greeting": f"Hello, {name}!"})

app.run()

request.state.invocation_idrequest.state.session_id を使うと、処理単位や会話単位のログをアプリ側でも残せます。Microsoft Learn では、x-agent-invocation-id がリクエスト・レスポンスで扱われ、agent_session_id query parameter、FOUNDRY_AGENT_SESSION_ID、自動生成UUIDの順に session ID が解決されると説明されています。(Microsoft Learn)

@app.invoke_handler
async def handle(request: Request) -> Response:
    data = await request.json()

    invocation_id = request.state.invocation_id
    session_id = request.state.session_id

    return JSONResponse({
        "invocation_id": invocation_id,
        "session_id": session_id,
        "received": data,
    })

OpenAPI spec の有無がログで分かるメリット

InvocationAgentServerHost では、OpenAPI spec を渡すと GET /invocations/docs/openapi.json で公開できます。今回の更新で spec の設定有無が起動時に見えるため、「ドキュメントエンドポイントが空なのは実装ミスか、意図した未設定か」を切り分けやすくなります。

app = InvocationAgentServerHost(openapi_spec={
    "openapi": "3.0.3",
    "info": {
        "title": "Customer Support Agent",
        "version": "1.0.0",
    },
    "paths": {
        "/invocations": {
            "post": {
                "summary": "Run customer support agent",
                "responses": {
                    "200": {"description": "Success"},
                },
            },
        },
    },
})

responses 1.0.0b2:会話型・SSE・状態管理の実装が見通しやすくなる

azure-ai-agentserver-responses_1.0.0b2 は、今回の beta wave で最も変更点が多いパッケージです。Release notes では、ResponsesAgentServerHost の起動時ログ、受信リクエストログ、handler-level diagnostic logging、orchestrator handler invocation logging、chat isolation key enforcement、response ID validation、Foundry storage logging policy、SSE replay 修正、item_reference 永続化時の解決などが追加・修正されています。(GitHub)

Responses protocol は、単発JSON処理よりも「会話」「ストリーミング」「background実行」「履歴」「キャンセル」「入力アイテム参照」を扱う場面に向いています。Microsoft Learn では、Responses パッケージが create、stream、cancel、delete、replay、input-item listing を含む response lifecycle を提供すると説明されています。(Microsoft Learn)

Responses の最小実装

テキスト応答だけなら、TextResponse を使うと lifecycle event の細かい生成を SDK に任せられます。

import asyncio

from azure.ai.agentserver.responses import (
    CreateResponse,
    ResponseContext,
    ResponsesAgentServerHost,
    TextResponse,
)

app = ResponsesAgentServerHost()

@app.response_handler
async def handler(
    request: CreateResponse,
    context: ResponseContext,
    cancellation_signal: asyncio.Event,
):
    text = await context.get_input_text()
    return TextResponse(context, request, text=f"Echo: {text}")

app.run()

この形は、まず Hosted Agent として動かしたい場合に向いています。アプリ側は「入力テキストをどう処理するか」に集中でき、SSE lifecycle の細かなイベント管理を後回しにできます。

TextResponse と ResponseEventStream の使い分け

Responses の実装では、TextResponseResponseEventStream の使い分けが重要です。GitHub の handler implementation guide では、単一のテキストメッセージや最小ボイラープレートなら TextResponse、reasoning、function calls、tool calls、細かな delta 制御が必要なら ResponseEventStream が適していると説明されています。(GitHub)

選択肢向いているケース避けたいケース
TextResponseEcho bot、FAQ、単純なテキスト回答、PoCfunction call や複数output typeを細かく出したい
ResponseEventStreamreasoning + message、function calling、token streaming、複数出力まず動かすだけの小規模実装

ResponseEventStream を使う場合は、イベントの順序を意識します。

from azure.ai.agentserver.responses import ResponseEventStream

@app.response_handler
def handler(request, context, cancellation_signal):
    stream = ResponseEventStream(
        response_id=context.response_id,
        request=request,
    )

    yield stream.emit_created()
    yield stream.emit_in_progress()

    yield from stream.output_item_message("処理を開始しました。")
    yield from stream.output_item_message("こちらが回答です。")

    yield stream.emit_completed()

チャット分離キーの強制で情報漏えいリスクを下げる

responses_1.0.0b2 で特に実務的なのが、chat isolation key enforcement です。Release notes では、response 作成時に x-agent-chat-isolation-key ヘッダーが指定された場合、後続の GET、DELETE、Cancel、InputItems でも同じキーが必要になり、欠落または不一致の場合は識別困難な404を返してクロスチャットの情報漏えいを防ぐと説明されています。(GitHub)

これは、マルチテナントや複数ユーザーが同じ Hosted Agent にアクセスする構成で重要です。

シナリオリスク対策
同一エージェントを複数ユーザーで共有response ID を推測・誤用されるchat isolation key をクライアント単位で付与
UI が複数チャットを同時に扱う別チャットの response を取得するchat ID / conversation ID と isolation key を対応させる
replay / input_items を使う過去入力の取り違え後続リクエストでも同じ key を送る
削除・キャンセルAPIを公開する他セッションの操作server 側で isolation key の一貫性を検証

実装側では、クライアントが response 作成後のすべての操作で同じヘッダーを送るように設計します。

curl -X POST "http://localhost:8088/responses" \
  -H "Content-Type: application/json" \
  -H "x-agent-chat-isolation-key: chat-tenant-a-001" \
  -d '{
    "input": "このチャットの要約を作ってください"
  }'

後続取得でも同じキーを送ります。

curl -X GET "http://localhost:8088/responses/resp_123" \
  -H "x-agent-chat-isolation-key: chat-tenant-a-001"

失敗しやすいのは、フロントエンドの初回 POST /responses にはヘッダーを付けているのに、polling、cancel、input_items 取得では付け忘れるパターンです。特に API client を複数箇所で実装している場合は、共通 client にヘッダー付与を集約しましょう。

response ID validation とエラーコード修正で自動化が安定する

responses_1.0.0b2 では、malformed response ID validation も追加されています。Release notes によると、response_id path parameter を受け取るエンドポイントでは、prefix が違う、短すぎるなどの不正なIDを storage に触る前に HTTP 400 として拒否し、previous_response_id も検証されます。また、400 / 404 の error code"invalid_request_error"、500 が "server_error" になるなど、spec-compliant な値に修正されています。(GitHub)

これは DevOps teams にとって大きな意味があります。CI、監視、Synthetic test、API gateway のルールでは、エラー形式が安定しているほど自動判定しやすくなるからです。

変更自動化で楽になる点
不正な response ID を storage 前に400で拒否無駄な storage 呼び出しを避け、異常入力を早く検出できる
deleted resource が404になる削除済みと不正リクエストを分けて扱いやすい
cancel terminal state のメッセージ修正テスト期待値を仕様寄りにできる
error code の標準化API client 側の分岐を単純化できる
Foundry storage errors の明示的な mapping例外が broad exception に飲み込まれにくい

API client 側では、文字列メッセージ全文に依存するより、status_codeerror.code を中心に分岐する設計が安全です。

def classify_agent_error(status_code: int, error: dict) -> str:
    code = error.get("code") or error.get("type")

    if status_code == 400 and code == "invalid_request_error":
        return "client_request_invalid"

    if status_code == 404:
        return "resource_not_found_or_isolated"

    if status_code >= 500 and code == "server_error":
        return "server_side_failure"

    return "unknown"

SSE stream replay と item_reference 修正はどこに効くか

responses_1.0.0b2 では、SSE stream replay と item_reference に関する修正も入っています。Release notes では、response provider が ResponseStreamProviderProtocol を実装していない場合でも GET /responses/{id}?stream=true の replay が動作するように in-memory stream provider を fallback として用意すること、また POST /responses の input に含まれる item_reference が永続化時に解決されるようになったことが説明されています。(GitHub)

この修正は、次のような実装で効きます。

実装シーン以前起きやすかった問題今回の改善で期待できること
background + stream接続断後の replay が扱いにくいstream provider が未設定でも fallback で再生しやすい
Foundry storage 利用stream provider 実装差が障害になるstorage と stream の責務差を吸収しやすい
file / item 参照入力inline item だけ残り、参照入力が落ちるinput_items で参照元を追いやすい
multi-turn history前回入力の再構成が不完全になる永続化時に item reference を解決しやすい

特に「ユーザーがファイルや画像を入力し、後続ターンで参照する」ようなエージェントでは、input_items の整合性が重要です。単純なテキストチャットでは目立ちませんが、業務アプリでは調査・監査・再実行の品質に直結します。

Foundry storage logging policy で外部依存の切り分けがしやすくなる

responses_1.0.0b2 では、FoundryStorageLoggingPolicy も追加されています。Release notes では、Foundry storage への HTTP 呼び出しについて method、URI、status code、duration、correlation headers を azure.ai.agentserver logger に記録し、4xx / 5xx では WARNING にエスカレーションすると説明されています。また、x-request-idapim-request-idx-ms-client-request-idx-ms-request-id などのレスポンスヘッダーも記録対象になっています。(GitHub)

この更新により、障害時に「アプリの handler が遅いのか」「Foundry storage への保存・取得が遅いのか」を分けて見やすくなります。

実務では、次のようにログを読むと効率的です。

見る順番確認するログ判断
1inbound request durationエンドポイント全体が遅いか
2handler-level diagnostic loghandler に入ったか、成功したか
3Foundry storage durationstorage 呼び出しが遅いか
4correlation headersクライアント、Agent Server、Foundry 側を突合できるか
5trace ID分散トレース上で一連の処理を追えるか

ログが増えると読みづらくなるため、最初から全ログを DEBUG にするより、INFO で標準ログを見て、再現性のある障害だけ詳細ログを追加する運用が向いています。

実装時のパッケージ選定:Invocations か Responses か

Azure AI Agent Server SDK for Python を使うとき、多くの開発者が迷うのは「Invocations と Responses のどちらを使うべきか」です。Microsoft の移行ガイドでは、CrewAI、Semantic Kernel、custom code などでは protocol libraries を直接使い、interaction pattern に応じて azure-ai-agentserver-responses または azure-ai-agentserver-invocations を選ぶ流れが示されています。(Microsoft Learn)

判断軸Invocations が向くResponses が向く
入力形式任意JSONResponses API 形式の input
会話履歴アプリ側で管理したいSDK の context / history を活用したい
ストリーミング独自 SSE で十分Responses lifecycle と SSE replay を使いたい
キャンセル独自ジョブ管理に寄せたいresponse lifecycle として扱いたい
function calling / reasoning自前でイベント設計するResponseEventStream で扱いたい
業務API公開OpenAPI spec と相性が良い会話UIやAIアシスタントUIと相性が良い

迷った場合は、まず次の基準で決めると失敗しにくいです。

単発の業務処理、Webhook、JSON APIなら Invocations。会話、ストリーミング、履歴、キャンセル、replay をまとめて扱うなら Responses。

旧プレビューからの移行で見るべきポイント

Microsoft Learn の移行ガイドでは、初期プレビューの framework-specific adapter packages から、refreshed preview では protocol-specific libraries に置き換わることが示されています。具体的には、azure-ai-agentserver-agentframeworkazure-ai-agentserver-langgraph から、azure-ai-agentserver-responses または azure-ai-agentserver-invocations への移行が案内されています。(Microsoft Learn)

移行時は、次の順で棚卸しすると安全です。

手順確認内容実務上のポイント
1現在使っている adapter packageagentframework / langgraph 依存を確認
2interaction pattern会話型なら Responses、任意JSONなら Invocations
3entry pointfrom_langgraph(...).run() などを host handler に置き換える
4protocol version"v1" から semver 形式 "1.0.0" への変更を確認
5agent.yamlprotocol version、tools definitions、routing を確認
6ログ・監視x-request-id、trace ID、Application Insights / OTLP を確認
7E2Eテストcreate、get、cancel、delete、stream、replay を再確認

移行で失敗しやすいのは、ライブラリだけを置き換えて、agent.yaml や protocol version、entry point の変更を見落とすことです。特に CI/CD でデプロイしている場合、コードと設定ファイルを同じPRで変更し、最小の smoke test を必ず通しましょう。

DevOps 観点の導入チェックリスト

今回の beta wave は「実装者が楽になる更新」であると同時に、「運用で困らないための土台」を整える更新でもあります。導入前に、次の項目を確認しておくと後戻りを減らせます。

項目推奨アクション
バージョン固定preview SDK は変化が早いため、requirements.txt や lock file でバージョンを固定する
起動確認起動時ログで agent name、version、port、registered protocols を確認する
リクエスト追跡クライアント側で x-request-id または相関IDをログに残す
分散トレースApplication Insights または OTLP exporter の接続を検証する
Responses の isolationx-agent-chat-isolation-key を全リクエストで一貫して送る
エラー判定メッセージ全文ではなく status code と error code で分岐する
SSE テストstream、background、disconnect、replay を別々に検証する
storage 切り分けFoundry storage の duration と status code を確認する
ログ量INFO を基本にし、DEBUG は再現性のある障害調査時に使う
ロールバック直前バージョンに戻せるよう container image と lock file を保存する

CIで最低限テストしたいリクエスト

SDK の更新を取り込むときは、ユニットテストだけでなく、ローカルまたは検証環境で HTTP レベルの smoke test を入れると効果的です。

Invocations の場合は、最低限 POST /invocations を確認します。

curl -i -X POST "http://localhost:8088/invocations" \
  -H "Content-Type: application/json" \
  -H "x-ms-client-request-id: ci-smoke-001" \
  -d '{"name":"Alice"}'

Responses の場合は、create と get を分けて確認します。

curl -i -X POST "http://localhost:8088/responses" \
  -H "Content-Type: application/json" \
  -H "x-agent-chat-isolation-key: ci-chat-001" \
  -d '{"input":"hello"}'

取得、キャンセル、削除、input_items、stream replay を使う構成なら、それぞれの正常系・異常系をテストします。特に x-agent-chat-isolation-key の欠落や不一致、壊れた response ID、削除済み response の再取得は、今回の更新で挙動を確認しておきたいポイントです。

今回の更新で「楽になること」と「まだ自分で設計すべきこと」

今回の coordinated beta wave により、Azure AI Agent Server SDK for Python は、実装後の可観測性とプロトコル運用がかなり扱いやすくなりました。ただし、SDK がすべてを肩代わりするわけではありません。

楽になることまだ自分で設計すべきこと
受信HTTPリクエストの共通ログ業務イベントのログ設計
起動設定の見える化環境変数とデプロイ設定の管理
trace ID / correlation header の活用クライアント側ログとの突合設計
Responses の lifecycle 管理どの output type を使うかの設計
chat isolation key enforcementkey の生成・配布・保持方法
Foundry storage 呼び出しの診断storage 障害時のリトライ・UX設計
エラーコードの標準化API client 側のリカバリー処理

開発チームでは、まず小さな Hosted Agent を Invocations または Responses のどちらかで実装し、次にログ・trace・エラー・キャンセル・replay を確認する順序が現実的です。最初から高度な function calling や multi-output を組み込むより、SDK の標準ログが期待通り出る状態を作る方が、後の移行や自動化で困りにくくなります。

まとめ:beta wave は「作れる」から「運用できる」への橋渡し

2026年4月20日時点の Coordinated Azure AI Agent Server Python beta wave は、Azure AI Agent Server SDK for Python を使った Hosted Agent 実装を、運用に近い形へ進めるための更新です。

core では起動時ログ、受信リクエストログ、trace ID の扱いが強化され、invocations では任意JSON APIとしての見通しが良くなりました。responses では、Responses lifecycle、SSE replay、chat isolation、response ID validation、Foundry storage logging など、会話型エージェントを実運用に近づけるための改善が多く入っています。

次に取るべき行動はシンプルです。まず自分のエージェントが「単発JSON処理」なのか「会話・ストリーミング・履歴を扱う処理」なのかを決め、前者なら azure-ai-agentserver-invocations、後者なら azure-ai-agentserver-responses で最小実装を作ります。そのうえで、起動時ログ、受信リクエストログ、trace ID、エラーコード、chat isolation key、SSE replay を検証環境で確認しましょう。ここまで通しておけば、PoC から業務利用へ進める判断材料がかなり揃います。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次