Bagikan melalui


Memulai AG-UI

Tutorial ini menunjukkan cara membangun aplikasi server dan klien menggunakan protokol AG-UI dengan .NET atau Python dan Agent Framework. Anda akan mempelajari cara membuat server AG-UI yang menghosting agen AI dan klien yang terhubung ke server tersebut untuk percakapan interaktif.

Apa yang akan Anda Bangun

Pada akhir tutorial ini, Anda akan memiliki:

  • Server AG-UI menghosting agen AI yang dapat diakses melalui HTTP
  • Aplikasi klien yang tersambung ke server dan mengalirkan respons
  • Memahami cara kerja protokol AG-UI dengan Agent Framework

Prasyarat

Sebelum memulai, pastikan Anda memiliki hal berikut:

Nota

Sampel ini menggunakan model Azure OpenAI. Untuk informasi selengkapnya, lihat cara menyebarkan model Azure OpenAI dengan Azure AI Foundry.

Nota

Sampel ini digunakan DefaultAzureCredential untuk autentikasi. Pastikan Anda diautentikasi dengan Azure (misalnya, melalui az login). Untuk informasi selengkapnya, lihat dokumentasi Azure Identity.

Peringatan

Protokol AG-UI masih dalam pengembangan dan dapat berubah. Kami akan terus memperbarui sampel ini saat protokol berkembang.

Langkah 1: Membuat Server AG-UI

Server AG-UI meng-host agen AI Anda dan mengeksposnya melalui endpoint HTTP menggunakan ASP.NET Core.

Nota

Proyek server memerlukan Microsoft.NET.Sdk.Web SDK. Jika Anda membuat proyek baru dari awal, gunakan dotnet new web atau pastikan file Anda .csproj menggunakan <Project Sdk="Microsoft.NET.Sdk.Web"> daripada Microsoft.NET.Sdk.

Pasang Paket yang Diperlukan

Instal paket yang diperlukan untuk 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

Nota

Paket Microsoft.Extensions.AI.OpenAI diperlukan untuk metode ekstensi AsIChatClient() yang mengonversi ChatClient milik OpenAI ke antarmuka IChatClient yang diharapkan oleh Agent Framework.

Kode Server

Buat file bernama 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();

Konsep utama

  • AddAGUI: Mendaftarkan layanan AG-UI ke dalam wadah injeksi ketergantungan
  • MapAGUI: Metode ekstensi yang mendaftarkan titik akhir AG-UI dengan penanganan permintaan/respons otomatis dan streaming SSE
  • ChatClient dan AsIChatClient(): AzureOpenAIClient.GetChatClient() mengembalikan jenis dari OpenAI ChatClient. Metode ekstensi AsIChatClient() (dari Microsoft.Extensions.AI.OpenAI) mengonversinya ke antarmuka IChatClient yang diperlukan oleh Agent Framework
  • AsAIAgent: Membuat agen Agent Framework dari IChatClient
  • Integrasi Inti ASP.NET: Menggunakan dukungan asinkron asli ASP.NET Core untuk respons streaming
  • Petunjuk: Agen dibuat dengan instruksi bawaan, yang dapat digantikan oleh pesan klien
  • Konfigurasi: AzureOpenAIClient dengan DefaultAzureCredential menyediakan autentikasi yang aman

Mengonfigurasi dan Menjalankan Server

Atur variabel lingkungan yang diperlukan:

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

Jalankan server:

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

Server akan mulai mendengarkan di http://localhost:8888.

Nota

Tetap jalankan server ini saat Anda menyiapkan dan menjalankan klien di Langkah 2. Server dan klien perlu berjalan secara bersamaan agar sistem lengkap berfungsi.

Langkah 2: Membuat Klien AG-UI

Klien AG-UI terhubung ke server jarak jauh dan menampilkan respons streaming.

Penting

Sebelum menjalankan klien, pastikan server AG-UI dari Langkah 1 berjalan di http://localhost:8888.

Pasang Paket yang Diperlukan

Instal pustaka klien AG-UI:

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

Nota

Paket Microsoft.Agents.AI menyediakan metode ekstensi AsAIAgent().

Kode Klien

Buat file bernama 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}");
}

Konsep utama

  • Server-Sent Events (SSE): Protokol menggunakan SSE untuk respons streaming
  • AGUIChatClient: Kelas klien yang terhubung ke server AG-UI dan menerapkan IChatClient
  • AsAIAgent: Metode ekstensi pada AGUIChatClient untuk membuat agen dari klien
  • RunStreamingAsync: Mengalirkan respons sebagai AgentResponseUpdate objek
  • AsChatResponseUpdate: Metode ekstensi untuk mengakses properti khusus obrolan seperti ConversationId dan ResponseId
  • Manajemen Sesi: AgentSession mempertahankan konteks percakapan di setiap permintaan
  • Jenis Konten: Respons termasuk TextContent untuk pesan dan ErrorContent untuk kesalahan

Mengonfigurasi dan Menjalankan Klien

Secara opsional atur URL server kustom:

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

Jalankan klien di terminal terpisah (pastikan server dari Langkah 1 berjalan):

dotnet run

Langkah 3: Menguji Sistem Lengkap

Dengan server dan klien yang berjalan, Anda sekarang dapat menguji sistem lengkap.

Output yang Diharapkan

$ 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

Output Color-Coded

Klien menampilkan jenis konten yang berbeda dengan warna yang berbeda:

  • Kuning: Menjalankan pemberitahuan yang dimulai
  • Cyan: Respons teks agen (dialirkan secara waktu nyata)
  • Hijau: Menjalankan pemberitahuan penyelesaian
  • Merah: Pesan kesalahan

Cara Kerjanya

Proses Server-Side

  1. Klien mengirim permintaan HTTP POST dengan pesan
  2. titik akhir ASP.NET Core menerima permintaan melalui MapAGUI
  3. Agen memproses pesan menggunakan Agent Framework
  4. Respon dikonversi menjadi peristiwa AG-UI
  5. Peristiwa ditransmisikan kembali sebagai Server-Sent Events (SSE)
  6. Koneksi ditutup saat proses selesai

Proses Sisi Klien

  1. AGUIChatClient mengirim permintaan HTTP POST ke titik akhir server
  2. Server merespons dengan aliran SSE
  3. Client menguraikan event masuk menjadi objek AgentResponseUpdate
  4. Setiap pembaruan ditampilkan berdasarkan tipe isinya
  5. ConversationId diambil untuk kelangsungan percakapan
  6. Aliran selesai saat proses selesai.

Detail Protokol

Protokol AG-UI menggunakan:

  • HTTP POST untuk mengirim permintaan
  • Server-Sent Events (SSE) untuk respons streaming
  • JSON untuk serialisasi peristiwa
  • ID Thread (sebagai ConversationId) untuk menjaga konteks percakapan
  • Jalankan ID (sebagai ResponseId) untuk melacak eksekusi individual

Langkah Selanjutnya

Sekarang setelah Anda memahami dasar-dasar AG-UI, Anda dapat:

Sumber Daya Tambahan

Prasyarat

Sebelum memulai, pastikan Anda memiliki hal berikut:

Nota

Sampel ini menggunakan model Azure OpenAI. Untuk informasi selengkapnya, lihat cara menyebarkan model Azure OpenAI dengan Azure AI Foundry.

Nota

Sampel ini digunakan DefaultAzureCredential untuk autentikasi. Pastikan Anda diautentikasi dengan Azure (misalnya, melalui az login). Untuk informasi selengkapnya, lihat dokumentasi Azure Identity.

Peringatan

Protokol AG-UI masih dalam pengembangan dan dapat berubah. Kami akan terus memperbarui sampel ini saat protokol berkembang.

Langkah 1: Membuat Server AG-UI

Server AG-UI menyimpan agen AI Anda dan mengaksesnya melalui endpoint HTTP dengan menggunakan FastAPI.

Pasang Paket yang Diperlukan

Instal paket yang diperlukan untuk server:

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

Atau menggunakan uv:

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

Ini akan secara otomatis menginstal agent-framework-core, fastapi, dan uvicorn sebagai dependensi.

Kode Server

Buat file bernama 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)

Konsep utama

  • add_agent_framework_fastapi_endpoint: Mendaftarkan titik akhir AG-UI dengan penanganan permintaan/respons otomatis dan streaming SSE
  • Agent: Agen Agen Framework yang akan menangani permintaan masuk
  • Integrasi FastAPI: Menggunakan dukungan asinkron asli FastAPI untuk respons streaming
  • Petunjuk: Agen dibuat dengan instruksi bawaan, yang dapat digantikan oleh pesan klien
  • Konfigurasi: AzureOpenAIChatClient membaca dari variabel lingkungan atau menerima parameter secara langsung

Mengonfigurasi dan Menjalankan Server

Atur variabel lingkungan yang diperlukan:

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

Jalankan server:

python server.py

Atau menggunakan uvicorn secara langsung:

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

Server akan mulai mendengarkan di http://127.0.0.1:8888.

Langkah 2: Membuat Klien AG-UI

Klien AG-UI terhubung ke server jarak jauh dan menampilkan respons streaming.

Pasang Paket yang Diperlukan

Paket AG-UI sudah diinstal, yang mencakup AGUIChatClient:

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

Kode Klien

Buat file bernama 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())

Konsep utama

  • Server-Sent Events (SSE): Protokol menggunakan format SSE (data: {json}\n\n)
  • Jenis Peristiwa: Peristiwa yang berbeda menyediakan metadata dan konten (HURUF BESAR dengan garis bawah):
    • RUN_STARTED: Agen telah mulai memproses
    • TEXT_MESSAGE_START: Awal dari pesan teks dari agen
    • TEXT_MESSAGE_CONTENT: Teks bertahap yang dialirkan dari agen (dengan bidang delta)
    • TEXT_MESSAGE_END: Akhir pesan teks
    • RUN_FINISHED: Penyelesaian berhasil
    • RUN_ERROR: Informasi kesalahan
  • Penamaan Bidang: Bidang peristiwa menggunakan camelCase (misalnya, , threadIdrunId, messageId)
  • Manajemen Utas: threadId mempertahankan konteks percakapan di seluruh permintaan
  • instruksiClient-Side: Pesan sistem dikirim dari klien

Mengonfigurasi dan Menjalankan Klien

Secara opsional atur URL server kustom:

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

Jalankan klien (di terminal terpisah):

python client.py

Langkah 3: Menguji Sistem Lengkap

Dengan server dan klien yang berjalan, Anda sekarang dapat menguji sistem lengkap.

Output yang Diharapkan

$ 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

Output Color-Coded

Klien menampilkan jenis konten yang berbeda dengan warna yang berbeda:

  • Kuning: Menjalankan pemberitahuan yang dimulai
  • Cyan: Respons teks agen (dialirkan secara waktu nyata)
  • Hijau: Menjalankan pemberitahuan penyelesaian
  • Merah: Pesan kesalahan

Pengujian dengan curl (Opsional)

Sebelum menjalankan klien, Anda dapat menguji server secara manual menggunakan 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?"}
    ]
  }'

Anda akan melihat streaming Server-Sent Events kembali:

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

Cara Kerjanya

Proses Server-Side

  1. Klien mengirim permintaan HTTP POST dengan pesan
  2. Titik akhir FastAPI menerima permintaan
  3. AgentFrameworkAgent pembungkus mengatur eksekusi
  4. Agen memproses pesan menggunakan Agent Framework
  5. AgentFrameworkEventBridge mengonversi pembaruan dari agen menjadi acara AG-UI
  6. Respons dialirkan kembali sebagai Server-Sent Events (SSE)
  7. Koneksi ditutup saat proses selesai

Proses Sisi Klien

  1. Klien mengirim permintaan HTTP POST ke titik akhir server
  2. Server merespons dengan aliran SSE
  3. Klien mengurai baris masuk data: sebagai peristiwa JSON
  4. Setiap peristiwa ditampilkan berdasarkan jenisnya
  5. threadId diambil untuk kelangsungan percakapan
  6. Penstriman selesai saat RUN_FINISHED peristiwa tiba

Detail Protokol

Protokol AG-UI menggunakan:

  • HTTP POST untuk mengirim permintaan
  • Server-Sent Events (SSE) untuk respons streaming
  • JSON untuk serialisasi peristiwa
  • ID benang untuk mempertahankan konteks percakapan
  • Jalankan ID untuk melacak eksekusi individual
  • Penamaan jenis peristiwa: HURUF BESAR dengan garis bawah (misalnya, RUN_STARTED, TEXT_MESSAGE_CONTENT)
  • Penamaan bidang: camelCase (misalnya, threadId, , runIdmessageId)

Pola Umum

Konfigurasi Server Kustom

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

Beberapa Agen

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

Penanganan Kesalahan

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

Troubleshooting

Koneksi yang Ditolak

Pastikan server berjalan sebelum memulai klien:

# Terminal 1
python server.py

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

Kesalahan Autentikasi

Pastikan Anda diautentikasi dengan Azure:

az login

Verifikasi bahwa Anda memiliki penetapan peran yang benar pada sumber daya Azure OpenAI.

Streaming Tidak Berfungsi

Periksa apakah batas waktu klien Anda cukup:

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

Untuk agen jangka panjang, tingkatkan batas waktu yang sesuai.

Konteks Utas Hilang

Klien secara otomatis mengelola kelangsungan utas. Jika konteks hilang:

  1. Pastikan bahwa threadId ditangkap dari kejadian RUN_STARTED
  2. Pastikan instans klien yang sama digunakan di seluruh pesan
  3. Verifikasi bahwa server menerima thread_id dalam permintaan berikutnya

Langkah Selanjutnya

Sekarang setelah Anda memahami dasar-dasar AG-UI, Anda dapat:

Sumber Daya Tambahan