Ügynökfolyamat-architektúra

A Microsoft Agent Framework ügynökei rétegzett folyamatarchitektúrát használnak a kérések feldolgozásához. Ennek az architektúrának a megértése segít testre szabni az ügynökök viselkedését, ha közbenső szoftvereket, környezetszolgáltatókat vagy ügyfélszintű módosításokat ad hozzá a megfelelő réteghez.

ChatClientAgent folyamatlánc

C# ügynökfolyamat architektúrája

A ChatClientAgent csővezeték három fő rétegből áll:

  1. Ügynök köztes szoftvere – Opcionális dekorátorok, amelyek az ügynököt .Use() naplózáshoz, ellenőrzéshez vagy átalakításhoz csomagolják
  2. Környezeti réteg – Kezeli a csevegési előzményeket (ChatHistoryProvider) és további környezeteket injektál (AIContextProviders)
  3. Csevegési ügyfélréteg – Az LLM-kommunikációt kezelő, opcionális köztes szoftveres dekorátorok

Amikor hívja a(z) RunAsync(), a kérés sorrendben halad végig az egyes rétegeken.

Ügynökfolyamat

Python-ügynökfolyamat-architektúra

Az Agent osztály egy folyamatot hoz létre az osztályösszetevőn keresztül két fő összetevővel:

Ügynök (külső összetevő):

  1. Agent Middleware + Telemetria – a AgentMiddlewareLayer és AgentTelemetryLayer osztályok kezelik a köztes szoftverhívást és az OpenTelemetry instrumentálását.
  2. RawAgent – Alapvető ügynöklogika, amely meghívja a környezetszolgáltatókat, és összegyűjti a szolgáltató által hozzáadott köztes szoftvereket
  3. Környezetszolgáltatók – Egyesített lista kezeli az előzményeket, a további környezeteket és a futtatásonkénti csevegési/függvényközvetített context_providers szoftvereket

ChatClient (különálló és felcserélhető összetevő):

  1. FunctionInvocation – Kezeli az eszköz hívási ciklusát, meghívja a függvényköztes réteget és a telemetriát minden eszközhívásnál
  2. Chat Middleware + Telemetria – Választható köztes szoftverlánc- és rendszerállapot-rétegek, beleértve a környezetszolgáltatók által hozzáadott, modellalapú hívásonként futó csevegőközvetítőt is
  3. RawChatClient – Szolgáltatóspecifikus implementáció (Azure OpenAI, OpenAI, antropikus stb.), amely kommunikál az LLM-sel

Híváskor run() a kérés az ügynökrétegeken keresztül halad az LLM-kommunikáció ChatClient csatornájába.

Az opcionális Agent Hooks képesség egy köztes szoftvercsomagot telepít az ügynök, a csevegés és a függvényrétegek között. Az alapvető streamelési és adatmegőrzési kapuk kiterjesztik ezt a határt, így a kimenet nem lesz felszabadítva vagy tárolva, mielőtt a vonatkozó ítélet megengedi.

Ügynökfolyamat-architektúra

A Go Agent folyamatarchitektúrája

A Go-ban az ügynökök rétegzett köztesszoftver-folyamatot használnak. A middleware-elemek körülveszik az ügynök Run függvényét, és mindegyik a next hívásával adja át a vezérlést a következő rétegnek.

Amikor egy ügynök fut, az életciklusa ebben a sorrendben kerül alkalmazásra:

  1. Egyéni ügynök köztes szoftvere – A regisztrált agent.Config.Middlewares, deklarációs sorrendben alkalmazva az ügynök teljes életciklusa körül
  2. Előzményszolgáltató – Betölti a korábbi üzeneteket, és később tárolja a kéréseket/válaszüzeneteket
  3. Környezetszolgáltatók – Környezet, beállítások és állapot beszúrása regisztrált agent.ContextProvider példányokból
  4. Szolgáltatói köztes szoftver – Szolgáltató által regisztrált köztes szoftver, például automatikus eszközhívás, strukturált kimenetek és válaszkészítés
  5. Szolgáltató – A mögöttes LLM-szolgáltató, például az OpenAI vagy a Anthropic

Ügynök köztes szoftver rétege

Az ügynök köztes szoftvere minden hívást lehallgat az ügynök futtatási módszerére, lehetővé téve a bemenetek és kimenetek vizsgálatát vagy módosítását.

Köztes szoftver hozzáadása az agent builder mintával:

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

Ügynök köztes szoftverként további üzeneteket is MessageAIContextProvider beszúrhat a kérésbe. Ez bármilyen ügynöktípussal működik, nem csak ChatClientAgent:

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

Ez a réteg a teljes ügynökvégrehajtást körbefuttatja, beleértve a környezetfeloldást és a csevegési ügyfélhívásokat. Ennek előnye, hogy ezek a dekorátorok bármilyen ügynökkel használhatók, például A2AAgent, GitHubCopilotAgent, és nem csak ChatClientAgent. Ez azt is jelenti, hogy ezen a szinten a dekorátorok nem feltétlenül tehetnek feltételezéseket arról az ügynökről, hogy dekorálják, ami azt jelenti, hogy a közös funkciók testreszabására vagy befolyásolására korlátozódik.

Köztes szoftver hozzáadása az ügynök létrehozásakor:

from agent_framework import Agent

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

Az Agent osztály a AgentMiddlewareLayer-ből öröklődik, amely kezeli a köztes réteg meghívását, mielőtt az alapvető ügynöklogikára delegálna. Azt is örökli, amely kezeli AgentTelemetryLayer a spanokat, eseményeket és metrikákat egy konfigurált OpenTelemetria-háttérrendszerbe történő kibocsájtást. Mindkét réteg nem tesz semmit, ha nincsenek konfigurálva.

Köztes szoftver hozzáadása a Middleware felület implementálásával vagy a agent.MiddlewareFunc használatával könnyűsúlyú köztes szoftverhez:

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

Minden köztes szoftver megkapja a függvényt next a láncban, és a hívás nextelőtt módosíthatja az üzeneteket vagy a beállításokat, feldolgozhatja a hívás nextutáni válaszokat, vagy rövidre zárhatja a folyamatot.

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},
    },
})

A köztes szoftver részletes és megfigyelhetőségi mintáit az Ügynök köztes szoftver és az Megfigyelhetőség című témakörben találja.

Környezeti réteg

A kontextusréteg minden LLM-hívás előtt fut, hogy felépítse a teljes üzenetelőzményeket, és további kontextust szúrjon be.

ChatClientAgent két különböző szolgáltatótípust különböztet meg:

  • ChatHistoryProvider (önálló) – A beszélgetési előzmények tárolásának és lekérésének kezelése
  • AIContextProviders (lista) – További környezeteket injektál, például emlékeket, lekért dokumentumokat vagy dinamikus utasításokat
var agent = new ChatClientAgent(chatClient, new ChatClientAgentOptions
{
    ChatHistoryProvider = new InMemoryChatHistoryProvider(),
    AIContextProviders = [new MyMemoryProvider(), new MyRagProvider()],
});

Az ügynök meghívja az egyes szolgáltatók metódusait InvokingAsync() , mielőtt üzeneteket küldene a csevegőügyfélnek, és az egyes szolgáltatók kimenete bemenetként továbbítva lesz a következő szolgáltatónak.

Az Agent osztály egy egységes context_providers listát használ, amely az előzményszolgáltatókat és a környezetszolgáltatókat is magában foglalja:

from agent_framework import Agent, InMemoryHistoryProvider

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

A környezetszolgáltatók csevegő- vagy függvényközvetítő szoftvereket is csatolhatnak egyetlen meghíváshoz a következőn keresztül SessionContext.extend_middleware(): . Az ügynök egyengeti ezeket a hozzáadásokat a szolgáltatók sorrendje szerint, mielőtt belép a ChatClient csővezetékébe.

A kontextusszolgáltatók az ügynök életciklusán belül futnak, miután az egyéni middleware belépett a futási folyamatba, és mielőtt a szolgáltatói middleware meghívja a modellt. A környezetszolgáltatók üzeneteket vagy beállításokat adhatnak hozzá a szolgáltató hívása előtt, és a futtatás után is megőrizhetik az állapotot.

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

A környezetszolgáltatói minták részletes leírása: Környezetszolgáltatók.

Csevegési ügyfélréteg

A csevegési ügyfélréteg kezeli az LLM szolgáltatással folytatott tényleges kommunikációt.

ChatClientAgent egy IChatClient példányt használ, amely további middleware-rel látható el:

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

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

Csevegőügyfél köztes szoftverként is használható AIContextProvider üzenetek, eszközök és utasítások ügyfélszinten történő bővítéséhez. Ezt egy futó AIAgentkörnyezetben kell használni:

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

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

Alapértelmezés szerint ChatClientAgent a megadott csevegőügyfélt függvényhívási támogatással burkolja. Az alapértelmezett körbefuttatás kihagyásához adja meg a UseProvidedChatClientAsIs = true beállításként.

Az Agent osztály minden ügyfelet elfogad, amely implementálja a SupportsChatGetResponse-t. A ChatClient-folyamat kezeli a köztes szoftvereket, a telemetriát, a függvényhívást és a szolgáltatóspecifikus kommunikációt:

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

A RawChatClient ChatClientben a különböző LLM-szolgáltatásokkal való kommunikáció szolgáltatóspecifikus logikáját valósítja meg.

A szolgáltatói köztes réteg az előzmény- és kontextusszolgáltatók után fut, közvetlenül az alapul szolgáló LLM-szolgáltató előtt. Az ügynökszintű segédkomponensek, például az OpenTelemetry és a futtatási naplózás, egyéni ügynök-middlewareként vannak regisztrálva, és a korábbi életciklus-lépések köré épülnek.

Komponens Registration Réteg Alkalmazás célja
Automatikus hívás agent/harness/toolautocall Szolgáltató köztes szoftvere Automatikusan meghívja a függvényekhez tartozó eszközöket
Strukturált kimenet agent.WithStructuredOutput Szolgáltató köztes szoftvere Strukturált kimeneti elemzés kezelése
OpenTelemetry provider/otelprovider Ügynök köztes szoftvere Nyomkövetési ügynökhívások
Naplózó futtatása agent.Config.Logger Ügynök köztes szoftvere Naplózza az ügynök interakcióit

agent.ContextProvider az értékek nem implementációk, hanem agent.Middleware életciklus-összetevők. Az egyéni ügynök köztes szoftver és a szolgáltató köztes szoftver között futnak.

Végrehajtási folyamat

Ügynök meghívásakor a kérés a folyamaton halad át:

  1. Ügynök köztes szoftver fut (ha konfigurálva van)
  2. A ChatHistoryProvider betölti a beszélgetési előzményeket a kérelem üzenetlistájába
  3. Az AIContextProviders üzeneteket, eszközöket vagy utasításokat ad hozzá a kéréshez
  4. Az IChatClient middleware végrehajtja (ha fel van címkézve)
  5. Az IChatClient elküldi a kérést az LLM-nek
  6. A válasz ugyanazokon a rétegeken halad át
  7. A ChatHistoryProvider és az AIContextProviders értesítést kap az új üzenetekről

Ügynökfolyamat:

  1. Agent Middleware + Telemetria middleware-t hajt végre (ha konfigurálva van), és a rekordok kiterjedéseit rögzíti
  2. RawAgent meghívja a környezetszolgáltatókat az előzmények betöltéséhez, a környezet hozzáadásához, és a szolgáltató által hozzáadott csevegés/függvény köztes szoftver összegyűjtéséhez.
  3. A kérés továbbítva van a ChatClientnek

ChatClient-folyamat:

  1. A FunctionInvocation kezeli az eszköz hívási ciklusát
    • Minden egyes eszközhívás esetében a Function Middleware + Telemetria fut, beleértve a környezetszolgáltatók által hozzáadott függvényközvetíteni való szoftvereket is.
  2. Csevegő middleware + Telemetria modellenkénti hívás esetén fut (ha konfigurálva van), beleértve a környezetszolgáltatók által hozzáadott csevegő middleware-t is.
  3. A RawChatClient kezeli a szolgáltatóspecifikus LLM-kommunikációt
  4. A válasz ugyanazokon a rétegeken halad át
  5. A kontextus szolgáltatók értesítést kapnak az új üzenetek tárolásáról

Megjegyzés:

A specializált ügynökök az itt leírt folyamattól eltérően működhetnek.

  1. Az egyéni ügynökközvetítő először végrehajtja, és a teljes ügynökéletciklust körbefuttatja.
  2. Az előzményszolgáltató betölti az aktuális munkamenet beszélgetési előzményeit, ha a helyi előzmények aktívak.
  3. A környezetszolgáltatók a szolgáltató hívása előtt üzeneteket, beállításokat vagy állapotot adnak hozzá.
  4. A szolgáltató köztes szoftvere fut, beleértve az automatikusan hívható köztes szoftvereket és a strukturált kimenet kezelését, ha engedélyezve van.
  5. A szolgáltató elküldi a kérést a modellnek.
  6. A válaszfrissítések a szolgáltató köztes szoftverén és az egyéni ügynök köztes szoftverén keresztül áramlanak vissza.
  7. Az előzményszolgáltatók és a környezetszolgáltatók a sikeres futtatás után tárolják a válasz állapotát.

Egyéb ügynöktípusok

Nem minden ügynök használja a teljes ChatClientAgent folyamatot. Az ügynökök, például A2AAgent, GitHubCopilotAgent, vagy CopilotStudioAgent, a távoli szolgáltatásokkal kommunikálnak, ahelyett hogy a helyi IChatClient-t használnának. Azonban továbbra is támogatják az ügynökszintű köztes szoftvereket.

Egyéb ügynöktípusok folyamat

Mivel ezek az ügynökök a AIAgent-ból származnak, ugyanazokat az ügynöki köztes szoftver mintákat használhatja.

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

Megjegyzés:

Nem adhat hozzá csevegőügyfél-köztes szoftvert ezekhez az ügynökökhöz, mert nem használják a IChatClient-t.

Egyéb ügynöktípusok

Nem minden Python-ügynök használja a teljes Agent + ChatClient folyamatot. GitHubCopilotAgent például a GitHub Copilot parancssoron keresztül küldi el a kéréseket egy helyi csevegőügyfél helyett.

Ennek ellenére a Python GitHubCopilotAgent továbbra is támogatja az ügynöki middleware-t, és most már minden hívás körül futtatásra kerül context_providers. A Szolgáltató által hozzáadott üzenetek és utasítások szerepelnek a Copilotnak küldött üzenetben, és a szolgáltatók a válasz rendelkezésre állása után megkapják a megfelelő after_run visszahívást.

Megjegyzés:

Mivel GitHubCopilotAgent nem használ helyi csevegőügyfélt, a csevegőügyfél köztes szoftvere továbbra sem érvényes.

Következő lépések