快速入門:使用回應 API 建立代理

在這個快速入門中,你從自己的程式碼呼叫 Foundry 專案端點的 回應 API ,建立一個 短暫代理 ——一個代理,其定義(指令、工具、模型)存在於你的應用程式程式碼中,而非作為 Foundry Agent Service 中的持久化資源。 每次呼叫都會在你的流程中建構代理,並呼叫回應 API,進行模型推論與工具協調。

這種模式適合開發者、獨立軟體供應商(ISV)以及數位原生企業;他們希望其代理程式定義能隨其餘應用程式碼一同交付並進行版本控管,而不是作為需要另外有人維持與應用程式同步的帶外資源。 與 提示代理不同,Foundry 中沒有代理資源可供建立、更新或刪除——生命週期管理被直接呼叫回應 API 取代。

回應 API 是 Foundry 唯一的模型與工具入口。 你可以在兩個不同的端點呼叫它:

  • Foundry 專案端點(建議使用此快速入門)— 提供完整的 Foundry 支援。 透過單一且以專案為範圍的 API 介面(可透過 {project_endpoint}/openai/v1/responses 存取),提供型錄中的 Foundry 模型和平台工具(檔案搜尋、程式碼直譯器、記憶、網頁搜尋、MCP、SharePoint、WorkIQ、Fabric IQ 等)。
  • Azure OpenAI 端點 — 最佳延遲與現有 OpenAI 用戶端的最大相容性。 當你只需要 OpenAI 模型和標準 OpenAI 工具,且不需要 Foundry 專屬功能時,才會用這個功能。

推薦的路徑是 Agent Framework,它能幫你處理認證、工具配線和訊息編排。 Python為FoundryChatClient;.NET為AIProjectClient.AsAIAgent(...)。 OpenAI SDK 也針對此端點運作,並作為替代方案在 「直接使用 OpenAI SDK 」中有所介紹。

如果您沒有 Azure 訂閱,請建立免費帳戶。

何時使用暫時性代理模式

當你在 Foundry 外托管代理程式碼——甚至可能嵌入在你自己的應用程式中——但想存取 Foundry 代理功能如模型和平台工具時,請使用此模式。

短暫模式與 宿主代理 是 加法,而非替代。 相同的 Agent Framework 代理程式碼也可以打包成託管代理,並透過 Foundry Agents API 公開——當你想要一個由 Foundry 管理的端點,讓其他應用程式、服務或代理都能呼叫時非常有用。 您可以從一個程式碼基底同時執行兩者:在應用程式隨附的處理序內執行 Agent,並在其他呼叫端需要時,將相同定義發佈為裝載 Agent。

Foundry 專案端點在 OpenAI 回應 API 之上新增的功能

Foundry 專案端點上的回應 API 與 OpenAI 回應 API 相容,因此現有的 OpenAI 客戶端只需最小的改動即可與之對抗。 Foundry 專案端點在上方新增以下內容:

  • Project-scoped data:檔案、向量儲存及其他資料存放於 project 層級,而非資源層級,這提供逐個project的資料隔離,並允許你透過標準代理設定使用自帶資源。
  • Foundry 模型除了 OpenAI 之外:Azure 直接銷售的 Foundry 模型(不僅僅是 OpenAI 模型)可透過同一 API 取得。
  • Foundry 專用工具:平台工具如 SharePoint、WorkIQ 和 Fabric IQ 與標準 OpenAI 工具同時可用。
  • 工具的代理者流程 (OBO) 驗證:工具可以作為登入使用者呼叫下游服務,而不只是作為應用程式身分識別。
  • Project層級可觀察性與治理:透過project端點發出的通話會經過project的追蹤、監控、內容過濾及身份設定,無需額外接線(參見可觀察性與企業能力)。

將 專案端點 命名為非資源層級的 OpenAI 端點,正是解鎖這些專案範圍能力的關鍵。

先決條件

  • 安裝了 Python 3.10 或更新版本。

設定環境變數

將 你的專案端點 和部署模型名稱存為環境變數。 以下樣本是從環境中讀取這些數值的。

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。

建立代理人

建立一個臨時代理,在你的程序中本地執行,並呼叫回應 API 進行模型推論與工具協調。

使用 FoundryChatClient 和 Agent 類別。

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 代理框架中的 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,並在本地執行,並以自然語言回傳結果。

使用網路搜尋工具

Foundry 專案端點上的 Responses API 提供內建裝載工具,例如 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())

該網頁搜尋工具透過 Foundry 專案的回應 API 在伺服器端執行。 你可以結合本地功能工具,讓你的代理同時具備網頁存取與自訂程式碼功能:

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?")}");

該網頁搜尋工具透過 Foundry 專案的回應 API 在伺服器端執行。 你可以結合本地功能工具,讓你的代理同時具備網頁存取與自訂程式碼功能:

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 可觀測性功能中。
  • 內容過濾與治理:Project級內容過濾與負責任的 AI 政策適用於每通電話。
  • 身份與存取:呼叫會根據專案的身份設定進行認證;支援 OBO 的工具可以扮演登入使用者的角色。

暫態模式並不是功能受限的層級——無論你是以程序內方式執行代理,或將相同的程式碼封裝為託管代理,你獲得的 Foundry 模型、工具、可觀察性和治理功能都完全相同。 選擇權在於部署形態,而非功能組合。

直接使用 OpenAI SDK

由於 Foundry 專案回應 API 相容 OpenAI,你也可以直接從 OpenAI SDK 呼叫它,將客戶端指向專案端點({project_endpoint}/openai/v1/responses)。 只有當你已有 OpenAI SDK 程式碼,或需要對請求與回應形狀進行較低階控制時,才使用此路徑。 新程式碼應該偏好 Agent Framework ,它負責認證、工具配線和協調。

SDK 範例請參見:

清理資源

由於此處建立的代理架構代理是短暫的,因此不需要服務端的清理。 代理人只存在於你當地的流程中。 如果你建立了不再需要的 Foundry 資源, 請在 Foundry 入口網站刪除它們。

深入探討這個圖案

打包與託管代理相同的代理代碼