通过


AG-UI 入门

本教程演示如何通过 .NET 或 Python 和代理框架使用 AG-UI 协议生成服务器和客户端应用程序。 你将学习如何创建一个托管 AI 智能代理的 AG-UI 服务器,以及一个与之连接进行交互式对话的客户端。

你将构建的内容

在本教程结束时,你将拥有:

  • 托管可通过 HTTP 访问的 AI 代理的 AG-UI 服务器
  • 连接到服务器并流式传输响应的客户端应用程序
  • 了解 AG-UI 协议如何与代理框架协作

先决条件

在开始之前,请确保具有以下各项:

注释

这些示例使用 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:扩展方法用于注册 AG-UI 终端,并进行自动请求/响应处理以及 SSE 流式传输
  • ChatClientAsIChatClient()AzureOpenAIClient.GetChatClient() 返回 OpenAI 的类型 ChatClientAsIChatClient()扩展方法(源自Microsoft.Extensions.AI.OpenAI)将其转换为 Agent Framework 所需的IChatClient接口
  • AsAIAgent:从IChatClient创建一个Agent Framework代理
  • 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.AI 提供 AsAIAgent() 扩展方法。

客户端代码

创建名为 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:用于访问聊天特定属性的扩展方法,例如 ConversationIdResponseId
  • 会话管理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

颜色编码输出

客户端显示具有不同颜色的不同内容类型:

  • 黄色:运行开始通知
  • 蓝绿色:代理文本响应(实时流式传输)
  • 绿色:运行完成通知
  • 红色:错误消息

工作原理

服务器端流程

  1. 客户端发送包含消息的 HTTP POST 请求
  2. ASP.NET Core 终结点通过 MapAGUI 接收请求
  3. 代理使用代理框架处理消息
  4. 响应将转换为 AG-UI 事件
  5. 事件以服务器发送事件(SSE)的形式流式传输回
  6. 运行完成后,连接将关闭

客户端流

  1. AGUIChatClient 将 HTTP POST 请求发送到服务器终结点
  2. 服务器使用 SSE 流进行响应
  3. 客户端将传入事件分析为 AgentResponseUpdate 对象
  4. 每个更新都基于其内容类型显示
  5. ConversationId 捕获以保持会话连续性
  6. 运行完成后,数据流才结束

协议详细信息

AG-UI 协议使用:

  • 用于发送请求的 HTTP POST
  • 用于流式处理响应的服务器传送事件(SSE)
  • 使用 JSON 进行事件序列化
  • 用于维护会话上下文的线程 ID(as ConversationId
  • 运行 ID(as ResponseId)以跟踪单个执行

后续步骤

了解 AG-UI 的基础知识后,可以:

其他资源

先决条件

在开始之前,请确保具有以下各项:

注释

这些示例使用 Azure OpenAI 模型。 有关详细信息,请参阅 如何使用 Azure AI Foundry 部署 Azure OpenAI 模型

注释

这些示例使用 DefaultAzureCredential 进行身份验证。 确保通过 Azure 进行身份验证(例如,通过 az login)。 有关详细信息,请参阅 Azure 标识文档

警告

AG-UI 协议仍在开发中,可能会发生更改。 随着协议的发展,我们将不断更新这些示例。

步骤 1:创建 AG-UI 服务器

AG-UI 服务器运行和托管你的智能代理,并使用 FastAPI 通过 HTTP 端点公开它。

安装所需的包

安装服务器所需的包:

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

或使用紫外线:

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

这将自动安装 agent-framework-corefastapiuvicorn 作为依赖项。

服务器代码

创建名为 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:注册 AG-UI 端点,具有自动请求/响应处理功能和 SSE 流式传输功能
  • 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:错误信息
  • 字段命名:事件字段使用 camelCase(例如, threadIdrunIdmessageId
  • 线程管理:在跨 threadId 的请求中维护会话上下文
  • 客户端说明:系统消息从客户端发送

配置并运行客户端

(可选)设置自定义服务器 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?"}
    ]
  }'

您将会看到服务器发送事件的流处理:

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

工作原理

服务器端流程

  1. 客户端发送包含消息的 HTTP POST 请求
  2. FastAPI 终结点接收请求
  3. AgentFrameworkAgent 封装器管理执行
  4. 代理使用代理框架处理消息
  5. AgentFrameworkEventBridge 将代理更新转换为 AG-UI 事件
  6. 响应作为服务器发送事件(SSE)被流式传输回
  7. 运行完成后,连接将关闭

客户端流

  1. 客户端将 HTTP POST 请求发送到服务器终结点
  2. 服务器使用 SSE 流进行响应
  3. 客户端将传入 data: 行分析为 JSON 事件
  4. 每个事件都根据其类型显示
  5. threadId 捕获以保持会话连续性
  6. RUN_FINISHED事件到达时,流完成

协议详细信息

AG-UI 协议使用:

  • 用于发送请求的 HTTP POST
  • 用于流式处理响应的服务器传送事件(SSE)
  • 使用 JSON 进行事件序列化
  • 用于维护会话上下文的线程 ID
  • 运行 ID 以跟踪单个执行
  • 事件类型命名:使用大写并用下划线分隔(例如,RUN_STARTEDTEXT_MESSAGE_CONTENT
  • 字段命名:camelCase(例如,threadIdrunIdmessageId

常见模式

自定义服务器配置

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

Troubleshooting

连接被拒绝

在启动客户端之前,请确保服务器正在运行:

# 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

对于长时间运行的软件代理,请相应地增加超时。

线程上下文丢失

客户端会自动管理线程连续性。 如果上下文丢失:

  1. 请检查threadId是否正在从RUN_STARTED事件中捕获
  2. 确保跨消息使用相同的客户端实例
  3. 验证服务器是否在后续请求中接收thread_id

后续步骤

了解 AG-UI 的基础知识后,可以:

其他资源