跳转到正文

架构

本页是 AI Genius S5E2 Agent HQ 演示的系统参考资料,概述了 .NET 10 Blazor WebAssembly 前端、ASP.NET Core Web API、GitHub Copilot SDK 集成,以及零配置的 SQLite 分析数据存储。

更想以交互方式探索?

系统地图 以交互式图表呈现相同的架构——您可以搜索节点、跟踪路由,并播放三个引导视图。

组件视图

该演示以两个本地进程运行:Blazor WebAssembly 用户界面使用端口 5051,API 使用端口 5050。 Program.cs (位于 API 中)将 CopilotChatService 注册为单例,并将 RetailAnalyticsService 注册为作用域服务,其后端由 RetailDbContext

graph LR
    Browser["Browser"]

    subgraph Web["AgentHQDemo.Web — Blazor WebAssembly :5051"]
        Blazor["Chat UI"]
        WebChat["ChatService"]
        Storage["StorageService<br/>localStorage"]
    end

    subgraph Api["AgentHQDemo.Api — ASP.NET Core Web API :5050"]
        ChatController["ChatController<br/>/api/chat"]
        TxController["TransactionsController<br/>/api/transactions"]
        SegController["SegmentsController<br/>/api/segments"]
        CopilotService["CopilotChatService<br/>singleton"]
        Analytics["RetailAnalyticsService<br/>scoped"]
        DbContext["RetailDbContext"]
    end

    subgraph Copilot["GitHub Copilot SDK"]
        Client["CopilotClient"]
        Session["Copilot session"]
        Models["Claude / GPT / Gemini models"]
    end

    subgraph Mcp["AgentHQDemo.McpServer — stdio subprocess"]
        RetailTools["RetailTools<br/>5 read-only tools"]
    end

    SQLite[("SQLite<br/>retail.db")]

    Browser --> Blazor
    Blazor --> WebChat
    Blazor --> Storage
    WebChat -->|"SSE and REST"| ChatController
    WebChat -->|"REST"| TxController
    WebChat -->|"REST"| SegController
    ChatController --> CopilotService
    CopilotService --> Client
    Client --> Session
    Session --> Models
    Session -->|"MCP over stdio"| RetailTools
    RetailTools -->|"Mode=ReadOnly"| SQLite
    TxController --> Analytics
    SegController --> Analytics
    Analytics --> DbContext
    DbContext --> SQLite

请注意,访问 retail.db有两条不同的路径。REST 控制器直接通过 RetailDbContext 进行读写。 模型 只能通过 MCP 服务器访问同一数据库;该连接以 Mode=ReadOnly方式打开,并且只能使用该服务器发布的五个领域工具。MCP 面向模型,而不是供应用程序访问自身数据库。

SSE 聊天时序

AgentHQDemo.Web.Services.ChatService.StreamChatAsync/api/chat/stream 发送请求,并使用 HttpCompletionOption.ResponseHeadersRead。API 设置 text/event-stream,刷新每个数据块,并以 data: [DONE] 结束数据流。

sequenceDiagram
    participant Browser as Browser
    participant UI as Blazor Home.razor
    participant WebChat as Web ChatService
    participant Controller as ChatController.StreamChat
    participant Service as CopilotChatService.ChatStreamAsync
    participant Client as CopilotClient session
    participant Channel as Channel of string

    Browser->>UI: Submit prompt
    UI->>WebChat: StreamChatAsync(prompt, model)
    WebChat->>Controller: POST /api/chat/stream
    Controller->>Service: ChatStreamAsync(prompt, model)
    Service->>Client: CreateSessionAsync(SessionConfig)
    Service->>Client: session.On (SessionEvent) subscription
    Service->>Client: SendAsync(MessageOptions)
    Client-->>Service: AssistantMessageDeltaEvent
    Service-->>Channel: TryWrite(delta content)
    Channel-->>Controller: ReadAllAsync chunk
    Controller-->>WebChat: data: {"content":"..."}
    WebChat-->>UI: yield chunk
    UI-->>Browser: Batched render at about 20fps
    Client-->>Service: SessionIdleEvent
    Controller-->>WebChat: data: [DONE]

数据模型

RetailDbContext 公开 TransactionsSegments 集合。客户分群预测由 RetailAnalyticsService 以记录形式返回,而不是存储在 SQLite 中。

classDiagram
    class Transaction {
        int Id
        string CustomerId
        decimal Amount
        string ProductCategory
        string StoreId
        DateTime Timestamp
        bool IsFlagged
    }

    class CustomerSegment {
        int Id
        string Name
        string Description
        int CustomerCount
        decimal AvgMonthlySpend
        decimal RetentionRate
    }

    class SegmentPrediction {
        string CustomerId
        string PredictedSegment
        double Confidence
        string[] TopFeatures
    }

    Transaction ..> SegmentPrediction : analysed for
    CustomerSegment ..> SegmentPrediction : predicted name

仓库结构

实现位于 src/AgentOrchestrator/ 目录下,其中 API、用户界面和测试各自使用独立项目。

src/AgentOrchestrator/
├── AgentHQDemo.Api/
│   ├── Controllers/
│   ├── Data/
│   ├── Models/
│   ├── Services/
│   └── Program.cs
├── AgentHQDemo.Web/
│   ├── Components/
│   ├── Layout/
│   ├── Pages/
│   ├── Services/
│   └── Program.cs
├── tests/
│   └── AgentHQDemo.Tests/
└── AgentHQDemo.slnx

关键设计决策

  • 单例 Copilot 客户端AgentHQDemo.Api.Services.CopilotChatService 注册为单例,并持有一个长期运行的 CopilotClientEnsureStartedAsync 会在连接丢失后重新创建客户端。
  • 用于流式传输的 Channel 桥接:Copilot SDK 回调将助手增量写入一个无界 Channel<string>。API 将该通道作为 IAsyncEnumerable<string> 读取,并将每一项转换为 SSE 帧。
  • 运行时模型发现CopilotChatService.ListModelsAsync 在运行时调用 Copilot SDK。 ChatController.GetModels 当无法连接 CLI 或 CLI 未返回任何模型时,会回退到静态目录。
  • 使用 SQLite 实现零配置分析Program.cs 使用 UseSqlite("Data Source=retail.db"),调用 EnsureCreatedAsync,并在启动时植入零售示例数据。