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 → │
│ │ /calendar → │
│ │ /knowledge-base → │
│ │ /security-issues → │
│ │ │ │
│ │ Each page wraps 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作为传输层。
请求响应流
- 用户发送消息 在CopilotChat用户界面中
- 复印机套件 打包消息并向发送POST
/api/copilotkit - 这 CopilotRuntime 正确的路线
HttpAgent基于agent名字 - 这
HttpAgent向发送HTTP POST。NET后端端点(例如。,http://localhost:5018/time_tracker) - 这 MapAGUI中间件 接收请求并调用
ChatClientAgent - 代理将用户消息+工具定义发送到 Azure OpenAI
- Azure OpenAI以以下任一方式响应 工具调用 或a 文本完成
- AG-UI中间件将响应转换为 SSE事件流
- 事件通过管道流回 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_FINISHEDAG-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();
// 2. Get the Azure OpenAI chat client
var chatClient = azureOpenAIClient.GetChatClient(deploymentName);
// 3. Create domain tools from store methods
var tools = new List
{
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))]
// ... all DTOs, enums, and List 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中间件:
- 反序列化传入消息
- 将它们传递给
ChatClientAgent - 代理使用消息和工具定义调用Azure OpenAI
- 如果LLM返回工具调用,代理将执行该工具并将结果发送回LLM
- 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 组件:
这 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在您的浏览器中。
