Microsoft Foundry 工具箱

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

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

這很重要

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

對於服務管理的 FoundryAgent,請將工具箱附加至 Foundry 中的代理程式定義。 目前尚未有客戶端 .NET 工具箱使用指引。

安裝套件

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,並參與代理的連線生命週期。

import asyncio
import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryToolbox, ResponsesHostServer
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()


async def main():
    credential = DefaultAzureCredential()

    # FoundryToolbox resolves the toolbox endpoint from the environment
    # (TOOLBOX_ENDPOINT, or FOUNDRY_PROJECT_ENDPOINT + TOOLBOX_NAME), authenticates
    # every request with the credential, and transparently forwards the platform
    # per-request call-id to the toolbox. The hosting server enters the agent, which
    # connects the toolbox on first use and closes it at shutdown.
    toolbox = FoundryToolbox(credential)

    # Create the chat client
    client = FoundryChatClient(
        project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
        model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
        credential=credential,
    )

    agent = Agent(
        client=client,
        instructions="You are a friendly assistant. Keep your answers brief.",
        tools=toolbox,
        # History will be managed by the hosting infrastructure, thus there
        # is no need to store history by the service. Learn more at:
        # https://developers.openai.com/api/reference/resources/responses/methods/create
        default_options={"store": False},
    )

    server = ResponsesHostServer(agent)
    await server.run_async()

公開工具箱技能

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

import asyncio
import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryToolbox, ResponsesHostServer
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()


async def main() -> None:
    credential = DefaultAzureCredential()

    # FoundryToolbox resolves the toolbox endpoint from the environment
    # (TOOLBOX_ENDPOINT, or FOUNDRY_PROJECT_ENDPOINT + TOOLBOX_NAME), authenticates
    # every request with the credential, and forwards the platform per-request
    # call-id. ``load_tools=False`` keeps the toolbox's tools hidden so only its
    # Agent Skills (SEP-2640) are surfaced; passing it via ``tools=`` connects the
    # MCP session that ``as_skills_provider()`` reads from.
    toolbox = FoundryToolbox(credential, load_tools=False)

    # as_skills_provider() discovers skills from skill://index.json on the toolbox
    # MCP session and exposes them as an agent context provider; SKILL.md bodies are
    # fetched on demand via resources/read. disable_load_skill_approval=True registers
    # the load_skill tool with approval_mode="never_require" so this unattended agent
    # can load skills without an approval round-trip -- the Responses host runs the
    # agent without an AgentSession, which the default approval flow requires.
    skills_provider = toolbox.as_skills_provider(disable_load_skill_approval=True)

    client = FoundryChatClient(
        project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
        model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
        credential=credential,
    )

    agent = 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],
        # History will be managed by the hosting infrastructure, thus there
        # is no need to store history by the service. Learn more at:
        # https://developers.openai.com/api/reference/resources/responses/methods/create
        default_options={"store": False},
    )

    server = ResponsesHostServer(agent)
    await server.run_async()

技能操作的核准預設仍為啟用狀態。 只在可信且無人值守的情境下關閉個別核准。

使用 FoundryAgent 搭配工具箱

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

透過原始 MCP 連接

當應用程式不使用MCPStreamableHTTPTool主機包裝時,直接使用FoundryToolbox。 透過 header_provider 提供 Toolbox 端點及一個 Entra ID 持有人權杖。

import asyncio
import os
from collections.abc import Callable
from typing import Any, cast

from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.foundry import FoundryChatClient
from azure.core.credentials import TokenCredential
from azure.identity import AzureCliCredential, DefaultAzureCredential, get_bearer_token_provider
from dotenv import load_dotenv
def make_toolbox_header_provider(credential: TokenCredential) -> Callable[[dict[str, Any]], dict[str, str]]:
    """Build a header_provider that injects a fresh Azure AI bearer token on every MCP request."""
    get_token = get_bearer_token_provider(credential, "https://ai.azure.com/.default")

    def provide(_kwargs: dict[str, Any]) -> dict[str, str]:
        return {
            "Authorization": f"Bearer {get_token()}",
        }

    return provide


async def main() -> None:
    credential = DefaultAzureCredential()

    toolbox_tool = MCPStreamableHTTPTool(
        name="foundry_toolbox",
        description="Tools exposed by the configured Foundry toolbox",
        url=os.environ["FOUNDRY_TOOLBOX_ENDPOINT"],
        header_provider=make_toolbox_header_provider(credential),
        load_prompts=False,
    )

    async with Agent(
        client=FoundryChatClient(
            project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
            model=os.environ["FOUNDRY_MODEL"],
            credential=credential,
        ),
        instructions="You are a helpful assistant. Use the available toolbox tools to answer the user.",
        tools=toolbox_tool,
    ) as agent:
        query = "What tools do you have access to?"
        print(f"User: {query}")
        result = await agent.run(query)
        print(f"Assistant: {result}")

較低層級的範例使用 FOUNDRY_TOOLBOX_ENDPOINT。 工具箱技能範例使用 FOUNDRY_TOOLBOX_MCP_SERVER_URL;這些名稱屬於該範例,且與 FoundryToolbox 職業 TOOLBOX_ENDPOINTTOOLBOX_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 工具箱 MCP 消耗 MCPStreamableHTTPTool
foundry_chat_client_with_toolbox_skills.py 以工具箱為基礎的技能配置
invoke_foundry_toolbox_mcp 工作流程端的 MCP 消耗

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