Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Lernprogramm wird das Erstellen von Server- und Clientanwendungen mithilfe des AG-UI-Protokolls mit Agent Framework veranschaulicht. Sie erfahren, wie Sie einen Agent hinter einem AG-UI Endpunkt hosten und einen Client für interaktive Unterhaltungen verbinden.
Was Sie erstellen werden
Am Ende dieses Lernprogramms haben Sie Folgendes:
- Ein AG-UI Server, auf den ein KI-Agent gehostet wird, auf den über HTTP zugegriffen werden kann
- Eine Clientanwendung, die eine Verbindung mit dem Server herstellt und Antworten streamt
- Grundlegendes zur Funktionsweise des AG-UI-Protokolls mit Agent Framework
Voraussetzungen
- .NET 8 oder höher
- Ein ASP.NET Core Projekt
- Ein konfiguriertes MAF
AIAgent
Im Beispiel wird Azure OpenAI verwendet, funktioniert jedoch MapAGUIServer mit jedem MAF-Agent.
Erstellen eines AG-UI Servers
Installieren Sie das Hostingpaket:
dotnet add package Microsoft.Agents.AI.Hosting.AGUI.AspNetCore --prerelease
Registrieren Sie das AG-UI-Hosting und ordnen Sie Ihren Agenten zu:
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 akzeptiert AG-UI RunAgentInput Anfragen und überträgt die Antwort des Agenten als AG-UI-Ereignisse über Server-Sent Events (SSE).
Führen Sie den Server auf der url aus, die vom Clientbeispiel verwendet wird:
dotnet run --urls http://localhost:8888
Tip
Sehen Sie sich das .NET Beispiel für erste Schritte für einen vollständigen Server- und Konsolenclient an.
Herstellen einer Verbindung mit einem .NET-Client
Das AG-UI .NET SDK bietet AGUIChatClient, das implementiert IChatClient und an einen MAF-Agent angepasst werden kann:
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);
}
}
Sie können auch eine Verbindung mit jedem Client herstellen, der das AG-UI-Protokoll implementiert.
Konversationskontinuität
AG-UI verwendet threadId und parentRunId zur Identifizierung von Fortsetzungsanfragen. Diese Bezeichner sind Protokolldaten, keine Autorisierungsanmeldeinformationen.
AGUIChatClient ist zustandslos. Um eine serverseitige Konversation fortzusetzen, rufen Sie die Bezeichner aus dem RunStartedEvent der ersten Nachricht ab und geben Sie dann in der nächsten Anfrage dieselbe threadId und die vorherige runId als parentRunId mit:
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.
}
Senden Sie nur die neuen Nachrichten in einer Fortsetzungsanforderung.
MapAGUIServer verwendet threadId, um die gehostete Agent-Sitzung auszuwählen, und parentRunId, um den fortgesetzten Lauf zu identifizieren. Ohne gehostete Sitzungspersistenz empfängt jede Anforderung eine neue Serversitzung; der Client kann stattdessen den Unterhaltungsverlauf erneut senden.
Um den servereigenen AgentSession Zustand über Anforderungen hinweg beizubehalten, konfigurieren Sie die Persistenz und Isolation der gehosteten Sitzung, und ordnen Sie dann den benannten gehosteten Agent zu MapAGUIServer. Informationen zur AG-UI-spezifischen Vertrauensgrenze finden Sie unter Produktions- und Sicherheitsaspekte.
Nächste Schritte
Verwandte Ressourcen
Voraussetzungen
Bevor Sie beginnen, sollten Sie sicherstellen, dass Folgendes vorhanden ist:
- Python 3.10 oder höher
- Azure OpenAI-Dienstendpunkt und -Bereitstellung konfiguriert
- Azure CLI installiert und authentifiziert
- Der Benutzer hat die
Cognitive Services OpenAI ContributorRolle für die Azure OpenAI-Ressource
Note
In diesen Beispielen werden Azure OpenAI-Modelle verwendet. Weitere Informationen finden Sie in der Bereitstellung von Azure OpenAI-Modellen mit Foundry.
Note
In diesen Beispielen wird DefaultAzureCredential zur Authentifizierung verwendet. Stellen Sie sicher, dass Sie bei Azure authentifiziert sind (z. B. über az login). Weitere Informationen finden Sie in der Azure Identity-Dokumentation.
Warning
Das AG-UI Protokoll befindet sich noch in der Entwicklung und kann geändert werden. Wir werden diese Beispiele aktualisieren, während sich das Protokoll weiterentwickelt.
Schritt 1: Erstellen eines AG-UI Servers
Der AG-UI-Server hostet Ihren KI-Agent und macht ihn über HTTP-Endpunkte mit FastAPI verfügbar.
Erforderliche Pakete installieren
Installieren Sie die erforderlichen Pakete für den Server:
pip install agent-framework-ag-ui --pre
Oder uv verwenden:
uv pip install agent-framework-ag-ui --prerelease=allow
Dadurch werden agent-framework-core, fastapi, uvicorn und sse-starlette automatisch als Abhängigkeiten installiert.
Servercode
Erstellen einer Datei mit dem Namen 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)
Wichtige Konzepte
-
add_agent_framework_fastapi_endpoint: Registriert den AG-UI Endpunkt mit automatischer Anforderungs-/Antwortbehandlung und SSE-Streaming -
Agent: Der Agent Framework-Agent, der eingehende Anforderungen verarbeitet - FastAPI-Integration: Verwendet die systemeigene asynchrone Unterstützung von FastAPI für Streamingantworten
- Anweisungen: Der Agent wird mit Standardanweisungen erstellt, die von Clientnachrichten überschrieben werden können.
-
Konfiguration:
OpenAIChatCompletionClientakzeptiert explizite Azure-Routingeingaben wiemodel,azure_endpoint,api_version, undcredential, und kann auch aus Umgebungsvariablen lesen
Konfigurieren und Ausführen des Servers
Legen Sie die erforderlichen Umgebungsvariablen fest:
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_CHAT_COMPLETION_MODEL="gpt-4o-mini"
Führen Sie den Server aus:
python server.py
Oder verwenden Sie uvicorn direkt:
uvicorn server:app --host 127.0.0.1 --port 8888
Der Server beginnt auf http://127.0.0.1:8888 zu lauschen.
Schritt 2: Erstellen eines AG-UI-Clients
Der AG-UI-Client verbindet sich mit dem Remoteserver und zeigt Streaming-Antworten an.
Erforderliche Pakete installieren
Das AG-UI-Paket ist bereits installiert, einschließlich: AGUIChatClient
# Already installed with agent-framework-ag-ui
pip install agent-framework-ag-ui --pre
Kundencode
Erstellen einer Datei mit dem Namen 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())
Wichtige Konzepte
-
Server-Sent Events (SSE):Das Protokoll verwendet das SSE-Format (
data: {json}\n\n) -
Ereignistypen: Verschiedene Ereignisse stellen Metadaten und Inhalte bereit (UPPERCASE mit Unterstrichen):
-
RUN_STARTED: Agent hat mit der Verarbeitung begonnen -
TEXT_MESSAGE_START: Beginn einer Textnachricht vom Agent -
TEXT_MESSAGE_CONTENT: Inkrementeller Text, der vom Agent gestreamt wurde (mitdeltaFeld) -
TEXT_MESSAGE_END: Ende einer Textnachricht -
RUN_FINISHED: Erfolgreicher Abschluss -
RUN_ERROR: Fehlerinformationen
-
-
Feldbenennung: Ereignisfelder verwenden camelCase (z. B.
threadId, ,runId)messageId -
Threadverwaltung: Das
threadIdverwaltet den Gesprächskontext über Anfragen hinweg. - Client-Side Anweisungen: Vom Client gesendete Systemnachrichten
Konfigurieren und Ausführen des Clients
Optional eine benutzerdefinierte Server-URL festlegen:
export AGUI_SERVER_URL="http://127.0.0.1:8888/"
Führen Sie den Client aus (in einem separaten Terminal):
python client.py
Schritt 3: Testen des vollständigen Systems
Wenn sowohl der Server als auch der Client ausgeführt wird, können Sie jetzt das vollständige System testen.
Erwartete Ausgabe
$ 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
Farbkodierte Ausgabe
Der Client zeigt verschiedene Inhaltstypen mit unterschiedlichen Farben an:
- Gelb: Gestartete Benachrichtigungen ausführen
- Cyan: Agent-Textantworten (in Echtzeit gestreamt)
- Grün: Ausführen von Abschlussbenachrichtigungen
- Rot: Fehlermeldungen
Testen mit curl (optional)
Bevor Sie den Client ausführen, können Sie den Server manuell mit curl testen:
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?"}
]
}'
Sie sollten das Streaming von Server-Sent-Events wieder sehen.
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":"..."}
Bei einem inaktiven Datenstrom kann curl auch : keepaliveKommentarzeilen anzeigen. Hierbei handelt es sich um SSE-Transportkommentare, nicht AG-UI Ereignisse.
Funktionsweise
Server-Side Ablauf
- Client sendet HTTP POST-Anforderung mit Nachrichten
- Der FastAPI-Endpunkt empfängt die Anforderung.
-
AgentFrameworkAgentWrapper orchestriert die Ausführung - Agent verarbeitet die Nachrichten mithilfe von Agent Framework
-
AgentFrameworkEventBridgekonvertiert Agentupdates in AG-UI Ereignisse - Antworten werden als Server-Sent Events (SSE) zurückübertragen.
- Die Verbindung schließt, wenn der Lauf abgeschlossen ist.
Client-seitiger Ablauf
- Client sendet HTTP POST-Anforderung an den Serverendpunkt
- Server antwortet mit SSE-Stream
- Client analysiert eingehende
data:Zeilen als JSON-Ereignisse - Jedes Ereignis wird basierend auf seinem Typ angezeigt.
-
threadIdwird zur Wahrung der Gesprächskontinuität erfasst. - Der Stream wird abgeschlossen, wenn das
RUN_FINISHEDEreignis eintrifft.
Protokolldetails
Das AG-UI Protokoll verwendet:
- HTTP POST zum Senden von Anforderungen
- Server-Sent Events (SSE) für Streamingantworten
- JSON für die Ereignis serialisierung
- Thread-IDs zur Aufrechterhaltung des Gesprächskontexts
- Ausführen von IDs zum Nachverfolgen einzelner Ausführungen
- Benennung des Ereignistyps: GROßBUCHSTABEN mit Unterstrichen (z. B.
RUN_STARTED,TEXT_MESSAGE_CONTENT) - Feldbenennung: camelCase (z. B.,
threadId,runId,messageId) - SSE-Keepalive-Kommentare alle 15 Sekunden senden, wenn ein Stream inaktiv ist. Clients, die nur
data:Zeilen verarbeiten, ignorieren diese Kommentare automatisch.
Allgemeine Muster
Benutzerdefinierte Serverkonfiguration
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 muss eine positive Zahl oder None sein.
Mehrere 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")
Fehlerbehandlung
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
Verbindung verweigert
Stellen Sie sicher, dass der Server ausgeführt wird, bevor Sie den Client starten:
# Terminal 1
python server.py
# Terminal 2 (after server starts)
python client.py
Authentifizierungsfehler
Stellen Sie sicher, dass Sie bei Azure authentifiziert sind:
az login
Stellen Sie sicher, dass Sie über die richtige Rollenzuweisung für die Azure OpenAI-Ressource verfügen.
Streaming funktioniert nicht
Überprüfen Sie, ob Ihr Client-Timeout angemessen ist:
httpx.AsyncClient(timeout=60.0) # 60 seconds should be enough
Erhöhen Sie bei lang laufenden Agenten das Timeout entsprechend.
Inaktive Streams senden standardmäßig alle 15 Sekunden einen SSE-Keepalive-Kommentar. Wenn ein Proxy Leerlaufverbindungen schneller schließt, konfigurieren Sie beim Registrieren des Endpunkts einen kleineren positiven keepalive_seconds Wert.
Threadkontext verloren
Der Client verwaltet automatisch die Threadkontinuität. Wenn der Kontext verloren geht:
- Überprüfen, ob
threadIdausRUN_STARTEDEreignissen erfasst wird - Stellen Sie sicher, dass dieselbe Clientinstanz über alle Nachrichten hinweg verwendet wird
- Überprüfen Sie, ob der Server das
thread_idbei den nachfolgenden Anfragen empfängt.
Nächste Schritte
Nachdem Sie nun die Grundlagen der AG-UI verstanden haben, können Sie:
- Hinzufügen von Back-End-Tools: Erstellen von benutzerdefinierten Funktionstools für Ihre Domäne
Zusätzliche Ressourcen
Go unterstützt AG-UI über provider/aguiprovider sowohl für Server als auch für 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)
}
Verwenden Sie aguiprovider.NewAgent, wenn Ihre Go-App einen AG-UI-Server als Agent aufrufen muss:
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
Siehe die AG-UI-Beispiele für den Einstieg mit dem Server und dem Client für vollständige ausführbare Beispiele.