Agentpipelinearkitektur

Agenter i Microsoft Agent Framework använder en pipelinearkitektur i flera lager för att bearbeta begäranden. Genom att förstå den här arkitekturen kan du anpassa agentbeteendet genom att lägga till mellanprogram, kontextprovidrar eller ändringar på klientnivå på lämpligt lager.

ChatClientAgent-pipeline

C#-agentens pipelinearkitektur

Skapar ChatClientAgent en pipeline med tre huvudlager:

  1. Agentmellanprogram – Valfria dekoratörer som omsluter agenten via .Use() för loggning, validering eller transformering
  2. Kontextskikt – Hanterar chatthistorik (ChatHistoryProvider) och ingjuter ytterligare kontext (AIContextProviders)
  3. ChattklientskiktIChatClient med valfria mellanprogramsmoduler som hanterar LLM-kommunikation

När du anropar RunAsync()flödar din begäran genom varje lager i följd.

Agentpipeline

Pipelinearkitektur för Python-agent

Klassen Agent skapar en pipeline via klasssammansättning med två huvudkomponenter:

Agent (yttre komponent):

  1. Agentmellanprogram + telemetriAgentMiddlewareLayer klasserna och AgentTelemetryLayer hanterar anrop av mellanprogram och OpenTelemetry-instrumentation
  2. RawAgent – Kärnagentlogik som anropar kontextproviders och samlar in providertillagt mellanprogram
  3. Kontextprovidrar – Enhetlig context_providers lista hanterar historik, ytterligare kontext och chatt-/funktionsmellanprogram per körning

ChatClient (separat och utbytbar komponent):

  1. FunctionInvocation – Hanterar verktygsanropsloop, anropar funktionsmellanprogram + telemetri per verktygsanrop
  2. Chattmellanprogram + telemetri – Valfria mellanprogramskedja och instrumentationslager, inklusive alla chattmellanprogram som läggs till av kontextleverantörer, som körs per modellanrop
  3. RawChatClient – Providerspecifik implementering (Azure OpenAI, OpenAI, Anthropic osv.) som kommunicerar med LLM

När du anropar run()flödar din begäran genom agentlagren och sedan till ChatClient-pipelinen för LLM-kommunikation.

Agentpipelinearkitektur

Arkitektur för Go-agentens pipeline

I Go använder agenter en pipeline för mellanprogram i flera lager. Mellanprogram omsluter agentens Run funktion, var och en anropar next för att skicka kontrollen till nästa lager.

När en agent körs tillämpas dess livscykel i den här ordningen:

  1. Anpassad agentmellanprogramvara – Din registrerade agent.Config.Middlewares, som tillämpas i deklarationsordning genom hela agentens livscykel
  2. Historikprovider – Läser in tidigare meddelanden och lagrar senare begärande-/svarsmeddelanden
  3. Kontextprovidrar – Mata in kontext, alternativ och tillstånd från registrerade agent.ContextProvider instanser
  4. Providermellanprogram – Providerregistrerade mellanprogram, till exempel automatisk anrop av verktyg, strukturerade utdata och redigering av svar
  5. Provider – den underliggande LLM-providern, till exempel OpenAI eller Anthropic

Mellanprogramslager för agent

Agentmellanprogram fångar upp varje anrop till agentens körningsmetod så att du kan inspektera eller ändra indata och utdata.

Lägg till mellanprogram med hjälp av agentverktygets mönster:

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

Du kan också använda MessageAIContextProvider som agentmellanprogram för att mata in ytterligare meddelanden i begäran. Detta fungerar med alla agenttyper, inte bara ChatClientAgent:

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

Det här lagret omsluter hela agentkörningen, inklusive kontextmatchning och chattklientanrop. Detta har fördelar, eftersom dessa dekoratörer kan användas med alla typer av agent, t.ex. A2AAgent eller GitHubCopilotAgent, inte bara ChatClientAgent. Det innebär också att dekoratörer på den här nivån inte nödvändigtvis kan göra antaganden om agenten som den dekorerar, vilket innebär att den är begränsad till att anpassa eller påverka vanliga funktioner.

Lägg till mellanprogram när du skapar agenten:

from agent_framework import Agent

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

Klassen Agent ärver från AgentMiddlewareLayer, som hanterar anrop av mellanprogram innan delegering till kärnagentlogik. Den ärver också från AgentTelemetryLayer vilken hanterar utsändande intervall, händelser och mått till en konfigurerad OpenTelemetry-serverdel. Båda dessa lager gör ingenting när de inte har konfigurerats.

Lägg till mellanprogram genom att implementera Middleware gränssnittet eller använda agent.MiddlewareFunc för lättviktsmellanprogram:

type Middleware interface {
    Run(next RunFunc, ctx context.Context, messages []*message.Message,
        options ...agent.Option) iter.Seq2[*agent.ResponseUpdate, error]
}

Varje mellanprogram tar emot next funktionen i kedjan och kan ändra meddelanden eller alternativ innan du anropar next, bearbetar svar efter anrop nexteller kortsluter pipelinen.

timing := agent.MiddlewareFunc(
    func(next agent.RunFunc, ctx context.Context, messages []*message.Message, options ...agent.Option) iter.Seq2[*agent.ResponseUpdate, error] {
        start := time.Now()
        return func(yield func(*agent.ResponseUpdate, error) bool) {
            defer log.Printf("agent run completed in %s", time.Since(start))
            for update, err := range next(ctx, messages, options...) {
                if !yield(update, err) {
                    return
                }
            }
        }
    },
)

a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
    Config: agent.Config{
        Middlewares: []agent.Middleware{timing},
    },
})

Detaljerade mönster för mellanprogram och observerbarhet finns i Agentmellanprogram och Observerbarhet.

Kontextskikt

Kontextlagret körs före varje LLM-anrop för att skapa hela meddelandehistoriken och mata in ytterligare kontext.

ChatClientAgent har två olika providertyper:

  • ChatHistoryProvider (enkel) – Hanterar lagring och hämtning av konversationshistorik
  • AIContextProviders (lista) – Ingjuter ytterligare kontext som minnen, hämtade dokument eller dynamiska instruktioner
var agent = new ChatClientAgent(chatClient, new ChatClientAgentOptions
{
    ChatHistoryProvider = new InMemoryChatHistoryProvider(),
    AIContextProviders = [new MyMemoryProvider(), new MyRagProvider()],
});

Agenten anropar varje providers InvokingAsync() metod innan den skickar meddelanden till chattklienten med varje providers utdata som skickas som indata till nästa provider.

Klassen Agent använder en enhetlig context_providers lista som kan innehålla både historikprovidrar och kontextprovidrar:

from agent_framework import Agent, InMemoryHistoryProvider

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

Kontextprovidrar kan också koppla chatt- eller funktionsmellanprogram till ett enda anrop via SessionContext.extend_middleware(). Agenten plattar ut dessa tillägg i providerordning innan du anger ChatClient-pipelinen.

Kontextprovidrar körs i agentens livscykel när anpassade mellanprogram har gått in i körningen och innan providerns mellanprogram anropar modellen. Kontextleverantörer kan lägga till meddelanden eller alternativ före leverantörsanropet och spara tillstånd efter körningen.

a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
    Config: agent.Config{
        ContextProviders: []agent.ContextProvider{memoryProvider},
    },
})

Detaljerade mönster för kontextprovider finns i Kontextprovidrar.

Chattklientlager

Chattklientlagret hanterar den faktiska kommunikationen med LLM-tjänsten.

ChatClientAgent använder en IChatClient instans som kan dekoreras med ytterligare mellanprogram:

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

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

Du kan också använda AIContextProvider som chattklientmellanprogram för att utöka meddelanden, verktyg och instruktioner på klientnivå. Detta måste användas i kontexten för en exekvering 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.");

Som standardinställning ChatClientAgent omsluter den tillhandahållna chattklienten med funktionssamtalsstöd. Ange UseProvidedChatClientAsIs = true alternativ för att hoppa över standardomslutningen.

Klassen Agent accepterar alla klienter som implementerar SupportsChatGetResponse. ChatClient-pipelinen hanterar mellanprogram, telemetri, funktionsanrop och leverantörsspecifik kommunikation:

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.")

I RawChatClient ChatClient implementeras den providerspecifika logiken för kommunikation med olika LLM-tjänster.

Provider-mellanprogram körs efter historik- och kontextleverantörer, omedelbart före den underliggande LLM-leverantören. Hjälpfunktioner på agentnivå, såsom OpenTelemetry och körningsloggning, registreras som anpassad middleware för agenter och omsluter de tidigare stegen i livscykeln.

Component Registration Skikt Purpose
Ring automatiskt agent/harness/toolautocall Middleware för leverantör Anropar funktionsverktyg automatiskt
Strukturerade utdata agent.WithStructuredOutput Middleware för leverantör Hanterar strukturerad utdataparsing
OpenTelemetry provider/otelprovider Mellanprogram för agent Spårning av agentanrop
Kör logger agent.Config.Logger Mellanprogram för agent Loggar agentinteraktioner

agent.ContextProvider värden är livscykelkomponenter snarare än agent.Middleware implementeringar. De körs mellan mellanprogram för anpassade agenter och mellanprogram för leverantören.

Körningsflöde

När du anropar en agent flödar begäran via pipelinen:

  1. Agentmellanprogram körs (om det är konfigurerat)
  2. ChatHistoryProvider läser in konversationshistorik i listan med begärandemeddelanden
  3. AIContextProviders lägger till meddelanden, verktyg eller instruktioner i begäran
  4. IChatClient-mellanprogram körs (om det är dekorerat)
  5. IChatClient skickar begäran till LLM
  6. Svaret flödar tillbaka genom samma lager
  7. ChatHistoryProvider och AIContextProviders meddelas om nya meddelanden

Agentpipeline:

  1. Agent Middleware + Telemetry kör middleware (om det är konfigurerat) och registrerar dataomfång
  2. RawAgent anropar kontextprovidrar för att läsa in historik, lägga till kontext och samla in providertillägg för chatt-/funktionsmellanprogram
  3. Begäran skickas till ChatClient

ChatClient-pipeline:

  1. FunctionInvocation hanterar verktygsanropsloopen
    • För varje verktygsanrop körs funktionsmellanprogram + telemetri , inklusive alla funktionsmellanprogram som läggs till av kontextprovidrar
  2. Chat Middleware + Telemetry körs per modellanrop (om det är konfigurerat), inklusive alla chattmellanprogram som läggs till av kontextleverantörer
  3. RawChatClient hanterar providerspecifik LLM-kommunikation
  4. Svaret flödar tillbaka genom samma lager
  5. Kontextprovidrar meddelas om nya meddelanden för lagring

Anmärkning

Specialiserade agenter kan fungera annorlunda än vad som beskrivs i pipelinen här.

  1. Den anpassade agentens mellanprogram körs först och omsluter hela agentens livscykel.
  2. Historikprovidern läser in konversationshistorik för den aktuella sessionen när den lokala historiken är aktiv.
  3. Kontextprovidrar lägger till meddelanden, alternativ eller tillstånd före provideranropet.
  4. Leverantörsmellanprogram körs, inklusive mellanprogram för automatiska verktygsanrop och hantering av strukturerade utdata när det är aktiverat.
  5. Providern skickar begäran till modellen.
  6. Svarsuppdateringar flödar tillbaka via mellanprogram för providern och mellanprogram för anpassad agent.
  7. Historikleverantörer och kontextleverantörer lagrar svarstillståndet efter en lyckad körning.

Andra agenttyper

Alla agenter använder inte den fullständiga ChatClientAgent pipelinen. Agenter som A2AAgent, GitHubCopilotAgenteller CopilotStudioAgent kommunicerar med fjärrtjänster i stället för att använda en lokal IChatClient. De stöder dock fortfarande mellanprogram på agentnivå.

Pipeline för andra agenttyper

Eftersom dessa agenter härleds från AIAgentkan du använda samma mellanprogramsmönster för agenten:

// 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();

Anmärkning

Du kan inte lägga till mellanprogram för chattklient till dessa agenter eftersom de inte använder IChatClient.

Andra agenttyper

Alla Python-agenter använder inte hela Agent + ChatClient pipelinen. GitHubCopilotAgentskickar till exempel begäranden via GitHub Copilot CLI i stället för en lokal chattklient.

Trots detta stöder Python GitHubCopilotAgent fortfarande mellanprogram för agenten och körs context_providers nu runt varje anrop. Provider-tillagda meddelanden och instruktioner ingår i uppmaningen som skickas till Copilot, och leverantörer får matchande after_run återanrop när ett svar är tillgängligt.

Anmärkning

Eftersom GitHubCopilotAgent inte använder en lokal chattklient gäller fortfarande inte mellanprogrammet för chattklienten.

Nästa steg