本教學課程示範如何使用 AG-UI 通訊協定搭配 .NET 或 Python 和代理程式架構來建置伺服器和用戶端應用程式。 您將學習如何建立託管 AI 代理的 AG-UI 伺服器以及連接到它進行互動式對話的用戶端。
您將構建什麼
在本教學課程結束時,您將擁有:
- 託管可通過 HTTP 訪問的 AI 代理的 AG-UI 服務器
- 連線到伺服器並串流回應的用戶端應用程式
- 了解 AG-UI 協定如何與代理程式框架搭配使用
先決條件
在開始之前,請確保您具備以下條件:
- .NET 8.0 或更新版本
- 已設定 Azure OpenAI 服務端點和部署
- 已安裝並驗證Azure CLI
- 使用者在 Azure OpenAI 資源中具有
Cognitive Services OpenAI Contributor角色
備註
這些範例會使用 Azure OpenAI 模型。 如需詳細資訊,請參閱 如何使用 Azure AI Foundry 部署 Azure OpenAI 模型。
備註
這些範例用於 DefaultAzureCredential 驗證。 請確定您已向 Azure 進行驗證 (例如,透過 az login)。 如需詳細資訊,請參閱 Azure 身分識別檔。
警告
AG-UI 協議仍在開發中,可能會發生變化。 隨著協議的發展,我們將不斷更新這些樣本。
第 1 步:建立 AG-UI 伺服器
AG-UI 伺服器託管您的 AI 代理程式,並使用 ASP.NET Core 透過 HTTP 端點公開它。
備註
伺服器專案需要 Microsoft.NET.Sdk.Web SDK。 如果您要從頭開始建立新專案,請使用 dotnet new web,或確保您的 .csproj 檔案使用 <Project Sdk="Microsoft.NET.Sdk.Web"> 而不是 Microsoft.NET.Sdk。
安裝必要的套件
安裝伺服器所需的套件:
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
備註
Microsoft.Extensions.AI.OpenAI套件是AsIChatClient()擴充方法所需,用於將OpenAI的ChatClient轉換為代理程式架構預期的IChatClient介面。
伺服器代碼
建立名為 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();
重要概念
-
AddAGUI:向相依注入容器註冊 AG-UI 服務 -
MapAGUI:使用自動要求/回應處理和 SSE 串流註冊 AG-UI 端點的擴充方法 -
ChatClient和AsIChatClient():AzureOpenAIClient.GetChatClient()傳回 OpenAI 的ChatClient類型。AsIChatClient()擴充方法(fromMicrosoft.Extensions.AI.OpenAI)將其轉換為IChatClient代理框架所需的介面 -
AsAIAgent:從IChatClient創建一個代理框架代理 - ASP.NET Core 集成: 使用 ASP.NET Core 的原生非同步支持進行流式回應
- 指示:代理程式是使用預設指示建立的,用戶端訊息可以覆寫這些指示
-
配置:
AzureOpenAIClient和DefaultAzureCredential提供安全的身份驗證
設定並執行伺服器
設定必要的環境變數:
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini"
執行伺服器:
dotnet run --urls http://localhost:8888
伺服器將開始監聽 http://localhost:8888。
備註
在步驟 2 中設定並執行用戶端時,讓此伺服器保持執行。 伺服器和用戶端都需要同時執行,整個系統才能運作。
第 2 步:建立 AG-UI 客戶端
AG-UI 用戶端會連線到遠端伺服器,並顯示串流回應。
這很重要
在執行用戶端之前,請確定步驟 1 中的 AG-UI 伺服器已在 http://localhost:8888 啟動。
安裝必要的套件
安裝 AG-UI 用戶端程式庫:
dotnet add package Microsoft.Agents.AI.AGUI --prerelease
dotnet add package Microsoft.Agents.AI --prerelease
備註
套件提供Microsoft.Agents.AIAsAIAgent()擴充方法。
用戶端代碼
建立名為 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}");
}
重要概念
- Server-Sent 事件 (SSE):該協定使用 SSE 進行串流回應
-
AGUIChatClient:連線到 AG-UI 伺服器並實作的用戶端類別
IChatClient -
AsAIAgent:在
AGUIChatClient上擴充方法以便從客戶端創建代理 -
RunStreamingAsync:將回應串流為
AgentResponseUpdate物件 -
AsChatResponseUpdate:用於存取聊天特定屬性的擴充方法,例如
ConversationId和ResponseId -
會話管理:
AgentSession維持對話上下文跨請求的連續性 -
內容類型:回應包括
TextContent訊息和ErrorContent錯誤
設定並執行用戶端
選擇性地設定自訂伺服器 URL:
export AGUI_SERVER_URL="http://localhost:8888"
在單獨的終端機中運行客戶端(確保步驟1中的服務器正在運行):
dotnet run
第 3 步:測試整個系統
伺服器和用戶端都執行完畢後,您現在可以測試整個系統。
預期輸出
$ 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
色彩標記輸出
用戶端會以不同的色彩顯示不同的內容類型:
- 黃色:運行已開始通知
- 青色:客服專員文字回應(即時串流)
- 綠色:執行完成通知
- 紅色:錯誤訊息
運作方式
伺服器端流程
- 用戶端傳送 HTTP POST 要求,並附有訊息
- ASP.NET 核心端點會透過
MapAGUI - 代理程式會使用 Agent Framework 處理訊息
- 回應被轉換為 AG-UI 事件
- 事件會以伺服器發送事件(SSE)的形式串流回來
- 執行完成時連線會關閉
用戶端流程
-
AGUIChatClient將 HTTP POST 要求傳送至伺服器端點 - 伺服器以 SSE 串流回應
- 用戶端會將傳入事件剖解析為
AgentResponseUpdate物件 - 每個更新都會根據其內容類型顯示
-
ConversationId會被捕捉以維持對話的連續性 - 運行結束時,串流結束
協議詳細信息
AG-UI 協定使用:
- HTTP POST 用於傳送請求
- 伺服器傳送事件 (SSE) 用於串流回應
- 用於事件序列化的 JSON
- 用於維護交談內容的執行緒識別碼 (as
ConversationId) - 執行 ID (作為
ResponseId) ,用於追蹤個別執行
後續步驟
現在您已瞭解 AG-UI 的基本概念,您可以:
- 添加後端工具: 為您的域名創建自定義功能工具
其他資源
先決條件
在開始之前,請確保您具備以下條件:
- Python 3.10 或更新版本
- 已設定 Azure OpenAI 服務端點和部署
- 已安裝並驗證Azure CLI
- 使用者在 Azure OpenAI 資源中具有
Cognitive Services OpenAI Contributor角色
備註
這些範例會使用 Azure OpenAI 模型。 如需詳細資訊,請參閱 如何使用 Azure AI Foundry 部署 Azure OpenAI 模型。
備註
這些範例用於 DefaultAzureCredential 驗證。 請確定您已向 Azure 進行驗證 (例如,透過 az login)。 如需詳細資訊,請參閱 Azure 身分識別檔。
警告
AG-UI 協議仍在開發中,可能會發生變化。 隨著協議的發展,我們將不斷更新這些樣本。
第 1 步:建立 AG-UI 伺服器
AG-UI 伺服器託管您的 AI 代理,並使用 FastAPI 透過 HTTP 端點公開它。
安裝必要的套件
安裝伺服器所需的套件:
pip install agent-framework-ag-ui --pre
或使用 uv:
uv pip install agent-framework-ag-ui --prerelease=allow
這將自動安裝 agent-framework-core、 fastapi和 uvicorn 作為依賴項。
伺服器代碼
建立名為 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)
重要概念
-
add_agent_framework_fastapi_endpoint:使用自動請求/回應處理和 SSE 串流註冊 AG-UI 端點 -
Agent:將處理傳入要求的 Agent Framework 代理程式 - FastAPI 集成: 使用 FastAPI 的原生非同步支持進行流式響應
- 指示:代理程式是使用預設指示建立的,用戶端訊息可以覆寫這些指示
-
配置:
AzureOpenAIChatClient從環境變數讀取或直接接受參數
設定並執行伺服器
設定必要的環境變數:
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini"
執行伺服器:
python server.py
或直接使用 uvicorn:
uvicorn server:app --host 127.0.0.1 --port 8888
伺服器將開始監聽 http://127.0.0.1:8888。
第 2 步:建立 AG-UI 客戶端
AG-UI 用戶端會連線到遠端伺服器,並顯示串流回應。
安裝必要的套件
AG-UI 套件已安裝,其中包括AGUIChatClient:
# Already installed with agent-framework-ag-ui
pip install agent-framework-ag-ui --pre
用戶端代碼
建立名為 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())
重要概念
-
Server-Sent 事件(SSE):協定使用SSE格式(
data: {json}\n\n) -
事件類型:不同的事件提供元資料和內容(大寫且帶有底線):
-
RUN_STARTED:客服專員已開始處理 -
TEXT_MESSAGE_START:客服專員的簡訊開始 -
TEXT_MESSAGE_CONTENT:從客服專員串流的增量文字 (含delta欄位) -
TEXT_MESSAGE_END:簡訊結束 -
RUN_FINISHED: 成功完成 -
RUN_ERROR:錯誤資訊
-
-
欄位命名:事件欄位使用駝峰命名法(例如,
threadIdrunIdmessageId) -
執行緒管理:
threadId負責維護跨不同請求的對話內容語境 - Client-Side 說明:系統訊息是從用戶端傳送的
設定並執行用戶端
選擇性地設定自訂伺服器 URL:
export AGUI_SERVER_URL="http://127.0.0.1:8888/"
執行用戶端 (在個別的終端機中):
python client.py
第 3 步:測試整個系統
伺服器和用戶端都執行完畢後,您現在可以測試整個系統。
預期輸出
$ 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
色彩標記輸出
用戶端會以不同的色彩顯示不同的內容類型:
- 黃色:運行已開始通知
- 青色:客服專員文字回應(即時串流)
- 綠色:執行完成通知
- 紅色:錯誤訊息
使用 curl 進行測試 (選用)
在執行用戶端之前,您可以使用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?"}
]
}'
您應該會看到 Server-Sent 事件串流回來:
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":"..."}
運作方式
伺服器端流程
- 用戶端傳送 HTTP POST 要求,並附有訊息
- FastAPI 端點接收請求
-
AgentFrameworkAgent包裝器會協調執行 - 代理程式會使用 Agent Framework 處理訊息
-
AgentFrameworkEventBridge將客服專員更新轉換為 AG-UI 事件 - 回應會以 Server-Sent 事件 (SSE) 的形式串流回來
- 執行完成時連線會關閉
用戶端流程
- 用戶端將 HTTP POST 要求傳送至伺服器端點
- 伺服器以 SSE 串流回應
- 客戶端會將傳入的
data:行解析為 JSON 事件 - 每個事件都會根據其類型顯示
-
threadId會被捕捉以維持對話的連續性 -
RUN_FINISHED串流會在事件到達時完成
協議詳細信息
AG-UI 協定使用:
- HTTP POST 用於傳送請求
- 伺服器傳送事件 (SSE) 用於串流回應
- 用於事件序列化的 JSON
- 用於維護交談內容的執行緒識別碼
- 用於追蹤個別執行的執行 ID
- 事件類型命名:大寫並帶有底線(例如,
RUN_STARTED,TEXT_MESSAGE_CONTENT) - 欄位命名:駝峰命名法(例如,
threadId,runId,messageId)
常見模式
自訂伺服器配置
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")
多個代理程式
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")
錯誤處理
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}")
故障排除
連線被拒絕
在啟動用戶端之前,請確定伺服器正在執行:
# Terminal 1
python server.py
# Terminal 2 (after server starts)
python client.py
身份驗證錯誤
請確定您已向 Azure 進行驗證:
az login
確認您在 Azure OpenAI 資源上具有正確的角色指派。
串流無法運作
檢查您的客戶端超時設定是否足夠:
httpx.AsyncClient(timeout=60.0) # 60 seconds should be enough
對於長時間執行的代理程式,請適當地增加等待時間。
執行緒內容已遺失
用戶端會自動管理執行緒連續性。 如果內容遺失:
- 檢查
threadId是否從RUN_STARTED的事件中擷取 - 確保在不同的訊息中使用相同的用戶端執行個體
- 確認伺服器是否在後續請求中接收
thread_id
後續步驟
現在您已瞭解 AG-UI 的基本概念,您可以:
- 添加後端工具: 為您的域名創建自定義功能工具