AG-UI代理界面协议演示

一个展示AG-UI(代理-用户界面)协议的演示应用,结合CopilotKit,通过.NET 9后端和Next.js前端实现,支持四种由Azure OpenAI驱动的AI代理场景。

  • by shoebsd31
  • C#
  • 本地部署
  • 更新于
在 GitHub 查看 shoebsd31/ag-ui-multiple-mcp-servers-azure-foundry

使用说明

AG-UI演示工作区

演示应用程序展示了 AG-UI(代理用户界面)协议 随着 复印机套件 --以a为特色。NET 9后端和Next.js前端,带有4个由Azure OpenAI支持的AI代理场景。

这是 非 4台独立的服务器。这是一个单一的。NET后端暴露了4个AG-UI端点,由单个Next.js前端通过CopilotKit使用。


建筑

                        User (Browser)
                             |
                             v
┌─────────────────────────────────────────────────────────┐
│  Next.js Frontend (port 3000)                           │
│                                                         │
│  ┌───────────────────────────────────────────────────┐  │
│  │ React Pages                                       │  │
│  │  /time-tracker    → <CopilotKit agent="time_tracker">│
│  │  /calendar        → <CopilotKit agent="calendar">   │
│  │  /knowledge-base  → <CopilotKit agent="knowledge_base">│
│  │  /security-issues → <CopilotKit agent="security_issues">│
│  │                                                   │  │
│  │  Each page wraps <CopilotChat> for the chat UI    │  │
│  └───────────────────────┬───────────────────────────┘  │
│                          │                              │
│  ┌───────────────────────▼───────────────────────────┐  │
│  │ API Route: /api/copilotkit                        │  │
│  │  CopilotRuntime + ExperimentalEmptyAdapter        │  │
│  │  Routes to 4 HttpAgent instances (from @ag-ui/client)│
│  └───────────────────────┬───────────────────────────┘  │
└──────────────────────────┼──────────────────────────────┘
                           │
                  HTTP POST + SSE Response
                  (AG-UI Protocol over SSE)
                           │
┌──────────────────────────▼──────────────────────────────┐
│  .NET 9 Backend (port 5018)                             │
│                                                         │
│  ┌───────────────────────────────────────────────────┐  │
│  │ ASP.NET Core Pipeline                             │  │
│  │  builder.Services.AddAGUI()                       │  │
│  │  app.MapAGUI("/time_tracker",    agent)            │  │
│  │  app.MapAGUI("/calendar",        agent)            │  │
│  │  app.MapAGUI("/knowledge_base",  agent)            │  │
│  │  app.MapAGUI("/security_issues", agent)            │  │
│  └───────────────────────┬───────────────────────────┘  │
│                          │                              │
│  ┌───────────────────────▼───────────────────────────┐  │
│  │ ChatClientAgent (per endpoint)                    │  │
│  │  - System prompt (Instructions)                   │  │
│  │  - Domain tools (AIFunctionFactory.Create)        │  │
│  │  - Source-gen JSON (McpAguiSerializerContext)      │  │
│  └───────────────────────┬───────────────────────────┘  │
│                          │                              │
│  ┌───────────────────────▼───────────────────────────┐  │
│  │ Azure OpenAI (GPT-4.1-mini)                       │  │
│  │  - Receives user message + tool definitions       │  │
│  │  - Returns tool calls or text completions         │  │
│  └───────────────────────────────────────────────────┘  │
│                                                         │
│  ┌───────────────────────────────────────────────────┐  │
│  │ In-Memory Data Stores (Singletons)                │  │
│  │  TimeEntryStore   → 30 days of seed entries       │  │
│  │  CalendarStore    → Recurring + scattered events  │  │
│  │  KnowledgeArticleStore → 21 seeded articles       │  │
│  │  SecurityIssueStore    → 24 seeded issues         │  │
│  └───────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘

AG-UI协议的工作原理

AG-UI(代理用户界面)是一个 事件驱动协议 该标准化了人工智能代理与前端的通信方式。使用 服务器发送事件(SSE) 通过HTTP作为传输层。

请求响应流

  1. 用户发送消息 在CopilotChat用户界面中
  2. 复印机套件 打包消息并向发送POST /api/copilotkit
  3. 这 CopilotRuntime 正确的路线 HttpAgent 基于 agent 名字
  4. 这 HttpAgent 向发送HTTP POST。NET后端端点(例如。, http://localhost:5018/time_tracker)
  5. 这 MapAGUI中间件 接收请求并调用 ChatClientAgent
  6. 代理将用户消息+工具定义发送到 Azure OpenAI
  7. Azure OpenAI以以下任一方式响应 工具调用 或a 文本完成
  8. AG-UI中间件将响应转换为 SSE事件流
  9. 事件通过管道流回 CopilotChat用户界面,实时呈现它们

SSE事件流

每个代理响应都是一个类型化的JSON事件流,每个事件都以 data: 并用双换行符分隔。典型的交互如下:

data: {"type":"RUN_STARTED","threadId":"","runId":""}

data: {"type":"TOOL_CALL_START","toolCallId":"call_abc","toolCallName":"get_security_summary"}
data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_abc","delta":"{}"}
data: {"type":"TOOL_CALL_END","toolCallId":"call_abc"}
data: {"type":"TOOL_CALL_RESULT","toolCallId":"call_abc","content":"...JSON data...","role":"tool"}

data: {"type":"TEXT_MESSAGE_START","messageId":"msg_1","role":"assistant"}
data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_1","delta":"Here"}
data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_1","delta":" is"}
data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_1","delta":" your"}
data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_1","delta":" summary"}
data: {"type":"TEXT_MESSAGE_END","messageId":"msg_1"}

data: {"type":"RUN_FINISHED","threadId":"","runId":""}

此演示中使用的事件类型

类别 活动 目的
生命周期 RUN_STARTED, RUN_FINISHED 标记代理运行的开始和结束
工具调用 TOOL_CALL_START, TOOL_CALL_ARGS, TOOL_CALL_END, TOOL_CALL_RESULT LLM调用域工具,接收结果,并使用它来制定响应
短信 TEXT_MESSAGE_START, TEXT_MESSAGE_CONTENT, TEXT_MESSAGE_END 实时将文本令牌从LLM流式传输到UI

事件协议规则

事件必须遵循严格的排序协议:

RUN_STARTED
  -> TOOL_CALL_START -> TOOL_CALL_ARGS* -> TOOL_CALL_END -> TOOL_CALL_RESULT
  -> TEXT_MESSAGE_START -> TEXT_MESSAGE_CONTENT* -> TEXT_MESSAGE_END
RUN_FINISHED

AG-UI客户端SDK验证此序列。无效的订单(例如。, TEXT_MESSAGE_CONTENT 没有前缀 TEXT_MESSAGE_START)被抓住并报告。

为什么选择WebSockets上的SSE

特性 SSE WebSockets
方向 服务器到客户端(单向) 双向
协议 标准HTTP/1.1 升级握手
重新连接 内置自动重新连接 手动
负载平衡器 开箱即用 需要粘性会话
复杂性 简单文本协议 二进制框架

SSE非常适合代理用户模式:用户发送单个请求(POST),代理将响应作为一系列事件流式返回。


后端如何工作

关键技术

包装 用途
Microsoft.Agents.AI.Hosting.AGUI.AspNetCore AG-UI中间件-- AddAGUI() 和 MapAGUI()
Microsoft.Agents.AI ChatClientAgent 和 ChatClientAgentOptions
Microsoft.Extensions.AI AIFunctionFactory.Create() 用于工具注册
Azure.AI.OpenAI Azure OpenAI客户端
DotNetEnv 负载 .env 凭证文件

代理创建模式

每个代理都是通过以下方式创建的 AgentFactory 使用此模式:

// 1. Get the domain store (singleton with seed data)
var store = sp.GetRequiredService<TimeEntryStore>();

// 2. Get the Azure OpenAI chat client
var chatClient = azureOpenAIClient.GetChatClient(deploymentName);

// 3. Create domain tools from store methods
var tools = new List<AITool>
{
    AIFunctionFactory.Create(store.LogTime, "log_time",
        "Log time against a project for a given date.",
        McpAguiSerializerContext.Default.Options),
    // ... more tools
};

// 4. Create the agent with system prompt + tools
return chatClient.CreateAIAgent(new ChatClientAgentOptions
{
    Instructions = "You are a time tracking assistant...",
    ChatOptions = new ChatOptions { Tools = tools }
});

源生成的JSON序列化

工具参数和返回值中使用的所有DTO都必须在中注册 McpAguiSerializerContext 为。NET的源代码生成的JSON序列化程序。这包括用作工具参数的图元类型:

[JsonSerializable(typeof(string))]
[JsonSerializable(typeof(int))]
[JsonSerializable(typeof(int?))]      // For optional tool parameters
[JsonSerializable(typeof(DateTime))]
[JsonSerializable(typeof(DateTime?))]
[JsonSerializable(typeof(TimeEntry))]
[JsonSerializable(typeof(List<TimeEntry>))]
// ... all DTOs, enums, and List<T> variants
internal sealed partial class McpAguiSerializerContext : JsonSerializerContext;

端点映射

每个代理都通过以下方式映射到HTTP端点 MapAGUI():

app.MapAGUI("/time_tracker",    AgentFactory.CreateTimeTracker(serviceProvider));
app.MapAGUI("/calendar",        AgentFactory.CreateCalendar(serviceProvider));
app.MapAGUI("/knowledge_base",  AgentFactory.CreateKnowledgeBase(serviceProvider));
app.MapAGUI("/security_issues", AgentFactory.CreateSecurityIssues(serviceProvider));

当POST请求到达这些端点中的任何一个时,AG-UI中间件:

  1. 反序列化传入消息
  2. 将它们传递给 ChatClientAgent
  3. 代理使用消息和工具定义调用Azure OpenAI
  4. 如果LLM返回工具调用,代理将执行该工具并将结果发送回LLM
  5. LLM的最终文本响应作为SSE事件流式传输回调用者

工具方法

所有工具方法返回 string (JSON序列化数据)。LLM解释原始JSON并为用户格式化。每个域有5个工具:

代理 工具
时间追踪 log_time, get_time_entries, get_project_time_summary, get_time_for_project, get_daily_breakdown
日历 get_schedule_for_day, get_schedule_for_week, get_schedule_for_month, get_upcoming_deadlines, get_free_slots
知识库 search_knowledge_articles, get_article, list_articles_by_project, list_articles_by_category, get_popular_articles
安全问题 get_security_issues, get_security_issue_detail, get_security_summary, get_issues_by_project, get_critical_and_high_issues

前端如何工作

关键技术

包装 用途
@copilotkit/react-core CopilotKit 提供者组件
@copilotkit/react-ui CopilotChat 带有markdown渲染的组件
@copilotkit/runtime CopilotRuntime API路线
@ag-ui/client HttpAgent --AG-UI客户端与后端进行SSE通信
@ag-ui/core AG-UI事件类型和协议定义

前端到后端桥

API路线(/api/copilotkit)充当CopilotKit和之间的桥梁。NET后端:

// Create HttpAgent instances pointing to each backend endpoint
const agents = {
  time_tracker:    new HttpAgent({ url: "http://localhost:5018/time_tracker" }),
  calendar:        new HttpAgent({ url: "http://localhost:5018/calendar" }),
  knowledge_base:  new HttpAgent({ url: "http://localhost:5018/knowledge_base" }),
  security_issues: new HttpAgent({ url: "http://localhost:5018/security_issues" }),
};

// CopilotRuntime routes requests to the correct agent
const runtime = new CopilotRuntime({ agents });

代理页面模式

每个代理页面都遵循相同的模式,使用共享 ChatLayout 组件:

<CopilotKit runtimeUrl="/api/copilotkit" agent="time_tracker">
  <CopilotChat
    labels={{ initial: "Hi! I'm your time tracking assistant...", title: "⏰ Time Tracker" }}
    suggestions={[
      { title: "📊 Show summary", message: "Show me a summary of my time..." },
    ]}
  />
</CopilotKit>

这 agent 道具打开 CopilotKit 告诉运行时 HttpAgent 使用,这反过来又决定了哪个后端端点接收请求。

CopilotChat如何呈现AG-UI事件

CopilotChat处理来自后端的SSE事件流并实时呈现:

SSE事件 CopilotChat行为
RUN_STARTED 显示加载指示器
TOOL_CALL_START 表示代理正在工作(活动点)
TOOL_CALL_RESULT 工具结果存储在内部(未显示给用户)
TEXT_MESSAGE_START 创建新的助手消息气泡
TEXT_MESSAGE_CONTENT 使用markdown渲染附加流式文本标记
TEXT_MESSAGE_END 完成消息
RUN_FINISHED 隐藏装载指示器

代理场景

1.时间追踪器(/time-tracker)

记录和跟踪4个项目的工作时间,每天上限为8小时。查询时间条目,查看项目摘要,分析每日明细。种子数据包括30个工作日的条目,每天3-5个条目。

2.日历(/calendar)

只读日历助手,可按天、周或月查询日程。查找空闲时间段并查看即将到来的截止日期。种子数据包括重复发生的事件(每日站立、午餐、周五回顾)和分散的会议、焦点块以及今天前后1个月的截止日期。

3.知识库(/knowledge-base)

ServiceNow风格的跨项目知识文章搜索。按关键字搜索,按项目或类别浏览,查看热门文章。种子数据包括21篇文章(每个项目5-6篇),涵盖了操作方法、故障排除、最佳实践、架构和部署等类别。

4.安全问题(/security-issues)

跨项目的安全发现仪表板。按严重性/状态查看问题,获取带有风险评分的安全态势摘要,并确定补救措施的优先级。种子数据包括24个问题(每个项目6个),严重程度从严重到低。


共享种子数据(4个项目)

代码 名称 描述
ALPHA Project ALPHA 内部CRM现代化平台
NEXUS NEXUS项目 API网关和微服务迁移
ORBIT Project ORBIT 面向客户的移动应用程序重新设计
VAULT 项目库 数据仓库和分析管道

所有数据都在内存中,并在后端重新启动时重置。


技术栈

层 技术
后端运行时 。净值9
AG-UI服务器SDK 微软。代理人。你好。阿吉。AspNetCore
代理框架 Microsoft。代理人。AI(聊天客户端代理)
工具创建 微软。扩展。AI(AIFunctionFactory)
LLM Azure OpenAI(GPT-4.1-mini通过Azure、AI、OpenAI)
前端 Next.js 15+React 19+TypeScript
AI UI CopilotKit(@CopilotKit/react core,react-UI,运行时)
AG-UI客户端 @AG UI/客户端(HttpAgent),@AG UI/core
样式 带有自定义CopilotKit覆盖的顺风CSS 4

项目结构

app/
├── .env                                # Azure OpenAI credentials (not committed)
├── .env.example                        # Credentials template
├── run.bat                             # Start both services (Windows batch)
├── run.ps1                             # Start both services (PowerShell)
├── backend/
│   └── McpAguiServer/
│       ├── McpAguiServer.csproj        # .NET 9 project with NuGet packages
│       ├── Program.cs                  # Entry point, DI, CORS, MapAGUI endpoints
│       ├── AgentFactory.cs             # Azure OpenAI client, 4 agent factory methods
│       ├── McpAguiSerializerContext.cs  # Source-generated JSON for all DTOs
│       ├── Shared/
│       │   ├── Project.cs              # Project DTO (Code, Name, Description)
│       │   └── ProjectSeed.cs          # 4 shared projects (ALPHA, NEXUS, ORBIT, VAULT)
│       ├── TimeTracker/
│       │   ├── TimeEntry.cs            # DTO
│       │   └── TimeEntryStore.cs       # Seed data + 5 tools
│       ├── Calendar/
│       │   ├── EventType.cs            # Enum: Meeting, FocusBlock, Deadline
│       │   ├── CalendarEvent.cs        # DTO
│       │   └── CalendarStore.cs        # Seed data + 5 tools
│       ├── KnowledgeBase/
│       │   ├── KnowledgeArticle.cs     # DTO
│       │   └── KnowledgeArticleStore.cs # 21 articles + 5 tools
│       └── SecurityIssues/
│           ├── Severity.cs             # Enum: Critical, High, Medium, Low
│           ├── IssueStatus.cs          # Enum: Open, InProgress, Resolved, Dismissed
│           ├── SecurityIssue.cs        # DTO
│           └── SecurityIssueStore.cs   # 24 issues + 5 tools
└── frontend/
    ├── package.json                    # Dependencies (CopilotKit, AG-UI, Next.js)
    ├── next.config.ts                  # serverExternalPackages config
    ├── tsconfig.json
    ├── postcss.config.mjs              # Tailwind CSS setup
    └── src/
        ├── app/
        │   ├── globals.css             # Tailwind + CopilotKit CSS overrides
        │   ├── layout.tsx              # Root layout with Nav
        │   ├── page.tsx                # Home page with agent cards
        │   ├── api/copilotkit/
        │   │   └── route.ts            # CopilotRuntime bridge (HttpAgent → backend)
        │   ├── time-tracker/page.tsx    # Time Tracker agent page
        │   ├── calendar/page.tsx        # Calendar agent page
        │   ├── knowledge-base/page.tsx  # Knowledge Base agent page
        │   └── security-issues/page.tsx # Security Issues agent page
        └── components/
            ├── nav.tsx                 # Navigation bar with active state
            └── chat-layout.tsx         # Shared CopilotKit + CopilotChat wrapper

运行项目

看 howtorun.md 有关详细的设置和运行说明。

快速启动:

# 1. Copy and fill in credentials
cp .env.example .env

# 2. Run both services
.\run.ps1          # PowerShell
# or
run.bat            # Command Prompt

然后打开http://localhost:3000在您的浏览器中。