Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Ce tutoriel montre comment générer des applications serveur et clientes à l’aide du protocole AG-UI avec Agent Framework. Vous allez apprendre à héberger un agent derrière un point de terminaison AG-UI et à connecter un client pour des conversations interactives.
Ce que vous allez construire
À la fin de ce tutoriel, vous disposez des points suivants :
- Un serveur AG-UI hébergeant un agent IA accessible via HTTP
- Application cliente qui se connecte au serveur et diffuse des réponses
- Compréhension du fonctionnement du protocole AG-UI avec Agent Framework
Prerequisites
- .NET 8 ou version ultérieure
- Un projet ASP.NET Core
- Un MAF configuré
AIAgent
L’exemple utilise Azure OpenAI, mais MapAGUIServer fonctionne avec n’importe quel agent MAF.
Créer un serveur AG-UI
Installez le package d’hébergement :
dotnet add package Microsoft.Agents.AI.Hosting.AGUI.AspNetCore --prerelease
Inscrivez AG-UI hébergement et mappez votre agent :
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 accepte AG-UI RunAgentInput demandes et diffuse la réponse de l’agent en tant qu’événements AG-UI sur les événements envoyés par le serveur (SSE).
Exécutez le serveur sur l’URL utilisée par l’exemple client :
dotnet run --urls http://localhost:8888
Tip
Consultez l’exemple de prise en main .NET pour un client de serveur et de console complet.
Se connecter avec un client .NET
Le sdk AG-UI .NET fournit AGUIChatClient, qui implémente IChatClient et peut être adapté à un agent MAF :
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);
}
}
Vous pouvez également vous connecter à n’importe quel client qui implémente le protocole AG-UI.
Continuité des conversations
AG-UI utilise threadId et parentRunId identifie les demandes de continuation. Ces identificateurs sont des données de protocole, et non des informations d’identification d’autorisation.
AGUIChatClient est sans état. Pour poursuivre une conversation appartenant au serveur, obtenez les identificateurs du premier tour RunStartedEvent, puis incluez le même et le précédent threadIdrunId que parentRunId lors de la requête suivante :
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.
}
Envoyez uniquement les nouveaux messages dans une demande de continuation.
MapAGUIServer permet threadId de sélectionner la session de l’agent hébergé et parentRunId d’identifier l’exécution en cours de poursuite. Sans persistance de session hébergée, chaque requête reçoit une nouvelle session de serveur ; le client peut à la place renvoyer l’historique des conversations.
Pour conserver l’état du AgentSession serveur entre les requêtes, configurez la persistance et l’isolation de session hébergée, puis mappez l’agent hébergé nommé avec MapAGUIServer. Pour connaître la limite d’approbation spécifique à l’interface utilisateur du groupe de disponibilité, consultez les considérations relatives à la production et à la sécurité.
Étapes suivantes
Ressources associées
Prerequisites
Avant de commencer, vérifiez que vous disposez des éléments suivants :
- Python 3.10 ou version ultérieure
- Point de terminaison et déploiement du service Azure OpenAI configurés
- Azure CLI installé et authentifié
- L’utilisateur a le
Cognitive Services OpenAI Contributorrôle pour la ressource Azure OpenAI
Note
Ces exemples utilisent des modèles Azure OpenAI. Pour plus d’informations, consultez comment déployer des modèles Azure OpenAI avec Foundry.
Note
Ces exemples utilisent DefaultAzureCredential pour l’authentification. Vérifiez que vous êtes authentifié auprès d’Azure (par exemple, via az login). Pour plus d’informations, consultez la documentation d’Azure Identity.
Warning
Le protocole AG-UI est toujours en cours de développement et peut être modifié. Nous allons conserver ces exemples mis à jour à mesure que le protocole évolue.
Étape 1 : Création d’un serveur AG-UI
Le serveur AG-UI héberge votre agent IA et l’expose via des points de terminaison HTTP à l’aide de FastAPI.
Installer les packages requis
Installez les packages nécessaires pour le serveur :
pip install agent-framework-ag-ui --pre
Ou en utilisant UV :
uv pip install agent-framework-ag-ui --prerelease=allow
Cela installera automatiquement agent-framework-core, fastapi, uvicorn et sse-starlette comme dépendances.
Code du serveur
Créez un fichier nommé 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)
Concepts clés
-
add_agent_framework_fastapi_endpoint: enregistre le point de terminaison AG-UI incluant la gestion automatique des demandes/réponses et la diffusion en continu SSE -
Agent: Agent Framework qui gère les demandes entrantes - Intégration de FastAPI : utilise la prise en charge asynchrone native de FastAPI pour les réponses de streaming
- Instructions : l’agent est créé avec des instructions par défaut, qui peuvent être remplacées par des messages clients
-
Configuration :
OpenAIChatCompletionClientaccepte des entrées de routage Azure explicites telles quemodel,azure_endpoint,api_versionetcredentialpeut également lire à partir de variables d’environnement
Configurer et exécuter le serveur
Définissez les variables d’environnement requises :
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_CHAT_COMPLETION_MODEL="gpt-4o-mini"
Exécutez le serveur :
python server.py
Ou en utilisant directement uvicorn :
uvicorn server:app --host 127.0.0.1 --port 8888
Le serveur va commencer à écouter http://127.0.0.1:8888.
Étape 2 : Création d’un client AG-UI
Le client AG-UI se connecte au serveur distant et affiche les réponses en streaming.
Installer les packages requis
Le package AG-UI est déjà installé, ce qui inclut les AGUIChatClientéléments suivants :
# Already installed with agent-framework-ag-ui
pip install agent-framework-ag-ui --pre
Client Code
Créez un fichier nommé 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())
Concepts clés
-
Server-Sent Events (SSE) : le protocole utilise le format SSE (
data: {json}\n\n) -
Types d’événements : différents événements fournissent des métadonnées et du contenu (MAJUSCULES soulignées) :
-
RUN_STARTED: l’agent a démarré le traitement -
TEXT_MESSAGE_START: Début d’un message texte de l’agent -
TEXT_MESSAGE_CONTENT: texte incrémentiel diffusé par l'agent (avec le champdelta) -
TEXT_MESSAGE_END: Fin d’un sms -
RUN_FINISHED:Achèvement réussi -
RUN_ERROR: Informations sur l’erreur
-
-
Nommage de champ : les champs d’événement utilisent camelCase (par exemple,
threadId,runId,messageId) -
Gestion des threads : le
threadIdcontextualise le contexte de conversation entre les demandes - Client-Side Instructions : les messages système sont envoyés à partir du client
Configurer et exécuter le client
Définissez éventuellement une URL de serveur personnalisée :
export AGUI_SERVER_URL="http://127.0.0.1:8888/"
Exécutez le client (dans un terminal distinct) :
python client.py
Étape 3 : Tester le système complet
Avec le serveur et le client en cours d’exécution, vous pouvez maintenant tester le système complet.
Sortie attendue
$ 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
Sortie Codée par Couleur
Le client affiche différents types de contenu avec des couleurs distinctes :
- Jaune : Exécuter les notifications démarrées
- Cyan : Réponses de texte de l’agent (diffusées en temps réel)
- Vert : Notifications d’exécution
- Rouge : Messages d’erreur
Test avec curl (facultatif)
Avant d’exécuter le client, vous pouvez tester le serveur manuellement à l’aide de 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?"}
]
}'
Vous devriez voir le flux des Server-Sent Events :
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":"..."}
Pour un flux inactif, curl peut également afficher des : keepalive lignes de commentaire. Il s’agit de commentaires de transport SSE, et non d’événements AG-UI.
Fonctionnement
flux du côté serveur
- Le client envoie une requête HTTP POST avec des messages
- Le point de terminaison FastAPI reçoit la requête
-
AgentFrameworkAgentun wrapper orchestre l’exécution - Agent traite les messages à l’aide d’Agent Framework
-
AgentFrameworkEventBridgeconvertit les mises à jour de l’agent en événements AG-UI - Les réponses sont diffusées en flux continu sous forme d'événements émis par le serveur (SSE)
- La connexion se ferme une fois l’exécution terminée
Flux Côté Client
- Le client envoie une requête HTTP POST au point de terminaison du serveur
- Le serveur répond avec le flux SSE
- Le client analyse les lignes entrantes
data:en tant qu’événements JSON - Chaque événement est affiché en fonction de son type
-
threadIdest capturé pour la continuité des conversations - Le flux se termine lorsque l'événement
RUN_FINISHEDarrive.
Détails du protocole
Le protocole AG-UI utilise :
- HTTP POST pour l’envoi de requêtes
- Événements émis par le serveur (SSE) pour les réponses en streaming
- JSON pour la sérialisation d’événements
- ID de thread pour la maintenance du contexte de conversation
- Identifiants d'exécution pour le suivi des exécutions individuelles
- Nommage de type d’événement : UPPERCASE avec traits de soulignement (par exemple,
RUN_STARTED,TEXT_MESSAGE_CONTENT) - Nommage de champ : camelCase (par exemple,
threadId,runId,messageId) - Commentaires keepalive SSE toutes les 15 secondes pendant qu’un flux est inactif. Les clients qui traitent uniquement les lignes
data:ignorent automatiquement ces commentaires.
Modèles courants
Configuration de serveur personnalisée
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 doit être un nombre positif ou None.
Agents multiples
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")
Gestion des erreurs
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
Connexion refusée
Vérifiez que le serveur est en cours d’exécution avant de démarrer le client :
# Terminal 1
python server.py
# Terminal 2 (after server starts)
python client.py
Erreurs d’authentification
Vérifiez que vous êtes authentifié auprès d’Azure :
az login
Vérifiez que vous disposez de l’attribution de rôle correcte sur la ressource Azure OpenAI.
Streaming non opérationnel
Vérifiez que le temps d'attente pour votre client est suffisant.
httpx.AsyncClient(timeout=60.0) # 60 seconds should be enough
Pour les agents fonctionnant sur de longues périodes, ajustez le délai d'attente en conséquence.
Les flux inactifs émettent un commentaire keepalive SSE toutes les 15 secondes par défaut. Si un proxy ferme les connexions inactives plus tôt, configurez une valeur positive keepalive_seconds plus petite lors de l’inscription du point de terminaison.
Contexte de thread perdu
Le client gère automatiquement la continuité des threads. Si le contexte est perdu :
- Vérifiez que
threadIdsoit capturé à partir des événementsRUN_STARTED - Vérifiez que la même instance cliente est utilisée entre les messages
- Vérifiez que le serveur reçoit le
thread_iddans les demandes suivantes
Prochaines étapes
Maintenant que vous comprenez les principes de base de l'AG-UI, vous pouvez :
- Ajouter des outils back-end : créer des outils de fonction personnalisés pour votre domaine
Ressources additionnelles
Go prend en charge AG-UI via provider/aguiprovider, pour les serveurs comme pour les 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)
}
Utilisez aguiprovider.NewAgent quand votre application Go doit appeler un serveur AG-UI en tant qu’agent :
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
Consultez les exemples de serveur de prise en main AG-UI et de client pour obtenir des exemples complets et fonctionnels.