AG-UI Kullanmaya Başlama

Bu öğreticide, Agent Framework ile AG-UI protokolü kullanılarak sunucu ve istemci uygulamaları oluşturma işlemi gösterilmektedir. Bir aracıyı bir AG-UI uç noktasının arkasında barındırmayı ve etkileşimli konuşmalar için bir istemciyi bağlamayı öğreneceksiniz.

Neler Oluşturacaksınız

Bu öğreticinin sonunda şunları elde etmiş olacaksınız:

  • HTTP üzerinden erişilebilen bir yapay zeka aracısı barındıran AG-UI sunucusu
  • Sunucuya bağlanan ve yanıtları akışla aktaran bir istemci uygulaması
  • AG-UI protokolünün Aracı Çerçevesi ile nasıl çalıştığını anlama

Prerequisites

  • .NET 8 veya üzeri
  • ASP.NET Core projesi
  • Yapılandırılmış bir MAF AIAgent

Örnekte OpenAI Azure kullanılır, ancak MapAGUIServer herhangi bir MAF aracısı ile çalışır.

AG-UI sunucusu oluşturma

Barındırma paketini yükleyin:

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

AG-UI barındırmasını kaydedin ve ajanınızı eşleyin:

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 AG-UI RunAgentInput isteklerini kabul eder ve ajanın yanıtını sunucu tarafından gönderilen olaylar (SSE) üzerinden AG-UI olayları olarak akış halinde iletir.

İstemci örneği tarafından kullanılan URL'de sunucuyu çalıştırın:

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

Tip

Eksiksiz bir sunucu ve konsol istemcisi için .NET kullanmaya başlama örneğine bakın.

.NET istemcisiyle bağlanma

AG-UI .NET SDK’sı, IChatClient öğesini uygulayan ve bir MAF aracısına uyarlanabilen AGUIChatClient sağlar:

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

ayrıca AG-UI protokollerini uygulayan herhangi bir istemciye de bağlanabilirsiniz.

Konuşma sürekliliği

AG-UI, devam isteklerini tanımlamak için parentRunId ve threadId kullanır. Bu tanımlayıcılar yetkilendirme kimlik bilgileri değil protokol verileridir.

AGUIChatClient durumsuzdur. Sunucunun sahip olduğu bir konuşmayı sürdürmek için, ilk turdaki RunStartedEvent içinden tanımlayıcıları alın, ardından sonraki isteğe aynı threadId ile önceki parentRunId değerini runId olarak ekleyin:

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

Bir devamlılık isteğinde yalnızca yeni iletileri gönderin. MapAGUIServer, barındırılan aracı oturumunu seçmek için parentRunId ve sürdürülen çalıştırmayı tanımlamak için threadId kullanır. Barındırılan oturum kalıcılığı olmadan her istek yeni bir sunucu oturumu alır; bunun yerine istemci, konuşma geçmişini yeniden gönderebilir.

İstekler arasında sunucuya ait AgentSession durumunu korumak için barındırılan oturum kalıcılığını ve yalıtımını yapılandırın, ardından MapAGUIServer ile adlandırılmış barındırılan aracıyı eşleyin. AG kullanıcı arabirimine özgü güven sınırı için bkz. Üretim ve güvenlikle ilgili dikkat edilmesi gerekenler.

Sonraki Adımlar

Prerequisites

Başlamadan önce aşağıdakilere sahip olduğunuzdan emin olun:

Uyarı

Bu örneklerde Azure OpenAI modelleri kullanılır. Daha fazla bilgi için bkz. Foundry ile Azure OpenAI modellerini dağıtma.

Uyarı

Bu örnekler kimlik doğrulaması için kullanılır DefaultAzureCredential . Azure ile kimliğinizin doğrulanmış olduğundan emin olun (örneğin aracılığıyla az login). Daha fazla bilgi için Azure Identity belgelerine bakın.

Warning

AG-UI protokolü hala geliştirme aşamasındadır ve değiştirilebilir. Protokol geliştikçe bu örnekleri güncel tutacağız.

1. Adım: AG-UI Sunucusu Oluşturma

AG-UI sunucusu yapay zeka aracınızı barındırıyor ve FastAPI kullanarak HTTP uç noktaları aracılığıyla kullanıma sunar.

Gerekli Paketleri Yükleme

Sunucu için gerekli paketleri yükleyin:

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

Veya uv kullanarak:

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

Bu, agent-framework-core, fastapi, uvicorn ve sse-starlette bileşenlerini bağımlılık olarak otomatik şekilde kuracaktır.

Sunucu Kodu

adlı server.pybir dosya oluşturun:

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

Önemli Kavramlar

  • add_agent_framework_fastapi_endpoint: otomatik istek/yanıt işleme ve SSE akışı ile AG-UI uç noktasını kaydeder
  • Agent: Gelen istekleri işleyecek Agent Framework aracısı
  • FastAPI Tümleştirmesi: Akış yanıtları için FastAPI'nin yerel zaman uyumsuz desteğini kullanır
  • Yönergeler: Aracı, istemci iletileri tarafından geçersiz kılınabilen varsayılan yönergelerle oluşturulur
  • Yapılandırma: OpenAIChatCompletionClient , , modelazure_endpointve gibi api_versionaçık Azure yönlendirme girişlerini kabul eder ve credentialortam değişkenlerinden de okuyabilir

Sunucuyu Yapılandırma ve Çalıştırma

Gerekli ortam değişkenlerini ayarlayın:

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

Sunucuyu çalıştırın:

python server.py

Veya doğrudan uvicorn kullanarak:

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

Sunucu http://127.0.0.1:8888 üzerinde dinlemeye başlayacak.

2. Adım: AG-UI İstemcisi Oluşturma

AG-UI istemcisi uzak sunucuya bağlanır ve akış yanıtlarını görüntüler.

AGUIChatClient yanıt çerezlerini kalıcı olarak saklamayan dahili bir HTTP istemcisini yeniden kullanır.

Sunucu kimlik doğrulama, oturumlar veya yük dengeleyici bağımlılığı için tanımlama bilgileri gerektiriyorsa, çağırana ait httpx.AsyncClient öğesini http_client= aracılığıyla geçirin. İstemcinin kapsamını kimliği doğrulanmış bir sorumlu olarak belirleyin ve uygulamanızda kapatın. Bir AG-UI iş parçacığı kimliği, kimlik doğrulama sınırı değil, ilişkilendirme tanımlayıcısıdır.

Gerekli paketleri yükleme

AG-UI paketi, AGUIChatClient öğesini içeren, zaten yüklüdür.

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

İstemci Kodu

adlı client.pybir dosya oluşturun:

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

Çok modüllü iletiler gönderme

AGUIChatClient kullanıcı iletilerindeki metin ve medya bölümlerinin sırasını korur. URI veya satır içi görüntü, ses, video ve belge içeriğini tanımlamak için MIME türü kullanın:

from pathlib import Path

from agent_framework import Content, Message

message = Message(
    role="user",
    contents=[
        Content.from_text("Compare this image with the attached brief."),
        Content.from_uri(
            "https://example.com/product.png",
            media_type="image/png",
        ),
        Content.from_data(
            Path("brief.pdf").read_bytes(),
            media_type="application/pdf",
        ),
    ],
)

await agent.run(message, session=thread)

Önemli Kavramlar

  • Server-Sent Olayları (SSE): Protokol SSE biçimini (data: {json}\n\n) kullanır
  • Olay Türleri: Çeşitli olaylar meta veri ve içerik sağlar (ALT ÇİZGİLİ BÜYÜK HARF).
    • RUN_STARTED: Aracı işlemeye başladı
    • TEXT_MESSAGE_START: Aracının gönderdiği kısa mesajın başlangıcı
    • TEXT_MESSAGE_CONTENT: Aracıdan, delta alanıyla akışa alınan artımlı metin
    • TEXT_MESSAGE_END: Kısa mesaj sonu
    • RUN_FINISHED: Başarılı tamamlama
    • RUN_ERROR: Hata bilgileri
  • Alan Adlandırma: Olay alanları camelCase kullanır (örneğin, threadId, runId, messageId)
  • İş Parçacığı Yönetimi: İstekler threadId arasında konuşma bağlamını korur
  • Client-Side Yönergeleri: Sistem iletileri istemciden gönderilir

İstemciyi Yapılandırma ve Çalıştırma

İsteğe bağlı olarak özel bir sunucu URL'si ayarlayın:

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

İstemciyi çalıştırın (ayrı bir terminalde):

python client.py

3. Adım: Tam Sistemi Test Etme

Hem sunucu hem de istemci çalışırken, artık sistemin tamamını test edebilirsiniz.

Beklenen Çıktı

$ 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

Renk Kodlu Çıktı

İstemci, farklı renklerde farklı içerik türleri görüntüler:

  • Sarı: Başlatılan bildirimleri çalıştırma
  • Cyan: Ajan metin yanıtları (gerçek zamanlı yayın akışı)
  • Yeşil: Tamamlama bildirimlerini çalıştırma
  • Kırmızı: Hata iletileri

Curl ile test etme (İsteğe bağlı)

İstemciyi çalıştırmadan önce curl kullanarak sunucuyu el ile test edebilirsiniz:

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?"}
    ]
  }'

Server-Sent Events akışının geri döndüğünü görmeniz gerekir.

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

Boşta bir akışta curl, : keepalive yorum satırlarını da görüntüleyebilir. Bunlar SSE aktarım açıklamalarıdır, AG-UI olayları değildir.

Nasıl Çalışır?

Server-Side Süreci

  1. İstemci, iletilerle HTTP POST isteği gönderir
  2. FastAPI uç noktası isteği alır
  3. AgentFrameworkAgent sarmalayıcı yürütmeyi koordine eder
  4. Aracı, Agent Framework kullanarak iletileri işler
  5. AgentFrameworkEventBridge aracı güncelleştirmelerini AG-UI olaylara dönüştürür
  6. Yanıtlar Server-Sent Olayları (SSE) olarak geri akışa alınır
  7. Çalıştırma tamamlandığında bağlantı kapatılır

İstemci Tarafı Süreci

  1. İstemci, sunucu uç noktasına HTTP POST isteği gönderir
  2. Sunucu, SSE akışıyla yanıt verir
  3. İstemci gelen data: satırları JSON olayları olarak ayrıştırıyor
  4. Her olay türüne göre görüntülenir
  5. threadId konuşma sürekliliği için kaydedilir
  6. Olay RUN_FINISHED geldiğinde akış tamamlanır

Protokol Ayrıntıları

AG-UI protokolü aşağıdakileri kullanır:

  • İstek göndermek için HTTP POST
  • Sunucu Tarafından Gönderilen Olaylar (SSE) ile akış yanıtları
  • Olay serileştirme için JSON
  • Konuşma bağlamını korumak için iş parçacığı kimliği
  • Tek tek yürütmeleri izlemek için kimlikleri çalıştırma
  • Olay türü adlandırma: Alt çizgili BÜYÜK HARF (ör. , RUN_STARTEDTEXT_MESSAGE_CONTENT)
  • Alan adlandırma: camelCase (örn. , threadIdrunId, messageId)
  • Akış boşta kaldığında, SSE her 15 saniyede bir bağlantıyı canlı tutan yorumlar gönderir. Yalnızca data: satırları işleyen istemciler bu açıklamaları otomatik olarak yoksayar.

Ortak Desenler

A2UI etkileşimli yüzeyleri ekleme

A2UI, bir aracının uyumlu bir AG-UI istemcisinin yanıt akışı olarak oluşturduğu etkileşimli yüzeyler oluşturmasına olanak tanır. İsteğe bağlı A2UI bağımlılığını yükleyin:

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

uv için uv pip install "agent-framework-ag-ui[a2ui]" --prerelease=allow çalıştırın.

Bir uç nokta için A2UI'yi varsayılan olarak etkinleştirmek üzere, arka uç katılımıyla bir a2ui_config geçirin:

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

Ön uç, aşağıdakiler için AG-UI A2UI ara yazılımına veya eşdeğer davranışa ihtiyaç duyar:

  • bileşen kataloğunu ve oluşturma kılavuzunu AG-UI isteği bağlamında sağlayın.
  • Akış olarak iletilen render_a2ui araç bağımsız değişkenlerini yüzey güncellemeleri olarak işleyin.
  • İstek için A2UI'nin ne zaman etkinleştirildiğini ayarlayın forwardedProps.injectA2UITool . Açık false bir değer, bu istek için arka uç kabul etme işlemini geçersiz kılar.

A2UI uç noktasına hizmet veren aracı için kullanın OpenAIChatCompletionClient . İstemcinin yüzeyi aşamalı olarak boyayabilmesi için araç çağrısı bağımsız değişken deltalarını akışla gönderir. Yanıtlar API istemcisi bu aşamalı işleme akışını desteklemez.

Bağdaştırıcı, sağlanan kataloğa göre tamamlanmış bileşen ağaçlarını doğrular. Doğrulama başarısız olursa, doğrulama hatalarını oluşturma istemine ekler ve recovery yapılandırmasına göre yeniden dener. Kurtarma girişimleri başarısız olursa, istemci bir istisna yerine bir başarısızlık zarfı alır.

Eksiksiz uygulamalar için Agent Framework reposunda Python A2UI ajanları ve A2UI uç nokta kurulumu bölümlerine bakın.

Özel Sunucu Yapılandırması

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 pozitif bir sayı veya Noneolmalıdır.

Çoklu Temsilciler

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

Hata İşleme

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

Sorun giderme

Bağlantı Reddedildi

İstemciyi başlatmadan önce sunucunun çalıştığından emin olun:

# Terminal 1
python server.py

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

Kimlik Doğrulaması Hataları

Azure ile kimliğinizin doğrulanmış olduğundan emin olun:

az login

Azure OpenAI kaynağında doğru rol atamasının olduğunu doğrulayın.

Akış Çalışmıyor

İstemci zaman aşımınızın yeterli olup olmadığını denetleyin:

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

Uzun süre çalışan aracılar için buna göre zaman aşımını artırın.

Boşta olan akışlar, varsayılan olarak her 15 saniyede bir SSE keepalive yorumu gönderir. Bir ara sunucu boşta bağlantıları daha kısa sürede kapatıyorsa, uç noktayı kaydederken keepalive_seconds için daha küçük, pozitif bir değer yapılandırın.

İş Parçacığı Bağlamı Kayboldu

İstemci, iş parçacığı sürekliliğini otomatik olarak yönetir. Bağlam kaybolursa:

  1. threadId olaylarından RUN_STARTED'nin yakalanıp yakalanmadığını kontrol edin.
  2. İletiler arasında aynı istemci örneğinin kullanıldığından emin olun
  3. Sunucunun sonraki isteklerde thread_id aldığını doğrulayın.

Sonraki Adımlar

AG-UI'nin temellerini anladığınıza göre şunları yapabilirsiniz:

Ek Kaynaklar

Go, hem sunucular hem de istemciler için provider/aguiprovider aracılığıyla AG-UI’yi destekler.

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

Go uygulamanızın bir AG-UI sunucusunu aracı olarak çağırması gerektiğinde kullanın aguiprovider.NewAgent :

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

Çalıştırılabilir örneklerin tamamı için AG-UI başlarken sunucusu ve istemci örneklerine bakın.