Foundry でホストされるエージェントとして LangGraph エージェントをホストする

langchain_azure_ai.agents.hosting パッケージを使用して、コンパイル済みの LangGraph グラフを、Microsoft Foundry でホストされる エージェント向けのプロトコルを通じて公開します。 ホスティング パッケージを使用すると、LangChain と LangGraph エージェントのロジックをコード内に保持し、Foundry はホストされるランタイム、セッション、スケール、ID、およびプロトコル エンドポイントを管理します。

この記事では、最小限の LangGraph エージェントを作成し、応答または呼び出しプロトコルを使用してエージェントを公開し、HTTP を使用してテストし、Azure Developer CLI または Foundry Toolkit Visual Studio Code 拡張機能を使用して Foundry にデプロイします。

前提条件

パッケージをインストールする

hosting extra を含めて、langchain-azure-ai 1.2.4 以降をインストールしてください。

pip install -U "langchain-azure-ai[hosting]>=1.2.4" azure-identity

hostingでは、ホスト サーバーによって使用される Foundry プロトコル ライブラリが追加でインストールされます。

  • azure-ai-agentserver-responses OpenAI と互換性のある /responses エンドポイント用。
  • azure-ai-agentserver-invocations ジェネリック /invocations エンドポイントの場合。

ホスティング プロトコルを選択する

ホストされるエージェントは、1 つ以上のプロトコルを公開できます。 ほとんどの会話エージェントの応答から始めます。

プロトコル ホスト クラス エンドポイント 次の場合に使用します。
Responses ResponsesHostServer /responses OpenAI と互換性のあるチャット、ストリーミング、応答履歴、会話スレッドが必要です。
呼び出し InvocationsHostServer /invocations カスタム JSON シェイプ、Webhook スタイルのエンドポイント、または非会話処理が必要です。

プロトコルの動作とセッションの背景については、「 ホストされたエージェント 」および「 ホストされたエージェント セッションの管理」を参照してください。

環境変数を構成する

ローカル開発のプロジェクト エンドポイントとモデルのデプロイ名を設定します。

export FOUNDRY_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
export FOUNDRY_MODEL_NAME="gpt-4.1"

Foundry でホストされているエージェントと同じコードを実行すると、プラットフォームによって FOUNDRY_PROJECT_ENDPOINTが挿入されます。 サンプル azd ai agent initazure.yamlを使用する場合、生成されたプロジェクトでは、選択したモデル配置にもFOUNDRY_MODEL_NAMEが使用されます。

応答プロトコル

ストリーミング、応答履歴、会話スレッドを含む OpenAI と互換性のあるチャット エンドポイントが必要な場合は、応答プロトコルを使用します。

応答ホストを作成する

Foundry モデルを使用する最小限の LangGraph エージェントを使用して、 main.py という名前のファイルを作成します。 このパターンは、 langchain-azure-ai ソース リポジトリの基本的な Responses サンプルと一致します。

import os

from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI

from langchain_azure_ai.agents.hosting import ResponsesHostServer

_AZURE_AI_SCOPE = "https://ai.azure.com/.default"


def build_chat_model() -> ChatOpenAI:
    project_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"].rstrip("/")
    deployment = os.environ.get("FOUNDRY_MODEL_NAME", "gpt-4.1")
    credential = DefaultAzureCredential()
    project = AIProjectClient(endpoint=project_endpoint, credential=credential)
    openai_client = project.get_openai_client()
    token_provider = get_bearer_token_provider(credential, _AZURE_AI_SCOPE)

    return ChatOpenAI(
        model=deployment,
        base_url=str(openai_client.base_url),
        api_key=token_provider,
    )


def main() -> None:
    graph = create_agent(build_chat_model(), tools=[])
    port = int(os.environ.get("PORT", "8088"))
    ResponsesHostServer(graph).run(port=port)


if __name__ == "__main__":
    main()

このスニペットの機能: LangChain の create_agentを使用して LangGraph エージェントを作成し、Foundry プロジェクトの OpenAI 互換モデル エンドポイントに接続し、コンパイルされたグラフを ResponsesHostServerに渡します。 ホストは HTTP サーバーを起動し、 POST /responsesを介してグラフを公開します。 既定では、サーバーはポート 8088にバインドするか、 PORT 環境変数の値 (設定されている場合) にバインドします。

アプリをローカルで実行します。

python main.py

応答エンドポイントをテストする

ストリーミング以外の応答要求をローカル サーバーに送信します。

Bash:

curl -sS -H "Content-Type: application/json" \
  -X POST http://localhost:8088/responses \
  -d '{"input":"Give me one practical tip for testing hosted agents.","stream":false}'

PowerShell:

$body = @{
  input = "Give me one practical tip for testing hosted agents."
  stream = $false
} | ConvertTo-Json

Invoke-RestMethod `
    -Uri http://localhost:8088/responses `
    -Method Post `
    -Body $body `
    -ContentType "application/json"

ストリーミング応答の場合は、 streamtrue に設定します。 ホストは、 response.createdresponse.output_text.deltaresponse.completedなどの Responses API サーバー送信イベントを出力します。

会話

ResponsesHostServer では、2 つの会話状態パターンがサポートされています。 使用するパターンは、コンパイルされたグラフに LangGraph チェックポイントがあるかどうかによって異なります。

グラフの構成 会話ソース ホストが後続のターンでグラフに送信するもの
チェックポイントなしグラフ プロトコル ランタイムからの応答履歴 以前の応答履歴と現在の要求入力
チェックポインターでコンパイルされたグラフ 会話または応答スレッドによってキー指定された LangGraph チェックポイントの状態 現在のリクエスト入力のみ

グラフに LangGraph ランタイム状態、割り込み、またはノードローカル状態がターン間で必要な場合は、チェックポイント機能を使用します。 ローカル テストでは、メモリ内チェックポイント機能を使用できます。

from langgraph.checkpoint.memory import MemorySaver

graph = create_agent(
    build_chat_model(),
    tools=[],
    checkpointer=MemorySaver(),
)

運用環境のホスト型エージェントの場合は、メモリ内チェックポイント機能の代わりに永続的なチェックポイントを使用して、コンテナーの再起動後もグラフの状態が保持されるようにします。

クライアントは、 previous_response_id または conversation ID を渡して応答の会話を続行します。 ローカル テストの場合は、次の要求で前の応答 ID をチェーンします。

POST http://localhost:8088/responses
Content-Type: application/json

{
  "input": "Can you make that more concise?",
  "previous_response_id": "<previous-response-id>",
  "stream": false
}

エージェントが Foundry で実行されている場合、同じパターンが Hosted Agent Responses エンドポイントを介して動作します。 後で同じホストされたサンドボックス ファイル システムも必要になる場合は、 agent_session_id を含めるか、 conversation ID を使用します。 詳細については、「 ホストされるエージェント セッションの管理」を参照してください。

ヒューマン・イン・ザ・ループ

グラフで LangGraph interrupt() 呼び出しが使用されている場合、 ResponsesHostServer は標準の Responses API 出力項目を介して割り込みを保留状態にします。

  • function_call という名前の __hosted_agent_adapter_interrupt__ 項目。
  • mcp_approval_requestserver_label に設定されている langgraph 項目。

クライアントは、function_call_outputが割り込み ID と一致するcall_id項目、または割り込み ID と一致するmcp_approval_responseapproval_request_id項目を送信することで、グラフを再開できます。 function_call_outputCommand、またはresumeフィールドを含むリッチな LangGraph update ペイロードを送信する必要がある場合は、gotoを使用します。 単純な承認または拒否フローには、 mcp_approval_response を使用します。

呼び出しプロトコル

呼び出し元が Responses API 要求の形状を使用できない場合、またはシナリオがチャット会話でない場合は、 InvocationsHostServer を使用します。 既定の呼び出しホストは、 message 文字列と省略可能な stream フラグを受け入れます。

呼び出しホストを作成する

Responses の例と同じモデル構築関数を使用しますが、InvocationsHostServerではなく、ResponsesHostServerを開始します。

import os

from langchain.agents import create_agent
from langgraph.checkpoint.memory import MemorySaver

from langchain_azure_ai.agents.hosting import InvocationsHostServer


def main() -> None:
    graph = create_agent(
        build_chat_model(),
        tools=[],
        checkpointer=MemorySaver(),
    )
    port = int(os.environ.get("PORT", "8088"))
    InvocationsHostServer(graph).run(port=port)


if __name__ == "__main__":
    main()

このスニペットの機能:POST /invocationsを使用して LangGraph エージェントをホストします。 MemorySaver チェックポイント機能は、特定のセッション ID に対してローカルのマルチターン継続性を提供します。 運用環境では、永続的なチェックポイント機能を使用して、コンテナーの再起動後も状態が保持されるようにします。

呼び出しエンドポイントをテストする

ストリーミング以外の要求を送信します。

curl -i -X POST http://localhost:8088/invocations \
  -H "Content-Type: application/json" \
  -d '{"message":"My name is Alice.","stream":false}'

ストリーミング以外の要求では、次の形式の JSON が返されます。

{
  "response": "Assistant text"
}

複数ターンの会話の場合は、次の要求で x-agent-session-id 応答ヘッダーを agent_session_id クエリ パラメーターとして再利用します。

curl -X POST "http://localhost:8088/invocations?agent_session_id=<session-id>" \
  -H "Content-Type: application/json" \
  -d '{"message":"What is my name?"}'

ストリーミング リクエストでは、トークン ペイロードを含む text/event-stream イベントが返されます。

curl -N -X POST http://localhost:8088/invocations \
  -H "Content-Type: application/json" \
  -d '{"message":"Count to 5.","stream":true}'

ストリームには、トークン イベントの後にターミナル done イベントが含まれます。

data: {"token": "..."}

event: done
data: {}

要求スキーマをカスタマイズする

要求本文をカスタマイズするには、 InvocationsHostServer をサブクラス化し、 parse_requestをオーバーライドします。 build_inputをオーバーライドして、解析されたデータをカスタム グラフの状態にマップすることもできます。

from starlette.requests import Request

from langchain_azure_ai.agents.hosting import InvocationsHostServer


class TicketHostServer(InvocationsHostServer):
    async def parse_request(self, request: Request) -> tuple[str, bool]:
        data = await request.json()
        ticket_id = data["ticket_id"]
        description = data["description"]
        stream = bool(data.get("stream", False))
        return f"Summarize ticket {ticket_id}: {description}", stream


if __name__ == "__main__":
    TicketHostServer(graph).run()

このスニペットの機能: カスタム チケット ペイロードを受け入れ、ホストがグラフを呼び出す前に 1 人のユーザー メッセージに変換します。 より複雑なグラフ状態の場合は、要求をテキストにフラット化するのではなく、 build_input をオーバーライドします。

Deploy

Azure Developer CLI または Foundry Toolkit Visual Studio Code 拡張機能を使用してデプロイできます。 Azure Developer CLI フローでは、サンプル azure.yaml ファイルと Docker が使用されます。 拡張機能フローは、Visual Studio Codeのガイド付きデプロイ エクスペリエンスを提供します。

ホスト型エージェントのデプロイには、プロジェクトにおける Foundry Project Manager ロールが必要です。 詳細については、「 ホストされたエージェントのデプロイ」を参照してください。

Azure Developer CLI を使用したデプロイ

langchain-azure-ai ソース リポジトリには、Azure Developer CLI を使用して実行およびデプロイできるホスト型エージェントサンプルが含まれています。 このフローでは、各サンプルの azure.yamlDockerfile、および main.pyが使用されます。 azure.yaml のホステッド エージェント構成について詳しくは、ホステッド エージェント用の azure.yaml を作成するを参照してください。

サンプルを初期化する前に、AI エージェント拡張機能をインストールしてサインインします。

azd ext install azure.ai.agents
azd auth login

サンプルの Dockerfile で宣言されたコンテナー イメージ azd ai agent run ビルドするため、Docker はローカルで実行されている必要があります。 コマンドの詳細については、Azure Developer CLI リファレンスを参照してください。

サンプルの azure.yaml から初期化する

新しいフォルダーを作成し、サンプル azure.yamlから初期化します。 azure.yaml URL を、使用するサンプルに置き換えます。

mkdir my-langchain-agent
cd my-langchain-agent

azd ai agent init -m https://github.com/langchain-ai/langchain-azure/blob/main/samples/hosting/langgraph-hosted-agents/responses/01_basic/azure.yaml

azd ai agent initの指示に従います。 Foundry プロジェクトとモデルのデプロイがまだない場合は、初期化フローで作成を進めることができます。

コンテナーをローカルで実行する

azdを使用してエージェント ホストをローカルで実行します。

azd ai agent run

ホストは http://127.0.0.1:8088で機能します。 別のターミナルで、ローカル プロトコル エンドポイントを直接呼び出します。

curl -X POST http://127.0.0.1:8088/responses \
  -H "Content-Type: application/json" \
  -d '{"input": "Hello!"}'

PowerShell に相当するもの:

(Invoke-WebRequest -Uri http://127.0.0.1:8088/responses `
  -Method POST -ContentType 'application/json' `
  -Body '{"input": "Hello!"}').Content

次の azdを使用してローカル エージェントを呼び出すこともできます。

azd ai agent invoke --local "Hello!"

Foundry にデプロイする

初期化されたプロジェクトで新しい Foundry プロジェクトとモデルのデプロイを使用する場合は、最初にAzureリソースをプロビジョニングします。

azd provision

エージェントをデプロイします。

azd deploy

デプロイによって、エージェントがコンテナー イメージにパッケージ化され、プロビジョニングされたコンテナー レジストリにプッシュされ、Foundry Hosted エージェント ランタイムにロールアウトされます。

Foundry ホスティング インフラストラクチャは、次のようなランタイム環境変数をエージェントに挿入します。

  • FOUNDRY_PROJECT_ENDPOINT: エージェントがデプロイされている Foundry プロジェクトのエンドポイント URL。
  • FOUNDRY_MODEL_NAME: azd ai agent init中に選択されたモデル デプロイ名。
  • APPLICATIONINSIGHTS_CONNECTION_STRING: プロジェクトの Application Insights インスタンスの接続文字列。

デプロイの概念、アクセス許可、管理の詳細については、「 ホストされたエージェントのデプロイ 」および「 ホストされたエージェントのライフサイクルの管理」を参照してください。

Foundry Toolkit Visual Studio Code 拡張機能を使用したデプロイ

拡張機能ベースのデプロイについては、「 クイック スタート: 最初のホステッド エージェントをデプロイする」を参照してください。

Troubleshooting

このチェックリストを使用して、 langchain_azure_ai.agents.hostingを使用してホスト型エージェントを開発する際の一般的な問題を診断します。

グラフ スキーマの検証が失敗する

既定のホストでは、状態が messages などのMessagesState フィールドを持つコンパイル済みの LangGraph グラフが必要です。 グラフでカスタム状態スキーマを使用する場合は、ホストをサブクラス化し、 build_inputをオーバーライドします。 応答の場合は、要求の解析、グラフの実行、および出力された応答イベントを完全に制御する必要がある場合は、 handle_create をオーバーライドします。

会話状態が継続されない

応答プロトコルの場合は、後で previous_response_id または conversation ID を渡します。 グラフでチェックポイントを使用する場合は、エージェントが実行されている環境に対してチェックポイントが構成され、永続的であることを確認します。

呼び出しプロトコルの場合、プラットフォームには会話履歴は格納されません。 agent_session_id クエリ パラメーターを使用して、以降の呼び出しを同じホステッド サンドボックスに振り分け、会話状態の管理には独自の状態ストアまたは LangGraph のチェックポインターを使用します。

ホストされているコンテナーでモデルに到達できない

ホストされるエージェントのバージョンに FOUNDRY_MODEL_NAMEが含まれていること、およびエージェント ID に Foundry プロジェクトを呼び出すアクセス許可があることを確認します。 プラットフォームセット FOUNDRY_PROJECT_ENDPOINT。コードは Foundry で実行するときにその変数を読み取る必要があります。

次のステップ