Dans l’article précédent, j’ai analysé l’idée même du multi-agent : pourquoi il est utile de diviser une longue tâche en plusieurs rôles, et pourquoi un agent universel commence assez vite à montrer ses limites. Mais comment passer de la théorie à la pratique ? La question ne consiste pas seulement à inventer les rôles d’orchestrator, d’executor et de critic, ni à écrire leurs prompts. Il faut comprendre comment les agents vont concrètement interagir, où vivra l’état, comment connecter les outils, quand un seul agent suffit, et quand un workflow explicite devient nécessaire. L’une des solutions est Microsoft Agent Framework. Regardons-le de plus près.
D’où vient Microsoft Agent FrameworkAuparavant, lorsqu’on parlait de systèmes agentiques chez Microsoft, la discussion menait presque inévitablement soit à AutoGen, soit à Semantic Kernel. Aujourd’hui, l’axe principal s’est déplacé vers Microsoft Agent Framework. Dans son overview officiel, Microsoft présente directement Agent Framework comme le successeur direct d’AutoGen et de Semantic Kernel. D’AutoGen, il reprend les abstractions simples d’agents et les patterns multi-agents. De Semantic Kernel, il reprend des éléments plus matures comme la gestion d’état basée sur les sessions, le type safety, les middleware, les filters et la telemetry. Par-dessus, il ajoute des workflows basés sur des graphes comme moyen explicite d’orchestrer des scénarios multi-étapes et multi-agents. Ainsi, l’apparition d’Agent Framework représente une nouvelle étape dans l’évolution des frameworks agentiques chez Microsoft. Dans la documentation, Agent Framework est explicitement divisé en deux grandes catégories de fonctionnalités :
Sous ces deux catégories se trouve une autre couche de blocs de construction fondamentaux : providers, sessions, memory/context providers, middleware, telemetry, hosting et mécanismes d’intégration.
En pratique, il est plus utile de comprendre Agent Framework non pas comme une seule grande API, mais comme plusieurs couches de responsabilité.
AgentsAgents est la couche dans laquelle les agents IA individuels sont décrits et exécutés comme des rôles de travail autonomes. Concrètement, un agent peut être vu comme une entité logicielle qui reçoit une tâche, communique avec un modèle, utilise les outils disponibles et avance progressivement vers un résultat. Ce n’est pas simplement un appel unique à un LLM, mais un niveau d’abstraction plus élevé : un agent possède un rôle, des instructions, des tools connectés, un accès à l’état de conversation et la capacité d’exécuter une tâche en plusieurs étapes. La couche Agents comprend généralement :
Agents est la couche adaptée aux scénarios où un agent unique, ou un rôle spécialisé unique, peut déjà produire un résultat utile par lui-même. Par exemple : un agent DevOps qui analyse un pipeline ; un agent support qui aide un utilisateur à résoudre un problème ; ou un agent de review qui vérifie une configuration et propose des corrections.
WorkflowsWorkflows est la couche dans laquelle le travail est décrit comme un processus d’exécution explicite. Si Agents est responsable des rôles individuels, Workflows est responsable de l’ordre et de la logique de leur interaction. Un workflow peut être compris comme un graphe d’étapes : un premier nœud s’exécute, puis un autre, puis il peut y avoir une branche, une vérification du résultat, une pause pour validation humaine ou un passage à l’agent suivant. Par exemple, un workflow peut décrire le processus suivant : d’abord collecter le contexte du pipeline, puis le transmettre à un agent pour analyse, ensuite lancer une vérification du Dockerfile, puis envoyer le résultat à un agent de review, et avant d’appliquer les changements, demander une confirmation humaine. La couche Workflows comprend généralement :
Workflows est la couche adaptée aux scénarios où le résultat ne suffit pas : il faut aussi un chemin contrôlé et vérifiable vers ce résultat. C’est particulièrement utile pour le DevOps, le CI/CD, le release management, l’incident response et d’autres tâches où le coût de l’erreur est élevé et où le processus doit être reproductible.
Foundational building blocks est la couche de base du framework, sur laquelle reposent à la fois les agents et les workflows. Si Agents décrit les rôles individuels et Workflows définit le processus d’exécution, alors les foundational building blocks sont responsables des capacités d’infrastructure : connexion aux modèles, stockage de l’état, gestion du contexte, outils, observabilité et extensibilité. Cette couche comprend :
Hosting & Integrations est la couche qui définit où l’application agentique sera exécutée et avec quels systèmes externes elle pourra interagir. Cette couche comprend :
Un Agent est un rôle IA distinct qui reçoit une tâche et tente de l’amener jusqu’au résultat. L’agent fonctionne via un modèle choisi, peut utiliser des outils, tenir compte du contexte de conversation et retourner une réponse à l’utilisateur ou à l’étape suivante du processus. Un provider ou client est le moyen de connecter l’agent à un modèle ou service IA donné. Par exemple, via un provider, le framework comprend où envoyer la requête : vers Azure OpenAI, OpenAI ou un autre backend. Session et state sont les mécanismes de stockage de l’état. Ils sont nécessaires pour que l’agent ne reparte pas « de zéro » à chaque fois, mais puisse se souvenir du contexte de la conversation en cours, poursuivre un scénario multi-turn et conserver des données intermédiaires entre les étapes. Tools, skills et MCP sont des moyens de donner à l’agent accès à des actions au-delà du texte. Avec les tools, l’agent peut appeler des fonctions, des API, des commandes ou des services externes. Les skills peuvent être vus comme des capacités réutilisables, tandis que MCP sert de standard pour connecter des outils et systèmes externes. Workflow, executors et edges sont les entités destinées aux processus multi-étapes. Quand la tâche devient complexe, l’important n’est plus seulement l’agent individuel, mais tout le parcours d’exécution : quelles étapes viennent d’abord, quelles données sont transmises ensuite, où existent les branches et qui est responsable de chaque étape. Middleware est une couche intermédiaire de traitement autour d’un agent ou d’un workflow. Elle est utile lorsque l’on veut ajouter de manière centralisée du logging, du filtrage, des politiques de sécurité, de la gestion d’erreurs ou une modification des requêtes et réponses sans réécrire la logique de chaque agent. Observability et hosting sont ce qui permet d’utiliser un système agentique non seulement dans une démo, mais dans une vraie application. L’observability fournit le tracing, les métriques et le diagnostic, tandis que le hosting et les intégrations aident à déployer la solution, à la connecter à d’autres systèmes et à l’intégrer dans une infrastructure de production.
Quand utiliser agents, et quand utiliser workflowsC’est l’un des embranchements les plus utiles de toute la documentation Agent Framework. Un agent est préférable lorsque la tâche n’est pas encore strictement formalisée. Par exemple, l’utilisateur pose une question ouverte, il faut comprendre le contexte, appeler un outil, prendre une petite décision en cours de route et retourner un résultat. Dans ce scénario, l’agent agit comme un rôle autonome : il reçoit la tâche, raisonne, utilise des tools si nécessaire et formule une réponse. Un agent convient là où un seul « exécutant intelligent » suffit. Par exemple :
Un workflow est préférable lorsque le processus peut déjà être décomposé en étapes compréhensibles. Si l’ordre d’exécution, les branches, les vérifications, les checkpoints ou la participation humaine doivent être définis à l’avance, il vaut mieux décrire la tâche comme un workflow. Les workflows sont, en pratique, l’endroit où vit le système multi-agent. Par exemple :
L’agent est bon pour travailler à l’intérieur d’un rôle ; le workflow sert à gérer un processus composé de plusieurs étapes.
Un passage ressemble généralement à ceci :
Agent Framework gère tout le cycle de vie d’un scénario agentique ou workflow.
Exemple d’agent simpleVoyons à quoi ressemble l’agent le plus simple dans Agent Framework. Commençons par ajouter les packages nécessaires :
dotnet add package Azure.AI.Projects --prerelease dotnet add package Azure.Identity dotnet add package Microsoft.Agents.AI.Foundry --prerelease Créons maintenant un agent minimal. Dans cet exemple, l’agent reçoit le rôle d’assistant DevOps, se connecte à un modèle via Azure AI Project et répond à la tâche de l’utilisateur. using System; using Azure.AI.Projects; using Azure.Identity; using Microsoft.Agents.AI; var endpoint = Environment.GetEnvironmentVariable("AZURE_AI_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_AI_PROJECT_ENDPOINT is not set."); var deploymentName = Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME") ?? "<model name>"; // Create a client for Azure AI Project. // AzureCliCredential is convenient for local development if you are already logged in via Azure CLI. var projectClient = new AIProjectClient( new Uri(endpoint), new AzureCliCredential()); // Convert the Azure AI Project client into an AI agent. // The agent gets a model, a name, and instructions that define its role. AIAgent agent = projectClient.AsAIAgent( model: deploymentName, name: "DevOpsAssistant", instructions: """ You are a DevOps assistant. You analyze deployment and release issues. Keep answers concrete. Do not invent facts if the context is missing. """); // Run the agent with a user task. // RunAsync is the simplest way to send a task and get the final response. var result = await agent.RunAsync( "Find out why the release pipeline started failing after the container image was changed.");Console.WriteLine(result); Ce qu’il faut remarquer ici :
Un tel agent convient aux scénarios simples : poser une question, analyser un problème, obtenir un brouillon d’analyse ou demander au modèle d’utiliser les tools connectés. Par exemple, dans un scénario DevOps, un tel agent peut être utilisé pour une première analyse :
var answer = await agent.RunAsync(""" The deployment failed after we changed the base image from ubuntu:22.04 to alpine. What should we check first? """); Console.WriteLine(answer); Ici, l’agent ne gère pas encore un processus complexe. Il joue simplement le rôle d’une entité qui aide l’ingénieur à comprendre la situation. Si vous devez recevoir la réponse progressivement, sans attendre le résultat final complet, vous pouvez utiliser le mode streaming via RunStreamingAsync(...). C’est pratique pour les UI, les chats et les réponses longues. Exemple minimal de workflowVoyons maintenant un workflow. Si un agent est un rôle, alors un workflow est déjà un graphe d’exécution. On y décrit explicitement les étapes, l’ordre d’exécution et le passage des données entre elles. L’exemple ci-dessous est volontairement simple. Son objectif est de montrer la mécanique : il y a une première étape, une deuxième étape, et un lien entre les deux.
using System; using System.Threading; using Microsoft.Agents.AI.Workflows; // This function represents the first workflow step. // It normalizes the input before passing it to the next step. Func<string, string> normalize = text => text.Trim(); // Bind the function as a workflow executor. // Executor is a workflow node that can receive input and produce output. var normalizeExecutor = normalize.BindAsExecutor("NormalizeExecutor"); // This executor represents the second workflow step. // It checks whether the deployment plan contains a rollback strategy. class RiskTagExecutor() : Executor<string, string>("RiskTagExecutor") { public override ValueTask<string> HandleAsync( string message, IWorkflowContext context, CancellationToken cancellationToken = default) { // This is intentionally simple demo logic. // In a real system, this could call an agent, a policy engine, or an external API. var output = message.Contains("rollback", StringComparison.OrdinalIgnoreCase) ? $"READY: {message}" : $"CHECK_MANUALLY: {message}"; return ValueTask.FromResult(output); } }RiskTagExecutor riskTag = new();
// Create a workflow that starts with NormalizeExecutor. WorkflowBuilder builder = new(normalizeExecutor); // Add an edge from the first executor to the second executor. // This means the output of NormalizeExecutor becomes input for RiskTagExecutor. builder.AddEdge(normalizeExecutor, riskTag).WithOutputFrom(riskTag); // Build the workflow graph. var workflow = builder.Build(); // Run the workflow in the current process. // The input goes to the first executor and then flows through the graph. await using Run run = await InProcessExecution.RunAsync( workflow, "Deploy plan includes rollback and smoke tests."); // Read workflow events. // ExecutorCompletedEvent tells us that a workflow node has finished execution. foreach (WorkflowEvent evt in run.NewEvents) { if (evt is ExecutorCompletedEvent completed) { Console.WriteLine($"{completed.ExecutorId}: {completed.Data}"); } }Ce workflow contient deux étapes. La première étape est NormalizeExecutor. Elle normalise le texte d’entrée. La deuxième étape est RiskTagExecutor. Elle vérifie si le plan contient le mot rollback. Si rollback est présent, le résultat est marqué comme READY. Si rollback n’est pas trouvé, le résultat est marqué comme CHECK_MANUALLY. Le processus ressemble donc à ceci :
Input -> NormalizeExecutor -> RiskTagExecutor -> OutputSur un exemple aussi simple, on voit bien la différence principale entre un workflow et un agent. À un agent, on dirait : « Regarde le deployment plan et décide si tout est correct ». Dans un workflow, on définit explicitement le processus :
Complexifions maintenant le schéma et examinons d’autres composants du framework.
1. Tools : l’agent ne fait plus que répondre, il agit aussiSans tools, un agent ne peut que raisonner à partir du texte qu’on lui donne. Avec des tools, il peut exécuter des actions : appeler des fonctions, accéder à des API, obtenir le statut d’un pipeline, vérifier un déploiement ou lire des données externes. Par exemple, ajoutons à l’agent un simple tool DevOps qui retourne le statut d’une release.
using System; using System.ComponentModel; using Azure.AI.Projects; using Azure.Identity; using Microsoft.Agents.AI; using Microsoft.Extensions.AI; var endpoint = Environment.GetEnvironmentVariable("AZURE_AI_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_AI_PROJECT_ENDPOINT is not set."); var deploymentName = Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME") ?? "gpt-4o-mini"; [Description("Get the release status by release id.")] static string GetReleaseStatus( [Description("Release id, for example release-1042.")] string releaseId) { // Demo implementation. In production, call Azure DevOps, GitHub Actions, or another release system. return releaseId switch { "release-1042" => "Failed: container image pull error. Registry returned unauthorized.", "release-1043" => "Succeeded.", _ => "Release was not found." }; } AIAgent agent = new AIProjectClient( new Uri(endpoint), new AzureCliCredential()) .AsAIAgent( model: deploymentName, name: "DevOpsAssistant", instructions: """ You are a DevOps assistant. Use available tools when you need factual release information. Keep answers concrete and do not invent facts. """, tools: [AIFunctionFactory.Create(GetReleaseStatus)]);Console.WriteLine(await agent.RunAsync("""
Analyze release-1042.Find out why it failed and suggest the first thing to check. """)); Le changement architectural important ici est que l’agent n’est plus limité au texte de l’utilisateur. Il peut appeler GetReleaseStatus, obtenir un résultat factuel et former sa réponse à partir de celui-ci. Avant, cela ressemblait à ceci :
User prompt ↓ Agent ↓ Model ↓ Text answer Maintenant, cela ressemble à ceci : User prompt ↓ Agent ↓ Model decides to call a tool ↓ GetReleaseStatus(...) ↓ Tool result ↓ Model ↓ Grounded answer Pour les scénarios DevOps, c’est une différence fondamentale. L’agent peut désormais fonctionner non seulement comme « conseiller », mais aussi comme participant au processus de diagnostic. 2. Sessions et state : l’agent cesse de recommencer chaque requête à zéroLe problème suivant d’un agent simple est l’absence de contexte stable entre les appels. Si vous appelez RunAsync(...) sans session à chaque fois, chaque exécution est une opération séparée. Mais le troubleshooting se fait presque toujours en plusieurs étapes : l’utilisateur décrit d’abord le problème, puis apporte un log, puis précise l’erreur, puis demande de vérifier une hypothèse. Pour cela, Agent Framework propose AgentSession.
AgentSession session = await agent.CreateSessionAsync();Console.WriteLine(await agent.RunAsync("""
Release release-1042 failed after we changed the container image. """, session));Console.WriteLine(await agent.RunAsync("""
The error says: unauthorized when pulling image from the registry.What should I check next? """, session)); Le deuxième appel reçoit la même session. L’agent continue donc la même conversation et peut tenir compte du contexte précédent. Selon la documentation, AgentSession est un conteneur de l’état de conversation ; il peut contenir l’historique, de la memory ou des références à un stockage externe, et RunAsync(...) met à jour la session avec les messages d’entrée et de sortie. Concrètement, cela transforme l’agent d’un appel ponctuel au modèle en assistant multi-turn :
Run 1:User: Release failed after image change. Agent: Check registry access, image tag, service connection.
Run 2 with same session:User: Error is unauthorized when pulling image. Agent: Since we are already investigating image pull failure, check registry credentials... Sans session, la deuxième réponse serait moins précise, car l’agent devrait reconstruire le contexte.
3. Memory et context providers : l’agent reçoit un contexte externeLa session résout le problème de l’historique de conversation. Mais l’agent a souvent besoin non seulement du dialogue, mais aussi d’éléments factuels supplémentaires : runbook, règles de release, ownership, known issues, notes d’architecture. Dans Agent Framework, cela passe par les context providers. Ils sont connectés à l’agent via les options et peuvent ajouter à la requête des instructions, messages ou tools supplémentaires avant l’appel au modèle. Dans la documentation, cela est décrit via AIContextProvider ; il peut stocker un état spécifique à la session dans AgentSession, et non dans l’instance du provider elle-même. Une version simplifiée du branchement d’un context provider ressemble à ceci :
using Microsoft.Agents.AI; AIAgent agentWithContext = new AIProjectClient( new Uri(endpoint), new AzureCliCredential()) .AsAIAgent( model: deploymentName, options: new ChatClientAgentOptions() { ChatOptions = new() { Instructions = """ You are a DevOps assistant. Use provided operational context when analyzing deployment issues. """ }, AIContextProviders = [ new DeploymentRunbookContextProvider() ] }); Le provider lui-même peut être un composant séparé qui ajoute le contexte opérationnel nécessaire avant l’exécution de l’agent. using System.Threading; using Microsoft.Agents.AI; using Microsoft.Extensions.AI; internal sealed class DeploymentRunbookContextProvider : AIContextProvider { public DeploymentRunbookContextProvider() : base(null, null) { } protected override ValueTask<AIContext> ProvideAIContextAsync( InvokingContext context, CancellationToken cancellationToken = default) { // In production, load this from Git, wiki, vector search, or an internal API. var runbook = """ Deployment policy: - Production releases require a rollback plan. - Smoke tests must run after deployment. - Registry access errors should be checked against service connection permissions. - Database migrations require manual approval. """; return new ValueTask<AIContext>(new AIContext { Messages = [ new ChatMessage( ChatRole.User, $"Operational context for this investigation:\n{runbook}") ] }); } } Désormais, l’agent reçoit non seulement la question de l’utilisateur, mais aussi un contexte d’ingénierie supplémentaire. Cela réduit fortement le risque de conseils génériques et rapproche les réponses des règles du système concret. 4. Middleware : le contrôle apparaît autour de l’agentQuand l’agent dispose de tools et d’un state, la question suivante apparaît : comment contrôler l’exécution ? Par exemple, nous pouvons avoir besoin de :
Dans Agent Framework, le middleware s’ajoute via un builder :
var middlewareEnabledAgent = agent .AsBuilder() .Use(runFunc: LoggingMiddleware, runStreamingFunc: null) .Build(); Le middleware lui-même pour un agent run ressemble à ceci : using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Agents.AI; using Microsoft.Extensions.AI; async Task<AgentResponse> LoggingMiddleware( IEnumerable<ChatMessage> messages, AgentSession? session, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken) { // Log input message count before the agent runs. Console.WriteLine($"Input messages: {messages.Count()}"); var stopwatch = Stopwatch.StartNew();try {
// Continue agent execution. var response = await innerAgent .RunAsync(messages, session, options, cancellationToken) .ConfigureAwait(false);stopwatch.Stop();
// Log output message count after the agent has completed. Console.WriteLine($"Output messages: {response.Messages.Count}"); Console.WriteLine($"Agent duration: {stopwatch.ElapsedMilliseconds} ms"); return response; } catch (Exception ex) { stopwatch.Stop(); // Log errors in one central place. Console.WriteLine($"Agent failed after {stopwatch.ElapsedMilliseconds} ms: {ex.Message}"); throw; } } Ensuite, on lance non pas l’agent initial, mais l’agent avec middleware : Console.WriteLine(await middlewareEnabledAgent.RunAsync("""Analyze release-1042 and explain why the deployment failed. """)); C’est une transition architecturale importante. Le logging, le contrôle, les policies et la gestion des erreurs ne sont plus dispersés dans les prompts et la business logic. Ils deviennent une couche séparée autour de l’agent.
5. Observability : le travail de l’agent peut être analysé après exécutionIl existe un autre niveau utile : le middleware non pas de l’exécution complète de l’agent, mais des appels de fonctions spécifiques. Par exemple, on peut logger chaque tool appelé par l’agent :
using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Agents.AI; async ValueTask<object?> FunctionCallingMiddleware( AIAgent agent, FunctionInvocationContext context, Func<FunctionInvocationContext, CancellationToken, ValueTask<object?>> next, CancellationToken cancellationToken) { // Log the function name before execution. Console.WriteLine($"Function call: {context.Function.Name}"); var result = await next(context, cancellationToken); // Log the function result after execution. Console.WriteLine($"Function result: {result}"); return result; } Il se branche ainsi : var agentWithFunctionMiddleware = agent .AsBuilder() .Use(FunctionCallingMiddleware) .Build();Console.WriteLine(await agentWithFunctionMiddleware.RunAsync("""
Check release-1042 and explain the failure. """)); C’est particulièrement utile lorsque les tools appellent des systèmes externes : Azure DevOps, GitHub, Kubernetes, ServiceNow, API internes. Vous voyez quel tool a été appelé, avec quel résultat, et vous pouvez ajouter une politique de sécurité ou une approval avant les actions dangereuses. Microsoft décrit séparément le function calling middleware comme un mécanisme d’interception des appels de fonctions ; pour poursuivre l’exécution, le middleware doit appeler le next transmis. Comment l’architecture changeAgent minimal :
User ↓ Agent ↓ Model ↓ Answer Agent avec tools, session et middleware : User ↓ Agent run middleware ↓ AgentSession ↓ Context providers ↓ Agent ↓ Model ↓ Function calling middleware ↓ Tools ↓ Tool result ↓ Model ↓ Answer Et c’est ici qu’Agent Framework devient intéressant non pas comme « encore une couche autour d’un LLM », mais comme un cadre d’ingénierie. Les tools donnent à l’agent la capacité d’agir.La session permet de poursuivre le travail en plusieurs étapes. Les context providers ajoutent la factographie nécessaire depuis des sources externes. Le middleware apporte le contrôle, le logging, la sécurité et la gestion des erreurs. L’observability permet ensuite d’analyser tout ce travail comme un vrai système de production : quels appels ont été faits, où l’erreur est apparue, quel tool a fonctionné, combien de temps a pris chaque étape. Au final, l’agent cesse d’être simplement un prompt avec un nom. Il devient un composant applicatif contrôlé, autour duquel on peut construire de vrais scénarios DevOps, support, release management et automation.
En pratique, Microsoft Agent Framework est plus confortable à utiliser non pas immédiatement comme une « grande plateforme multi-agent », mais comme un ensemble de niveaux auxquels on peut passer progressivement. Il vaut mieux commencer par l’option la plus simple : un seul agent et un provider clair. À ce stade, l’objectif n’est pas de construire une architecture complexe, mais de vérifier le scénario de base : quel rôle l’agent joue, quel modèle il utilise, quelles instructions lui sont nécessaires et quel résultat il doit retourner. L’étape suivante consiste à ajouter des tools ou des intégrations MCP. Cela n’est nécessaire que lorsque l’agent a réellement besoin de sortir du texte : obtenir des données depuis une API, vérifier le statut d’un pipeline, lire une configuration, aller dans GitHub, Azure DevOps, Kubernetes ou un système interne. À ce niveau, l’agent devient non seulement un interlocuteur, mais un participant au processus d’ingénierie. Ensuite apparaît la gestion d’état : sessions, conversations multi-turn, memory et context providers. C’est nécessaire lorsque la tâche ne se termine pas par une seule réponse. Par exemple, si l’agent mène une investigation d’incident, aide à une migration, analyse plusieurs fichiers ou accompagne l’utilisateur à travers une suite de clarifications. L’état permet à l’agent de ne pas recommencer chaque étape à zéro, mais de continuer à travailler dans le cadre d’une même tâche. Après cela, il vaut la peine d’ajouter middleware, telemetry et couche de policies. Plus l’agent possède de capacités, plus il devient important de contrôler son comportement. Le middleware aide à ajouter de manière centralisée logging, filtrage, gestion d’erreurs, safety checks, restrictions sur les tool calls et règles pour les actions de production. La telemetry et le tracing permettent de voir ce que l’agent a fait, quels tools il a appelés, combien de temps les étapes ont pris et où l’erreur est survenue. Ce n’est que lorsqu’il devient clair qu’un seul rôle ne suffit plus qu’il est logique de passer à plusieurs agents. Par exemple, un agent collecte le contexte, le deuxième analyse l’infrastructure, le troisième vérifie les risques, le quatrième prépare la solution finale. À ce stade, il ne s’agit pas simplement de « créer beaucoup d’agents », mais de répartir les responsabilités entre eux pour que chaque rôle soit compréhensible et vérifiable. Lorsque ces rôles commencent à former un processus stable, l’étape suivante devient le workflow. Le workflow est nécessaire là où l’ordre d’exécution ne peut plus être laissé à la discrétion d’un seul modèle. Par exemple : d’abord collecter les données, puis mener l’analyse, ensuite faire une security review, après cela demander une confirmation humaine, et seulement ensuite exécuter l’action. Ici, le système multi-agent devient un graphe d’exécution avec des étapes explicites, des edges, des checkpoints et du human-in-the-loop. La dernière étape est le hosting et les intégrations. Lorsque le système cesse d’être une expérimentation locale, il faut le déployer, le connecter à des services externes, l’intégrer à l’infrastructure existante et assurer son exploitation normale. À ce niveau, Azure Functions, Durable Task, A2A, DevUI, les intégrations avec les systèmes d’entreprise et l’observabilité production deviennent importants. La trajectoire pratique ressemble à ceci :
Single Agent ↓ Tools / MCP ↓ Sessions / State / Memory ↓ Middleware / Telemetry / Policies ↓ Multiple Agents ↓ Workflows ↓ Hosting / Integrations L’idée principale est qu’un système multi-agent n’a pas besoin d’être conçu dès le départ de haut en bas comme un graphe complexe d’une dizaine de rôles. Il est plus fiable de commencer par un agent utile, puis d’ajouter progressivement les outils, l’état, le contrôle du comportement, et seulement ensuite de выделить de nouveaux rôles agentiques et de formaliser le processus comme workflow. Ainsi, Microsoft Agent Framework permet de passer d’un agent simple à un véritable système multi-agent sans changement brutal de modèle architectural. ConclusionMicrosoft Agent Framework représente une étape très mature dans l’évolution des frameworks multi-agents de Microsoft. Il sépare bien les différents niveaux de la tâche : où un simple agent est nécessaire, où un workflow explicite est nécessaire, où il faut de l’état, où il faut des policies, de la telemetry et du hosting, et où il vaut mieux se contenter d’une fonction classique. Tout cela permet de mettre efficacement en œuvre les idées et approches que nous avons discutées dans l’article précédent. Cependant, Microsoft Agent Framework reste un SDK. Autrement dit, il faut être développeur pour construire quelque chose avec lui. Et le résultat sera une application autonome. C’est très bien lorsque l’on construit un système indépendant et fermé. Mais cela convient moins à nos tâches DevOps quotidiennes, où nous avons besoin de plus de liberté et de moins de « programmation ». On aimerait disposer de quelque chose de déjà prêt : prendre et utiliser. Et un tel outil existe aussi : GitHub Copilot dans Visual Studio Code. Le plus intéressant, c’est qu’il permet lui aussi de mettre pleinement en œuvre toutes les idées de l’approche multi-agent. C’est précisément ce dont nous parlerons dans le prochain article.