Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Ce tutoriel montre comment ajouter une fonctionnalité agentique à une application CRUD basée sur les données existante Express.js. Cela utilise deux approches différentes : LangGraph et Foundry Agent Service.
Si votre application web dispose déjà de fonctionnalités utiles, telles que le shopping, la réservation d’hôtels ou la gestion des données, il est relativement simple d’ajouter des fonctionnalités d’agent à votre application web en encapsulant ces fonctionnalités dans un plug-in (pour LangGraph) ou en tant que point de terminaison OpenAPI (pour le service De l’agent Foundry). Dans ce tutoriel, vous commencez par une application de liste to-do simple. À la fin, vous pourrez créer, mettre à jour et gérer des tâches avec un agent dans une application App Service.
LangGraph et Foundry Agent Service vous permettent de créer des applications web agentiques avec des fonctionnalités basées sur l’IA. LangGraph est similaire au noyau sémantique Microsoft et est un SDK, mais le noyau sémantique ne prend pas en charge JavaScript actuellement. Le tableau suivant présente certaines considérations et compromis :
| Consideration | LangGraph | Service d’agent de la fonderie |
|---|---|---|
| Performance | Rapide (s’exécute localement) | Plus lent (service géré, distant) |
| Development | Code complet, contrôle maximal | Faible code, intégration rapide |
| Testing | Tests manuels/unitaires dans le code | Terrain de jeu intégré pour les tests rapides |
| Scalability | Géré par l’application | Géré par Azure, mise à l’échelle automatique |
| Garde-fous de sécurité | Implémentation personnalisée requise | Sécurité et modération du contenu intégrées |
| Identité | Implémentation personnalisée requise | ID et authentification de l’agent intégrés |
| Entreprise | Intégration personnalisée requise | Déploiement natif de Microsoft 365/Teams et appels d’outils intégrés à Microsoft 365. |
Dans l’application déployée, l’authentification App Service nécessite la connexion Microsoft Entra à la fois pour l’interface utilisateur du navigateur et les API. LangGraph s’exécute dans App Service et appelle directement le service de tâches. Foundry Agent Service s’exécute à distance et appelle l’API de tâche protégée via son outil OpenAPI.
Dans ce tutoriel, vous allez apprendre à :
- Convertissez les fonctionnalités d’application existantes en plug-in pour LangGraph.
- Ajoutez le plug-in à un agent LangGraph et utilisez-le dans une application web.
- Convertir les fonctionnalités de l'application existante en un point de terminaison OpenAPI pour le Service de l’Agent Foundry.
- Appelez un agent Foundry dans une application web.
- Attribuez les autorisations requises pour la connectivité d’identité managée.
- Protégez une application web de service d’applications et ses API avec Microsoft Entra ID.
- Configurez un outil OpenAPI Foundry pour appeler des API de services d’applications protégées avec une identité managée.
Prerequisites
- Un compte Azure avec un abonnement actif : créez un compte gratuitement.
- Compte GitHub pour utiliser GitHub Codespaces - En savoir plus sur GitHub Codespaces.
Ouvrir l’exemple avec Codespaces
Le moyen le plus simple de commencer consiste à utiliser GitHub Codespaces, qui fournit un environnement de développement complet avec tous les outils requis préinstallés.
Accédez au dépôt GitHub à l’adresse https://github.com/Azure-Samples/app-service-agentic-langgraph-foundry-node.
Sélectionnez le bouton Code , sélectionnez l’onglet Espaces de code, puis sélectionnez Créer un espace de code dans l’espace de code principal.
Attendez quelques instants pour que votre espace de code s’initialise. Une fois prêt, vous verrez un environnement de développement entièrement configuré dans votre navigateur.
Exécutez l’application localement :
npm install npm run build npm startLorsque vous voyez que votre application s’exécute sur le port 3000 et est disponible, sélectionnez Ouvrir dans le navigateur et ajoutez quelques tâches.
Les agents ne sont pas entièrement configurés, donc ils ne fonctionnent pas encore. Vous les configurerez ultérieurement.
Passer en revue le code de l’agent
Les deux approches utilisent le même modèle d’implémentation, où l’agent est initialisé au démarrage de l’application et répond aux messages utilisateur par requêtes POST.
Le LangGraphTaskAgent est initialisé dans le constructeur de src/agents/LangGraphTaskAgent.ts. Le code d’initialisation effectue les opérations suivantes :
- Configure le client AzureChatOpenAI à l’aide de variables d’environnement.
- Crée l’agent ReAct prédéfini avec un ensemble d’outils CRUD pour la gestion des tâches (voir LangGraph : comment utiliser l’agent ReAct prédéfini).
- Configure la gestion de la mémoire (voir LangGraph : Ajout de la mémoire à l’agent ReAct prédéfini).
constructor(taskService: TaskService) {
this.taskService = taskService;
this.memory = new MemorySaver();
try {
const endpoint = process.env.AZURE_OPENAI_ENDPOINT;
const deploymentName = process.env.AZURE_OPENAI_DEPLOYMENT_NAME;
if (!endpoint || !deploymentName) {
console.warn('Azure OpenAI configuration missing for LangGraph agent');
return;
}
// Initialize Azure OpenAI client
const credential = new DefaultAzureCredential();
const azureADTokenProvider = getBearerTokenProvider(credential, "https://cognitiveservices.azure.com/.default");
this.llm = new AzureChatOpenAI({
azureOpenAIEndpoint: endpoint,
azureOpenAIApiDeploymentName: deploymentName,
azureADTokenProvider: azureADTokenProvider,
azureOpenAIApiVersion: "2024-10-21"
});
// Define tools directly in the array
const tools = [
tool(
async ({ title, isComplete = false }) => {
const task = await this.taskService.addTask(title, isComplete);
return `Task created successfully: "${task.title}" (ID: ${task.id})`;
},
{
name: 'createTask',
description: 'Create a new task',
schema: z.object({
title: z.string(),
isComplete: z.boolean().optional()
}) as any
}
),
tool(
async () => {
const tasks = await this.taskService.getAllTasks();
if (tasks.length === 0) {
return 'No tasks found.';
}
return `Found ${tasks.length} tasks:\n` +
tasks.map(t => `- ${t.id}: ${t.title} (${t.isComplete ? 'Complete' : 'Incomplete'})`).join('\n');
},
{
name: 'getTasks',
description: 'Get all tasks',
schema: z.object({}) as any
}
),
tool(
async ({ id }) => {
const task = await this.taskService.getTaskById(id);
if (!task) {
return `Task with ID ${id} not found.`;
}
return `Task ${task.id}: "${task.title}" - Status: ${task.isComplete ? 'Complete' : 'Incomplete'}`;
},
{
name: 'getTask',
description: 'Get a specific task by ID',
schema: z.object({
id: z.number()
}) as any
}
),
tool(
async ({ id, title, isComplete }) => {
const updated = await this.taskService.updateTask(id, title, isComplete);
if (!updated) {
return `Task with ID ${id} not found.`;
}
return `Task ${id} updated successfully.`;
},
{
name: 'updateTask',
description: 'Update an existing task',
schema: z.object({
id: z.number(),
title: z.string().optional(),
isComplete: z.boolean().optional()
}) as any
}
),
tool(
async ({ id }) => {
const deleted = await this.taskService.deleteTask(id);
if (!deleted) {
return `Task with ID ${id} not found.`;
}
return `Task ${id} deleted successfully.`;
},
{
name: 'deleteTask',
description: 'Delete a task',
schema: z.object({
id: z.number()
}) as any
}
)
];
// Create the ReAct agent with memory
this.agent = createReactAgent({
llm: this.llm,
tools,
checkpointSaver: this.memory,
stateModifier: `You are an AI assistant that manages tasks using CRUD operations.
You have access to tools for creating, reading, updating, and deleting tasks.
Always use the appropriate tool for any task management request.
Be helpful and provide clear responses about the actions you take.
If you need more information to complete a request, ask the user for it.`
});
} catch (error) {
console.error('Error initializing LangGraph agent:', error);
}
}
L’échantillon déployé est protégé par l’authentification App Service et utilise un seul thread LangGraph sélectionné par le serveur. Lorsque vous traitez les messages utilisateur, l’agent invoque invoke() avec le message de l’utilisateur et l’identifiant du thread géré par le serveur :
private readonly conversationThreadId = 'authenticated-conversation';
const result = await this.agent.invoke(
{
messages: [
{ role: 'user', content: message }
]
},
{
configurable: {
thread_id: this.conversationThreadId
}
}
);
Déployer l’exemple d’application
Le dépôt d’exemples contient un modèle Azure Developer CLI (AZD), qui crée une application App Service et déploie votre application d’exemple. Le modèle permet une identité managée attribuée au système pour les appels Azure AI sortants et configure l’authentification des services applicatifs avec Microsoft Entra ID. Pour plus d’informations sur la configuration d’authentification sous-jacente, voir Terminaux OpenAPI sécurisés pour le service d’agent Foundry.
Dans le terminal, connectez-vous à Azure en utilisant la CLI de développeur Azure :
azd auth loginSuivez les instructions pour terminer le processus d’authentification.
Déploie l’application Azure App Service en utilisant le modèle AZD :
azd upLorsque vous y êtes invité, fournissez les réponses suivantes :
Question Answer Entrez un nouveau nom d’environnement : Tapez un nom unique. Sélectionnez un abonnement Azure à utiliser : Sélectionnez l’abonnement. Choisissez un groupe de ressources à utiliser : Sélectionnez Créer un groupe de ressources. Sélectionnez un emplacement dans lequel créer le groupe de ressources : Sélectionnez Suède Centre. Entrez un nom pour le nouveau groupe de ressources : Tapez Entrée. Dans la sortie AZD, recherchez l’URL de votre application. Copiez également la valeur de l’audience de l’identité managée Foundry OpenAPI pour une utilisation ultérieure. Le résultat se présente ainsi :
Deploying services (azd deploy) (✓) Done: Deploying service web - Endpoint: <URL> Foundry OpenAPI managed identity audience: api://<generated-client-id>
Ouvrez le point de terminaison App Service dans la sortie d’AZD.
Lorsque Microsoft vous le demande, connectez-vous en utilisant un compte dans le locataire de déploiement et vérifiez que la liste des tâches se charge.
Dans le même navigateur authentifié, ouvrez le schéma OpenAPI autogénéré à
https://<app-name>.azurewebsites.net/api/schema.Copiez ou enregistrez le schéma OpenAPI généré. Vous l’utilisez dans le pivot Service de l'agent Foundry
Note
L’authentification par service d’applications renvoie une redirection HTTP 302 pour les requêtes navigateur non authentifiées. Cet exemple contient à la fois une interface utilisateur de navigateur et des API, ce qui permet à la redirection d’offrir une expérience de connexion utilisable. Les applications uniquement API utilisent généralement HTTP 401 à la place.
Vous avez désormais une application App Service authentifiée. Son identité managée attribuée au système est utilisée pour les appels sortants Foundry. Une identité managée distincte attribuée par l’utilisateur fournit des identifiants sans secret pour l’authentification des services d’applications.
Créer et configurer la ressource Microsoft Foundry
Dans le portail Foundry, créez un projet.
Déployez un modèle de votre choix (consultez Démarrage rapide Microsoft Foundry : Créer des ressources).
Depuis le haut du model playground, copiez le nom du modèle.
Sur la page d’accueil, copiez le point de terminaison Azure OpenAI pour plus tard.
Attribuer des autorisations requises
Dans le portail Foundry, sélectionnez Gérer dans le menu supérieur.
Dans les détails du Project, sélectionnez la ressource parente de votre project, puis sélectionnez Ouvrir dans le portail Azure.
Depuis le portail Azure, vous pouvez attribuer un accès basé sur les rôles pour la ressource.
Ajoutez le rôle suivant à l’identité gérée de l’application App Service ainsi qu’à l’utilisateur que vous utilisez avec
az login:Ressource cible Rôle requis Nécessaire pour Fonderie Utilisateur OpenAI de Cognitive Services Service d’achèvement de conversation dans Microsoft Agent Framework. Pour obtenir des instructions, consultez Attribuer des rôles Azure à l’aide du portail Azure.
Configurer des variables de connexion dans votre exemple d’application
Ouvrez .env. À l’aide des valeurs que vous avez copiées précédemment à partir du portail Foundry, configurez les variables suivantes :
Variable Description AZURE_OPENAI_ENDPOINTAzure OpenAI endpoint (copié depuis la page d’accueil du portail Foundry). AZURE_OPENAI_DEPLOYMENT_NAMENom du modèle dans le déploiement (copié depuis le model playground dans le nouveau portail Foundry). Note
Pour simplifier le didacticiel, vous allez utiliser ces variables dans .env au lieu de les remplacer par les paramètres d’application dans App Service.
Note
Pour simplifier le didacticiel, vous allez utiliser ces variables dans .env au lieu de les remplacer par les paramètres d’application dans App Service.
Les valeurs dans .env configurent la connexion sortante de l’application vers Foundry.
AZURE_AI_FOUNDRY_ACCOUNT_CLIENT_IDconfigure la connexion OpenAPI entrante distincte de Foundry vers App Service et est stocké dans l’environnement AZD.
L’authentification des services d’applications s’exécute sous Azure, et non dans le processus local Express, donc le flux de travail local de test reste inchangé.
Connectez-vous à Azure avec Azure CLI :
az loginCela permet à la bibliothèque cliente Azure Identity dans l’exemple de code de recevoir un jeton d’authentification pour l’utilisateur connecté. N’oubliez pas que vous avez ajouté le rôle requis pour cet utilisateur précédemment.
Exécutez l’application localement :
npm run build npm startLorsque vous voyez que votre application fonctionne sur le port 3000 et est disponible, sélectionnez Ouvrir dans le navigateur.
Validez les deux pivots séparément :
- LangGraph :Sélectionnez LangGraph Agent, et demandez à l’agent de créer une tâche. LangGraph appelle l’outil de tâche en cours de traitement.
-
Service Foundry Agent : Sélectionnez le Foundry Agent, puis demandez à l’agent de créer une tâche. L’agent Foundry à distance appelle le point de terminaison
/api/tasksdéployé et protégé avec une identité gérée.
La tâche créée par l’agent Foundry apparaît dans l’instance du service applicatif déployé, et non dans la base de données locale en mémoire. L’outil OpenAPI de Foundry utilise toujours l’URL serveur intégrée dans le schéma OpenAPI.
De retour dans l’espace de code GitHub, déployez les modifications apportées à votre application.
azd upNaviguez vers l’application déployée, connectez-vous et testez les deux pivots. Créez et listez des tâches avec l’agent LangGraph, puis créez et listez les tâches avec l’agent Foundry. Vérifiez que les deux pivots mettent à jour la liste des tâches.
Questions fréquemment posées
Comment ajouter la génération augmentée par récupération (RAG) à l’agent Foundry ?
Cette consigne s’applique au parcours Foundry Agent Service de ce tutoriel. Cela ne modifie pas les implémentations de LangGraph, Noyau sémantique ou Microsoft Agent Framework affichées dans l'autre onglet.
Créez ou sélectionnez une base de connaissances Foundry IQ, puis connectez cette base à l’agent du service d’agent Foundry. La connexion est mise à la disposition de l’agent sous la forme d’un outil de connaissances MCP géré.
Le code d’App Service continue d’invoquer le même agent en utilisant son nom via son client Foundry existant et agent_reference. L'application web n'a pas besoin d'une intégration directe Recherche Azure AI ni de son propre client MCP. Si l’interface affiche les sources, traitez les annotations de citation retournées par l’agent.
Quelle identité gérée chaque connexion utilise-t-elle ?
| Direction | Identité |
|---|---|
| App Service appelle Foundry | Identité assignée au système App Service |
Appels d’outils OpenAPI de Foundry /api/tasks |
Identifiant attribué par le système de ressources Parent Foundry |
Le point de terminaison du projet sélectionne le projet et l’agent. Il ne détermine pas l’identité utilisée par l’outil OpenAPI hébergé.
Nettoyer les ressources
Lorsque vous avez terminé avec l’application, vous pouvez supprimer les ressources App Service pour éviter d’entraîner d’autres coûts :
azd down --purge
Ensuite, supprime la ressource Foundry si tu l’as créée séparément.