Sdílet prostřednictvím


Začínáme s AG-UI

Tento kurz ukazuje, jak sestavovat serverové i klientské aplikace pomocí protokolu AG-UI s rozhraním .NET nebo Python a Agent Framework. Dozvíte se, jak vytvořit AG-UI server, který hostuje agenta AI, a klienta, který se k němu připojuje pro interaktivní konverzace.

Co budete vytvářet

Na konci tohoto kurzu budete mít:

  • Server AG-UI hostující agenta AI přístupný prostřednictvím protokolu HTTP
  • Klientská aplikace, která se připojuje k serveru a streamuje odpovědi
  • Principy fungování protokolu AG-UI s rozhraním Agent Framework

Požadavky

Než začnete, ujistěte se, že máte následující:

Poznámka:

Tyto ukázky používají modely Azure OpenAI. Další informace najdete v tématu nasazení modelů Azure OpenAI pomocí Azure AI Foundry.

Poznámka:

Tyto ukázky používají DefaultAzureCredential k autentizaci. Ujistěte se, že jste ověřeni pomocí Azure (např. prostřednictvím az login). Další informace najdete v dokumentaci k identitě Azure.

Výstraha

Protokol AG-UI je stále ve vývoji a může se změnit. Tyto ukázky budeme udržovat aktualizované, jak se protokol vyvíjí.

Krok 1: Vytvoření serveru AG-UI

Server AG-UI hostuje vašeho agenta AI a zveřejňuje ho prostřednictvím koncových bodů HTTP pomocí ASP.NET Core.

Poznámka:

Serverový projekt vyžaduje Microsoft.NET.Sdk.Web sadu SDK. Pokud vytváříte nový projekt úplně od začátku, použijte dotnet new web nebo se ujistěte, že soubor .csproj používá <Project Sdk="Microsoft.NET.Sdk.Web"> místo Microsoft.NET.Sdk.

Instalace požadovaných balíčků

Nainstalujte potřebné balíčky pro server:

dotnet add package Microsoft.Agents.AI.Hosting.AGUI.AspNetCore --prerelease
dotnet add package Azure.AI.OpenAI --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease

Poznámka:

Balíček Microsoft.Extensions.AI.OpenAI je vyžadován pro rozšiřující metodu AsIChatClient() , která převádí OpenAI ChatClient na IChatClient rozhraní očekávaného rozhraním Agent Framework.

Kód serveru

Vytvořte soubor s názvem Program.cs:

// Copyright (c) Microsoft. All rights reserved.

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI.Hosting.AGUI.AspNetCore;
using Microsoft.Extensions.AI;
using OpenAI.Chat;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient().AddLogging();
builder.Services.AddAGUI();

WebApplication app = builder.Build();

string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"]
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"]
    ?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT_NAME is not set.");

// Create the AI agent
ChatClient chatClient = new AzureOpenAIClient(
        new Uri(endpoint),
        new DefaultAzureCredential())
    .GetChatClient(deploymentName);

AIAgent agent = chatClient.AsIChatClient().AsAIAgent(
    name: "AGUIAssistant",
    instructions: "You are a helpful assistant.");

// Map the AG-UI agent endpoint
app.MapAGUI("/", agent);

await app.RunAsync();

Klíčové koncepty

  • AddAGUI: Zaregistruje služby AG-UI pomocí kontejneru injektáže závislostí.
  • MapAGUI: Metoda rozšíření, která zaregistruje koncový bod AG-UI pomocí automatického zpracování požadavků a odpovědí a streamování SSE
  • ChatClient a AsIChatClient(): AzureOpenAIClient.GetChatClient() vrátí typ ChatClient od OpenAI. Rozšiřující metoda AsIChatClient() (z Microsoft.Extensions.AI.OpenAI) ho převede na rozhraní IChatClient požadované Agent Frameworkem.
  • AsAIAgent: Vytvoří agenta Frameworku agenta z IChatClient
  • integrace ASP.NET Core: Používá nativní asynchronní podporu ASP.NET Core pro odpovědi na streamování.
  • Pokyny: Agent se vytvoří s výchozími pokyny, které je možné přepsat pomocí zpráv klienta.
  • Konfigurace: AzureOpenAIClient s DefaultAzureCredential poskytuje zabezpečené ověřování

Konfigurace a spuštění serveru

Nastavte požadované proměnné prostředí:

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

Spusťte server:

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

Server začne naslouchat na http://localhost:8888.

Poznámka:

Udržujte tento server spuštěný při nastavování a spouštění klienta v kroku 2. Server i klient musí běžet současně, aby celý systém fungoval.

Krok 2: Vytvoření klienta AG-UI

Klient AG-UI se připojí ke vzdálenému serveru a zobrazí streamové odpovědi.

Důležité

Před spuštěním klienta se ujistěte, že server AG-UI z kroku 1 běží na adrese http://localhost:8888.

Instalace požadovaných balíčků

Nainstalujte klientskou knihovnu AG-UI:

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

Poznámka:

Balíček Microsoft.Agents.AI poskytuje metodu AsAIAgent() rozšíření.

Klientský kód

Vytvořte soubor s názvem Program.cs:

// Copyright (c) Microsoft. All rights reserved.

using Microsoft.Agents.AI;
using Microsoft.Agents.AI.AGUI;
using Microsoft.Extensions.AI;

string serverUrl = Environment.GetEnvironmentVariable("AGUI_SERVER_URL") ?? "http://localhost:8888";

Console.WriteLine($"Connecting to AG-UI server at: {serverUrl}\n");

// Create the AG-UI client agent
using HttpClient httpClient = new()
{
    Timeout = TimeSpan.FromSeconds(60)
};

AGUIChatClient chatClient = new(httpClient, serverUrl);

AIAgent agent = chatClient.AsAIAgent(
    name: "agui-client",
    description: "AG-UI Client Agent");

AgentSession session = await agent.CreateSessionAsync();
List<ChatMessage> messages =
[
    new(ChatRole.System, "You are a helpful assistant.")
];

try
{
    while (true)
    {
        // Get user input
        Console.Write("\nUser (:q or quit to exit): ");
        string? message = Console.ReadLine();

        if (string.IsNullOrWhiteSpace(message))
        {
            Console.WriteLine("Request cannot be empty.");
            continue;
        }

        if (message is ":q" or "quit")
        {
            break;
        }

        messages.Add(new ChatMessage(ChatRole.User, message));

        // Stream the response
        bool isFirstUpdate = true;
        string? threadId = null;

        await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(messages, session))
        {
            ChatResponseUpdate chatUpdate = update.AsChatResponseUpdate();

            // First update indicates run started
            if (isFirstUpdate)
            {
                threadId = chatUpdate.ConversationId;
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine($"\n[Run Started - Thread: {chatUpdate.ConversationId}, Run: {chatUpdate.ResponseId}]");
                Console.ResetColor();
                isFirstUpdate = false;
            }

            // Display streaming text content
            foreach (AIContent content in update.Contents)
            {
                if (content is TextContent textContent)
                {
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.Write(textContent.Text);
                    Console.ResetColor();
                }
                else if (content is ErrorContent errorContent)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine($"\n[Error: {errorContent.Message}]");
                    Console.ResetColor();
                }
            }
        }

        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine($"\n[Run Finished - Thread: {threadId}]");
        Console.ResetColor();
    }
}
catch (Exception ex)
{
    Console.WriteLine($"\nAn error occurred: {ex.Message}");
}

Klíčové koncepty

  • Server-Sent Events (SSE):Protokol používá protokol SSE pro odpovědi na streamování.
  • AGUIChatClient: Klientská třída, která se připojuje k AG-UI serverům a implementuje IChatClient
  • AsAIAgent: Metoda rozšíření pro AGUIChatClient vytvoření agenta z klienta
  • RunStreamingAsync: Streamuje odpovědi jako AgentResponseUpdate objekty
  • AsChatResponseUpdate: Metoda rozšíření pro přístup k vlastnostem specifických pro chat, jako ConversationId a ResponseId
  • Správa relací: Systém udržuje kontext konverzace mezi jednotlivými požadavky.
  • Typy obsahu: Odpovědi zahrnují TextContent zprávy a ErrorContent chyby

Konfigurace a spuštění klienta

Volitelně můžete nastavit vlastní adresu URL serveru:

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

Spusťte klienta v samostatném terminálu (ujistěte se, že je spuštěný server z kroku 1):

dotnet run

Krok 3: Testování kompletního systému

S běžícím serverem i klientem teď můžete otestovat celý systém.

Očekávaný výstup

$ dotnet run
Connecting to AG-UI server at: http://localhost:8888

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

[Run Started - Thread: thread_abc123, Run: run_xyz789]
2 + 2 equals 4.
[Run Finished - Thread: thread_abc123]

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

[Run Started - Thread: thread_abc123, Run: 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: thread_abc123]

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

Barevně kódovaný výstup

Klient zobrazí různé typy obsahu s odlišnými barvami:

  • Žlutá: Oznámení o zahájení spuštění
  • Azurová: Textové odpovědi agenta (streamované v reálném čase)
  • Zelená: Oznámení o dokončení spuštění
  • Červená: Chybové zprávy

Jak to funguje

Server-Side proces

  1. Klient odešle požadavek HTTP POST se zprávami.
  2. ASP.NET koncový bod Core obdrží požadavek prostřednictvím MapAGUI
  3. Agent zpracovává zprávy pomocí rozhraní Agent Framework
  4. Odpovědi se převedou na události AG-UI
  5. Události jsou streamovány zpět jako Server-Sent Events (SSE)
  6. Připojení se uzavře po dokončení spuštění.

Klientský proces

  1. AGUIChatClient odešle požadavek HTTP POST do koncového bodu serveru.
  2. Server reaguje streamem SSE
  3. Klient analyzuje příchozí události do AgentResponseUpdate objektů.
  4. Každá aktualizace se zobrazí na základě typu obsahu.
  5. ConversationId je zachycen pro kontinuitu konverzace.
  6. Stream se dokončí po skončení spuštění.

Podrobnosti protokolu

Protokol AG-UI používá:

  • HTTP POST pro odesílání požadavků
  • Události Server-Sent (SSE) pro streamování odpovědí
  • JSON pro serializaci událostí
  • ID vláken (as ConversationId) pro zachování kontextu konverzace
  • ID spuštění (jako ResponseId) pro sledování jednotlivých spuštění

Další kroky

Teď, když rozumíte základům AG-UI, můžete:

Další zdroje

Požadavky

Než začnete, ujistěte se, že máte následující:

Poznámka:

Tyto ukázky používají modely Azure OpenAI. Další informace najdete v tématu nasazení modelů Azure OpenAI pomocí Azure AI Foundry.

Poznámka:

Tyto ukázky používají DefaultAzureCredential k autentizaci. Ujistěte se, že jste ověřeni pomocí Azure (např. prostřednictvím az login). Další informace najdete v dokumentaci k identitě Azure.

Výstraha

Protokol AG-UI je stále ve vývoji a může se změnit. Tyto ukázky budeme udržovat aktualizované, jak se protokol vyvíjí.

Krok 1: Vytvoření serveru AG-UI

Server AG-UI hostuje vašeho agenta AI a zveřejňuje ho prostřednictvím koncových bodů HTTP pomocí FastAPI.

Instalace požadovaných balíčků

Nainstalujte potřebné balíčky pro server:

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

Nebo použijte uv:

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

Tím se automaticky nainstaluje agent-framework-core, fastapia uvicorn jako závislosti.

Kód serveru

Vytvořte soubor s názvem server.py:

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

import os

from agent_framework import Agent
from agent_framework.azure import AzureOpenAIChatClient
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_DEPLOYMENT_NAME")

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

chat_client = AzureOpenAIChatClient(
    credential=AzureCliCredential(),
    endpoint=endpoint,
    deployment_name=deployment_name,
)

# Create the AI agent
agent = Agent(
    name="AGUIAssistant",
    instructions="You are a helpful assistant.",
    chat_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)

Klíčové koncepty

  • add_agent_framework_fastapi_endpoint: Zaregistruje koncový bod AG-UI pomocí automatického zpracování požadavků a odpovědí a streamování SSE.
  • Agent: Agent frameworku, který bude zpracovávat příchozí požadavky
  • Integrace FastAPI: Používá nativní asynchronní podporu FastAPI pro streamování odpovědí.
  • Pokyny: Agent se vytvoří s výchozími pokyny, které je možné přepsat pomocí zpráv klienta.
  • Konfigurace: AzureOpenAIChatClient Čte z proměnných prostředí nebo přijímá parametry přímo

Konfigurace a spuštění serveru

Nastavte požadované proměnné prostředí:

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

Spusťte server:

python server.py

Nebo použijte uvicorn přímo:

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

Server začne naslouchat na http://127.0.0.1:8888.

Krok 2: Vytvoření klienta AG-UI

Klient AG-UI se připojí ke vzdálenému serveru a zobrazí streamové odpovědi.

Instalace požadovaných balíčků

Balíček AG-UI je již nainstalován, který zahrnuje AGUIChatClient:

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

Klientský kód

Vytvořte soubor s názvem 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(server_url=server_url)

    # Create agent with the chat client
    agent = Agent(
        name="ClientAgent",
        chat_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())

Klíčové koncepty

  • Server-Sent Events (SSE):Protokol používá formát SSE (data: {json}\n\n)
  • Typy událostí: Různé události poskytují metadata a obsah (VELKÁ PÍSMENA s podtržítky):
    • RUN_STARTED: Agent začal zpracovávat.
    • TEXT_MESSAGE_START: Začátek textové zprávy od agenta
    • TEXT_MESSAGE_CONTENT: Inkrementální text streamovaný od agenta (s polem delta)
    • TEXT_MESSAGE_END: Konec textové zprávy
    • RUN_FINISHED: Úspěšné dokončení
    • RUN_ERROR: Informace o chybě
  • Pojmenování polí: Pole událostí používají camelCase (např. threadId, runId, messageId)
  • Správa vláken: threadId udržuje kontext konverzace napříč požadavky.
  • Client-Side Pokyny: Systémové zprávy se odesílají z klienta

Konfigurace a spuštění klienta

Volitelně můžete nastavit vlastní adresu URL serveru:

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

Spusťte klienta (v samostatném terminálu):

python client.py

Krok 3: Testování kompletního systému

S běžícím serverem i klientem teď můžete otestovat celý systém.

Očekávaný výstup

$ 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

Barevně kódovaný výstup

Klient zobrazí různé typy obsahu s odlišnými barvami:

  • Žlutá: Oznámení o zahájení spuštění
  • Azurová: Textové odpovědi agenta (streamované v reálném čase)
  • Zelená: Oznámení o dokončení spuštění
  • Červená: Chybové zprávy

Testování pomocí curl (volitelné)

Před spuštěním klienta můžete server otestovat ručně pomocí nástroje 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?"}
    ]
  }'

Měli byste vidět streamované události odesílané serverem zpět.

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":"..."}

Jak to funguje

Server-Side proces

  1. Klient odešle požadavek HTTP POST se zprávami.
  2. Koncový bod FastAPI obdrží požadavek.
  3. AgentFrameworkAgent Wrapper řídí provádění.
  4. Agent zpracovává zprávy pomocí rozhraní Agent Framework
  5. AgentFrameworkEventBridge převádí aktualizace agenta na události AG-UI.
  6. Odpovědi se streamují zpět jako události Server-Sent (SSE)
  7. Připojení se uzavře po dokončení spuštění.

Klientský proces

  1. Klient odešle požadavek HTTP POST do koncového bodu serveru.
  2. Server reaguje streamem SSE
  3. Klient analyzuje příchozí data: řádky jako události JSON.
  4. Každá událost se zobrazí na základě jejího typu.
  5. threadId je zachycen pro kontinuitu konverzace.
  6. Stream se dokončí, když přijde událost RUN_FINISHED.

Podrobnosti protokolu

Protokol AG-UI používá:

  • HTTP POST pro odesílání požadavků
  • Události Server-Sent (SSE) pro streamování odpovědí
  • JSON pro serializaci událostí
  • ID vláken pro zachování kontextu konverzace
  • Identifikátory běhu pro sledování jednotlivých spouštění
  • Pojmenování typu události: VELKÁ PÍSMENA s podtržítky (např. RUN_STARTED, TEXT_MESSAGE_CONTENT)
  • Pojmenování polí: camelCase (např. threadId, runId, messageId)

Běžné vzory

Vlastní konfigurace serveru

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

Více agentů

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

Zpracování chyb

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

Řešení problémů

Připojení odmítnuto

Před spuštěním klienta se ujistěte, že je server spuštěný:

# Terminal 1
python server.py

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

Chyby ověřování

Ujistěte se, že jste ověřeni pomocí Azure:

az login

Ověřte, že u prostředku Azure OpenAI máte správné přiřazení role.

Nefunguje streamování

Zkontrolujte, jestli je dostatečný časový limit pro klienta:

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

U dlouhotrvajících agentů odpovídajícím způsobem zvyšte časový limit.

Ztráta kontextu vlákna

Klient automaticky spravuje kontinuitu vláken. Pokud dojde ke ztrátě kontextu:

  1. Zkontrolujte, že threadId se zaznamenává z událostí RUN_STARTED.
  2. Ujistěte se, že se stejná instance klienta používá napříč zprávami.
  3. Ověřte, že server přijímá thread_id v následujících požadavcích.

Další kroky

Teď, když rozumíte základům AG-UI, můžete:

Další zdroje