Aan de slag met AG-UI

In deze zelfstudie ziet u hoe u server- en clienttoepassingen bouwt met behulp van het AG-UI-protocol met Agent Framework. U leert hoe u een agent achter een AG-UI-eindpunt host en een client verbindt voor interactieve gesprekken.

Wat je gaat bouwen

Aan het einde van deze zelfstudie hebt u het volgende:

  • Een AG-UI-server die als host fungeert voor een AI-agent die toegankelijk is via HTTP
  • Een clienttoepassing die verbinding maakt met de server en reacties streamt
  • Inzicht in de werking van het AG-UI-protocol met Agent Framework

Prerequisites

  • .NET 8 of hoger
  • Een ASP.NET Core-project
  • Een geconfigureerde MAF AIAgent

In het voorbeeld wordt Azure OpenAI gebruikt, maar MapAGUIServer werkt met elke MAF-agent.

Een AG-UI-server maken

Installeer het hostingpakket:

dotnet add package Microsoft.Agents.AI.Hosting.AGUI.AspNetCore --prerelease

Registreer AG-UI hosting en wijs uw agent toe:

using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AGUI.AspNetCore;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddAGUIServer();

AIAgent agent = CreateAgent();

WebApplication app = builder.Build();
app.MapAGUIServer("/", agent);
await app.RunAsync();

MapAGUIServer accepteert AG-UI RunAgentInput verzoeken en streamt het antwoord van de agent als AG-UI-gebeurtenissen via server-sent events (SSE).

Voer de server uit op de URL die wordt gebruikt door het clientvoorbeeld:

dotnet run --urls http://localhost:8888

Tip

Zie het voorbeeld .NET aan de slag voor een volledige server- en consoleclient.

Verbinding maken met een .NET-client

De AG-UI .NET SDK bevat AGUIChatClient, die IChatClient implementeert en kan worden aangepast tot een MAF-agent:

dotnet add package AGUI.Client --prerelease
dotnet add package Microsoft.Agents.AI --prerelease
using AGUI.Abstractions;
using AGUI.Client;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

using HttpClient httpClient = new() { BaseAddress = new Uri("http://localhost:8888") };
AGUIChatClient chatClient = new(new AGUIChatClientOptions(httpClient, "/"));
AIAgent remoteAgent = chatClient.AsAIAgent();
AgentSession session = await remoteAgent.CreateSessionAsync();

List<AgentResponseUpdate> firstTurnUpdates = [];
await foreach (AgentResponseUpdate update in
    remoteAgent.RunStreamingAsync("Hello", session))
{
    firstTurnUpdates.Add(update);

    foreach (TextContent text in update.Contents.OfType<TextContent>())
    {
        Console.Write(text.Text);
    }
}

U kunt ook verbinding maken met elke client die het AG-UI-protocol implementeert.

Gesprekscontinuïteit

AG-UI gebruikt threadId en parentRunId om vervolgaanvragen te identificeren. Deze id's zijn protocolgegevens, geen autorisatiereferenties.

AGUIChatClient staatloos is. Als u een door de server beheerd gesprek wilt voortzetten, haalt u de id’s uit de eerste beurt op via RunStartedEvent, en neemt u dezelfde threadId en de vorige runId als parentRunId op in het volgende verzoek:

RunStartedEvent started = firstTurnUpdates
    .Select(update => update.AsChatResponseUpdate().RawRepresentation)
    .OfType<RunStartedEvent>()
    .FirstOrDefault()
    ?? throw new InvalidOperationException("The server didn't return a run-started event.");

ChatMessage nextMessage = new(ChatRole.User, "What did I just say?");
ChatClientAgentRunOptions continuationOptions = new()
{
    ChatOptions = new ChatOptions
    {
        RawRepresentationFactory = _ => new RunAgentInput
        {
            ThreadId = started.ThreadId,
            ParentRunId = started.RunId,
            Messages = new[] { nextMessage }.AsAGUIMessages().ToList(),
        },
    },
};

await foreach (AgentResponseUpdate update in
    remoteAgent.RunStreamingAsync([nextMessage], session, continuationOptions))
{
    // Process the continued response.
}

Alleen de nieuwe berichten in een vervolgaanvraag verzenden. MapAGUIServer gebruikt threadId om de gehoste agentsessie te selecteren en parentRunId de uitvoering te identificeren die wordt voortgezet. Zonder gehoste sessiepersistentie ontvangt elke aanvraag een nieuwe serversessie; de client kan in plaats daarvan de gespreksgeschiedenis opnieuw verzenden.

Om de servereigen status van AgentSession tussen verzoeken te behouden, configureert u hosted sessiepersistentie en isolatie en koppelt u vervolgens de hosted agent met naam aan met MapAGUIServer. Zie Productie- en beveiligingsoverwegingen voor de grenzen van de AG-UI-specifieke vertrouwensrelatie.

Volgende stappen 

Prerequisites

Zorg ervoor dat u het volgende hebt voordat u begint:

Opmerking

In deze voorbeelden worden Azure OpenAI-modellen gebruikt. Zie voor meer informatie hoe u Azure OpenAI-modellen implementeert met Foundry.

Opmerking

Deze voorbeelden gebruiken DefaultAzureCredential voor verificatie. Zorg ervoor dat u bent geverifieerd met Azure (bijvoorbeeld via az login). Zie de Documentatie voor Azure Identity voor meer informatie.

Warning

Het AG-UI-protocol is nog in ontwikkeling en kan worden gewijzigd. We houden deze voorbeelden bijgewerkt naarmate het protocol zich ontwikkelt.

Stap 1: een AG-UI-server maken

De AG-UI-server fungeert als host voor uw AI-agent en maakt deze beschikbaar via HTTP-eindpunten met behulp van FastAPI.

Vereiste pakketten installeren

Installeer de benodigde pakketten voor de server:

pip install agent-framework-ag-ui --pre

Of door uv te gebruiken:

uv pip install agent-framework-ag-ui --prerelease=allow

Hiermee worden agent-framework-core, fastapi, uvicorn en sse-starlette automatisch als afhankelijkheden geïnstalleerd.

Servercode

Maak een bestand met de naam server.py:

"""AG-UI server example."""

import os

from agent_framework import Agent
from agent_framework.openai import OpenAIChatCompletionClient
from agent_framework_ag_ui import add_agent_framework_fastapi_endpoint
from azure.identity import AzureCliCredential
from fastapi import FastAPI

# Read required configuration
endpoint = os.environ.get("AZURE_OPENAI_ENDPOINT")
deployment_name = os.environ.get("AZURE_OPENAI_CHAT_COMPLETION_MODEL")

if not endpoint:
    raise ValueError("AZURE_OPENAI_ENDPOINT environment variable is required")
if not deployment_name:
    raise ValueError("AZURE_OPENAI_CHAT_COMPLETION_MODEL environment variable is required")

chat_client = OpenAIChatCompletionClient(
    model=deployment_name,
    azure_endpoint=endpoint,
    api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
    credential=AzureCliCredential(),
)

# Create the AI agent
agent = Agent(
    name="AGUIAssistant",
    instructions="You are a helpful assistant.",
    client=chat_client,
)

# Create FastAPI app
app = FastAPI(title="AG-UI Server")

# Register the AG-UI endpoint
add_agent_framework_fastapi_endpoint(app, agent, "/")

if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="127.0.0.1", port=8888)

Belangrijkste concepten

  • add_agent_framework_fastapi_endpoint: Registreert het AG-UI-eindpunt met automatische verwerking van aanvragen/antwoorden en SSE-streaming
  • Agent: De Agent Framework-agent die binnenkomende aanvragen verwerkt
  • FastAPI-integratie: maakt gebruik van systeemeigen asynchrone ondersteuning van FastAPI voor streamingantwoorden
  • Instructies: De agent wordt gemaakt met standaardinstructies, die kunnen worden overschreven door clientberichten
  • Configuratie: OpenAIChatCompletionClient accepteert expliciete Azure-routeringsinvoer, zoals model, azure_endpointapi_versionen , en credentialkan ook lezen uit omgevingsvariabelen

De server configureren en uitvoeren

Stel de vereiste omgevingsvariabelen in:

export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_CHAT_COMPLETION_MODEL="gpt-4o-mini"

Voer de server uit:

python server.py

Of uvicorn rechtstreeks gebruiken:

uvicorn server:app --host 127.0.0.1 --port 8888

De server zal beginnen met luisteren op http://127.0.0.1:8888.

Stap 2: een AG-UI-client maken

De AG-UI-client maakt verbinding met de externe server en geeft streamingantwoorden weer.

Vereiste pakketten installeren

Het AG-UI-pakket is al geïnstalleerd, waaronder het AGUIChatClientvolgende:

# Already installed with agent-framework-ag-ui
pip install agent-framework-ag-ui --pre

Cliëntcode

Maak een bestand met de naam client.py:

"""AG-UI client example."""

import asyncio
import os

from agent_framework import Agent
from agent_framework_ag_ui import AGUIChatClient


async def main():
    """Main client loop."""
    # Get server URL from environment or use default
    server_url = os.environ.get("AGUI_SERVER_URL", "http://127.0.0.1:8888/")
    print(f"Connecting to AG-UI server at: {server_url}\n")

    # Create AG-UI chat client
    chat_client = AGUIChatClient(endpoint=server_url)

    # Create agent with the chat client
    agent = Agent(
        name="ClientAgent",
        client=chat_client,
        instructions="You are a helpful assistant.",
    )

    # Get a thread for conversation continuity
    thread = agent.create_session()

    try:
        while True:
            # Get user input
            message = input("\nUser (:q or quit to exit): ")
            if not message.strip():
                print("Request cannot be empty.")
                continue

            if message.lower() in (":q", "quit"):
                break

            # Stream the agent response
            print("\nAssistant: ", end="", flush=True)
            async for update in agent.run(message, session=thread, stream=True):
                # Print text content as it streams
                if update.text:
                    print(f"\033[96m{update.text}\033[0m", end="", flush=True)

            print("\n")

    except KeyboardInterrupt:
        print("\n\nExiting...")
    except Exception as e:
        print(f"\n\033[91mAn error occurred: {e}\033[0m")


if __name__ == "__main__":
    asyncio.run(main())

Belangrijkste concepten

  • Server-Sent Events (SSE): het protocol maakt gebruik van SSE-indeling (data: {json}\n\n)
  • Gebeurtenistypen: verschillende gebeurtenissen bieden metagegevens en inhoud (HOOFDLETTERS met onderstrepingstekens):
    • RUN_STARTED: Agent is begonnen met de verwerking
    • TEXT_MESSAGE_START: Begin van een sms-bericht van de agent
    • TEXT_MESSAGE_CONTENT: Incrementele tekst die vanuit de agent wordt gestreamd (met delta veld)
    • TEXT_MESSAGE_END: Einde van een tekstbericht
    • RUN_FINISHED: Geslaagde voltooiing
    • RUN_ERROR: Foutinformatie
  • Veldnaam: Gebeurtenisvelden maken gebruik van camelCase (bijvoorbeeld threadId, , runIdmessageId)
  • Threadbeheer: de threadId gesprekscontext tussen aanvragen wordt onderhouden
  • Client-Side instructies: systeemberichten worden verzonden vanaf de client

De client configureren en uitvoeren

Stel desgewenst een aangepaste server-URL in:

export AGUI_SERVER_URL="http://127.0.0.1:8888/"

Voer de client uit (in een afzonderlijke terminal):

python client.py

Stap 3: Het volledige systeem testen

Nu zowel de server als de client draaien, kunt u het volledige systeem testen.

Verwachte uitvoer

$ python client.py
Connecting to AG-UI server at: http://127.0.0.1:8888/

User (:q or quit to exit): What is 2 + 2?

[Run Started - Thread: abc123, Run: xyz789]
2 + 2 equals 4.
[Run Finished - Thread: abc123, Run: xyz789]

User (:q or quit to exit): Tell me a fun fact about space

[Run Started - Thread: abc123, Run: def456]
Here's a fun fact: A day on Venus is longer than its year! Venus takes
about 243 Earth days to rotate once on its axis, but only about 225 Earth
days to orbit the Sun.
[Run Finished - Thread: abc123, Run: def456]

User (:q or quit to exit): :q

Gekleurde uitvoer

De client geeft verschillende inhoudstypen weer met verschillende kleuren:

  • Geel: Gestarte meldingen uitvoeren
  • Cyaan: Tekstreacties van agenten (gestreamd in realtime)
  • Groen: Voltooiingsmeldingen uitvoeren
  • Rood: Foutberichten

Testen met curl (optioneel)

Voordat u de client uitvoert, kunt u de server handmatig testen met behulp van curl:

curl -N http://127.0.0.1:8888/ \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "messages": [
      {"role": "user", "content": "What is 2 + 2?"}
    ]
  }'

U ziet nu Server-Sent gebeurtenissen die worden gestreamd:

data: {"type":"RUN_STARTED","threadId":"...","runId":"..."}

data: {"type":"TEXT_MESSAGE_START","messageId":"...","role":"assistant"}

data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"...","delta":"The"}

data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"...","delta":" answer"}

...

data: {"type":"TEXT_MESSAGE_END","messageId":"..."}

data: {"type":"RUN_FINISHED","threadId":"...","runId":"..."}

Voor een inactieve stroom kan curl ook : keepalive commentaarregels weergeven. Dit zijn SSE-transportopmerkingen, niet AG-UI gebeurtenissen.

Hoe het werkt

Server-side flow

  1. Client verzendt HTTP POST-aanvraag met berichten
  2. Het FastAPI-eindpunt ontvangt de aanvraag
  3. AgentFrameworkAgent wrapper organiseert de uitvoering
  4. Agent verwerkt de berichten met Agent Framework
  5. AgentFrameworkEventBridge converteert agentupdates naar AG-UI gebeurtenissen
  6. Antwoorden worden teruggestreamd als Server-Sent Events (SSE)
  7. De verbinding wordt gesloten wanneer de uitvoering is voltooid

Client-Side flow

  1. Client verzendt HTTP POST-aanvraag naar servereindpunt
  2. Server reageert met SSE-stream
  3. Client parseert binnenkomende data: regels als JSON-gebeurtenissen
  4. Elke gebeurtenis wordt weergegeven op basis van het type
  5. threadId wordt vastgelegd voor gesprekscontinuïteit
  6. Stream wordt voltooid wanneer RUN_FINISHED de gebeurtenis binnenkomt

Protocol details

Het AG-UI-protocol maakt gebruik van:

  • HTTP POST voor het verzenden van aanvragen
  • Server-Sent Events (SSE) voor streaming-antwoorden
  • JSON voor gebeurtenisserialisatie
  • Thread-id's voor het onderhouden van gesprekscontext
  • Id's uitvoeren voor het bijhouden van afzonderlijke uitvoeringen
  • Naamgeving van gebeurtenistype: HOOFDLETTERS met onderstrepingstekens (bijvoorbeeld RUN_STARTED, TEXT_MESSAGE_CONTENT)
  • Veldnaam: camelCase (bijvoorbeeld , threadId, runIdmessageId)
  • SSE keepalive opmerkingen elke 15 seconden terwijl een stream niet actief is. Clients die alleen data: regels verwerken, negeren deze opmerkingen automatisch.

Algemene patronen

Interactieve A2UI-oppervlakken toevoegen

Met A2UI kan een agent interactieve oppervlakken genereren die door een compatibele AG-UI-client worden weergegeven als antwoordstromen. Installeer de optionele A2UI-afhankelijkheid:

pip install "agent-framework-ag-ui[a2ui]" --pre

Voor uv, voer uv pip install "agent-framework-ag-ui[a2ui]" --prerelease=allow uit.

Als u A2UI standaard wilt inschakelen voor een eindpunt, geeft u een a2ui_config door met de opt-in voor de back-end:

from agent_framework.ag_ui import add_agent_framework_fastapi_endpoint

add_agent_framework_fastapi_endpoint(
    app=app,
    agent=agent,
    path="/a2ui",
    a2ui_config={"inject_a2ui_tool": True},
)

De frontend heeft de AG-UI A2UI-middleware, of een gelijkwaardige werking, nodig om:

  • Geef de componentencatalogus en richtlijnen voor het genereren ervan op in de context van het AG-UI-verzoek.
  • Geef de gestreamde render_a2ui toolargumenten weer als oppervlakte-updates.
  • Stel forwardedProps.injectA2UITool in als A2UI is ingeschakeld voor een verzoek. Een expliciete false waarde overschrijft de opt-in van de back-end voor die aanvraag.

Gebruik OpenAIChatCompletionClient voor de agent die het A2UI-eindpunt bedient. Het streamt delta's van argumenten voor toolaanroepen, zodat de client de weergave geleidelijk kan opbouwen. De Response API-client biedt geen ondersteuning voor deze progressieve renderingstroom.

De adapter valideert voltooide onderdeelstructuren op basis van de opgegeven catalogus. Als de validatie mislukt, worden de validatiefouten toegevoegd aan de generatieprompt en probeert het systeem het opnieuw volgens de recovery-configuratie. Als alle herstelpogingen zijn uitgeput, ontvangt de client een foutenvelop in plaats van een uitzondering.

Zie de Python A2UI-agents en het A2UI-eindpunt instellen in de agentframeworkopslagplaats voor volledige implementaties.

Aangepaste serverconfiguratie

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# Add CORS for web clients
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

add_agent_framework_fastapi_endpoint(
    app,
    agent,
    "/agent",
    keepalive_seconds=30,  # Defaults to 15; set to None to disable
)

keepalive_seconds moet een positief getal of None.

Meerdere agenten

app = FastAPI()

weather_agent = Agent(name="weather", ...)
finance_agent = Agent(name="finance", ...)

add_agent_framework_fastapi_endpoint(app, weather_agent, "/weather")
add_agent_framework_fastapi_endpoint(app, finance_agent, "/finance")

Foutafhandeling

try:
    async for event in client.send_message(message):
        if event.get("type") == "RUN_ERROR":
            error_msg = event.get("message", "Unknown error")
            print(f"Error: {error_msg}")
            # Handle error appropriately
except httpx.HTTPError as e:
    print(f"HTTP error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")

Probleemoplossing

Verbinding geweigerd

Zorg ervoor dat de server actief is voordat je de client start.

# Terminal 1
python server.py

# Terminal 2 (after server starts)
python client.py

Authenticatiefouten

Zorg ervoor dat u bent geverifieerd met Azure:

az login

Controleer of u de juiste roltoewijzing hebt voor de Azure OpenAI-resource.

Streaming werkt niet

Controleer of uw cliënttime-out voldoende ingesteld is:

httpx.AsyncClient(timeout=60.0)  # 60 seconds should be enough

Voor langlopende agents verhoogt u de time-out dienovereenkomstig.

Niet-actieve streams verzenden standaard elke 15 seconden een SSE-keepalive-opmerking. Als een proxy eerder niet-actieve verbindingen sluit, configureert u een kleinere positieve keepalive_seconds waarde bij het registreren van het eindpunt.

Het Threadcontext is verloren gegaan

De client beheert automatisch threadcontinuïteit. Als de context verloren gaat:

  1. Controleren of threadId wordt vastgelegd vanuit RUN_STARTED gebeurtenissen
  2. Zorg ervoor dat hetzelfde clientexemplaar wordt gebruikt over berichten.
  3. Controleer of de server de thread_id in de volgende aanvragen ontvangt

Volgende stappen

Nu u de basisprincipes van AG-UI begrijpt, kunt u het volgende doen:

Aanvullende bronnen

Go ondersteunt AG-UI door provider/aguiprovider voor zowel servers als clients.

import "github.com/microsoft/agent-framework-go/provider/aguiprovider"

mux := http.NewServeMux()
mux.Handle("/", aguiprovider.NewJSONHTTPHandler(myAgent, aguiprovider.HandlerConfig{}))

if err := http.ListenAndServe(":8888", mux); err != nil {
    log.Fatal(err)
}

Gebruik aguiprovider.NewAgent deze functie wanneer uw Go-app een AG-UI-server als agent moet aanroepen:

import aguiSSEClient "github.com/ag-ui-protocol/ag-ui/sdks/community/go/pkg/client/sse"

a := aguiprovider.NewAgent(
    aguiSSEClient.NewClient(aguiSSEClient.Config{Endpoint: serverURL}),
    aguiprovider.AgentConfig{},
)

Tip

Zie de AG-UI-startserver en client-voorbeelden voor volledige uitvoerbare voorbeelden.