Microsoft Foundry 工具箱

Microsoft Foundry 工具箱是一個有名稱、有版本限制的伺服器端工具組合包,包含程式碼解譯器、檔案搜尋、影像產生、MCP 及網頁搜尋等。 工具箱讓你在 Foundry 裡管理工具設定,並在不同代理間重複使用。

代理框架涵蓋 Toolbox 的使用方式。 透過 Foundry 入口網站或 azure-ai-projects SDK 建立並更新 Toolbox 版本。

這很重要

FoundryToolbox 由測試 agent-framework-foundry-hosting 套件提供,且可在穩定版發行前進行變更。

對於服務受控 FoundryAgent,請將工具箱附加至 Foundry 中的代理程式定義。

對於使用 Microsoft Agent Framework 建置的託管代理,請使用來自 Microsoft.Agents.AI.Foundry.Hosting 的 AddFoundryToolboxes,如下列範例所示。

使用啟用隱含使用、與 、 、 和 的版本Microsoft.Agents.AI.FoundryMicrosoft.Agents.AI.Foundry.HostingDotNetEnv相符的 .NET 10 網頁專案。 將 TOOLBOX_NAME 設為現有的工具箱,並將 AZURE_AI_MODEL_DEPLOYMENT_NAME 設為你的模型部署。 鑄造廠供應 FOUNDRY_PROJECT_ENDPOINT 給部署的主機。 若要存取本地模型,請設定AZURE_AI_PROJECT_ENDPOINT並登入 Azure CLI。 主機整合會在 FOUNDRY_PROJECT_ENDPOINT 可用時載入工具箱中的工具。

using Azure.AI.Projects;
using Azure.Identity;
using DotNetEnv;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Foundry.Hosting;

// Load .env file if present (for local development)
Env.TraversePath().Load();

string endpoint = System.Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
    ?? System.Environment.GetEnvironmentVariable("AZURE_AI_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException(
        "Neither FOUNDRY_PROJECT_ENDPOINT (platform-injected in hosted runtime) " +
        "nor AZURE_AI_PROJECT_ENDPOINT (local-dev convention) is set.");
string deploymentName = FirstNonBlank(
    System.Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME"),
    System.Environment.GetEnvironmentVariable("FOUNDRY_MODEL"),
    "gpt-4o")!;
string toolboxName = FirstNonBlank(
    System.Environment.GetEnvironmentVariable("TOOLBOX_NAME"),
    "my-toolset")!;

var credential = new DefaultAzureCredential();

AIAgent agent = new AIProjectClient(new Uri(endpoint), credential)
    .AsAIAgent(
        model: deploymentName,
        instructions: """
            You are a helpful assistant with access to tools provided by the Foundry Toolbox.
            Use the available tools to answer user questions.
            If a tool is not available for a request, let the user know clearly.
            """,
        name: System.Environment.GetEnvironmentVariable("AGENT_NAME") ?? "hosted-toolbox-agent",
        description: "Hosted agent backed by Foundry Toolbox MCP tools");

var builder = WebApplication.CreateBuilder(args);

// Register the agent and response handler
builder.Services.AddFoundryResponses(agent);

builder.Services.AddFoundryToolboxes(credential, toolboxName);

var app = builder.Build();
app.MapFoundryResponses();


app.Run();

static string? FirstNonBlank(params string?[] candidates) =>
    Array.Find(candidates, candidate => !string.IsNullOrWhiteSpace(candidate));

同一託管註冊支援其工具箱連接中已設定為每位使用者 OAuth 同意的工具。 使用者仍需取得必要的權限與同意;不需要獨立的主機註冊區塊。

關於專案檔案與部署說明,請參閱 Hosted-Toolbox。 關於每位使用者同意的設定,請參見 Hosted-Toolbox-AuthPaths。

安裝套件

pip install agent-framework-foundry-hosting agent-framework-foundry --pre

FoundryToolbox 是從 agent_framework.foundry 匯入,並由 agent-framework-foundry-hosting 提供。

配置工具箱

設定明確的 Toolbox MCP 端點:

TOOLBOX_ENDPOINT="https://<account>.services.ai.azure.com/api/projects/<project>/toolboxes/<name>/mcp?api-version=v1"

或者讓 FoundryToolbox 建立端點:

FOUNDRY_PROJECT_ENDPOINT="https://<account>.services.ai.azure.com/api/projects/<project>"
TOOLBOX_NAME="<toolbox-name>"

託管代理程式範例也使用 AZURE_AI_MODEL_DEPLOYMENT_NAME 作為 FoundryChatClient。

將 FoundryToolbox 與託管代理程式搭配使用

FoundryToolbox解決其端點,使用提供的 Azure 憑證驗證每個 MCP 請求,轉發 Foundry 的每個請求呼叫 ID,並參與代理的連線生命週期。 在託管的回應代理中,請在請求範圍代理工廠內建立工具箱、其客戶端及其憑證。 MCP 撰寫者會在請求連線時擷取請求上下文,因此不要在同一呼叫者間共用一個連接的工具箱。

import asyncio
import os
from contextlib import AsyncExitStack
from types import TracebackType

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryToolbox
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.ai.agentserver.core import AgentConfig, get_request_context
from azure.identity.aio import AzureCliCredential, ManagedIdentityCredential
from dotenv import load_dotenv


def create_agent() -> Agent:
    """Create tools inside this request so the MCP writer captures its call ID."""
    endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
    model = os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"]
    credential = (
        ManagedIdentityCredential(client_id=os.environ.get("FOUNDRY_AGENT_INSTANCE_CLIENT_ID"))
        if AgentConfig.from_env().is_hosted
        else AzureCliCredential()
    )

    class RequestClient(FoundryChatClient):
        async def __aenter__(self) -> RequestClient:
            return self

        async def __aexit__(
            self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
        ) -> None:
            async with AsyncExitStack() as cleanup:
                cleanup.push_async_callback(credential.close)
                cleanup.push_async_callback(self.project_client.close)
                cleanup.push_async_callback(self.client.close)

    toolbox = FoundryToolbox(credential)
    client = RequestClient(
        project_endpoint=endpoint,
        model=model,
        credential=credential,
        default_headers=get_request_context().platform_headers(),
    )
    return Agent(
        client=client,
        instructions="You are a friendly assistant. Keep your answers brief.",
        tools=toolbox,
    )


async def main() -> None:
    load_dotenv()
    server = ResponsesHostServer(agent=create_agent, history_source="agent_server")
    await server.run_async()

公開工具箱技能

工具箱可以透過 MCP 公開代理技能。 當只應讓技能對模型可見時,請設定 load_tools=False,然後將 Toolbox 新增為工具,使其 MCP 工作階段得以連線,並使用 as_skills_provider() 作為情境提供者。

import asyncio
import os
from contextlib import AsyncExitStack
from types import TracebackType

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryToolbox
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.ai.agentserver.core import AgentConfig, get_request_context
from azure.identity.aio import AzureCliCredential, ManagedIdentityCredential
from dotenv import load_dotenv


def create_agent() -> Agent:
    """Keep skill caches, credentials and the MCP writer within this request."""
    endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
    model = os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"]
    credential = (
        ManagedIdentityCredential(client_id=os.environ.get("FOUNDRY_AGENT_INSTANCE_CLIENT_ID"))
        if AgentConfig.from_env().is_hosted
        else AzureCliCredential()
    )

    class RequestClient(FoundryChatClient):
        async def __aenter__(self) -> RequestClient:
            return self

        async def __aexit__(
            self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
        ) -> None:
            async with AsyncExitStack() as cleanup:
                cleanup.push_async_callback(credential.close)
                cleanup.push_async_callback(self.project_client.close)
                cleanup.push_async_callback(self.client.close)

    # tools= connects the MCP session; context_providers= reads skills from that same session.
    toolbox = FoundryToolbox(credential, load_tools=False)
    skills_provider = toolbox.as_skills_provider(disable_load_skill_approval=True)
    client = RequestClient(
        project_endpoint=endpoint,
        model=model,
        credential=credential,
        default_headers=get_request_context().platform_headers(),
    )
    return Agent(
        client=client,
        name=os.environ.get("AGENT_NAME", "hosted-toolbox-mcp-skills"),
        instructions="You are a helpful assistant.",
        tools=toolbox,
        context_providers=[skills_provider],
    )


async def main() -> None:
    load_dotenv()
    server = ResponsesHostServer(agent=create_agent, history_source="agent_server")
    await server.run_async()

技能操作的核准預設仍為啟用狀態。 僅針對受信任的無人參與情境停用個別核准。 將工具箱和技能提供者放在同一個請求工廠,這樣兩者共用同一個 MCP 會話並一起處理。

將工具箱與 FoundryAgent 搭配使用

將工具箱附加到 Foundry 中的提示或託管代理程式定義中。 FoundryAgent 會使用該已儲存的工具組態;從用戶端傳入 Toolbox 並不會將其新增至受管理代理程式。

透過 MCP 與 FoundryToolbox 連線

使用 FoundryToolbox with ResponsesHostServer 將託管代理連接到 Toolbox MCP 端點。 包裝程式會驗證 MCP 請求,並轉送目前代管請求的呼叫端內容,以進行每位使用者的身分直通傳遞。 在 agent 工廠內建立連線,讓每個請求都能取得各自的呼叫者上下文。

import asyncio
import os
from contextlib import AsyncExitStack
from types import TracebackType

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryToolbox
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.ai.agentserver.core import AgentConfig, get_request_context
from azure.identity.aio import AzureCliCredential, ManagedIdentityCredential
from dotenv import load_dotenv


def create_agent() -> Agent:
    """Create tools inside this request so the MCP writer captures its call ID."""
    endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
    model = os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"]
    credential = (
        ManagedIdentityCredential(client_id=os.environ.get("FOUNDRY_AGENT_INSTANCE_CLIENT_ID"))
        if AgentConfig.from_env().is_hosted
        else AzureCliCredential()
    )

    class RequestClient(FoundryChatClient):
        async def __aenter__(self) -> RequestClient:
            return self

        async def __aexit__(
            self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
        ) -> None:
            async with AsyncExitStack() as cleanup:
                cleanup.push_async_callback(credential.close)
                cleanup.push_async_callback(self.project_client.close)
                cleanup.push_async_callback(self.client.close)

    toolbox = FoundryToolbox(credential)
    client = RequestClient(
        project_endpoint=endpoint,
        model=model,
        credential=credential,
        default_headers=get_request_context().platform_headers(),
    )
    return Agent(
        client=client,
        instructions="You are a friendly assistant. Keep your answers brief.",
        tools=toolbox,
    )


async def main() -> None:
    load_dotenv()
    server = ResponsesHostServer(agent=create_agent, history_source="agent_server")
    await server.run_async()

設定 TOOLBOX_ENDPOINT,或同時設定 FOUNDRY_PROJECT_ENDPOINT 和 TOOLBOX_NAME,如 設定工具箱中所述。 範例使用 AZURE_AI_MODEL_DEPLOYMENT_NAME 進行模型部署。

限制

  • 工具箱內的 MCP 工具透過 Foundry project_connection_id進行伺服器端認證;Agent Framework 用戶端不持有上游 MCP 承載憑證。
  • 將 Toolbox 作為 MCP 伺服器來使用時,需要對 Toolbox 端點進行用戶端 Entra ID 驗證。
  • 同意流程回應(如 ) CONSENT_REQUIRED 是在代理執行時處理,而非在 Toolbox 連線建立時處理。

Samples

Sample 說明
foundry_toolbox/main.py FoundryToolbox 搭配託管 Responses
foundry_toolbox_mcp_skills/main.py 工具箱支援的代理程式技能
foundry_chat_client_with_toolbox.py 搭配 MCPStreamableHTTPTool 的工具箱 MCP 取用
foundry_chat_client_with_toolbox_skills.py 以工具箱為基礎的技能配置
invoke_foundry_toolbox_mcp 工作流程端的 MCP 消耗

Go 目前尚未提供 Foundry Toolbox 輔助函式。 透過 Foundry 配置工具箱,並使用支援的本地或託管工具宣告給 Go 代理使用。