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 les requêtes AG-UI RunAgentInput et transmet en continu la réponse de l’agent sous forme d’événements AG-UI via des é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 pour identifier les requêtes de continuation. Ces identificateurs sont des données de protocole, et non des informations d’identification d’autorisation.
AGUIChatClient n’a pas d’état. Pour poursuivre une conversation gérée par le serveur, récupérez les identifiants à partir du RunStartedEvent du premier tour, puis incluez le même threadId et le runId précédent en tant que parentRunId dans 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 utilise threadId pour sélectionner la session d’agent hébergé et parentRunId pour identifier l’exécution reprise. 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 plus d’informations sur la limite de confiance spécifique à AG-UI, 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.
Avertissement
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
Ajouter des surfaces interactives A2UI
A2UI permet à un agent de générer des surfaces interactives qu’un client compatible AG-UI affiche en tant que flux de réponse. Installez la dépendance A2UI facultative :
pip install "agent-framework-ag-ui[a2ui]" --pre
Pour uv, exécutez uv pip install "agent-framework-ag-ui[a2ui]" --prerelease=allow.
Pour activer A2UI par défaut pour un point de terminaison, passez un a2ui_config avec l’activation côté backend :
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},
)
Le serveur frontal a besoin du middleware AG-UI A2UI, ou d’un comportement équivalent, pour :
- Fournissez son catalogue de composants et ses conseils de génération dans le contexte de requête AG-UI.
- Affichez les arguments d’outil diffusés en continu
render_a2uisous forme de mises à jour de l’interface. - Définissez
forwardedProps.injectA2UIToolquand A2UI est activé pour une requête. Une valeur explicitefalseremplace l’opt-in principal pour cette demande.
Utilisez OpenAIChatCompletionClient pour l’agent qui héberge le point de terminaison A2UI.
Il diffuse des deltas d’arguments d’appel d’outil afin que le client puisse peindre progressivement la surface. Le client d’API Réponses ne prend pas en charge ce flux de rendu progressif.
L’adaptateur valide les arborescences de composants terminées par rapport au catalogue fourni.
En cas d’échec de la validation, elle ajoute les erreurs de validation à l’invite de génération et réessaye en fonction de la recovery configuration. Si la récupération est épuisée, le client reçoit une enveloppe d’échec au lieu d’une exception.
Pour des implémentations complètes, consultez les agents A2UI pour Python et la configuration du point de terminaison A2UI dans le référentiel Agent Framework.
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.