Connecter des agents aux outils OpenAPI

Connectez vos agents Microsoft Foundry aux API externes à l’aide des spécifications OpenAPI 3.0 et 3.1. Le modèle Foundry qui alimente votre agent peut appeler des services externes, récupérer des données en temps réel et étendre ses fonctionnalités au-delà des fonctions intégrées.

Les spécifications OpenAPI définissent un moyen standard de décrire les API HTTP. Vous pouvez donc intégrer des services existants à vos agents. Utilisez l’authentification anonyme, par clé API ou avec l’identité managée du projet. Pour obtenir de l’aide sur le choix d’une méthode d’authentification, consultez Choisir une méthode d’authentification.

Conseil

Envisagez d’ajouter cet outil à l’aide d’une boîte à outils. À l’aide d’une boîte à outils, vous pouvez réutiliser l’outil entre les agents et les runtimes, ainsi que centraliser la gestion des informations d’identification, le contrôle de version et l’application des stratégies via un point de terminaison MCP géré. Consultez le guide de démarrage rapide de la boîte à outils.

Conditions préalables

Avant de commencer, assurez-vous d’avoir :

  • Un abonnement Azure disposant des autorisations appropriées.

  • Rôle Utilisateur Foundry dans le projet Foundry pour créer et exécuter des agents.

    Important

    Les rôles Foundry RBAC ont été récemment renommés. Foundry User, Foundry Owner, Propriétaire du compteFoundry et Foundry Project Manager ont été précédemment nommés Azure utilisateur IA, Azure propriétaire d’IA, propriétaire Azure compte IA et Azure gestionnaire Project IA. Il se peut que vous voyiez encore les anciens noms à certains endroits pendant le déploiement de ce changement de nom. Les ID de rôle et les autorisations de base ne sont pas modifiés par ce changement de nom.

  • rôle de Foundry Project Manager sur le projet Foundry pour créer une connexion au projet. Ce rôle inclut les connexions anonymes, par clé API et d’identité managée de projet.

  • Projet Foundry créé avec un point de terminaison configuré.

  • Modèle IA déployé dans votre projet. Vérifiez que le modèle et la région de projet prennent en charge les outils OpenAPI dans l’outil par région et par modèle.

  • Environnement d’agent de base ou standard.

  • Dépendances installées pour votre langue préférée :

    • Python exemples du Kit de développement logiciel (SDK) : azure-ai-projects, azure-identityet jsonref. L’exemple Réponses directes utilise openaiégalement .
    • Exemples du Kit de développement logiciel (SDK) C# : Azure.AI.Projects, Azure.AI.Projects.Agents, Azure.AI.Extensions.OpenAIet Azure.Identity. L’exemple HTTP direct utilise Azure.Identity.
    • Exemples du Kit de développement logiciel (SDK) JavaScript/TypeScript : @azure/ai-projects et @azure/identity. L’exemple HTTP direct utilise @azure/identity.
    • Java exemple HTTP : com.azure:azure-identity et com.fasterxml.jackson.core:jackson-databind.
  • Fichier de spécification OpenAPI 3.0 ou 3.1 qui répond aux exigences suivantes :

    • Chaque fonction doit avoir un operationId (requis pour l’outil OpenAPI).
    • operationId ne doit contenir que des lettres, -et _.
    • Utilisez des noms descriptifs pour aider les modèles à choisir efficacement la fonction à utiliser.
    • Types de contenu du corps de la requête pris en charge : application/json, application/json-patch+json
  • Pour l'authentification d'identité managée du projet : une connexion de projet OpenAPI avec authType: "ProjectManagedIdentity" et le rôle du service cible avec le niveau de privilèges minimal affecté à l'identité managée du projet. Transmettez l’ID de ressource complet de la connexion à l’outil. Consultez Créer une connexion d'identité managée par un projet.

  • Pour l’authentification par clé/jeton d’API : connexion de projet configurée avec votre clé d’API ou votre jeton. Consultez Ajouter une nouvelle connexion à votre projet.

  • Pour l’authentification anonyme : une connexion de projet OpenAPI avec authType: "None". Consultez Créer une connexion OpenAPI anonyme.

Variables d’environnement

Variable Description
FOUNDRY_PROJECT_ENDPOINT Votre point de terminaison de projet Foundry, tel que https://<account>.services.ai.azure.com/api/projects/<project>. N’utilisez pas le point de terminaison d’API externe.
FOUNDRY_MODEL_DEPLOYMENT_NAME Nom de votre modèle déployé.
OPENAPI_CONNECTION_ID ID de ressource ARM complet de la connexion OpenAPI pour la méthode d’authentification sélectionnée.
TOOLBOX_CONNECTION_ID Pour les exemples qui associent une boîte à outils via une connexion de projet, l'identifiant complet de la ressource correspondant à cette connexion distincte au point de terminaison MCP de la boîte à outils.

Note

La valeur FOUNDRY_PROJECT_ENDPOINT fait référence à votre point de terminaison de projet Microsoft Foundry, et non au point de terminaison de service OpenAPI externe. Vous trouverez ce point de terminaison dans le portail Microsoft Foundry sous la page Vue d’ensemble de votre projet. Ce point de terminaison est requis pour authentifier le service d’agent et est distinct de tous les points de terminaison OpenAPI définis dans votre fichier de spécification.

Support d'utilisation

Le tableau suivant présente la prise en charge du KIT de développement logiciel (SDK) et de la configuration.

Prise en charge de Microsoft Foundry SDK Python Kit de développement logiciel (SDK) C# Kit de développement logiciel (SDK) JavaScript Kit de développement logiciel (SDK) Java REST API Configuration de l’agent de base Configuration de l’agent standard
✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️

Note

L'exemple Java de cet article utilise le client HTTP de Java et Azure Identity pour envoyer la même charge utile Responses que les autres langues. Il ne nécessite pas de modèles d’outils OpenAPI typés.

Exécuter le flux anonyme de première réussite

Commencez par l’API météo anonyme pour vérifier que votre agent peut charger une spécification OpenAPI et appeler une opération. Créez une connexion de projet OpenAPI même pour l’authentification anonyme et transmettez son ID de ressource complet à l’outil. L’authentification anonyme ne nécessite pas d’informations d’identification d’API externes. Consultez Créer une connexion OpenAPI anonyme.

  1. Installez le package du Kit de développement logiciel (SDK) pour votre langue sélectionnée à partir des prérequis.
  2. Téléchargez weather_openapi.jsonet enregistrez-le dans le assets chemin d’accès utilisé par l’exemple.
  3. Définissez le point de terminaison de votre projet Foundry et les valeurs de déploiement de modèle.
  4. Créez une connexion OpenAPI anonyme pour https://wttr.in et définissez OPENAPI_CONNECTION_ID sur son ID de ressource complet.
  5. Exécutez l’exemple anonyme dans votre section de langue sélectionnée.
  6. Vérifiez que la réponse contient la météo actuelle pour Seattle, puis supprimez la version de l’agent créée par l’exemple.

Une fois l’appel anonyme réussi, configurez l’authentification requise par votre API cible. Conservez l’authentification par clé API, l’authentification par jeton Bearer et l’authentification par identité managée du projet en tant que variantes distinctes.

Comprendre les limitations

  • Votre spécification OpenAPI doit inclure operationId pour chaque opération et operationId peut inclure uniquement des lettres, -et _.
  • Types de contenu du corps de la demande pris en charge : application/json, application/json-patch+json.
  • Pour l’authentification par clé API, utilisez un schéma de sécurité de clé API par outil OpenAPI. Si vous avez besoin de plusieurs schémas de sécurité, créez plusieurs outils OpenAPI.
  • Renouvelez régulièrement les clés API et les jetons du porteur, et immédiatement dès qu’une exposition est suspectée. Mettez à jour la connexion du projet lorsque les informations d’identification changent ; ne placez pas d’informations d’identification dans la spécification OpenAPI ou le code source.

Configurer l’authentification OpenAPI dans le portail Foundry

Lorsque vous ajoutez un outil OpenAPI par le biais de Outils>Personnalisés>OpenAPI, créez une connexion de projet pour l’outil. Anonyme, clé API et identité managée nécessitent toutes une connexion, que vous configuriez l’outil via le portail, le SDK ou l’API REST.

L’option Identité managée du portail utilise l’identité managée du projet Foundry, et non l’identité managée du compte Foundry. Les outils OpenAPI dans les kits d’outils ont toujours requis une identité managée de projet, quel que soit l’historique des abonnements. L'identité managée du compte est prise en charge uniquement pour les outils OpenAPI associés directement aux agents de prompt dans les abonnements existants. Migrez ces configurations vers l’identité managée affectée au projet dès que possible. Consultez la prise en charge des identités managées.

L’authentification anonyme signifie que l’API cible ne nécessite pas d’informations d’identification. Cela ne signifie pas que vous pouvez ignorer la création de la connexion.

Authentication Configuration de la connexion
Anonyme Créez une connexion de projet OpenAPI sans authentification (authType: "None"). Aucune clé API ou jeton n’est nécessaire.
Clé API Créez une connexion de projet qui stocke la clé API. Faire correspondre le nom de clé au paramètre d’en-tête ou de requête dans le schéma de sécurité OpenAPI. Consultez S'authentifier avec la clé API.
Identité gérée (identité gérée du projet) Créez une connexion de projet OpenAPI avec authType: "ProjectManagedIdentity", le point de terminaison de l'API cible et l'audience attendue par cette API. Attribuez à l’identité managée du projet le rôle requis sur le service cible. Cette option n’utilise pas l’identité managée du compte.

Configurer l’authentification anonyme

  1. Ouvrez Tools>Custom>OpenAPI dans votre projet Foundry.
  2. Dans Créer un outil OpenAPI, entrez le nom et la description de l’outil.
  3. Définissez la méthode d’authentification sur Anonyme.
  4. Sous Connexion, sélectionnez une connexion anonyme existante ou sélectionnez Créer une nouvelle connexion pour en créer une.
  5. Entrez le schéma OpenAPI 3.0+ et sélectionnez Créer un outil.

Le champ Connexion est obligatoire même quand Anonyme est sélectionné.

Capture d’écran de l’authentification OpenAPI anonyme avec un champ Connexion obligatoire et un bouton Créer une connexion.

Configurer l’authentification d’identité managée

L’option Identité managée nécessite l’identité managée du projet. Une attribution de rôle existante pour l’identité managée du compte n’accorde pas l’accès à l’identité managée du projet.

  1. Dans Créer un outil OpenAPI, définissez la méthode d’authentification sur l’identité managée.
  2. Sous Connexion, sélectionnez une connexion d’identité managée de projet existante ou sélectionnez Créer une nouvelle connexion.
  3. Dans Créer une connexion OpenAPI, entrez un nom de connexion et définissez le type d’authentification sur Identité managée.
  4. Entrez l’URL cible de l’API et l’audience attendue par l’API. L'audience n'est pas votre point de terminaison de projet Foundry.
  5. Sélectionnez Créer une connexion, puis sélectionnez cette connexion dans le champ Connexion de l’outil.
  6. Entrez le Nom, la Description et le schéma OpenAPI 3.0+ de l’outil, puis sélectionnez Créer un outil.

Attribuez à l’identité managée du projet le rôle requis sur le service cible avant d’appeler l’outil.

Capture d’écran de la boîte de dialogue Créer une connexion OpenAPI montrant le nom de connexion requis, le type d’authentification, l’URL cible et le champ Audience pour l’identité managée.

Pour connaître la configuration de la connexion d’identité managée de projet via REST, consultez Créer une connexion d’identité managée de projet. Lorsque vous utilisez cette connexion dans le code, transmettez son ID de ressource complet avec auth.type: "project_connection".

Les exemples SDK et REST font également référence à une connexion au projet. Créez la connexion avant de les exécuter.

Créer une connexion OpenAPI anonyme

Utilisez les étapes du portail dans la section précédente ou exécutez les commandes Bash suivantes avec Azure CLI et curl après vous être connecté avec az login. Remplacez les espaces réservés par les détails de votre projet Foundry. Cette connexion utilise authType: "None" parce que l’API météo ne nécessite pas d’informations d’identification.

SUB="<subscription-id>"
RESOURCE_GROUP="<resource-group>"
ACCOUNT="<foundry-account-name>"
PROJECT_NAME="<foundry-project-name>"
PROJECT="/subscriptions/$SUB/resourceGroups/$RESOURCE_GROUP"
PROJECT="$PROJECT/providers/Microsoft.CognitiveServices"
PROJECT="$PROJECT/accounts/$ACCOUNT/projects/$PROJECT_NAME"
export OPENAPI_CONNECTION_ID="$PROJECT/connections/weather-anonymous"

ARM_TOKEN="$(az account get-access-token \
  --subscription "$SUB" \
  --resource https://management.azure.com \
  --query accessToken -o tsv)"

curl --fail-with-body --request PUT \
  --url "https://management.azure.com$OPENAPI_CONNECTION_ID?api-version=2025-06-01" \
  --header "Authorization: Bearer $ARM_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "properties": {
      "category": "OpenAPI",
      "authType": "None",
      "target": "https://wttr.in",
      "metadata": {
        "type": "openapi"
      }
    }
  }'

Référence : Schéma de ressource de connexion de projet Foundry.

Transmettez OPENAPI_CONNECTION_ID dans le auth.security_scheme.project_connection_id de l'outil, avec auth.type: "project_connection". Le authType de la connexion détermine que l'API cible est appelée anonymement.

Ajouter des outils OpenAPI à une boîte à outils

Utilisez ce modèle pour exposer une API REST décrite par une spécification OpenAPI. Pour l’authentification anonyme, par clé API ou par identité managée du projet, définissez le auth.type de l’outil sur project_connection. Le type d’authentification de la connexion authType détermine comment Foundry s’authentifie auprès de l’API cible.

Pour l'authentification par identité managée, les boîtes à outils nécessitent une identité managée du projet. L’identité managée du compte n’est pas prise en charge dans les toolboxes, y compris pour les abonnements existants.

Les extraits de code suivants montrent la configuration de l’outil, pas les programmes complets. Remplacez chaque objet vide spec par votre spécification OpenAPI. Pour la création de boîte à outils, utilisez les échantillons linguistiques complets dans les sections suivantes.

Important

Lorsque vous utilisez l’authentification d’identité managée, affectez à l’identité managée du projet Foundry le rôle RBAC le moins privilégié qui autorise les opérations d’API requises sur le service cible. Par exemple, affectez lecteur sur la ressource de Azure cible uniquement lorsque l’API a besoin d’un accès en lecture seule Azure Resource Manager. Sans l’affectation requise, l’agent reçoit une 401 Unauthorized réponse lors de l’appel de l’API. Pour connaître les étapes d’installation complètes, consultez Authentifier à l’aide de l’identité managée.

Authentification anonyme :

Créez d’abord une connexion authType: "None" OpenAPI et remplacez <OPENAPI_CONNECTION_ID> par son ID de ressource complet.

{
  "description": "REST API via OpenAPI spec",
  "tools": [
    {
      "type": "openapi",
      "openapi": {
        "name": "my-api",
        "spec": {},
        "auth": {
          "type": "project_connection",
          "security_scheme": {
            "project_connection_id": "<OPENAPI_CONNECTION_ID>"
          }
        }
      }
    }
  ]
}

Authentification de connexion de projet :

Utilisez ce modèle lorsque l’API nécessite une clé ou un jeton stocké dans une connexion de projet Foundry.

{
  "description": "REST API with connection-based auth",
  "tools": [
    {
      "type": "openapi",
      "openapi": {
        "name": "my-api",
        "spec": {},
        "auth": {
          "type": "project_connection",
          "security_scheme": {
            "project_connection_id": "<OPENAPI_CONNECTION_ID>"
          }
        }
      }
    }
  ]
}

Authentification par identité managée du projet :

Créez une connexion de projet OpenAPI avec authType: "ProjectManagedIdentity", puis transmettez son ID de ressource complet avec auth.type: "project_connection". N'utilisez pas la configuration de l'audience directe managed_identity dans une boîte à outils.

{
  "description": "REST API with project managed identity auth",
  "tools": [
    {
      "type": "openapi",
      "openapi": {
        "name": "my-api",
        "spec": {},
        "auth": {
          "type": "project_connection",
          "security_scheme": {
            "project_connection_id": "<OPENAPI_CONNECTION_ID>"
          }
        }
      }
    }
  ]
}
import os
from azure.ai.projects.models import (
    OpenApiFunctionDefinition,
    OpenApiProjectConnectionAuthDetails,
    OpenApiProjectConnectionSecurityScheme,
    OpenApiToolboxTool,
)

tools = [
    OpenApiToolboxTool(
        openapi=OpenApiFunctionDefinition(
            name="my-api",
            spec={},
            auth=OpenApiProjectConnectionAuthDetails(
                security_scheme=OpenApiProjectConnectionSecurityScheme(
                    project_connection_id=os.environ["OPENAPI_CONNECTION_ID"]
                )
            ),
        )
    )
]
using System;
using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects.Agents;

BinaryData specBytes = BinaryData.FromString("<OpenAPI spec JSON>");
OpenApiToolboxTool tool = new(
    new OpenApiFunctionDefinition(
        name: "my-api",
        specification: specBytes,
        authentication: new OpenApiProjectConnectionAuthenticationDetails(
            new OpenApiProjectConnectionSecurityScheme(
                Environment.GetEnvironmentVariable("OPENAPI_CONNECTION_ID")
                ?? throw new InvalidOperationException(
                    "Set OPENAPI_CONNECTION_ID before running.")))
    )
);

ToolboxVersion toolboxVersion = await toolboxClient.CreateVersionAsync(
    name: "my-toolbox",
    tools: [tool],
    description: "REST API via OpenAPI spec"
);
const connectionId = process.env.OPENAPI_CONNECTION_ID;
if (!connectionId) {
  throw new Error("Set OPENAPI_CONNECTION_ID before running.");
}

const tools = [
  {
    type: "openapi",
    openapi: {
      name: "my-api",
      spec: { /* paste OpenAPI spec object here */ },
      auth: {
        type: "project_connection",
        security_scheme: {
          project_connection_id: connectionId,
        },
      },
    },
  },
];

Créer une boîte à outils OpenAPI avec l’interface CLI Azure développeur

Les outils OpenAPI incorporent directement la spécification sous tools:. L'authentification basée sur la connexion (connection_auth) fait référence à une connexion au projet. Créez également une connexion pour l’authentification anonyme.

Étape 1. Créer la connexion d’authentification

Pour l’authentification anonyme, suivez la procédure pour créer une connexion OpenAPI anonyme. Pour l’authentification par clé API, utilisez la commande suivante :

# API-key auth (passed by the platform on every call)
# Set OPENAPI_AUTHORIZATION_HEADER in your shell without committing its value.
azd ai connection create my-api-conn \
  --kind remote-tool \
  --target https://api.example.com \
  --auth-type custom-keys \
  --custom-key "Authorization=$OPENAPI_AUTHORIZATION_HEADER"

Pour consulter la liste complète des options azd ai connection create, voir Authentification et configuration de Toolbox MCP.

Étape 2. Définir la boîte à outils

La spécification OpenAPI est incluse sous tools[].openapi.spec.

# my-toolbox.yaml
description: OpenAPI toolbox
tools:
  - type: openapi
    name: my-api
    openapi:
      name: my-api
      spec:
        openapi: "3.0.1"
        info:
          title: "My API"
          version: "1.0"
        servers:
          - url: https://api.example.com/v1
        paths:
          /search:
            get:
              operationId: search
              parameters:
                - name: query
                  in: query
                  required: true
                  schema:
                    type: string
              responses:
                "200":
                  description: OK
      auth:
        type: connection_auth
        connection_id: my-api-conn

Pour les API anonymes, conservez l’authentification basée sur la connexion. Par exemple, pour utiliser la connexion météorologique créée précédemment, remplacez l'exemple de spécification par weather_openapi.json et utilisez ce bloc auth: :

      auth:
        type: connection_auth
        connection_id: weather-anonymous

Étape 3. Créer la boîte à outils

azd ai toolbox create my-toolbox --from-file my-toolbox.yaml

Avant d’exécuter les exemples de code

  • Créez la connexion de projet OpenAPI avant d’exécuter un exemple, y compris des exemples anonymes. Pour les échantillons météo, utilisez une connexion anonyme ciblant https://wttr.in, et définissez OPENAPI_CONNECTION_ID sur son ID de ressource ARM complet.
  • Téléchargez la spécification tripadvisor_openapi.json maintenue et enregistrez-la dans le chemin d’accès assets utilisé par votre exemple de langage.

Note

  • Vous avez besoin du dernier package sdk. Le sdk .NET est actuellement en préversion. Pour plus d’informations, consultez le guide de démarrage rapide .
  • Utilisez l’ID de ressource de connexion complet : /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.CognitiveServices/accounts/<account>/projects/<project>/connections/<connection>.

Important

Pour que l’authentification par clé API fonctionne, votre fichier de spécification OpenAPI doit inclure :

  1. Section securitySchemes avec votre configuration de clé API, telle que le nom d’en-tête et le nom du paramètre.
  2. Section security qui fait référence au schéma de sécurité.
  3. Connexion de projet configurée avec le nom et la valeur de clé correspondants.

Sans ces configurations, la clé API n’est pas incluse dans les requêtes. Pour obtenir des instructions d’installation détaillées, consultez la section Authentifier avec la clé API .

Vous pouvez également utiliser l’authentification basée sur les jetons (par exemple, un jeton du porteur) en stockant le jeton dans une connexion de projet. Pour l’authentification par jeton porteur, créez une connexion de clés personnalisées avec la clé définie sur Authorization et la valeur définie sur Bearer <token> (remplacez <token> par votre jeton réel). Le mot Bearer suivi d’un espace doit être inclus dans la valeur. Pour plus d’informations, consultez Connexion avec un jeton Bearer.

Exemple d’utilisation d’agents avec l’outil OpenAPI

Cet exemple montre comment utiliser des services décrits par une spécification OpenAPI à l’aide d’un agent. Il utilise le service wttr.in pour obtenir le temps et son fichier de spécification weather_openapi.json. Sélectionnez Prompt Agents pour utiliser le SDK Azure AI Projects afin de créer un agent de prompt côté serveur, ou Agents hébergés pour utiliser le framework Microsoft Agent afin de créer un agent éphémère dans le processus.

Agents déclencheurs

import os
import jsonref
from typing import Any, cast
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import (
    PromptAgentDefinition,
    OpenApiTool,
    OpenApiFunctionDefinition,
    OpenApiProjectConnectionAuthDetails,
    OpenApiProjectConnectionSecurityScheme,
)

# Format: "https://resource_name.ai.azure.com/api/projects/project_name"
PROJECT_ENDPOINT = "your_project_endpoint"
AGENT_NAME = "MyAgent"

# Create a client to call Foundry API
with AIProjectClient(
    endpoint=PROJECT_ENDPOINT,
    credential=DefaultAzureCredential(),
) as project:
    weather_asset_file_path = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "../assets/weather_openapi.json")
    )

    with open(weather_asset_file_path, "r") as f:
        openapi_weather = cast(dict[str, Any], jsonref.loads(f.read()))

    # Initialize agent OpenAPI tool using the read in OpenAPI spec
    weather_tool = OpenApiTool(
        openapi=OpenApiFunctionDefinition(
            name="get_weather",
            spec=openapi_weather,
            description="Retrieve weather information for a location.",
            auth=OpenApiAnonymousAuthDetails(),
        )
    )

    agent = project.agents.create_version(
        agent_name=AGENT_NAME,
        definition=PromptAgentDefinition(
            model="gpt-4.1-mini",
            instructions="You are a helpful assistant.",
            tools=[weather_tool],
        ),
    )

    with project.get_openai_client(agent_name=agent.name) as openai:
        response = openai.responses.create(
            input="What's the weather in Seattle?",
        )
        print(response.output_text)

    # Clean up resources
    project.agents.delete_version(agent_name=agent.name, agent_version=agent.version)

Cet exemple crée un assistant de requête avec un outil OpenAPI qui appelle l’API Weather wttr.in avec authentification anonyme. L’outil est attaché directement à la définition de l’agent. Lorsque vous exécutez le code :

  1. Il charge la spécification OpenAPI météorologique à partir d’un fichier JSON local.
  2. Crée un assistant de requête avec l’outil Weather configuré pour un accès anonyme.
  3. Envoie une requête demandant la météo de Seattle.
  4. L’agent utilise l’outil OpenAPI pour appeler l’API météo et retourne les résultats mis en forme.
  5. Nettoie en supprimant la version de l’agent.

Agents hébergés

Cet exemple utilise FoundryChatClient du framework Microsoft Agent et se connecte au point de terminaison MCP de la boîte à outils en utilisant FoundryToolbox. Installez les versions de package compatibles avec pip install "agent-framework-foundry==1.15.0" "azure-ai-projects>=2.3.0,<2.8.0" jsonref, définissez la variable d’environnement FOUNDRY_PROJECT_ENDPOINT et connectez-vous avec az login. OpenApiToolboxTool est le modèle propre à la boîte à outils ; utilisez OpenApiTool uniquement lorsque vous attachez l’outil directement à un agent de prompt.

import asyncio
import os
import jsonref
from typing import Any, cast

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryToolbox
from azure.identity import AzureCliCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import (
    OpenApiToolboxTool,
    OpenApiFunctionDefinition,
    OpenApiProjectConnectionAuthDetails,
    OpenApiProjectConnectionSecurityScheme,
)

PROJECT_ENDPOINT = os.environ["FOUNDRY_PROJECT_ENDPOINT"]


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

    # 1. Create the OpenAPI tool and add it to a toolbox. Using a toolbox is the
    #    recommended way to give agents tools: curate tools once and reuse the
    #    toolbox across agents. See /azure/foundry/agents/concepts/toolbox-overview
    project = AIProjectClient(endpoint=PROJECT_ENDPOINT, credential=credential)

    weather_asset_file_path = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "../assets/weather_openapi.json")
    )
    with open(weather_asset_file_path, encoding="utf-8") as f:
        openapi_weather = cast(dict[str, Any], jsonref.loads(f.read()))

    weather_tool = OpenApiToolboxTool(
        openapi=OpenApiFunctionDefinition(
            name="get_weather",
            spec=openapi_weather,
            description="Retrieve weather information for a location.",
            auth=OpenApiProjectConnectionAuthDetails(
                security_scheme=OpenApiProjectConnectionSecurityScheme(
                    project_connection_id=os.environ["OPENAPI_CONNECTION_ID"]
                )
            ),
        )
    )

    toolbox = project.toolboxes.create_version(
        name="openapi-toolbox",
        description="Toolbox with the OpenAPI weather tool",
        tools=[weather_tool],
    )

    # 2. The toolbox exposes an MCP-compatible endpoint.
    TOOLBOX_MCP_URL = (
        f"{PROJECT_ENDPOINT}/toolboxes/{toolbox.name}"
        f"/versions/{toolbox.version}/mcp?api-version=v1"
    )

    # 3. Attach the toolbox to the hosted agent as an MCP tool.
    toolbox_tool = FoundryToolbox(credential, url=TOOLBOX_MCP_URL)

    agent = Agent(
        client=FoundryChatClient(credential=credential),
        instructions="You are a helpful assistant. Use the OpenAPI weather tool to answer questions.",
        tools=[toolbox_tool],
    )

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


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

Sortie attendue

Agent: The weather in Seattle is currently cloudy with a temperature of 52°F (11°C)...

Exemple d’utilisation d’agents avec l’outil OpenAPI

Cet exemple montre comment utiliser des services décrits par une spécification OpenAPI à l’aide d’un agent. Il utilise le service wttr.in pour obtenir le temps et son fichier de spécification weather_openapi.json. Sélectionnez Prompt Agents pour utiliser le SDK Azure AI Projects afin de créer un agent de prompt côté serveur, ou Agents hébergés pour utiliser le framework Microsoft Agent afin de créer un agent éphémère dans le processus.

Agents déclencheurs

Cet exemple utilise des méthodes synchrones de la bibliothèque cliente Azure AI Projects. Pour obtenir un exemple qui utilise des méthodes asynchrones, consultez le sample dans le Kit de développement logiciel (SDK) Azure pour .NET référentiel sur GitHub.

using System;
using System.IO;
using System.Runtime.CompilerServices;
using Azure.AI.Projects;
using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects.Agents;
using Azure.Identity;
using OpenAI.Responses;

#pragma warning disable AAIP002

class OpenAPIDemo
{
    // Utility method to get the OpenAPI specification file from the Assets folder.
    private static string GetFile([CallerFilePath] string pth = "")
    {
        var dirName = Path.GetDirectoryName(pth) ?? "";
        return Path.Combine(dirName, "Assets", "weather_openapi.json");
    }

    public static void Main()
    {
        var projectEndpoint =
            Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
            ?? throw new InvalidOperationException(
                "Set FOUNDRY_PROJECT_ENDPOINT before running.");
        var deploymentName =
            Environment.GetEnvironmentVariable("FOUNDRY_MODEL_DEPLOYMENT_NAME")
            ?? throw new InvalidOperationException(
                "Set FOUNDRY_MODEL_DEPLOYMENT_NAME before running.");

        // Create project client to call Foundry API
        AIProjectClient projectClient = new(
            endpoint: new Uri(projectEndpoint),
            tokenProvider: new DefaultAzureCredential());

        // The connection specifies anonymous authentication to the weather API.
        string filePath = GetFile();
        OpenApiFunctionDefinition toolDefinition = new(
            name: "get_weather",
            specification: BinaryData.FromBytes(File.ReadAllBytes(filePath)),
            authentication: new OpenApiProjectConnectionAuthenticationDetails(
                new OpenApiProjectConnectionSecurityScheme(
                    Environment.GetEnvironmentVariable("OPENAPI_CONNECTION_ID")
                    ?? throw new InvalidOperationException(
                        "Set OPENAPI_CONNECTION_ID before running.")))
        );
        toolDefinition.Description = "Retrieve weather information for a location.";
        OpenApiTool openapiTool = new(toolDefinition);

        // Create the agent definition and the agent version.
        DeclarativeAgentDefinition agentDefinition = new(model: deploymentName)
        {
            Instructions = "You are a helpful assistant.",
            Tools = { openapiTool }
        };
        ProjectsAgentVersion agentVersion = projectClient.AgentAdministrationClient.CreateAgentVersion(
            agentName: "myAgent",
            options: new(agentDefinition));

        // Create a response object and ask the question about the weather in Seattle, WA.
        ProjectResponsesClient responseClient = projectClient.ProjectOpenAIClient.GetProjectResponsesClientForAgent(agentVersion.Name);
        ResponseResult response = responseClient.CreateResponse(
                userInputText: "Use the OpenAPI tool to print out, what is the weather in Seattle, WA today."
            );
        Console.WriteLine(response.GetOutputText());

        // Finally, delete all the resources created in this sample.
        projectClient.AgentAdministrationClient.DeleteAgentVersion(agentName: agentVersion.Name, agentVersion: agentVersion.Version);
    }
}

Ce que fait ce code

Cet exemple C# crée un agent avec un outil OpenAPI qui récupère les informations météorologiques de wttr.in à l’aide de l’authentification anonyme. Lorsque vous exécutez le code :

  1. Il lit la spécification OpenAPI météorologique à partir d’un fichier JSON local.
  2. Crée un agent avec l’outil météo configuré.
  3. Envoie une demande demandant la météo de Seattle à l’aide de l’outil OpenAPI.
  4. L’agent appelle l’API météo et retourne les résultats.
  5. Nettoie en supprimant de l’agent.

Entrées requises

  • Variables d’environnement : FOUNDRY_PROJECT_ENDPOINT, FOUNDRY_MODEL_DEPLOYMENT_NAMEet OPENAPI_CONNECTION_ID.
  • Fichier local : Assets/weather_openapi.json (spécification OpenAPI)

Sortie attendue

The weather in Seattle, WA today is cloudy with temperatures around 52°F...

Erreurs courantes

  • FileNotFoundException: Fichier de spécification OpenAPI introuvable dans le dossier Assets
  • UnauthorizedAccessException: informations d’identification non valides ou autorisations RBAC insuffisantes
  • Clé API non injectée : vérifiez que votre spécification OpenAPI inclut à la fois securitySchemes (en components) et security les sections avec des noms de schéma correspondants

Agents hébergés

Cet exemple crée la boîte à outils OpenAPI avec le sdk Azure AI Projects, puis utilise l’intégration Microsoft Agent FrameworkAddFoundryToolboxes. Utilisez un projet ASP.NET Core avec Azure.AI.AgentServer.Responses et Microsoft.Agents.AI.Foundry.Hosting, en plus des dépendances C# dans les conditions préalables. Définissez FOUNDRY_PROJECT_ENDPOINT, FOUNDRY_MODEL_DEPLOYMENT_NAME et OPENAPI_CONNECTION_ID, puis connectez-vous avec az login.

using System;
using System.IO;
using System.Runtime.CompilerServices;
using Azure.AI.AgentServer.Responses;
using Azure.AI.Projects;
using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.AspNetCore.Builder;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Foundry.Hosting;
using Microsoft.Extensions.DependencyInjection;
using OpenAI.Chat;

string GetFile([CallerFilePath] string pth = "")
{
    var dirName = Path.GetDirectoryName(pth) ?? "";
    return Path.Combine(dirName, "Assets", "weather_openapi.json");
}

string projectEndpoint = Environment.GetEnvironmentVariable(
    "FOUNDRY_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("Set FOUNDRY_PROJECT_ENDPOINT.");
string deploymentName = Environment.GetEnvironmentVariable(
    "FOUNDRY_MODEL_DEPLOYMENT_NAME")
    ?? throw new InvalidOperationException("Set FOUNDRY_MODEL_DEPLOYMENT_NAME.");
DefaultAzureCredential credential = new();

// 1. Create the OpenAPI tool and add it to a toolbox. Using a toolbox is the
//    recommended way to give agents tools. See /azure/foundry/agents/concepts/toolbox-overview
AIProjectClient projectClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: credential);
string filePath = GetFile();
OpenApiFunctionDefinition toolDefinition = new(
    name: "get_weather",
    specification: BinaryData.FromBytes(File.ReadAllBytes(filePath)),
    authentication: new OpenApiProjectConnectionAuthenticationDetails(
        new OpenApiProjectConnectionSecurityScheme(
            Environment.GetEnvironmentVariable("OPENAPI_CONNECTION_ID")
            ?? throw new InvalidOperationException(
                "Set OPENAPI_CONNECTION_ID before running.")))
);
toolDefinition.Description = "Retrieve weather information for a location.";
OpenApiToolboxTool openapiTool = new(toolDefinition);
ToolboxVersion toolboxVersion = projectClient.AgentAdministrationClient
    .GetAgentToolboxes().CreateVersion(
        name: "openapi-toolbox",
        tools: [openapiTool],
        description: "Toolbox with the OpenAPI weather tool");
projectClient.AgentAdministrationClient.GetAgentToolboxes()
    .UpdateDefaultVersion(toolboxVersion.Name, toolboxVersion.Version);

// Create the hosted agent and register the toolbox integration.
AIAgent agent = projectClient.AsAIAgent(
    model: deploymentName,
    instructions: "You are a helpful assistant with access to the toolbox tools.",
    name: "hosted-toolbox-agent");

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddFoundryResponses(agent);
builder.Services.AddFoundryToolboxes(credential, toolboxVersion.Name);

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

Sortie attendue

L’exemple démarre un serveur HTTP. Lorsque vous envoyez une demande de réponses concernant la météo, l’agent appelle l’API via la boîte à outils et retourne les conditions actuelles :

The current weather in Seattle is <temperature> with <conditions>.

Pour obtenir l’exemple complet, y compris les modèles d’API authentifiés, consultez Agent_Step17_OpenAPITools.


Exemple d’utilisation d’agents avec l’outil OpenAPI sur le service web, nécessitant une authentification

Dans cet exemple, vous associez directement un outil OpenAPI authentifié à un agent de prompt. Vous utilisez la spécification Trip Advisor et une clé API stockée dans une connexion de projet.

Le service TripAdvisor nécessite l’authentification par clé API. Créez la connexion de projet comme décrit dans Authentifier avec la clé API et définissez OPENAPI_CONNECTION_ID sur son ID de ressource complet. Le nom de clé de la connexion doit correspondre à la spécification TripAdvisor.

using System;
using System.IO;
using System.Runtime.CompilerServices;
using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects;
using Azure.AI.Projects.Agents;
using Azure.Identity;
using OpenAI.Responses;

#pragma warning disable AAIP002

class OpenAPIConnectedDemo
{
    // Utility method to get the OpenAPI specification file from the Assets folder.
    private static string GetFile([CallerFilePath] string pth = "")
    {
        var dirName = Path.GetDirectoryName(pth) ?? "";
        return Path.Combine(dirName, "Assets", "tripadvisor_openapi.json");
    }

    public static void Main()
    {
        var projectEndpoint =
            Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
            ?? throw new InvalidOperationException(
                "Set FOUNDRY_PROJECT_ENDPOINT before running.");
        var deploymentName =
            Environment.GetEnvironmentVariable("FOUNDRY_MODEL_DEPLOYMENT_NAME")
            ?? throw new InvalidOperationException(
                "Set FOUNDRY_MODEL_DEPLOYMENT_NAME before running.");

        // Create project client to call Foundry API
        AIProjectClient projectClient = new(
            endpoint: new Uri(projectEndpoint),
            tokenProvider: new DefaultAzureCredential());

        // Create an OpenAPI tool with authentication by project connection security scheme.
        string filePath = GetFile();
        var connectionId =
            Environment.GetEnvironmentVariable("OPENAPI_CONNECTION_ID")
            ?? throw new InvalidOperationException(
                "Set OPENAPI_CONNECTION_ID to the TripAdvisor connection ID.");
        OpenApiFunctionDefinition toolDefinition = new(
            name: "tripadvisor",
            specification: BinaryData.FromBytes(File.ReadAllBytes(filePath)),
            authentication: new OpenApiProjectConnectionAuthenticationDetails(new OpenApiProjectConnectionSecurityScheme(
                projectConnectionId: connectionId
            ))
        );
        toolDefinition.Description = "Trip Advisor API to get travel information.";
        OpenApiTool openapiTool = new(toolDefinition);

        // Create the agent definition and the agent version.
        DeclarativeAgentDefinition agentDefinition = new(model: deploymentName)
        {
            Instructions = "You are a helpful assistant.",
            Tools = { openapiTool }
        };
        ProjectsAgentVersion agentVersion = projectClient.AgentAdministrationClient.CreateAgentVersion(
            agentName: "myAgent",
            options: new(agentDefinition));

        // Create a response object and ask the question about the hotels in France.
        // Test the Web service access before you run production scenarios.
        // It can be done by setting:
        // ToolChoice = ResponseToolChoice.CreateRequiredChoice()`
        // in the ResponseCreationOptions. This setting will
        // force Agent to use tool and will trigger the error if it is not accessible.
        ProjectResponsesClient responseClient = projectClient.ProjectOpenAIClient.GetProjectResponsesClientForAgent(agentVersion.Name);
        CreateResponseOptions responseOptions = new()
        {
            ToolChoice = ResponseToolChoice.CreateRequiredChoice(),
            InputItems =
            {
                ResponseItem.CreateUserMessageItem("Recommend me 5 top hotels in paris, France."),
            }
        };
        ResponseResult response = responseClient.CreateResponse(
            options: responseOptions
        );
        Console.WriteLine(response.GetOutputText());

        // Finally, delete all the resources we have created in this sample.
        projectClient.AgentAdministrationClient.DeleteAgentVersion(agentName: agentVersion.Name, agentVersion: agentVersion.Version);
    }
}

Ce que fait ce code

Cet exemple C# utilise un outil OpenAPI avec l’authentification par clé API via une connexion de projet. Lorsque vous exécutez le code :

  1. Il charge la spécification TripAdvisor OpenAPI à partir d’un fichier local.
  2. Il fait référence à la connexion de projet Trip Advisor contenant votre clé API.
  3. Il attache l'outil TripAdvisorà l'agent, configuré pour utiliser la connexion pour l'authentification.
  4. Envoie une demande de recommandations d’hôtel à Paris.
  5. L’agent appelle l’API Trip Advisor à l’aide de votre clé API stockée et retourne les résultats.
  6. Nettoie en supprimant de l’agent.

Entrées requises

  • Variables d’environnement : FOUNDRY_PROJECT_ENDPOINT, FOUNDRY_MODEL_DEPLOYMENT_NAMEet OPENAPI_CONNECTION_ID.
  • Fichier local : Assets/tripadvisor_openapi.json
  • connexion Project : tripadvisor avec une clé API valide configurée

Sortie attendue

Here are 5 top hotels in Paris, France:
1. Hotel Name - Rating: 4.5/5, Location: ...
2. Hotel Name - Rating: 4.4/5, Location: ...
...

Erreurs courantes

  • ConnectionNotFoundException: Aucune connexion de projet nommée tripadvisor trouvée.
  • AuthenticationException: clé API non valide dans la connexion de projet, ou configuration manquante/incorrecte securitySchemes dans la spécification OpenAPI.
  • Outil non utilisé : vérifiez que ToolChoice = ResponseToolChoice.CreateRequiredChoice() impose l’utilisation de l’outil.
  • Clé API non transmise à l’API : vérifiez que la spécification OpenAPI a des sections appropriées securitySchemes et security configurées.

Créer un agent Java avec des fonctionnalités d’outil OpenAPI

Cette configuration Java peut référencer les outils MCP, mais le SDK Java n'expose pas encore d'API de création de boîte à outils.

Conseil

Recommandé: Pour la plupart des agents, ajoutez l’outil OpenAPI via une boîte à outils et joignez la boîte à outils à votre agent en tant qu’outil MCP. Créez la boîte à outils à l’aide de l’exemple Python, API REST, C# ou TypeScript, ou du portail Foundry, puis référencez son point de terminaison MCP à partir de votre agent Java en tant que McpTool.

Les exemples suivants montrent comment appeler un outil OpenAPI à l’aide de l’API REST.

Obtenez un jeton d’accès :

AGENT_TOKEN=$(az account get-access-token --scope https://ai.azure.com/.default --query accessToken -o tsv)

Authentification anonyme

Ajoutez des outils OpenAPI via une boîte à outils, puis attachez la boîte à outils à votre agent en tant qu’outil MCP. Pour plus d’informations, consultez Qu’est-ce qu’une boîte à outils ?

  1. Créez une boîte à outils qui contient l’outil météo OpenAPI :
curl --request POST \
  --url "$FOUNDRY_PROJECT_ENDPOINT/toolboxes/openapi-toolbox/versions?api-version=v1" \
  --header "Foundry-Features: Toolboxes=V1Preview" \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "description": "Toolbox with the OpenAPI weather tool",
    "tools": [
      {
        "type": "openapi",
        "openapi": {
          "name": "weather",
          "description": "Tool to get weather data",
          "auth": {
            "type": "project_connection",
            "security_scheme": {
              "project_connection_id": "'$OPENAPI_CONNECTION_ID'"
            }
          },
          "spec": {
            "openapi": "3.1.0",
            "info": {
              "title": "get weather data",
              "description": "Retrieves current weather data for a location.",
              "version": "v1.0.0"
            },
            "servers": [{ "url": "https://wttr.in" }],
            "paths": {
              "/{location}": {
                "get": {
                  "description": "Get weather information for a specific location",
                  "operationId": "GetCurrentWeather",
                  "parameters": [
                    {
                      "name": "location",
                      "in": "path",
                      "description": "City or location to retrieve the weather for",
                      "required": true,
                      "schema": { "type": "string" }
                    },
                    {
                      "name": "format",
                      "in": "query",
                      "description": "Format in which to return data. Always use 3.",
                      "required": true,
                      "schema": { "type": "integer", "default": 3 }
                    }
                  ],
                  "responses": {
                    "200": {
                      "description": "Successful response",
                      "content": {
                        "text/plain": {
                          "schema": { "type": "string" }
                        }
                      }
                    },
                    "404": { "description": "Location not found" }
                  }
                }
              }
            }
          }
        }
      }
    ]
  }'

La boîte à outils expose un point de terminaison compatible MCP à l’emplacement $FOUNDRY_PROJECT_ENDPOINT/toolboxes/openapi-toolbox/versions/<version>/mcp?api-version=v1où <version> est la version retournée par l’appel précédent.

  1. Créez une connexion de projet d’outil distant qui pointe vers le point de terminaison de la boîte à outils, en utilisant un jeton Entra utilisateur afin que l’identité de l’appelant soit transmise (audience https://ai.azure.com).
azd ai connection create openapi-toolbox-conn \
  --kind remote-tool \
  --target "$FOUNDRY_PROJECT_ENDPOINT/toolboxes/openapi-toolbox/versions/<version>/mcp?api-version=v1" \
  --auth-type user-entra-token \
  --audience https://ai.azure.com
  1. Créez une réponse qui utilise la boîte à outils en l’attachant en tant qu’outil MCP.

    Définissez TOOLBOX_CONNECTION_ID sur l’ID de ressource complet de openapi-toolbox-conn. Cette connexion est distincte de la connexion OpenAPI anonyme dans OPENAPI_CONNECTION_ID. Remplacez <version> par la version retournée lorsque vous avez créé la toolbox.

curl --request POST \
  --url "$FOUNDRY_PROJECT_ENDPOINT/openai/v1/responses" \
  --header "Authorization: Bearer $AGENT_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "model": "'$FOUNDRY_MODEL_DEPLOYMENT_NAME'",
    "input": "Use the OpenAPI tool to get the weather in Seattle, WA today.",
    "tool_choice": "required",
    "tools": [
      {
        "type": "mcp",
        "server_label": "toolbox",
        "server_url": "'$FOUNDRY_PROJECT_ENDPOINT'/toolboxes/openapi-toolbox/versions/<version>/mcp?api-version=v1",
        "require_approval": "never",
        "project_connection_id": "'$TOOLBOX_CONNECTION_ID'",
        "headers": {
          "Foundry-Features": "Toolboxes=V1Preview"
        }
      }
    ]
  }'

Authentification par clé API (connexion de projet)

Utilisez cette variante uniquement une fois le flux anonyme réussi. Téléchargez tripadvisor_openapi.json depuis Avant d'exécuter les exemples de code. Configurez la connexion à la clé API et les entrées securitySchemes et security de la spécification, comme décrit dans Authentifier avec la clé API. Définissez OPENAPI_CONNECTION_ID sur l’ID de ressource complet de cette connexion, et non sur la connexion météorologique anonyme.

Cet exemple Bash utilise jq pour inclure la spécification dans la même remote_tool structure de requête que les exemples d'identité managée du projet.

jq -n \
  --arg model "$FOUNDRY_MODEL_DEPLOYMENT_NAME" \
  --arg connection_id "$OPENAPI_CONNECTION_ID" \
  --slurpfile spec tripadvisor_openapi.json \
  '{
    model: $model,
    input: "Recommend five top hotels in the United States.",
    tools: [
      {
        type: "remote_tool",
        tool_arguments: [
          {
            name: "openapi",
            arguments: {
              name: "tripadvisor",
              description: "TripAdvisor travel information.",
              auth: {
                type: "project_connection",
                security_scheme: {
                  project_connection_id: $connection_id
                }
              },
              spec: $spec[0]
            }
          }
        ]
      }
    ],
    tool_choice: "required"
  }' > openapi-api-key-request.json

curl --fail-with-body --request POST \
  --url "${FOUNDRY_PROJECT_ENDPOINT%/}/openai/v1/responses" \
  --header "Authorization: Bearer $AGENT_TOKEN" \
  --header "Content-Type: application/json" \
  --data @openapi-api-key-request.json

Pour une API de jeton de porteur, conservez la même project_connection forme de requête, mais utilisez une connexion configurée comme décrit dans Configurer une connexion de jeton du porteur. La valeur de connexion doit commencer par Bearer, suivi d’un espace.

Authentification d’identité managée

Pour l’identité managée du projet, créez d’abord une connexion de projet OpenAPI. Ensuite, transmettez son ID de ressource complet dans la requête Réponses. Consultez l’exemple REST dans Appeler un outil OpenAPI avec une identité managée affectée au projet.

L'identité managée du compte est prise en charge uniquement pour les outils OpenAPI associés directement aux agents de prompt dans les abonnements existants. Elle n'est pas prise en charge dans les boîtes à outils. Utilisez également l'identité managée du projet pour les agents de prompt. Migrez les configurations existantes dès que possible.

Ce que fait ce code

Cet exemple d’API REST montre comment appeler un outil OpenAPI avec différentes méthodes d’authentification. La demande :

  1. Pour l’authentification anonyme, crée une boîte à outils contenant la définition de l’outil OpenAPI et la spécification de l’API météo.
  2. Crée une réponse qui attache la boîte à outils en tant qu’outil MCP et demande la météo de Seattle.
  3. Affiche une définition d’outil REST directe supplémentaire pour l’authentification par clé API via une connexion de projet.
  4. L’agent appelle l’API sélectionnée par la configuration de l’outil et retourne les résultats.

Entrées requises

  • Variables d’environnement : FOUNDRY_PROJECT_ENDPOINT, AGENT_TOKEN, FOUNDRY_MODEL_DEPLOYMENT_NAME.
  • Pour l’authentification anonyme : OPENAPI_CONNECTION_ID, référençant la connexion de projet OpenAPI anonyme et TOOLBOX_CONNECTION_ID, référençant la connexion MCP de toolbox.
  • Pour l’authentification par clé API : OPENAPI_CONNECTION_ID, faisant référence à la connexion de clé API TripAdvisor, et tripadvisor_openapi.json.
  • Pour l’authentification d’identité managée du projet : OPENAPI_CONNECTION_ID, comme indiqué dans l’exemple d’identité managée du projet.
  • Spécification OpenAPI inline dans le corps de la requête.

Sortie attendue

{
  "id": "resp_abc123",
  "object": "response",
  "output": [
    {
      "type": "message",
      "content": [
        {
          "type": "output_text",
          "text": "The weather in Seattle, WA today is cloudy with a temperature of 52°F (11°C)..."
        }
      ]
    }
  ]
}

Erreurs courantes

  • 401 Unauthorized: non valide ou manquant AGENT_TOKEN, ou clé API non injectée car securitySchemes et security sont manquants dans votre spécification OpenAPI
  • 404 Not Found: nom de modèle ou de point de terminaison incorrect pour le déploiement
  • 400 Bad Request: Spécification OpenAPI incorrecte ou configuration d’authentification non valide
  • Clé API non envoyée avec demande : vérifiez que la components.securitySchemes section de votre spécification OpenAPI est correctement configurée (pas vide) et correspond au nom de la clé de connexion de votre projet.

Créer un agent avec des fonctionnalités d’outil OpenAPI

L’exemple de code TypeScript suivant montre comment créer un agent IA avec des fonctionnalités d’outil OpenAPI en ajoutant l’outil OpenAPI à une boîte à outils et en attachant la boîte à outils en tant qu’outil MCP. L’agent peut appeler des API externes définies par les spécifications OpenAPI. Pour obtenir une version JavaScript de cet exemple, consultez l'sample dans le Kit de développement logiciel (SDK) Azure pour le référentiel JavaScript sur GitHub.

import { DefaultAzureCredential } from "@azure/identity";
import {
  AIProjectClient,
  OpenApiToolboxTool,
  OpenApiFunctionDefinition,
  OpenApiProjectConnectionAuthDetails,
} from "@azure/ai-projects";
import * as fs from "fs";
import * as path from "path";

function requiredEnv(name: string): string {
  const value = process.env[name];
  if (!value) {
    throw new Error(`Set ${name} before running.`);
  }
  return value;
}
const PROJECT_ENDPOINT = requiredEnv("FOUNDRY_PROJECT_ENDPOINT");
const deploymentName = requiredEnv("FOUNDRY_MODEL_DEPLOYMENT_NAME");
const weatherSpecPath = path.resolve("assets", "weather_openapi.json");

function loadOpenApiSpec(specPath: string): unknown {
  if (!fs.existsSync(specPath)) {
    throw new Error(`OpenAPI specification not found at: ${specPath}`);
  }

  try {
    const data = fs.readFileSync(specPath, "utf-8");
    return JSON.parse(data);
  } catch (error) {
    throw new Error(`Failed to read or parse OpenAPI specification at ${specPath}: ${error}`);
  }
}

function createWeatherTool(spec: unknown): OpenApiToolboxTool {
  const connectionId = process.env.OPENAPI_CONNECTION_ID;
  if (!connectionId) {
    throw new Error("Set OPENAPI_CONNECTION_ID before running.");
  }
  const auth: OpenApiProjectConnectionAuthDetails = {
    type: "project_connection",
    security_scheme: {
      project_connection_id: connectionId,
    },
  };
  const definition: OpenApiFunctionDefinition = {
    name: "get_weather",
    description: "Retrieve weather information for a location using wttr.in",
    spec,
    auth,
  };

  return {
    type: "openapi",
    openapi: definition,
  };
}

export async function main(): Promise<void> {
  const weatherSpec = loadOpenApiSpec(weatherSpecPath);

  // Create clients to call Foundry API
  const project = new AIProjectClient(PROJECT_ENDPOINT, new DefaultAzureCredential());
  const openai = project.getOpenAIClient();

  const weatherTool = createWeatherTool(weatherSpec);

  console.log("Creating a toolbox with the OpenAPI weather tool...");

  // 1. Add the OpenAPI tool to a toolbox. Using a toolbox is the recommended
  //    way to give agents tools. See /azure/foundry/agents/concepts/toolbox-overview
  const toolbox = await project.toolboxes.createVersion(
    "openapi-toolbox",
    [weatherTool],
    { description: "Toolbox with the OpenAPI weather tool" },
  );

  // 2. The toolbox exposes an MCP-compatible endpoint.
  const toolboxMcpUrl =
    `${PROJECT_ENDPOINT}/toolboxes/${toolbox.name}` +
    `/versions/${toolbox.version}/mcp?api-version=v1`;

  // 3. Create a remote-tool project connection that points at the toolbox endpoint.
  //    Use a user Entra token so the caller's identity is passed through
  //    (audience https://ai.azure.com). Create the connection once, for example
  //    with the Azure Developer CLI:
  //
  //    azd ai connection create openapi-toolbox-conn \
  //      --kind remote-tool \
  //      --target "<toolboxMcpUrl>" \
  //      --auth-type user-entra-token \
  //      --audience https://ai.azure.com
  const toolboxConnectionId = process.env.TOOLBOX_CONNECTION_ID;
  if (!toolboxConnectionId) {
    throw new Error("Set TOOLBOX_CONNECTION_ID to the toolbox connection ID.");
  }

  // 4. Attach the toolbox to a prompt agent as an MCP tool.
  const agent = await project.agents.createVersion("MyOpenApiAgent", {
    kind: "prompt",
    model: deploymentName,
    instructions:
      "You are a helpful assistant that can call external APIs defined by OpenAPI specs to answer user questions.",
    tools: [
      {
        type: "mcp",
        server_label: "toolbox",
        server_url: toolboxMcpUrl,
        require_approval: "never",
        project_connection_id: toolboxConnectionId,
        headers: {
          "Foundry-Features": "Toolboxes=V1Preview",
        },
      },
    ],
  });

  // Send a request and stream the response
  const streamResponse = await openai.responses.create(
    {
      input:
        "What's the weather in Seattle and how should I plan my outfit for the day based on the forecast?",
      stream: true,
    },
    {
      body: {
        agent_reference: { name: agent.name, type: "agent_reference" },
        tool_choice: "required",
      },
    },
  );

  // Process the streaming response
  for await (const event of streamResponse) {
    if (event.type === "response.output_text.delta") {
      process.stdout.write(event.delta);
    } else if (event.type === "response.output_text.done") {
      console.log("\n");
    }
  }

  // Clean up resources
  await project.agents.deleteVersion(agent.name, agent.version);
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
  process.exitCode = 1;
});

Ce que fait ce code

Cet exemple TypeScript crée un agent avec un outil OpenAPI pour les données météorologiques à l’aide de l’authentification anonyme. Lorsque vous exécutez le code :

  1. Il charge la spécification OpenAPI météorologique à partir d’un fichier JSON local.
  2. Crée une version de boîte à outils contenant l’outil météo.
  3. Associe la boîte à outils à l’agent en tant qu’outil MCP, puis envoie une requête en streaming sur la météo à Seattle et la tenue à prévoir.
  4. Traite la réponse en flux et affiche les deltas au fur et à mesure de leur arrivée.
  5. Il impose l'utilisation de l'outil en utilisant tool_choice: "required" pour garantir que l'API est appelée.
  6. Nettoie en supprimant de l’agent.

Entrées requises

  • Variables d’environnement : FOUNDRY_PROJECT_ENDPOINT, FOUNDRY_MODEL_DEPLOYMENT_NAME, OPENAPI_CONNECTION_ID et TOOLBOX_CONNECTION_ID.
  • Fichier local : assets/weather_openapi.json (spécification OpenAPI).

Sortie attendue

Creating a toolbox with the OpenAPI weather tool...
The weather in Seattle is <conditions>. Consider wearing <suggestion>.

Erreurs courantes

  • Error: OpenAPI specification not found: chemin d’accès du fichier incorrect ou fichier manquant
  • AuthenticationError : informations d’identification de Azure non valides
  • Clé API non fonctionnelle : si vous passez de l’authentification anonyme à l’authentification par clé API, vérifiez que votre spécification OpenAPI a securitySchemes et security correctement configurés

Créer un agent qui utilise des outils OpenAPI authentifiés avec une connexion de projet

L’exemple de code TypeScript suivant montre comment créer un agent IA qui utilise des outils OpenAPI authentifiés via une connexion de projet. L’agent charge la spécification Trip Advisor OpenAPI à partir de ressources locales et peut appeler l’API via la connexion de projet configurée. Pour obtenir une version JavaScript de cet exemple, consultez l'sample dans le Kit de développement logiciel (SDK) Azure pour le référentiel JavaScript sur GitHub.

import { DefaultAzureCredential } from "@azure/identity";
import {
  AIProjectClient,
  OpenApiTool,
  OpenApiFunctionDefinition,
  OpenApiProjectConnectionAuthDetails,
} from "@azure/ai-projects";
import * as fs from "fs";
import * as path from "path";

function requiredEnv(name: string): string {
  const value = process.env[name];
  if (!value) {
    throw new Error(`Set ${name} before running.`);
  }
  return value;
}
const PROJECT_ENDPOINT = requiredEnv("FOUNDRY_PROJECT_ENDPOINT");
const deploymentName = requiredEnv("FOUNDRY_MODEL_DEPLOYMENT_NAME");
const connectionId = requiredEnv("OPENAPI_CONNECTION_ID");
const tripAdvisorSpecPath = path.resolve("assets", "tripadvisor_openapi.json");

function loadOpenApiSpec(specPath: string): unknown {
  if (!fs.existsSync(specPath)) {
    throw new Error(`OpenAPI specification not found at: ${specPath}`);
  }

  try {
    const data = fs.readFileSync(specPath, "utf-8");
    return JSON.parse(data);
  } catch (error) {
    throw new Error(`Failed to read or parse OpenAPI specification at ${specPath}: ${error}`);
  }
}

function createTripAdvisorTool(spec: unknown): OpenApiTool {
  const auth: OpenApiProjectConnectionAuthDetails = {
    type: "project_connection",
    security_scheme: {
      project_connection_id: connectionId,
    },
  };

  const definition: OpenApiFunctionDefinition = {
    name: "get_tripadvisor_location_details",
    description:
      "Fetch TripAdvisor location details, reviews, or photos using the Content API via project connection auth.",
    spec,
    auth,
  };

  return {
    type: "openapi",
    openapi: definition,
  };
}

export async function main(): Promise<void> {
  const tripAdvisorSpec = loadOpenApiSpec(tripAdvisorSpecPath);

  // Create clients to call Foundry API
  const project = new AIProjectClient(PROJECT_ENDPOINT, new DefaultAzureCredential());
  const openai = project.getOpenAIClient();

  // Create an agent with the OpenAPI project-connection tool
  const agent = await project.agents.createVersion("MyOpenApiConnectionAgent", {
    kind: "prompt",
    model: deploymentName,
    instructions:
      "You are a travel assistant that consults the TripAdvisor Content API via project connection to answer user questions about locations.",
    tools: [createTripAdvisorTool(tripAdvisorSpec)],
  });

  // Send a request and stream the response
  const streamResponse = await openai.responses.create(
    {
      input:
        "Provide a quick overview of the TripAdvisor location 293919 including its name, rating, and review count.",
      stream: true,
    },
    {
      body: {
        agent_reference: { name: agent.name, type: "agent_reference" },
        tool_choice: "required",
      },
    },
  );

  // Process the streaming response
  for await (const event of streamResponse) {
    if (event.type === "response.output_text.delta") {
      process.stdout.write(event.delta);
    } else if (event.type === "response.output_text.done") {
      console.log("\n");
    }
  }

  // Clean up resources
  await project.agents.deleteVersion(agent.name, agent.version);
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
  process.exitCode = 1;
});

Ce que fait ce code

Cet exemple TypeScript illustre l’utilisation d’un outil OpenAPI avec l’authentification par clé API via une connexion de projet. Lorsque vous exécutez le code :

  1. Il charge la spécification TripAdvisor OpenAPI à partir d’un fichier local.
  2. Il fait référence à la connexion de clé API en utilisant OPENAPI_CONNECTION_ID.
  3. Il crée un agent avec l’outil TripAdvisor qui utilise la connexion de projet pour l’authentification par API clé.
  4. Il envoie une demande de streaming pour les détails de l’emplacement TripAdvisor.
  5. Il impose l'utilisation de l'outil en utilisant tool_choice: "required" pour garantir que l'API est appelée.
  6. Il traite et affiche la réponse de diffusion en continu.
  7. Il effectue un nettoyage en supprimant l’agent.

Entrées requises

  • Variables d’environnement : FOUNDRY_PROJECT_ENDPOINT, FOUNDRY_MODEL_DEPLOYMENT_NAMEet OPENAPI_CONNECTION_ID.
  • Fichier local : ../assets/tripadvisor_openapi.json
  • Connexion du projet configurée avec la clé API TripAdvisor

Sortie attendue

Location 293919: <name>, rating: <rating>, review count: <count>.

Erreurs courantes

  • Error: OpenAPI specification not found: vérifiez le chemin du fichier.
  • Connexion introuvable : vérifiez que OPENAPI_CONNECTION_ID est l’identifiant de ressource complet de la connexion de clé API.
  • AuthenticationException: clé API non valide dans la connexion de projet.
  • Clé API non injectée dans les requêtes : votre spécification OpenAPI doit inclure correctement les sections sous securitySchemes, components, et security. Le nom de clé dans securitySchemes doit correspondre à la clé dans votre connexion de projet.
  • Content type is not supported: Actuellement, seuls ces deux types de contenu de corps de requête sont pris en charge : application/json et application/json-patch+json. Les types de contenu de réponse ne sont pas limités.

Considérations relatives à la sécurité et aux données

Lorsque vous connectez un agent à un outil OpenAPI, l’agent peut envoyer des paramètres de requête dérivés de l’entrée utilisateur à l’API cible.

  • Utilisez des connexions de projet pour les secrets (clés API et jetons). Évitez de placer des secrets dans un fichier de spécification OpenAPI ou du code source.
  • Passez en revue les données reçues par l’API et ce qu’elle retourne avant d’utiliser l’outil en production.
  • Utilisez l’accès avec des privilèges minimum. Attribuez à l’identité managée du projet uniquement les rôles dont le service cible a besoin.

Avant d'ajouter un outil OpenAPI, examinez la spécification OpenAPI, notamment les descriptions de l'API, des opérations et des paramètres, ainsi que les opérations qu'elle expose. Ces informations peuvent être incluses dans le contexte envoyé au modèle et influencer la façon dont votre agent sélectionne des outils et construit des demandes.

Traitez les descriptions fournies par le fournisseur comme des données d’entrée non fiables. Connectez-vous uniquement aux fournisseurs d’API approuvés, passez en revue les modifications de spécification et appliquez les autorisations et les exigences d’approbation indépendamment des décisions générées par le modèle.

S’authentifier avec la clé API

Utilisez cette variante pour une API qui attend une clé dans un paramètre d’en-tête ou de requête. Vous ne pouvez utiliser qu’un seul schéma de sécurité de clé API par outil OpenAPI. Si l’API nécessite plusieurs schémas de sécurité, créez plusieurs outils OpenAPI.

  1. Mettez à jour vos schémas de sécurité de spécification OpenAPI. Il a une securitySchemes section et un schéma de type apiKey. Par exemple :

     "securitySchemes": {
         "apiKeyHeader": {
                 "type": "apiKey",
                 "name": "x-api-key",
                 "in": "header"
             }
     }
    

    Vous devez généralement mettre à jour le champ name, qui correspond au nom de key dans la connexion. Si les schémas de sécurité incluent plusieurs schémas, ne conservez qu’un seul d’entre eux.

  2. Mettez à jour votre spécification OpenAPI pour inclure une security section :

    "security": [
         {  
         "apiKeyHeader": []  
         }  
     ]
    
  3. Supprimez n’importe quel paramètre dans la spécification OpenAPI nécessitant une clé API, car la clé API est stockée et transmise via une connexion, comme décrit plus loin dans cet article.

  4. Créez une connexion pour stocker votre clé API.

  5. Accédez au portail Foundry et ouvrez votre projet.

  6. Créez ou sélectionnez une connexion qui stocke le secret. Consultez Ajouter une nouvelle connexion à votre projet.

    Note

    Si vous régénérez la clé API à une date ultérieure, vous devez mettre à jour la connexion avec la nouvelle clé.

  7. Entrez les informations suivantes

    • clé : name champ de votre schéma de sécurité. Dans cet exemple, il doit être x-api-key

             "securitySchemes": {
                "apiKeyHeader": {
                          "type": "apiKey",
                          "name": "x-api-key",
                          "in": "header"
                      }
              }
      
    • valeur : YOUR_API_KEY

  8. Après avoir créé une connexion, vous pouvez l’utiliser via le Kit de développement logiciel (SDK) ou l’API REST. Utilisez les onglets en haut de cet article pour afficher des exemples de code.

Configurer une connexion de jeton porteur

Utilisez cette variante pour une API qui attend un jeton de porteur dans l’en-tête Authorization. Il utilise le même project_connection type d’authentification que l’authentification par clé API, mais le schéma de sécurité OpenAPI et les valeurs de connexion diffèrent.

Votre spécification OpenAPI se présente comme suit :

  BearerAuth:
    type: http
    scheme: bearer
    bearerFormat: JWT

Vous devez :

  1. Mettez à jour votre spécification securitySchemes OpenAPI pour l’utiliser Authorization comme nom d’en-tête :

    "securitySchemes": {
        "bearerAuth": {
            "type": "apiKey",
            "name": "Authorization",
            "in": "header"
        }
    }
    
  2. Ajoutez une security section qui référence le schéma :

    "security": [
        {
            "bearerAuth": []
        }
    ]
    
  3. Créez une connexion de clés personnalisées dans votre projet Foundry :

    1. Accédez au portail Foundry et ouvrez votre projet.
    2. Créez ou sélectionnez une connexion qui stocke le secret. Consultez Ajouter une nouvelle connexion à votre projet.
    3. Entrez les valeurs suivantes :
      • clé : Authorization (doit correspondre au name champ dans votre securitySchemes)
      • valeur : Bearer <token> (remplacez <token> par votre jeton réel)

    Important

La valeur doit inclure le mot Bearer suivi d’un espace avant le jeton. Par exemple : Bearer eyJhbGciOiJSUzI1NiIs.... Si vous omettez le préfixe et l’espace Bearer suivant, l’API reçoit un jeton brut sans le préfixe de schéma d’autorisation requis et la requête échoue.

  1. Après avoir créé la connexion, utilisez-la avec le project_connection type d’authentification dans votre code, de la même façon que pour l’authentification par clé API. L’ID de connexion utilise le même format : /subscriptions/{{subscriptionID}}/resourceGroups/{{resourceGroupName}}/providers/Microsoft.CognitiveServices/accounts/{{foundryAccountName}}/projects/{{foundryProjectName}}/connections/{{foundryConnectionName}}.

S’authentifier à l’aide de l’identité managée (Microsoft Entra ID)

Microsoft Entra ID est un service de gestion des identités et des accès cloud que vos employés peuvent utiliser pour accéder aux ressources externes. En utilisant Microsoft Entra ID, vous pouvez ajouter une sécurité supplémentaire à vos API sans avoir à utiliser de clés API. Lorsque vous configurez l’authentification d’identité managée, l’agent s’authentifie via l’outil Foundry qu’il utilise.

Important

L’authentification d’identité managée fonctionne uniquement lorsque le service cible accepte des jetons Microsoft Entra ID. Si l'API cible utilise un schéma d'authentification personnalisé qui ne prend pas en charge Microsoft Entra ID, utilisez l'authentification par clé API ou token Bearer à la place.

Prise en charge des identités managées

Pour l’authentification par identité managée, les outils OpenAPI dans les boîtes à outils ont toujours requis l’identité managée du projet Foundry. Cette exigence s’applique à tous les abonnements.

Pour les outils OpenAPI associés directement aux agents de prompt, les nouveaux abonnements aux outils OpenAPI doivent utiliser l'identité managée du projet. Les abonnements existants prennent en charge les deux identités sur ce chemin, mais l'identité managée du projet est recommandée. Migrez les configurations existantes d'identité managée du compte dès que possible.

Chemin de l’outil OpenAPI Abonnement Identité gérée prise en charge
Outil associé via une boîte à outils. Tous les abonnements. Uniquement l'identité managée du projet Foundry, depuis l'introduction des boîtes à outils. L'identité managée de compte n'est pas prise en charge.
Outil associé directement à un agent de prompt. Nouvel abonnement aux outils OpenAPI. Identité managée du projet Foundry uniquement. L'identité managée de compte n'est pas prise en charge.
Outil associé directement à un agent de prompt. Un abonnement existant qui a déjà utilisé les outils OpenAPI. L'identité managée du compte Foundry et celle du projet Foundry. L'identité managée de projet est recommandée ; migrez à partir de l'identité managée de compte dès que possible.

Attribuez à l’identité managée du projet le rôle le moins privilégié qui autorise les opérations d’API requises sur le service cible.

Les deux identités utilisent différentes configurations d’authentification :

  • L'identité managée de projet nécessite une connexion OpenAPI dans le projet Foundry avec authType: "ProjectManagedIdentity". Transmettez l’ID de ressource ARM complet de cette connexion dans auth.security_scheme.project_connection_id, avec auth.type: "project_connection".
  • L'identité managée attribuée au compte, prise en charge uniquement pour les outils associés directement aux agents de prompt dans les abonnements existants, utilise auth.type: "managed_identity" et transmet directement le audience du service cible dans la définition de l'outil. Cette configuration n’est pas prise en charge dans les toolboxes, ne sélectionne pas l’identité managée du projet et n’est pas l’option Managed identity du portail.

Migrer d'une identité managée de compte vers une identité managée de projet

Ces étapes de migration s'appliquent aux outils OpenAPI associés directement à des agents de prompt dans des abonnements existants. Les boîtes à outils nécessitent déjà une identité managée de projet. Utilisez l'identité managée du projet pour les nouvelles configurations et migrez les configurations d'identité managée du compte prompt-agent existantes dès que possible :

  1. Affectez à l’identité managée du projet Foundry le rôle le moins privilégié requis sur le service cible. Une attribution de rôle d’identité managée de compte ne s’applique pas à l’identité du projet.
  2. Créez une connexion de projet OpenAPI avec authType: "ProjectManagedIdentity", le point de terminaison cible et le public attendu par l’API cible.
  3. Remplacez la configuration de l’audience directe managed_identity de l’outil par auth.type: "project_connection". Transmettez l’ID de ressource ARM complet de la connexion dans auth.security_scheme.project_connection_id.
  4. Appelez l’outil pour vérifier que l’identité managée du projet peut accéder à l’API cible.
  5. Supprimez l’attribution de rôle de service cible de l’identité de compte uniquement après avoir confirmé qu’aucune autre charge de travail n’en a besoin.

Comprendre l’URI de l’audience

L’identificateur audience (parfois appelé identificateur resource ou URI d’ID d’application) indique Microsoft Entra ID quel service ou API le jeton est destiné à accéder. La valeur d’audience doit correspondre à ce que le service cible attend, ou l’authentification échoue avec une erreur 401.

Note

L’audience n’est pas le point de terminaison de votre projet Foundry. Il s’agit de l’identificateur de ressource du service cible que votre outil OpenAPI appelle.

Le tableau suivant répertorie les URI d’audience pour les services Azure courants :

Service cible URI d’audience
stockage Azure https://storage.azure.com
Azure Key Vault https://vault.azure.net
Recherche Azure AI https://search.azure.com
Azure Traducteur https://cognitiveservices.azure.com
Azure Logic Apps Audience configurée pour l'autorisation Microsoft Entra ID du flux de travail. Consultez Accès sécurisé aux applications logiques.
Gestion des API Azure (plan de gestion) https://management.azure.com
API protégée par une inscription d’application Microsoft Entra (y compris APIM avec OAuth) URI d'ID d'application de l'enregistrement de votre application (par exemple, api://<client-id>)

Conseil

Si vous utilisez Gestion des API Azure pour protéger une API personnalisée avec une stratégie de validation OAuth 2.0, l’audience est l’URI de l’ID d’application de l’inscription d’application qui protège l’API , et non https://management.azure.com. L’audience du plan de gestion s’applique uniquement aux opérations de Azure Resource Manager sur la ressource APIM elle-même.

Pour plus d’informations sur la façon dont les agents s’authentifient avec Microsoft Entra ID, consultez Identité et authentificationagent.

Rechercher et vérifier votre audience

Procédez comme suit pour déterminer et vérifier la valeur d’audience correcte :

  • For Azure services : consultez la documentation du service pour connaître son identificateur de ressource Microsoft Entra ID. La plupart des services Azure répertorient l’URI d’audience dans leur documentation d’authentification.
  • Pour les API protégées par une inscription d'application Microsoft Entra : dans le portail Azure, accédez à Microsoft Entra ID>inscriptions d'applications> sélectionnez votre application >Exposer une API. L’URI d’ID d’application en haut de la page correspond à votre valeur d’audience.
  • Pour vérifier le public cible d’un jeton : décoder le jeton d’accès et https://jwt.ms vérifier l’aud affirmation. La aud valeur doit correspondre à l’audience attendue par votre service cible.

Configurer l’authentification d’identité managée

Pour configurer l’authentification d’identité managée du projet :

  1. Utilisez l’identité managée du projet Foundry pour les nouvelles configurations. Assurez-vous que l’identité managée du projet est activée. L'identité managée du compte est une option héritée uniquement pour les outils associés directement aux agents de prompt dans les abonnements existants ; migrez ces configurations dès que possible.
  2. Créez ou identifiez le service cible que votre outil OpenAPI appelle.
  3. Attribuez l’accès requis à l’identité managée du projet Foundry sur la ressource cible.
    1. Sélectionnez Access Control pour votre ressource.

    2. Sélectionnez Ajouter , puis ajoutez une attribution de rôle en haut de l’écran.

      Capture d’écran du portail Azure montrant l’action Ajouter une attribution de rôle.

    3. Sélectionnez le rôle de plan de données ou d’application le moins privilégié qui accorde les opérations dans votre spécification OpenAPI. Le seul accès Reader à Azure Resource Manager ne confère pas d’accès au plan de données. Ensuite, sélectionnez Suivant.

    4. Sélectionnez Identité managée , puis sélectionnez membres.

    5. Sélectionnez l’identité managée du projet Foundry.

    6. Sélectionnez Terminer.

  4. Créez une connexion à une identité managée de projet et transmettez son ID de ressource complet dans la définition de l'outil.

Créer une connexion d'identité managée par un projet

Créez la connexion dans le même projet Foundry, de sorte qu'elle envoie la requête Réponses. La connexion stocke le point de terminaison cible et l’audience, pas une clé API ni un jeton d’accès.

L’exemple Bash suivant utilise Azure CLI et curl pour créer une connexion OpenAPI pour Azure Translator dans Foundry Tools. Connectez-vous d'abord avec az login. Remplacez les placeholders par votre abonnement, votre groupe de ressources, votre compte Foundry, votre projet et votre ressource Translator.

SUB="<subscription-id>"
RESOURCE_GROUP="<resource-group>"
ACCOUNT="<foundry-account-name>"
PROJECT_NAME="<foundry-project-name>"
CONNECTION_NAME="translator-project-mi"
TRANSLATOR_ENDPOINT="https://<translator-resource>.cognitiveservices.azure.com"

PROJECT="/subscriptions/$SUB/resourceGroups/$RESOURCE_GROUP"
PROJECT="$PROJECT/providers/Microsoft.CognitiveServices"
PROJECT="$PROJECT/accounts/$ACCOUNT/projects/$PROJECT_NAME"
export OPENAPI_CONNECTION_ID="$PROJECT/connections/$CONNECTION_NAME"

ARM_TOKEN="$(az account get-access-token \
  --subscription "$SUB" \
  --resource https://management.azure.com \
  --query accessToken -o tsv)"

curl --fail-with-body --request PUT \
  --url "https://management.azure.com$OPENAPI_CONNECTION_ID?api-version=2025-06-01" \
  --header "Authorization: Bearer $ARM_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "properties": {
      "category": "OpenAPI",
      "authType": "ProjectManagedIdentity",
      "target": "'"$TRANSLATOR_ENDPOINT"'/",
      "audience": "https://cognitiveservices.azure.com",
      "metadata": {
        "type": "openapi"
      }
    }
  }'

Référence : Schéma de ressource de connexion de projet Foundry.

Conservez OPENAPI_CONNECTION_ID pour les exemples de langue. Utilisez l’ID de ressource de connexion complet, pas seulement le nom de la connexion. L'audience appartient à la connexion ; ne transmettez pas une audience d'identité managée par compte à la place de l'identifiant de connexion.

Appeler un outil OpenAPI avec l’identité managée du projet

Ces exemples appellent Azure Translator via la connexion que vous avez créée. Ils envoient une spécification OpenAPI inline dans une remote_tool charge utile au point de terminaison Réponses.

Avant d’exécuter un exemple :

  • Attribuez à l’identité managée du projet le rôle de service cible requis pour la traduction.
  • Créez la connexion OpenAPI avec authType: "ProjectManagedIdentity" comme décrit dans Créer une connexion d'identité managée du projet.
  • Définir FOUNDRY_PROJECT_ENDPOINT, FOUNDRY_MODEL_DEPLOYMENT_NAMEet OPENAPI_CONNECTION_ID. La connexion doit appartenir à ce projet.
  • Enregistrez la spécification suivante sous le nom translator_openapi.json dans le répertoire dans lequel vous exécutez l’exemple. Remplacez <translator-resource> par la ressource utilisée dans le target de la connexion.
{
  "openapi": "3.0.1",
  "info": {
    "title": "Azure Translator Service",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://<translator-resource>.cognitiveservices.azure.com/translator/text/v3.0/"
    }
  ],
  "paths": {
    "/translate": {
      "post": {
        "operationId": "Translator_Translate",
        "description": "Translate text into one or more languages.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "default": "3.0" }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "text": { "type": "string" }
                  },
                  "required": ["text"]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Translation response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "translations": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "text": { "type": "string" },
                            "to": { "type": "string" }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Référence : Opération de traduction de Translator.

L'appelant s'authentifie auprès de Foundry avec des informations d'identification Azure Identity. Foundry résout l’authentification pour Translator à partir de la connexion de projet et utilise l’identité managée du projet.

Installez les dépendances avec pip install openai azure-identity.

import json
import os

from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from openai import OpenAI


def main() -> None:
    with open("translator_openapi.json", encoding="utf-8") as spec_file:
        spec = json.load(spec_file)

    tool = {
        "type": "remote_tool",
        "tool_arguments": [
            {
                "name": "openapi",
                "arguments": {
                    "name": "language",
                    "description": "Azure Translator API for text translation.",
                    "default_params": ["api-version"],
                    "auth": {
                        "type": "project_connection",
                        "security_scheme": {
                            "project_connection_id": os.environ[
                                "OPENAPI_CONNECTION_ID"
                            ],
                        },
                    },
                    "spec": spec,
                },
            }
        ],
    }

    with DefaultAzureCredential() as credential:
        token_provider = get_bearer_token_provider(
            credential, "https://ai.azure.com/.default"
        )
        with OpenAI(
            base_url=(
                os.environ["FOUNDRY_PROJECT_ENDPOINT"].rstrip("/")
                + "/openai/v1/"
            ),
            api_key=token_provider,
        ) as client:
            response = client.responses.create(
                model=os.environ["FOUNDRY_MODEL_DEPLOYMENT_NAME"],
                input="Translate 'Hello, how are you?' to Spanish.",
                extra_body={
                    "tools": [tool],
                    "tool_choice": "required",
                },
            )
            print(response.output_text)


if __name__ == "__main__":
    main()

Référence : Fournisseur de jetons Azure Identity.

L’argument extra_body transmet la charge utile spécifique au service remote_tool sans nécessiter de modèle d’outil OpenAPI typé dans le Kit de développement logiciel (SDK) OpenAI.

Utilisez .NET 8 ou version ultérieure et installez la bibliothèque d'informations d'identification avec dotnet add package Azure.Identity. Cet exemple envoie la charge utile de l’outil spécifique au service avec HttpClient.

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using Azure.Core;
using Azure.Identity;

static string RequiredEnvironmentVariable(string name) =>
    Environment.GetEnvironmentVariable(name)
    ?? throw new InvalidOperationException($"Set {name} before running.");

string endpoint = RequiredEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT");
string model = RequiredEnvironmentVariable("FOUNDRY_MODEL_DEPLOYMENT_NAME");
string connectionId = RequiredEnvironmentVariable("OPENAPI_CONNECTION_ID");
JsonElement spec = JsonSerializer.Deserialize<JsonElement>(
    File.ReadAllText("translator_openapi.json"));

var tool = new
{
    type = "remote_tool",
    tool_arguments = new[]
    {
        new
        {
            name = "openapi",
            arguments = new
            {
                name = "language",
                description = "Azure Translator API for text translation.",
                default_params = new[] { "api-version" },
                auth = new
                {
                    type = "project_connection",
                    security_scheme = new
                    {
                        project_connection_id = connectionId
                    }
                },
                spec
            }
        }
    }
};

var credential = new DefaultAzureCredential();
AccessToken token = await credential.GetTokenAsync(
    new TokenRequestContext(new[] { "https://ai.azure.com/.default" }));
using var client = new HttpClient();
using var request = new HttpRequestMessage(
    HttpMethod.Post, $"{endpoint.TrimEnd('/')}/openai/v1/responses");
request.Headers.Authorization =
    new AuthenticationHeaderValue("Bearer", token.Token);
request.Content = JsonContent.Create(new
{
    model,
    input = "Translate 'Hello, how are you?' to Spanish.",
    tools = new[] { tool },
    tool_choice = "required"
});
using HttpResponseMessage response = await client.SendAsync(request);
string responseBody = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
    throw new HttpRequestException(
        $"HTTP {(int)response.StatusCode}: {responseBody}");
}
Console.WriteLine(responseBody);

Référence : DefaultAzureCredential, HttpClient.

Utilisez Node.js 20 ou version ultérieure et installez la bibliothèque d'identifiants avec npm install @azure/identity. Enregistrez cet exemple JavaScript en tant que openapi-project-mi.mjs.

import { readFile } from "node:fs/promises";
import { DefaultAzureCredential } from "@azure/identity";

function requiredEnvironmentVariable(name) {
  const value = process.env[name];
  if (!value) {
    throw new Error(`Set ${name} before running.`);
  }
  return value;
}

const endpoint = requiredEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT");
const model = requiredEnvironmentVariable("FOUNDRY_MODEL_DEPLOYMENT_NAME");
const connectionId = requiredEnvironmentVariable("OPENAPI_CONNECTION_ID");
const spec = JSON.parse(
  await readFile("translator_openapi.json", "utf8"),
);

const tool = {
  type: "remote_tool",
  tool_arguments: [
    {
      name: "openapi",
      arguments: {
        name: "language",
        description: "Azure Translator API for text translation.",
        default_params: ["api-version"],
        auth: {
          type: "project_connection",
          security_scheme: {
            project_connection_id: connectionId,
          },
        },
        spec,
      },
    },
  ],
};

const credential = new DefaultAzureCredential();
const token = await credential.getToken("https://ai.azure.com/.default");
const response = await fetch(
  `${endpoint.replace(/\/$/, "")}/openai/v1/responses`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token.token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model,
      input: "Translate 'Hello, how are you?' to Spanish.",
      tools: [tool],
      tool_choice: "required",
    }),
  },
);
const responseBody = await response.text();
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${responseBody}`);
}
console.log(responseBody);

Référence : DefaultAzureCredential.

Utilisez Java 11 ou version ultérieure. Ajoutez com.fasterxml.jackson.core:jackson-databind et com.azure:azure-identity à vos dépendances Maven. Cet exemple envoie la charge utile de l'outil spécifique au service avec le client HTTP de Java.

import com.azure.core.credential.AccessToken;
import com.azure.core.credential.TokenRequestContext;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class OpenApiProjectMi {
    private static String requiredEnvironmentVariable(String name) {
        String value = System.getenv(name);
        if (value == null || value.isBlank()) {
            throw new IllegalStateException("Set " + name + " before running.");
        }
        return value;
    }

    public static void main(String[] args) throws Exception {
        String endpoint = requiredEnvironmentVariable(
            "FOUNDRY_PROJECT_ENDPOINT");
        String model = requiredEnvironmentVariable(
            "FOUNDRY_MODEL_DEPLOYMENT_NAME");
        String connectionId = requiredEnvironmentVariable(
            "OPENAPI_CONNECTION_ID");
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> spec = mapper.readValue(
            new File("translator_openapi.json"),
            new TypeReference<Map<String, Object>>() { });

        Map<String, Object> tool = Map.of(
            "type", "remote_tool",
            "tool_arguments", List.of(Map.of(
                "name", "openapi",
                "arguments", Map.of(
                    "name", "language",
                    "description",
                        "Azure Translator API for text translation.",
                    "default_params", List.of("api-version"),
                    "auth", Map.of(
                        "type", "project_connection",
                        "security_scheme", Map.of(
                            "project_connection_id", connectionId)),
                    "spec", spec))));
        Map<String, Object> body = Map.of(
            "model", model,
            "input", "Translate 'Hello, how are you?' to Spanish.",
            "tools", List.of(tool),
            "tool_choice", "required");

        var credential = new DefaultAzureCredentialBuilder().build();
        AccessToken token = Objects.requireNonNull(credential.getToken(
            new TokenRequestContext()
                .addScopes("https://ai.azure.com/.default")).block());
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(endpoint.replaceAll("/$", "")
                + "/openai/v1/responses"))
            .header("Authorization", "Bearer " + token.getToken())
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(
                mapper.writeValueAsString(body)))
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient().send(
            request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() < 200 || response.statusCode() >= 300) {
            throw new IllegalStateException(
                "HTTP " + response.statusCode() + ": " + response.body());
        }
        System.out.println(response.body());
    }
}

Référence : DefaultAzureCredentialBuilder.

Utilisez Bash, Azure CLI, curl et jq pour générer la requête à partir de translator_openapi.json. Le jeton de l’appelant cible Foundry, pas Azure Resource Manager ni Translator.

AGENT_TOKEN="$(az account get-access-token \
  --resource https://ai.azure.com \
  --query accessToken -o tsv)"

jq -n \
  --arg model "$FOUNDRY_MODEL_DEPLOYMENT_NAME" \
  --arg connection_id "$OPENAPI_CONNECTION_ID" \
  --slurpfile spec translator_openapi.json \
  '{
    model: $model,
    input: "Translate '\''Hello, how are you?'\'' to Spanish.",
    tools: [
      {
        type: "remote_tool",
        tool_arguments: [
          {
            name: "openapi",
            arguments: {
              name: "language",
              description: "Azure Translator API for text translation.",
              default_params: ["api-version"],
              auth: {
                type: "project_connection",
                security_scheme: {
                  project_connection_id: $connection_id
                }
              },
              spec: $spec[0]
            }
          }
        ]
      }
    ],
    tool_choice: "required"
  }' > openapi-project-mi-request.json

curl --fail-with-body --request POST \
  --url "${FOUNDRY_PROJECT_ENDPOINT%/}/openai/v1/responses" \
  --header "Authorization: Bearer $AGENT_TOKEN" \
  --header "Content-Type: application/json" \
  --data @openapi-project-mi-request.json

Référence : Azure CLI jetons d’accès.

La réponse contient une traduction espagnole de « Hello, how are you? », l'exemple Python imprime le texte de la réponse. Les exemples HTTP impriment la réponse JSON complète, y compris la sortie de l’outil et le message d’assistant.

Résoudre les erreurs courantes

Symptôme Cause probable Résolution
La clé API n’est pas incluse dans les requêtes. Les sections securitySchemes ou security de la spécification OpenAPI sont manquantes. Vérifiez que votre spécification OpenAPI inclut à la fois components.securitySchemes et une section de niveau security supérieur. Vérifiez que le schéma name correspond au nom de clé dans la connexion de votre projet.
L’agent n’appelle pas l’outil OpenAPI. Le choix de l’outil n’est pas défini ou operationId non descriptif. Utilisez tool_choice="required" pour forcer l'appel de l'outil. Vérifiez que les operationId valeurs sont descriptives afin que le modèle puisse choisir l’opération appropriée.
L’authentification échoue pour l’identité managée du projet. L'identité managée du projet n'est pas activée, ou son attribution de rôle est manquante. Vérifiez que l’identité managée du projet Foundry est activée et dispose du rôle d’application ou de plan de données du service cible avec le minimum de privilèges pour les opérations de votre spécification OpenAPI.
L’identité managée du projet n’est pas utilisée. L’outil utilise la configuration d’audience directe managed_identity au lieu d’une connexion de projet. Créez une connexion OpenAPI avec authType: "ProjectManagedIdentity". Définissez le auth.type de l'outil sur project_connection et auth.security_scheme.project_connection_id sur l'ID complet de la ressource de connexion.
L’identité managée du projet retourne 401 même si le rôle est attribué. L’URI d’audience de la connexion ne correspond pas à ce que le service cible attend. Vérifiez l’URI d’audience dans la ProjectManagedIdentity connexion par rapport à la documentation du service cible. Pour les API protégées par Microsoft Entra ID, utilisez l’URI d’ID d’application de votre enregistrement d’application. Consultez Comprendre l’URI de l’audience.
Le jeton d’identité managée du projet a été rejeté par l’API cible. Le service cible n'accepte pas les jetons Microsoft Entra ID. Vérifiez que le service cible prend en charge l’authentification Microsoft Entra ID. Si ce n’est pas le cas, utilisez une clé API ou une autre méthode d’authentification prise en charge par le service cible.
La requête échoue avec le code 400 Requête Incorrecte. Les spécifications OpenAPI ne correspondent pas à l’API réelle. Validez votre spécification OpenAPI par rapport à l’API réelle. Vérifiez les noms, les types et les champs obligatoires des paramètres.
La demande échoue avec erreur 401 Non autorisée. Clé API ou jeton non valide ou expiré. Régénérez la clé/le jeton d’API et mettez à jour votre connexion de projet. Vérifiez que l’ID de connexion est correct.
L’outil retourne un format de réponse inattendu. Schéma de réponse non défini dans la spécification OpenAPI. Ajoutez des schémas de réponse à votre spécification OpenAPI pour une meilleure compréhension du modèle.
operationId erreur de validation. Caractères non valides dans operationId. Utilisez uniquement des lettres, - et _ dans operationId valeurs. Supprimez des nombres et des caractères spéciaux.
Erreur : Connexion introuvable L’ID de ressource de connexion est incorrect ou appartient à un autre projet. Vérifiez que OPENAPI_CONNECTION_ID est l’ID de ressource ARM complet de la connexion dans le projet Foundry qui envoie la requête.
Jeton porteur non envoyé correctement. Il manque à la valeur de connexion le préfixe Bearer et l’espace qui suit. Définissez la valeur Bearer <token> de connexion sur (avec le mot Bearer et un espace avant le jeton). Vérifiez que la spécification securitySchemes OpenAPI utilise "name": "Authorization".

Choisir une méthode d’authentification

Le tableau suivant vous aide à choisir la méthode d’authentification appropriée pour votre outil OpenAPI :

Méthode d’authentification Idéal pour Complexité de l’installation
Anonyme Des API publiques sans authentification. Nécessite une connexion de projet OpenAPI avec authType: "None". Faible
Clé API API non Microsoft avec accès basé sur des clés Moyen
Identité gérée (identité gérée du projet) Azure services et API protégées par Microsoft Entra ID. Nécessite une ProjectManagedIdentity connexion et le rôle de service cible requis attribué à l’identité managée du projet. Moyen-Haut