クイック スタート: Responses API を使用してエージェントを構築する

このクイック スタートでは、Foundry プロジェクト エンドポイントの Responses API を独自のコードから呼び出してエ フェメラル エージェント を構築します。このエージェントの定義 (命令、ツール、モデル) は、Foundry Agent Service の永続化されたリソースとしてではなく、アプリケーション コード内に存在します。 各呼び出しは、プロセス内でエージェントを構築し、モデルの推論とツールオーケストレーションのために Responses API を呼び出します。

このパターンは、他のユーザーがアプリと同期し続ける必要がある帯域外リソースとしてではなく、エージェント定義を他のアプリケーション コードに付属させ、バージョン管理することを望む開発者、ISV、デジタル ネイティブに適しています。 プロンプト エージェントとは異なり、Foundry で作成、更新、または削除するエージェント リソースはありません。ライフサイクル管理は、Responses API を直接呼び出すことによって置き換えられます。

Responses API は、Foundry の単一のモデルとツールのエントリ ポイントです。 2 つの異なるエンドポイントで呼び出すことができます。

  • Foundry プロジェクト エンドポイント (このクイック スタート、推奨) - Foundry の完全なサポート。 カタログおよびプラットフォーム ツール (ファイル検索、コード インタープリター、メモリ、Web 検索、MCP、SharePoint、WorkIQ、Fabric IQ など) から、{project_endpoint}/openai/v1/responses に到達した単一のプロジェクト スコープ API サーフェスを介して Foundry モデルを公開します。
  • Azure OpenAI エンドポイント — 既存の OpenAI クライアントとの最適な待機時間と最大互換性。 これは、OpenAI モデルと標準の OpenAI ツールのみが必要で、Foundry 固有の機能が必要ない場合に使用します。

推奨されるパスは、認証、ツールの配線、およびメッセージ オーケストレーションを自動的に処理する エージェント フレームワークです。 Pythonでは、これはFoundryChatClientです。.NETではAIProjectClient.AsAIAgent(...)です。 また、OpenAI SDK はこのエンドポイントに対しても機能し、「 OpenAI SDK を直接使用する」の代替手段として説明されています。

Azure サブスクリプションをお持ちでない場合は、無料アカウントを作成してください。

エフェメラル エージェント パターンを使用する場合

独自のアプリケーションに埋め込まれている可能性がある Foundry の外部でエージェント コードをホストしているが、モデルやプラットフォーム ツールなどの Foundry エージェント機能にアクセスする場合は、このパターンを使用します。

エフェメラル パターンと ホステッド エージェント追加的であり、代替ではありません。 同じ Agent Framework エージェント コードをホストされたエージェントとしてパッケージ化し、Foundry Agents API を介して公開することもできます。これは、他のアプリ、サービス、またはエージェントが呼び出すことができる Foundry マネージド エンドポイントが必要な場合に便利です。 1 つのコードベースから、アプリに付属するインプロセスでエージェントを実行し、他の呼び出し元が必要とするホストされたエージェントと同じ定義を発行します。

OpenAI Responses API の上に Foundry プロジェクト エンドポイントが追加するもの

Foundry プロジェクト エンドポイントの Responses API は OpenAI Responses API と互換性があるため、既存の OpenAI クライアントは最小限の変更でそれに対して動作します。 Foundry プロジェクト エンドポイントでは、上に次のものが追加されます。

  • Project スコープ データ: ファイル、ベクター ストア、およびその他のデータは、リソース レベルではなく project レベルで格納されます。これにより、projectごとのデータ分離が可能になり、標準エージェントのセットアップを通じて独自のリソースを使用できます。
  • OpenAI に加えて利用できる Foundry モデル: Azure によって直接提供される Foundry モデル(OpenAI モデルに限りません)も、同じ API を通じて利用できます。
  • Foundry 固有のツール: SharePoint、WorkIQ、Fabric IQ などのプラットフォーム ツールは、標準の OpenAI ツールと共に使用できます。
  • ツールの代理 (OBO) 認証: ツールは、アプリケーション ID だけでなく、サインインユーザーとしてダウンストリーム サービスを呼び出すことができます。
  • Project レベルの可観測性とガバナンス: project エンドポイントを介して行われた呼び出しは、追加の配線なしで、projectのトレース、監視、コンテンツ フィルター、ID 構成を通過します (「Observability and enterprise capabilities」を参照)。

リソース レベルの OpenAI エンドポイントではなく、プロジェクト エンドポイント を呼び出すと、これらのプロジェクト スコープ機能のロックが解除されます。

Prerequisites

  • Python 3.10 以降がインストールされています。
  • .NET 8 SDK 以降がインストールされています。

環境変数の設定

プロジェクト エンドポイントとデプロイされたモデル名を環境変数として格納します。 次のサンプルでは、環境からこれらの値を読み取ります。

FOUNDRY_PROJECT_ENDPOINT=<endpoint copied from welcome screen>
FOUNDRY_MODEL=<your deployed model name>

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

Foundry プロバイダーを使用して Agent Framework パッケージをインストールします。

pip install agent-framework-foundry aiohttp
dotnet add package Microsoft.Agents.AI.Foundry --prerelease
dotnet add package Azure.AI.Projects --prerelease
dotnet add package Azure.Identity

Microsoft.Agents.AI.Foundry は、AsAIAgent(...)AIProjectClient 拡張メソッドを提供し、推移的に Microsoft.Agents.AI を取り込みます。

エージェントを作成する

プロセスでローカルに実行され、モデル推論とツール オーケストレーションのために Responses API を呼び出すエフェメラル エージェントを作成します。

FoundryChatClientAgent クラスを使用します。

import asyncio
import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential

async def main() -> None:
    agent = Agent(
        client=FoundryChatClient(
            project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
            model=os.environ["FOUNDRY_MODEL"],
            credential=AzureCliCredential(),
        ),
        instructions="You are a helpful assistant.",
    )

    result = await agent.run("What is the capital of France?")
    print(f"Agent: {result}")

if __name__ == "__main__":
    asyncio.run(main())

出力により、エージェントの応答が出力されます。 エージェントはエフェメラルであるため、定義はサービスに永続化されません。Python プロセスの有効期間中のみ存在します。

Microsoft Agent Framework の AIProjectClient.AsAIAgent(...) を使用して、Foundry プロジェクト エンドポイントを AIAgent としてラップします。

using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;

string endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("FOUNDRY_MODEL")
    ?? throw new InvalidOperationException("FOUNDRY_MODEL is not set.");

AIAgent agent =
    new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a helpful assistant.",
        name: "Assistant");

Console.WriteLine($"Agent: {await agent.RunAsync("What is the capital of France?")}");

出力により、エージェントの応答が出力されます。 エージェントはエフェメラルであるため、定義はサービスに永続化されません。この定義はプロセスの有効期間中のみ存在します。

関数ツールを追加する

ローカル関数ツールを定義し、エージェントに渡します。 エージェントは、会話中に必要なときにこれらのツールを自動的に呼び出します。

@tool デコレーターを使用してローカル関数ツールを定義します。

import asyncio
import os
from random import randint
from typing import Annotated

from agent_framework import Agent, tool
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential
from pydantic import Field

@tool(approval_mode="never_require")
def get_weather(
    location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
    """Get the weather for a given location."""
    conditions = ["sunny", "cloudy", "rainy", "stormy"]
    return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."

async def main() -> None:
    agent = Agent(
        client=FoundryChatClient(
            project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
            model=os.environ["FOUNDRY_MODEL"],
            credential=AzureCliCredential(),
        ),
        instructions="You are a helpful weather agent.",
        tools=get_weather,
    )

    result = await agent.run("What's the weather like in Seattle?")
    print(f"Agent: {result}")

if __name__ == "__main__":
    asyncio.run(main())

エージェントは Responses API を使用して、 get_weather 関数を呼び出すタイミングを判断し、ローカルで実行し、結果を自然言語で返します。

ローカル メソッドを定義し、 [Description] 属性で装飾し、 AIFunctionFactory.Create(...)でラップします。

using System.ComponentModel;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

[Description("Get the weather for a given location.")]
static string GetWeather(
    [Description("The location to get the weather for.")] string location)
{
    string[] conditions = ["sunny", "cloudy", "rainy", "stormy"];
    Random rng = Random.Shared;
    return $"The weather in {location} is {conditions[rng.Next(conditions.Length)]} with a high of {rng.Next(10, 31)}°C.";
}

AITool weatherTool = AIFunctionFactory.Create(GetWeather);

string endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("FOUNDRY_MODEL")
    ?? throw new InvalidOperationException("FOUNDRY_MODEL is not set.");

AIAgent agent =
    new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a helpful weather agent.",
        name: "WeatherAssistant",
        tools: [weatherTool]);

Console.WriteLine($"Agent: {await agent.RunAsync("What's the weather like in Seattle?")}");

エージェントは Responses API を使用して、 GetWeatherを呼び出すタイミングを判断し、ローカルで実行し、結果を自然言語で返します。

Web 検索ツールを使用する

Foundry プロジェクト エンドポイント上の Responses API には、Web 検索などの組み込みのホステッド ツールが用意されています。 ローカル実装なしでエージェントに Web 検索へのアクセス権を付与します。

FoundryChatClient.get_web_search_tool() を使用して次のことを行います。

import asyncio
import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential

async def main() -> None:
    agent = Agent(
        client=FoundryChatClient(
            project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
            model=os.environ["FOUNDRY_MODEL"],
            credential=AzureCliCredential(),
        ),
        instructions="You are a research assistant. Use web search to find current information.",
        tools=[
            FoundryChatClient.get_web_search_tool(),
        ],
    )

    result = await agent.run("What are the latest updates to Microsoft Foundry?")
    print(f"Agent: {result}")

if __name__ == "__main__":
    asyncio.run(main())

Web 検索ツールは、Foundry プロジェクト応答 API を使用してサーバー側を実行します。 これをローカル関数ツールと組み合わせて、エージェントに Web アクセス機能とカスタム コード機能の両方を提供できます。

agent = Agent(
    client=FoundryChatClient(
        project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
        model=os.environ["FOUNDRY_MODEL"],
        credential=AzureCliCredential(),
    ),
    instructions="You are a helpful assistant with web and weather capabilities.",
    tools=[
        FoundryChatClient.get_web_search_tool(),
        get_weather,  # Local function tool defined with @tool
    ],
)

new HostedWebSearchTool()リストでtoolsを渡します。

using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

string endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("FOUNDRY_MODEL")
    ?? throw new InvalidOperationException("FOUNDRY_MODEL is not set.");

AIAgent agent =
    new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a research assistant. Use web search to find current information.",
        name: "ResearchAssistant",
        tools: [new HostedWebSearchTool()]);

Console.WriteLine($"Agent: {await agent.RunAsync("What are the latest updates to Microsoft Foundry?")}");

Web 検索ツールは、Foundry プロジェクト応答 API を使用してサーバー側を実行します。 これをローカル関数ツールと組み合わせて、エージェントに Web アクセス機能とカスタム コード機能の両方を提供できます。

AIAgent agent =
    new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a helpful assistant with web and weather capabilities.",
        name: "Assistant",
        tools: [new HostedWebSearchTool(), weatherTool]);

ストリーム応答

メッセージ全体を待つ代わりに、生成された応答を受け取ります。

stream=True パラメーターを使用します。

import asyncio
import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential

async def main() -> None:
    agent = Agent(
        client=FoundryChatClient(
            project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
            model=os.environ["FOUNDRY_MODEL"],
            credential=AzureCliCredential(),
        ),
        instructions="You are a helpful assistant.",
    )

    print("Agent: ", end="", flush=True)
    async for chunk in agent.run("Tell me a fun fact.", stream=True):
        if chunk.text:
            print(chunk.text, end="", flush=True)
    print()

if __name__ == "__main__":
    asyncio.run(main())

RunStreamingAsyncを呼び出し、AgentResponseUpdate ストリームを反復処理します。

using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;

string endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("FOUNDRY_MODEL")
    ?? throw new InvalidOperationException("FOUNDRY_MODEL is not set.");

AIAgent agent =
    new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a helpful assistant.",
        name: "Assistant");

Console.Write("Agent: ");
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync("Tell me a fun fact."))
{
    Console.Write(update);
}
Console.WriteLine();

モデルが各トークンを生成すると、ストリーミング出力がコンソールに増分的に表示されます。

可観測性とエンタープライズ機能

エフェメラルはアンマネージドを意味するものではありません。 呼び出しはプロジェクト エンドポイントを通過するため、追加の配線なしでプロジェクトのエンタープライズ構成を継承します。

  • トレースと監視: 要求、ツールの呼び出し、トークンの使用フローが、プロジェクトの Foundry の可観測性に入ります。
  • Content フィルターとガバナンス: Project レベルのコンテンツ フィルターと責任ある AI ポリシーがすべての呼び出しに適用されます。
  • ID とアクセス: 呼び出しは、プロジェクトの ID 構成に対して認証されます。OBO 対応ツールは、サインインしているユーザーとして機能できます。

エフェメラル パターンは、機能が低下するレベルではありません。エージェントをインプロセスで実行するか、 ホストされたエージェントと同じコードをパッケージ化するかに関係なく、同じ Foundry モデル、ツール、可観測性、ガバナンスを得ることができます。 その選択は、機能ではなく、デプロイ形態に関するものです。

OpenAI SDK を直接使用する

Foundry プロジェクト Responses API は OpenAI 互換であるため、クライアントをプロジェクト エンドポイント ({project_endpoint}/openai/v1/responses) にポイントすることで、OpenAI SDK から直接呼び出すこともできます。 このパスは、既に OpenAI SDK コードがある場合、または要求と応答の図形を下位レベルで制御する必要がある場合にのみ使用します。 新しいコードでは、認証、ツールの配線、オーケストレーションを自動的に処理するエージェント フレームワークを使用する必要があります。

SDK のサンプルについては、以下を参照してください。

リソースをクリーンアップする

ここで作成された Agent Framework エージェントはエフェメラルであるため、サービス側のクリーンアップは必要ありません。 エージェントはローカル プロセスにのみ存在します。 不要になった Foundry リソースを作成した場合は、 Foundry ポータルで削除します。

このパターンをさらに詳しく見る

ホストされるエージェントと同じエージェント コードをパッケージ化する