Héberger des agents Microsoft Agent Framework en tant qu’agents hébergés dans Foundry

Utilisez les packages d’hébergement Microsoft Agent Framework pour exposer un agent Agent Framework via les protocoles pour les agents hébergés Foundry. Les packages d’hébergement vous permettent de conserver la logique de votre agent dans le code tandis que Foundry gère le runtime hébergé, les sessions, la mise à l’échelle, l’identité et les points de terminaison de protocole.

Dans cet article, vous allez créer un agent Agent Framework minimal, l’exposer via le protocole Réponses ou Appels, le tester via HTTP et le déployer sur Foundry avec l’interface CLI de développeur Azure.

La compétence Microsoft Foundry peut aider à implémenter l’adaptateur, tester les protocoles et déployer avec azd.

Prerequisites

  • Un abonnement Azure. Créez-en un gratuitement.
  • Un projet Foundry.
  • Un modèle de conversation déployé, tel que gpt-4.1 ou gpt-4o.
  • Le rôle Gestionnaire de projet Foundry sur le projet pour déployer un agent hébergé. Pour plus d’informations, consultez Déployer un agent hébergé.
  • Azure CLI connecté (az login) afin que DefaultAzureCredential puisse s’authentifier.
  • Python 3.10 ou version ultérieure.
  • .NET 10 SDK ou version ultérieure.

Installer les packages

Installez Agent Framework et le package d’hébergement Foundry :

pip install -U agent-framework agent-framework-foundry-hosting azure-identity python-dotenv

Le agent_framework_foundry_hosting package fournit les serveurs hôtes pour les protocoles Foundry :

  • ResponsesHostServer pour l’endpoint compatible OpenAI /responses.
  • InvocationsHostServer pour le point de terminaison générique /invocations .

Ajoutez les packages d’hébergement Agent Framework et Foundry à votre projet :

dotnet add package Microsoft.Agents.AI
dotnet add package Microsoft.Agents.AI.Foundry.Hosting
dotnet add package Azure.AI.Projects
dotnet add package Azure.Identity

Pour le protocole Invocations, ajoutez également le package de serveur Invocations :

dotnet add package Azure.AI.AgentServer.Invocations

Ces packages fournissent les extensions d’hôte pour les protocoles Foundry :

  • AddFoundryResponses et MapFoundryResponses pour le point de terminaison /responses compatible avec OpenAI.
  • AddInvocationsServer et MapInvocationsServer pour le point de terminaison générique /invocations .

Choisir un protocole d’hébergement

Les agents hébergés peuvent exposer un ou plusieurs protocoles. Commencez par Responses pour la majorité des agents conversationnels.

Protocol Endpoint À utiliser lorsque
Responses /responses Vous souhaitez une conversation compatible OpenAI, la diffusion en continu, l’historique des réponses et le thread de conversation.
Appels /invocations Vous souhaitez une forme JSON personnalisée, un point de terminaison de style webhook ou un traitement non conversationnel.

Pour plus d’informations sur le comportement et les sessions de protocole, consultez Agents hébergés et Gérer les sessions d’agent hébergé.

Configurer des variables d’environnement

Définissez le point de terminaison du projet et le nom de déploiement de modèle pour le développement local :

export FOUNDRY_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
export AZURE_AI_MODEL_DEPLOYMENT_NAME="gpt-4.1"

Dans PowerShell :

$env:FOUNDRY_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
$env:AZURE_AI_MODEL_DEPLOYMENT_NAME="gpt-4.1"

Lorsque le même code s’exécute en tant qu’agent hébergé dans Foundry, la plateforme injecte FOUNDRY_PROJECT_ENDPOINT et AZURE_AI_MODEL_DEPLOYMENT_NAME au moment de l’exécution.

Protocole des réponses

Utilisez le protocole Responses lorsque vous souhaitez un point de terminaison de chat compatible OpenAI avec la diffusion en continu, l’historique des réponses et les fils de conversation.

Créer un hôte de réponses

Créez un fichier nommé main.py avec un agent Agent Framework minimal qui utilise un modèle Foundry.

import os

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

# Load environment variables from a .env file when present.
load_dotenv()


def main() -> None:
    client = FoundryChatClient(
        project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
        model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
        credential=DefaultAzureCredential(),
    )

    agent = Agent(
        client=client,
        instructions="You are a friendly assistant. Keep your answers brief.",
        # The hosting infrastructure manages conversation history, so the
        # service doesn't need to store it.
        default_options={"store": False},
    )

    server = ResponsesHostServer(agent)
    server.run()


if __name__ == "__main__":
    main()

Ce que fait cet extrait de code : Crée un agent Agent Framework soutenu par un modèle Foundry via FoundryChatClient, puis transmet l’agent à ResponsesHostServer. L’hôte démarre un serveur HTTP et expose l’agent via POST /responses. Par défaut, le serveur est lié au port 8088.

Référence : documentation de Microsoft Agent Framework

Exécutez l’application localement :

python main.py

Créez un Program.cs fichier avec un agent Agent Framework minimal qui utilise un modèle Foundry via le protocole Réponses.

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

var projectEndpoint = new Uri(
    Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set."));

var deployment =
    Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME")
    ?? "gpt-4o";

// Create the agent via the AI project client using the Responses API.
AIAgent agent = new AIProjectClient(projectEndpoint, new DefaultAzureCredential())
    .AsAIAgent(
        model: deployment,
        instructions: "You are a friendly assistant. Keep your answers brief.",
        name: "assistant",
        description: "A simple general-purpose AI assistant");

// Host the agent as a Foundry hosted agent using the Responses API.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddFoundryResponses(agent);

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

Ce que fait cet extrait de code : Crée un AIAgent à partir du client de projet Foundry, l’inscrit en tant qu’hôte Foundry Responses avec AddFoundryResponses, et associe le point de terminaison POST /responses avec MapFoundryResponses. Par défaut, l’hôte sert sur le port 8088.

Référence : AIProjectClient | DefaultAzureCredential

Exécutez l’application localement :

dotnet run

Testez le point de terminaison Responses

Envoyez une demande de réponses sans diffusion en continu au serveur local.

Bash:

curl -sS -H "Content-Type: application/json" \
  -X POST http://localhost:8088/responses \
  -d '{"input":"Give me one practical tip for testing hosted agents.","stream":false}'

PowerShell :

$body = @{
  input  = "Give me one practical tip for testing hosted agents."
  stream = $false
} | ConvertTo-Json

Invoke-RestMethod `
    -Uri http://localhost:8088/responses `
    -Method Post `
    -Body $body `
    -ContentType "application/json"

Le serveur répond avec un objet JSON qui contient le texte de réponse et un ID de réponse. Pour les réponses diffusées en continu, définissez stream sur true. L’hôte émet des événements envoyés par le serveur d’API Réponses, tels que response.created, response.output_text.deltaet response.completed.

Conversations à plusieurs tours

Pour poursuivre une conversation, transmettez l’ID de réponse précédent dans le previous_response_id champ de la requête suivante :

curl -sS -H "Content-Type: application/json" \
  -X POST http://localhost:8088/responses \
  -d '{"input":"Can you make that more concise?","previous_response_id":"<previous-response-id>","stream":false}'

Lorsque l'agent s'exécute dans Foundry, le même modèle fonctionne via le point de terminaison Responses de l'agent hébergé. Si les tours suivants nécessitent également le même système de fichiers du bac à sable hébergé, incluez agent_session_id ou utilisez un identifiant conversation. Pour plus d’informations, consultez Gérer les sessions d’agent hébergées.

Protocole d'invocation

Utilisez le protocole Invocations lorsque vos appelants ne peuvent pas utiliser la forme de requête de l’API Réponses ou lorsque votre scénario n’est pas une conversation de conversation. L’hôte Invocations gère l’état de session par le biais d’un paramètre de requête et d’un agent_session_id en-tête de réponse.

Créer un hôte d’invocation

Utilisez la même configuration de l’agent que l’exemple Réponses, mais démarrez InvocationsHostServer au lieu de ResponsesHostServer.

import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import InvocationsHostServer
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv

# Load environment variables from a .env file when present.
load_dotenv()


def main() -> None:
    client = FoundryChatClient(
        project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
        model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
        credential=DefaultAzureCredential(),
    )

    agent = Agent(
        client=client,
        instructions="You are a friendly assistant. Keep your answers brief.",
        default_options={"store": False},
    )

    server = InvocationsHostServer(agent)
    server.run()


if __name__ == "__main__":
    main()

Ce que fait cet extrait de code : Héberge l’agent Agent Framework via POST /invocations. L’hôte gère l’état par session via le paramètre de requête et l’en-tête agent_session_id de réponse.

Référence : documentation de Microsoft Agent Framework

Le protocole Invocations utilise un InvocationHandler processus que vous implémentez pour traiter chaque requête. Inscrivez le serveur d’appels et votre gestionnaire, puis mappez les points de terminaison.

using Azure.AI.AgentServer.Invocations;
using Microsoft.Agents.AI;

var builder = WebApplication.CreateBuilder(args);

// Register your agent and the Invocations server services.
builder.Services.AddInvocationsServer();
builder.Services.AddScoped<InvocationHandler, MyInvocationHandler>();

var app = builder.Build();

// Map the Invocations protocol endpoints:
//   POST /invocations              - invoke the agent
//   GET  /invocations/{id}         - get result
//   POST /invocations/{id}/cancel  - cancel
app.MapInvocationsServer();
app.Run();

Ce que fait cet extrait de code : Inscrit les services de serveur d’appel et votre InvocationHandler implémentation, puis mappe les /invocations points de terminaison. Vous implémentez MyInvocationHandler pour définir la façon dont chaque requête est traitée. Pour un exemple complet de gestionnaire, consultez l’exemple d’invocation .NET.

Référence : AddInvocationsServer

Tester le point de terminaison des appels

Envoyez une requête au serveur local :

curl -sS -X POST http://localhost:8088/invocations \
  -H "Content-Type: application/json" \
  -d '{"message":"My name is Alice.","stream":false}'

Pour les conversations à plusieurs échanges, réutilisez la valeur agent_session_id de l’en-tête de réponse comme paramètre de requête agent_session_id dans la requête suivante :

curl -sS -X POST "http://localhost:8088/invocations?agent_session_id=<session-id>" \
  -H "Content-Type: application/json" \
  -d '{"message":"What is my name?"}'

La plateforme ne stocke pas l’historique des conversations pour le protocole Invocations. Utilisez le agent_session_id paramètre de requête pour router les appels ultérieurs vers le même bac à sable hébergé.

Deploy

Déployez à l’aide de l’interface CLI Azure développeur (azd). Le flux utilise des exemples de manifestes et Docker pour générer l’image conteneur de l’agent et la déployer dans le runtime de l’agent hébergé par Foundry.

Le déploiement d’un agent hébergé nécessite le rôle Foundry Project Manager dans le projet. Pour plus d’informations, consultez Déployer un agent hébergé.

Installer l’extension Azure Developer CLI

Installez l’extension de l’agent AI et connectez-vous avant d’initialiser un exemple :

azd ext install azure.ai.agents
azd auth login

Docker doit s’exécuter localement, car azd ai agent run génère l’image conteneur déclarée dans le fichier Dockerfile de l’exemple. Pour plus de détails sur la commande, consultez la documentation de référence de Azure Developer CLI.

Initialiser à partir d’un exemple de manifeste

Créez un dossier et initialisez-le à partir d’un exemple de manifeste. Remplacez l’URL du manifeste par l’exemple que vous souhaitez utiliser.

mkdir my-agent-framework-agent
cd my-agent-framework-agent

azd ai agent init -m https://github.com/microsoft/agent-framework/blob/main/python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/agent.manifest.yaml
mkdir my-agent-framework-agent
cd my-agent-framework-agent

azd ai agent init -m https://github.com/microsoft/agent-framework/blob/main/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/agent.manifest.yaml

Suivez les instructions affichées par azd ai agent init. Si vous n’avez pas encore de déploiement de projet et de modèle Foundry, le flux d’initialisation peut vous guider tout au long de leur création.

Approvisionner des ressources Azure

Si le projet initialisé utilise un nouveau projet foundry et un déploiement de modèle, approvisionnez d’abord les ressources Azure :

azd provision

Cette commande crée un groupe de ressources qui contient, entre autres, une instance Foundry, un projet Foundry avec un déploiement de modèle, une instance Application Insights et un registre de conteneurs pour les images d’agent hébergées.

Exécutez localement le conteneur

Exécutez l’hôte de l’agent localement via azd:

azd ai agent run

L’hôte fonctionne sur http://localhost:8088. Dans un autre terminal, appelez le point de terminaison de protocole local :

azd ai agent invoke --local "Hello!"

Vous pouvez également appeler le point de terminaison directement avec curl:

curl -X POST http://localhost:8088/responses \
  -H "Content-Type: application/json" \
  -d '{"input": "Hello!"}'

Déployer sur Foundry

Déployez l’agent :

azd deploy

Le déploiement empaquette l'agent dans une image de conteneur, la pousse vers le registre de conteneurs approvisionné et la déploie dans le runtime de l'agent hébergé Foundry.

L’infrastructure d’hébergement Foundry injecte des variables d’environnement runtime dans l’agent, notamment :

  • FOUNDRY_PROJECT_ENDPOINT: URL du point de terminaison du projet Foundry où l’agent est déployé.
  • AZURE_AI_MODEL_DEPLOYMENT_NAME: nom de déploiement du modèle sélectionné pendant azd ai agent init.
  • APPLICATIONINSIGHTS_CONNECTION_STRING : chaîne de connexion de l'instance Application Insights du projet.

Pour obtenir des concepts de déploiement complets, des autorisations et des détails de gestion, consultez Déployer un agent hébergé et gérer le cycle de vie de l’agent hébergé.

Troubleshooting

Utilisez cette liste de contrôle pour diagnostiquer les problèmes courants lors du développement d’agents hébergés avec Agent Framework.

Impossible d’atteindre le modèle dans le conteneur hébergé

Vérifiez que la version de l'agent hébergé inclut AZURE_AI_MODEL_DEPLOYMENT_NAME et que l'identité de l'agent est autorisée à appeler le projet Foundry. La plateforme définit FOUNDRY_PROJECT_ENDPOINT ; votre code doit lire cette variable lors de son exécution dans Foundry.

L’état de la conversation ne se poursuit pas

Pour le protocole Responses, transmettez previous_response_id ou un ID conversation lors des tours suivants.

Pour le protocole Invocations, la plateforme ne stocke pas l’historique des conversations. Utilisez un paramètre de requête agent_session_id pour acheminer les appels suivants vers la même sandbox hébergée.

Incompatibilité de version du protocole

Si les demandes échouent après une mise à niveau, vérifiez que votre manifeste et votre package d’hébergement utilisent tous deux le protocole version 2.0.0. Les versions de protocole 1.0.0 et 2.0.0 sont incompatibles.

Étape suivante