Partager via


Architecture du pipeline d’agent

Les agents de Microsoft Agent Framework utilisent une architecture de pipeline en couches pour traiter les demandes. La compréhension de cette architecture vous aide à personnaliser le comportement de l’agent en ajoutant des middlewares, des fournisseurs de contexte ou des modifications au niveau du client au niveau de la couche appropriée.

ChatClientAgent Pipeline

Architecture du pipeline de l’agent C#

Le ChatClientAgent construit un pipeline avec trois couches principales :

  1. Agent middleware - Décorateurs facultatifs qui encapsulent l’agent pour .Use() la journalisation, la validation ou la transformation
  2. Couche de contexte : gère l’historique des conversations (ChatHistoryProvider) et injecte un contexte supplémentaire (AIContextProviders)
  3. Client de chat : IChatClient avec des décorateurs d’intergiciels facultatifs qui gèrent la communication LLM

Lorsque vous appelez RunAsync(), votre demande transite par chaque couche en séquence.

Pipeline d’agent

Architecture du pipeline de l’agent Python

La Agent classe génère un pipeline par le biais de la composition de classes avec deux composants principaux :

Agent (composant externe) :

  1. Intergiciel Agent + télémétrie : les classes AgentMiddlewareLayer et AgentTelemetryLayer gèrent les appels d'intergiciels et l'instrumentation OpenTelemetry.
  2. RawAgent - Logique de base de l'agent qui appelle des fournisseurs de contexte et collecte le middleware ajouté par le fournisseur
  3. Fournisseurs de contexte - La liste unifiée context_providers assure la gestion de l'historique, du contexte supplémentaire et du middleware de conversation/fonction pour chaque exécution.

ChatClient (composant distinct et interchangeable) :

  1. FunctionInvocation - Gère la boucle d’appel de l’outil, en invoquant le middleware de fonction + la télémétrie pour chaque appel d’outil
  2. Intergiciel de conversation + télémétrie - Couches d’intergiciels et d’instrumentation facultatives, y compris tout intergiciel de conversation ajouté par les fournisseurs de contexte, en cours d’exécution par appel de modèle
  3. RawChatClient - Implémentation spécifique au fournisseur (Azure OpenAI, OpenAI, Anthropic, etc.) qui communique avec le LLM

Lorsque vous appelez run(), votre requête transite par les couches Agent, puis dans le pipeline ChatClient pour la communication LLM.

Couche d'agent intermédiaire

L’intergiciel agent intercepte chaque appel à la méthode d’exécution de l’agent, ce qui vous permet d’inspecter ou de modifier des entrées et des sorties.

Ajoutez un intergiciel à l’aide du modèle de générateur d’agents :

var middlewareAgent = originalAgent
    .AsBuilder()
    .Use(runFunc: MyAgentMiddleware, runStreamingFunc: MyStreamingMiddleware)
    .Build();

Vous pouvez également utiliser MessageAIContextProvider comme intergiciel agent pour injecter des messages supplémentaires dans la demande. Cela fonctionne avec n’importe quel type d’agent, pas seulement ChatClientAgent:

var contextAgent = originalAgent
    .AsBuilder()
    .UseAIContextProviders(new MyMessageContextProvider())
    .Build();

Cette couche encapsule l’intégralité de l’exécution de l’agent, y compris la résolution de contexte et les appels clients de conversation. Cela présente des avantages, car ces décorateurs peuvent être utilisés avec n’importe quel type d’agent, par exemple A2AAgent , ou GitHubCopilotAgentpas seulement ChatClientAgent. Cela implique également que les décorateurs à ce niveau ne peuvent pas nécessairement faire des suppositions concernant l'agent qu'ils décorent, ce qui limite leur capacité à personnaliser ou à modifier les fonctionnalités communes.

Ajoutez un intergiciel lors de la création de l’agent :

from agent_framework import Agent

agent = Agent(
    client=my_client,
    instructions="You are helpful.",
    middleware=[my_middleware_func],
)

La Agent classe hérite de AgentMiddlewareLayer, qui gère l’appel d’intergiciel avant de déléguer à la logique de l’agent principal. Il hérite également de AgentTelemetryLayer, ce qui gère l’émission d’étendues, d’événements et de métriques vers un back-end OpenTelemetry configuré. Ces deux couches, ne font rien quand elles ne sont pas configurées.

Pour obtenir des modèles d’intergiciel et d’observabilité détaillés, consultez Intergiciel Agent et Observabilité.

Couche de contexte

La couche de contexte s’exécute avant chaque appel LLM pour générer l’historique complet des messages et injecter un contexte supplémentaire.

ChatClientAgent a deux types de fournisseurs distincts :

  • ChatHistoryProvider (unique) - Gère le stockage et la récupération de l’historique des conversations
  • AIContextProviders (liste) : injecte un contexte supplémentaire comme des souvenirs, des documents récupérés ou des instructions dynamiques
var agent = new ChatClientAgent(chatClient, new ChatClientAgentOptions
{
    ChatHistoryProvider = new InMemoryChatHistoryProvider(),
    AIContextProviders = [new MyMemoryProvider(), new MyRagProvider()],
});

L’agent appelle la méthode de InvokingAsync() de chaque fournisseur avant d’envoyer des messages au client de messagerie, en passant la sortie de chaque fournisseur comme entrée au fournisseur suivant.

La Agent classe utilise une liste unifiée context_providers qui peut inclure à la fois des fournisseurs d’historique et des fournisseurs de contexte :

from agent_framework import Agent, InMemoryHistoryProvider

agent = Agent(
    client=my_client,
    context_providers=[
        InMemoryHistoryProvider(),
        MyMemoryProvider(),
        MyRagProvider(),
    ],
)

Les fournisseurs de contexte peuvent également attacher des intergiciels de conversation ou de fonction à un appel unique via SessionContext.extend_middleware(). L'agent aplatit ces ajouts selon l'ordre du fournisseur avant d'entrer dans le pipeline du client de discussion.

Pour obtenir des modèles de fournisseur de contexte détaillés, consultez Fournisseurs de contexte.

Couche client de chat

La couche cliente de conversation gère la communication réelle avec le service LLM.

ChatClientAgent utilise une IChatClient instance, qui peut être décorée avec un intergiciel supplémentaire :

var chatClient = new AIProjectClient(endpoint, credential)
    .GetProjectOpenAIClient()
    .GetProjectResponsesClient()
    .AsIChatClient(deploymentName)
    .AsBuilder()
    .Use(CustomChatClientMiddleware)
    .Build();

var agent = new ChatClientAgent(chatClient, instructions: "You are helpful.");

Vous pouvez également utiliser AIContextProvider comme intergiciel client de conversation pour enrichir les messages, les outils et les instructions au niveau du client. Cela doit être utilisé dans le contexte d’une exécution AIAgent:

var chatClient = new AIProjectClient(endpoint, credential)
    .GetProjectOpenAIClient()
    .GetProjectResponsesClient()
    .AsIChatClient(deploymentName)
    .AsBuilder()
    .UseAIContextProviders(new MyContextProvider())
    .Build();

var agent = new ChatClientAgent(chatClient, instructions: "You are helpful.");

Par défaut, ChatClientAgent encapsule le client de conversation fourni avec la prise en charge des appels de fonction. Définissez UseProvidedChatClientAsIs = true dans les options pour ignorer cet enveloppement par défaut.

La Agent classe accepte tout client qui implémente SupportsChatGetResponse. Le pipeline ChatClient gère les intergiciels, les données de télémétrie, l’appel de fonction et la communication spécifique au fournisseur :

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient

client = FoundryChatClient(
    credential=credential,
    project_endpoint=endpoint,
    model=model,
)

agent = Agent(client=client, instructions="You are helpful.")

Le RawChatClient dans le ChatClient implémente la logique spécifique au fournisseur pour communiquer avec différents services LLM.

Flux d’exécution

Lorsque vous appelez un agent, la requête transite par le pipeline :

  1. L’intergiciel de l’agent s’exécute (s’il est configuré)
  2. ChatHistoryProvider charge l’historique des conversations dans la liste des messages de requête
  3. AIContextProviders ajoute des messages, des outils ou des instructions à la demande
  4. L’intergiciel IChatClient s’exécute (s’il est décoré)
  5. IChatClient envoie la requête au LLM
  6. La réponse revient à travers les mêmes couches
  7. ChatHistoryProvider et AIContextProviders sont avertis des nouveaux messages

Pipeline d’agent :

  1. L’agent Middleware + Télémétrie exécute l’intergiciel (s’il est configuré) et enregistre les spans
  2. RawAgent invoque des fournisseurs de contexte pour charger l'historique, ajouter un contexte et collecter le middleware de chat/fonction ajouté par le fournisseur.
  3. La demande est transmise à ChatClient

Pipeline ChatClient :

  1. FunctionInvocation gère la boucle d’appel d’outil
    • Pour chaque appel d’outil, l’intergiciel de fonction + télémétrie s’exécute, y compris tout intergiciel de fonction ajouté par les fournisseurs de contexte
  2. Chat Middleware + Télémétrie s’exécute par appel de modèle (s’il est configuré), y compris tout intergiciel de conversation ajouté par les fournisseurs de contexte
  3. RawChatClient gère la communication LLM spécifique au fournisseur
  4. La réponse revient à travers les mêmes couches
  5. Les fournisseurs de contexte sont avertis des nouveaux messages en vue de leur stockage

Note

Les agents spécialisés peuvent fonctionner différemment du pipeline décrit ici.

Autres types d’agents

Tous les agents n’utilisent pas le pipeline complet ChatClientAgent . Les agents tels que A2AAgent, GitHubCopilotAgentou CopilotStudioAgent communiquent avec des services distants plutôt que d’utiliser un agent local IChatClient. Toutefois, ils prennent toujours en charge les intergiciels au niveau de l’agent.

Pipeline des autres types d’agents

Étant donné que ces agents dérivent de AIAgent, vous pouvez utiliser les mêmes modèles de middleware d'agent :

// Agent middleware works with any AIAgent
var a2aAgent = originalA2AAgent
    .AsBuilder()
    .Use(runFunc: LoggingMiddleware)
    .UseAIContextProviders(new MyMessageContextProvider())
    .Build();

// Same pattern works for GitHubCopilotAgent
var copilotAgent = originalCopilotAgent
    .AsBuilder()
    .Use(runFunc: AuditMiddleware)
    .Build();

Note

Vous ne pouvez pas ajouter d’intergiciel client de conversation à ces agents, car ils n’utilisent IChatClientpas .

Autres types d’agents

Tous les agents Python n’utilisent pas le pipeline complet Agent + ChatClient . GitHubCopilotAgent, par exemple, envoie des requêtes via l’interface CLI GitHub Copilot au lieu d’un client de conversation local.

Même si Python GitHubCopilotAgent supporte toujours le middleware d’agent et exécute maintenant context_providers autour de chaque appel. Les messages et instructions ajoutés par le fournisseur sont inclus dans l’invite envoyée à Copilot, et les fournisseurs reçoivent le rappel correspondant after_run une fois qu’une réponse est disponible.

Note

Étant donné que GitHubCopilotAgent n’utilise pas de client de conversation local, le middleware client de conversation ne s’applique toujours pas.

Étapes suivantes