22 KiB
Frontend Multi-Agent / MCP Process UI Change
1. 目标
前端聊天页要从“单一消息流”升级成“可视化协作工作台”,让用户在一次聊天里同时看到:
- 主对话区里的用户问题与最终总结回复。
- 每个 sub-agent / A2A agent / MCP server 的独立处理框。
- agent 之间的流式进展、状态变化、问答片段。
- MCP 工具调用产物,例如文本结果、结构化 JSON、文件、链接、图片。
- 一个固定的结果侧栏,用来汇总当前运行中的过程结果与最终产物。
- 独立的 Agent 管理页和 MCP 管理页,体验上与现有
skills/plugins页面一致。
这个需求本质上不是“把聊天页面做复杂一点”,而是要把聊天 UI 的数据模型从 messages[] 升级成 messages[] + process runs[] + artifacts[] + actor registry[]。
2. 当前现状
2.1 前端现状
当前前端的核心限制如下:
- 聊天页集中在
/home/ivan/xuan/steven_project/nanobot-fronted/app/page.tsx。 - 聊天状态只在
/home/ivan/xuan/steven_project/nanobot-fronted/lib/store.ts里维护:messagesisLoadingisThinkingstreamingContent
- WebSocket 只在
/home/ivan/xuan/steven_project/nanobot-fronted/lib/api.ts里处理非常薄的一层消息:type=statustype=message
- 类型定义
/home/ivan/xuan/steven_project/nanobot-fronted/types/index.ts没有“运行事件 / agent 卡片 / artifact / process timeline”概念。 - 顶部导航
/home/ivan/xuan/steven_project/nanobot-fronted/components/Header.tsx目前没有Agents/MCP页入口。 - 现有
skills/plugins页面适合复用作管理页风格参考:/home/ivan/xuan/steven_project/nanobot-fronted/app/skills/page.tsx/home/ivan/xuan/steven_project/nanobot-fronted/app/plugins/page.tsx
2.2 后端现状
后端已经具备部分多 agent 能力,但还不够支撑前端过程可视化:
- 已有统一 agent 列表接口:
GET /api/agents- 位置:
/home/ivan/xuan/steven_project/nanobot-backend/nanobot/web/server.py
- 位置:
- 已有 A2A / group delegation 逻辑:
/home/ivan/xuan/steven_project/nanobot-backend/nanobot/agent/delegation.py
- 已有 A2A streaming / resubscribe / cancel:
/home/ivan/xuan/steven_project/nanobot-backend/nanobot/a2a/client.py
- 但当前对前端暴露的实时消息仍然只有:
status=thinkingassistant message
DelegationManager现在对外发布的也只是普通_progress文本,例如:[AgentName] ...
- MCP 目前只有后端连接配置和工具注册,没有独立的 Web 管理接口,也没有结构化 MCP 运行事件。
结论:
前端可以先做布局和状态层改造,但如果想真正展示“每个 agent 的框、每个 MCP 的产物、agent 间问答”,后端必须补一层结构化 process event 协议。只靠现在的纯文本 progress 不够。
3. 推荐的界面形态
桌面端建议改成三栏工作台,而不是继续沿用现在的单栏聊天布局。
3.1 桌面布局
┌──────────────┬───────────────────────────────────────┬──────────────────────────┐
│ 会话侧栏 │ 主聊天 + 过程泳道 │ 结果侧栏 │
│ Sessions │ │ Results / Artifacts │
│ │ 用户消息 │ 当前运行摘要 │
│ │ assistant 最终总结 │ agent 产物列表 │
│ │ ─────────────────────────────────── │ MCP 产物列表 │
│ │ Agent A 卡片 │ 文件/图片/JSON 预览 │
│ │ Agent B 卡片 │ 错误/告警 │
│ │ MCP github 卡片 │ 最终汇总结论 │
│ │ MCP browser 卡片 │ │
└──────────────┴───────────────────────────────────────┴──────────────────────────┘
3.2 移动端布局
移动端不要硬保留三栏:
- 主聊天区保留为默认视图。
- 过程泳道和结果侧栏改成底部
Tabs或Drawer。 - 正在运行时,顶部显示一个
Process (3)悬浮入口。
3.3 视觉原则
不要把过程信息混成普通 assistant markdown。
应明确区分三类对象:
Chat Message:用户问题、最终总结。Process Card:某个 agent 或 MCP 的运行容器。Artifact:某个步骤产出的结构化结果。
建议:
- Agent 卡片用清晰的状态边框和标题区。
- MCP 卡片强调“工具/服务器”属性,避免与 agent 混淆。
- 结果侧栏始终可见,展示当前选中卡片的详细结果。
4. 目标交互
4.1 单 Agent
用户发出问题后:
- 主聊天区出现用户消息。
- assistant 进入
thinking。 - 若命中
spawn/ A2A delegation,过程泳道新增一个 Agent 卡片。 - 卡片内部流式更新:
- 状态:queued / running / waiting / done / error / cancelled
- 文本片段
- agent 生成的中间消息
- 关键参数或结果摘要
- 如果 agent 调了 MCP,再在该卡片内部挂子步骤,或在泳道新增 MCP 卡片。
- 右侧结果栏展示:
- 当前 agent 的最新摘要
- 产物列表
- 可预览文件
- 所有 agent 结束后,主 assistant 再给一条最终总结回复。
4.2 多 Agent Group
如果是 group delegation:
- 过程泳道里要同时出现多个 Agent 卡片。
- 每个卡片独立流式刷新,不要合并成一条文本。
- 结果侧栏支持切换:
AllAgent AAgent BMCP Outputs
- 最终 assistant 总结要包含:
- 共识
- 分歧
- 失败项
- 最终建议
4.3 Agent 间“一问一答”
如果未来后端能发出 agent-to-agent message event,前端直接把这些消息渲染到卡片里的 transcript 区。
建议 UI 表现:
- 卡片头:agent 名称、来源、状态、耗时
- 卡片体:
TranscriptStepsArtifacts
- 卡片尾:最终摘要 / 错误信息
5. 前端改造点
5.1 先不要继续把逻辑堆进 app/page.tsx
当前 /home/ivan/xuan/steven_project/nanobot-fronted/app/page.tsx 已经过大。这个需求如果继续直接堆,会很快失控。
建议拆分。
5.2 建议新增的组件与文件
建议新增目录:
components/chat-workbench/ChatWorkbench.tsxcomponents/chat-workbench/ProcessLane.tsxcomponents/chat-workbench/ProcessRunCard.tsxcomponents/chat-workbench/ProcessTranscript.tsxcomponents/chat-workbench/ArtifactSidebar.tsxcomponents/chat-workbench/RunSummaryPanel.tsxcomponents/chat-workbench/AgentBadge.tsxcomponents/chat-workbench/McpBadge.tsxcomponents/chat-workbench/StatusPill.tsx
建议职责:
ChatWorkbench.tsx- 负责三栏布局组合。
ProcessLane.tsx- 渲染当前 session 的所有 process run。
ProcessRunCard.tsx- 渲染单个 agent / MCP 卡片。
ProcessTranscript.tsx- 渲染步骤流、问答片段、进度文本。
ArtifactSidebar.tsx- 渲染右侧产物栏。
RunSummaryPanel.tsx- 展示当前 run 的状态概览和最终摘要。
5.3 对现有文件的插入建议
/home/ivan/xuan/steven_project/nanobot-fronted/app/page.tsx
保留职责:
- session 列表
- 输入框
- 顶层页面组织
减少职责:
- 不再在这里直接渲染复杂过程 UI
- 不再在这里直接解析 process 事件
建议修改为:
- 左侧会话侧栏基本保留。
- 中间改成
<ChatWorkbench />。 MessageBubble可以保留,但只负责普通user/assistant消息。- 新增一个
selectedRunId/selectedArtifactId的页面级状态,或者放进 Zustand store。
/home/ivan/xuan/steven_project/nanobot-fronted/lib/store.ts
这里需要从“聊天 store”升级成“聊天 + 过程 store”。
建议新增状态:
processRuns: ProcessRun[]processEvents: ProcessEvent[]artifacts: ProcessArtifact[]selectedRunId: string | nullselectedArtifactId: string | nullactiveRunIds: string[]agentRegistry: UiAgentDescriptor[]mcpRegistry: UiMcpServerDescriptor[]
建议新增 action:
resetProcessState(sessionId)upsertProcessRun(run)appendProcessEvent(event)appendProcessArtifact(artifact)finishProcessRun(runId, status)cancelProcessRun(runId)setSelectedRunId(runId)setSelectedArtifactId(artifactId)setAgentRegistry(agents)setMcpRegistry(servers)
/home/ivan/xuan/steven_project/nanobot-fronted/types/index.ts
这里需要新增完整类型层。
建议新增:
export type ProcessActorType = 'agent' | 'mcp' | 'system';
export type ProcessRunStatus = 'queued' | 'running' | 'waiting' | 'done' | 'error' | 'cancelled';
export type ProcessEventKind =
| 'run_started'
| 'run_progress'
| 'run_message'
| 'run_artifact'
| 'run_status'
| 'run_finished'
| 'run_cancelled';
export interface UiAgentDescriptor {
id: string;
name: string;
description: string;
source: 'workspace' | 'plugin' | 'skill' | 'builtin';
kind: string;
protocol: string | null;
tags: string[];
aliases: string[];
support_group: boolean;
support_streaming: boolean;
}
export interface UiMcpServerDescriptor {
id: string;
name: string;
transport: 'stdio' | 'http';
url?: string;
command?: string;
enabled: boolean;
tool_count?: number;
tool_names?: string[];
status?: 'connected' | 'disconnected' | 'error';
last_error?: string | null;
}
export interface ProcessRun {
run_id: string;
parent_run_id?: string | null;
session_id: string;
actor_type: ProcessActorType;
actor_id: string;
actor_name: string;
title: string;
status: ProcessRunStatus;
started_at: string;
finished_at?: string | null;
summary?: string | null;
source?: string | null;
}
export interface ProcessEvent {
event_id: string;
run_id: string;
parent_run_id?: string | null;
kind: ProcessEventKind;
actor_type: ProcessActorType;
actor_id: string;
actor_name: string;
text?: string;
status?: ProcessRunStatus;
message_role?: 'system' | 'user' | 'assistant' | 'tool';
metadata?: Record<string, unknown>;
created_at: string;
}
export interface ProcessArtifact {
artifact_id: string;
run_id: string;
actor_type: ProcessActorType;
actor_id: string;
title: string;
artifact_type: 'text' | 'json' | 'file' | 'image' | 'link' | 'markdown';
content?: string;
data?: Record<string, unknown> | unknown[];
file_id?: string;
url?: string;
created_at: string;
}
/home/ivan/xuan/steven_project/nanobot-fronted/lib/api.ts
这里要扩展三类能力:
- Agent 管理 API
- MCP 管理 API
- WebSocket process event 订阅
建议新增:
listAgents()addAgent()deleteAgent()refreshAgents()listMcpServers()addMcpServer()updateMcpServer()deleteMcpServer()testMcpServer()
同时把 WsMessageHandler 从现在的宽松结构,升级成联合类型:
export type WsEvent =
| ChatAssistantEvent
| ChatThinkingEvent
| ProcessRunStartedEvent
| ProcessRunUpdatedEvent
| ProcessArtifactEvent
| ProcessRunFinishedEvent
| ProcessRunCancelledEvent;
/home/ivan/xuan/steven_project/nanobot-fronted/components/Header.tsx
导航中建议新增:
/agents/mcp
放在 skills / plugins 旁边,不要塞进聊天页内部。
5.4 建议新增页面
/home/ivan/xuan/steven_project/nanobot-fronted/app/agents/page.tsx/home/ivan/xuan/steven_project/nanobot-fronted/app/mcp/page.tsx
Agent 页面参考 skills + plugins 的中间态:
- 列表视图
- 支持新增、删除、刷新
- 展示来源:workspace / plugin / skill / builtin
- 展示协议:a2a / local
- 展示标签、别名、streaming/group 支持
MCP 页面建议分两块:
Configured ServersDiscovered Tools
每个 MCP server 展示:
- 连接方式:stdio / http
- 地址或命令
- tool 数量
- 连接状态
- 最后错误
- 编辑/删除/测试按钮
6. 聊天页的推荐逻辑链路
这是前端应当遵守的主链路。
6.1 用户发消息
- 用户在
app/page.tsx输入消息。 - 立即写入
messages[]。 - 设置
isLoading=true。 - 如果 WebSocket 已连接,消息通过
wsManager.sendRaw()发出去。 - 前端等待两类数据:
- 普通 assistant reply
- process events
6.2 触发 sub-agent / group / MCP
后端一旦进入 delegation / MCP tool 调用,应向前端发结构化 process event。
前端收到后:
run_started-> 创建卡片。run_progress-> 更新卡片中的 transcript。run_artifact-> 写入右侧侧栏。run_status-> 更新状态 pill。run_finished-> 收起 loading,保留结果。- 最终
assistant message-> 输出总结性回复。
6.3 用户点击某个 Agent / MCP 卡片
- 设置
selectedRunId。 - 右侧
ArtifactSidebar切换到该 run 的 artifact 列表。 - 中间卡片高亮。
- 若有 transcript,则显示完整流。
6.4 用户取消运行
如果后端暴露 cancel 接口或 WebSocket cancel command:
- 卡片上显示
Cancel。 - 用户点击后发送 cancel 请求。
- run 状态变为
cancelled。 - 侧栏保留已有产物,但标记“未完成”。
7. 后端必须补的事件协议
这是这次前端能否做成的关键。
当前后端只发普通文本 _progress,不够。
必须新增结构化 WebSocket 事件。建议统一成 type=process_*。
7.1 建议的事件集合
process_run_started
{
"type": "process_run_started",
"session_id": "web:default",
"run_id": "deleg-123",
"parent_run_id": null,
"actor_type": "agent",
"actor_id": "repo-reviewer",
"actor_name": "Repo Reviewer",
"source": "workspace",
"title": "Review auth refactor",
"status": "running",
"created_at": "2026-03-06T10:00:00Z"
}
process_run_progress
{
"type": "process_run_progress",
"run_id": "deleg-123",
"actor_type": "agent",
"actor_id": "repo-reviewer",
"text": "Scanning auth middleware and session lifecycle",
"created_at": "2026-03-06T10:00:03Z"
}
process_run_message
用于展示 agent 间问答或 agent 内部消息。
{
"type": "process_run_message",
"run_id": "deleg-123",
"actor_type": "agent",
"actor_id": "repo-reviewer",
"message_role": "assistant",
"text": "I need the gateway config file before deciding.",
"created_at": "2026-03-06T10:00:04Z"
}
process_run_artifact
{
"type": "process_run_artifact",
"run_id": "mcp-456",
"actor_type": "mcp",
"actor_id": "github",
"title": "Pull Request Diff Summary",
"artifact_type": "markdown",
"content": "...",
"created_at": "2026-03-06T10:00:08Z"
}
process_run_status
{
"type": "process_run_status",
"run_id": "deleg-123",
"status": "waiting",
"text": "Waiting for remote agent task completion",
"created_at": "2026-03-06T10:00:10Z"
}
process_run_finished
{
"type": "process_run_finished",
"run_id": "deleg-123",
"status": "done",
"summary": "Found 2 risks in auth token refresh flow.",
"created_at": "2026-03-06T10:00:20Z"
}
process_run_cancelled
{
"type": "process_run_cancelled",
"run_id": "deleg-123",
"status": "cancelled",
"created_at": "2026-03-06T10:00:12Z"
}
7.2 后端推荐插入点
如果你后面让我直接改前后端,我会从这些点切:
/home/ivan/xuan/steven_project/nanobot-backend/nanobot/agent/delegation.py
这里最适合发 agent 级 process event:
dispatch()开始时发process_run_started_build_progress_callback()中把 A2A stream 文本转成process_run_progress_run_group()中每个 descriptor 启动时发独立子 run_announce_single_result()之前发process_run_finished_announce_group_result()之前发 group summary run finishedcancel()/_announce_cancelled()发process_run_cancelled
/home/ivan/xuan/steven_project/nanobot-backend/nanobot/a2a/client.py
这里最适合补更细的远端 agent 消息:
_consume_stream_method()_resume_subscription()
如果远端流里有 message chunk / state / artifact,就在这里归一化后向上抛给 DelegationManager。
/home/ivan/xuan/steven_project/nanobot-backend/nanobot/agent/tools/mcp.py
这里最适合发 MCP 级事件:
- MCP 工具调用开始 ->
process_run_started(actor_type=mcp) - 工具标准输出 / 中间结果 ->
process_run_progress - 工具返回文本 / JSON / 文件 ->
process_run_artifact - 工具调用完成 ->
process_run_finished - 超时 / 失败 ->
process_run_status+process_run_finished(status=error)
/home/ivan/xuan/steven_project/nanobot-backend/nanobot/web/server.py
这里需要扩展 WebSocket 发送协议,而不是只发 thinking/message。
8. Agent 管理页方案
8.1 页面目标
让用户能像管理 skills 一样管理委派目标 agent。
8.2 数据来源
直接用现有接口:
GET /api/agentsPOST /api/agentsDELETE /api/agents/{id}POST /api/agents/refresh
8.3 页面布局建议
参考 plugins 页的卡片布局,但要比 plugins 更偏“资源管理”。
建议字段:
- 名称
- id
- description
- source
- protocol
- tags
- aliases
- support_group
- support_streaming
- endpoint / base_url / card_url
建议交互:
- 顶部
Refresh - 顶部
Add Agent - 列表卡片
- workspace agent 允许删除
- plugin / skill / builtin agent 只读
8.4 Add Agent 弹窗字段
idnamedescriptionprotocol,先只放a2abase_urlendpointcard_urlauth_envtagsaliasesenabled
9. MCP 管理页方案
9.1 结论先说
这个页面前端不能单独完成,因为当前后端没有 MCP 管理 API。
所以文档给的是“前端页面方案 + 后端配套接口定义”。
9.2 后端建议增加的 API
建议新增:
GET /api/mcp/serversPOST /api/mcp/serversPUT /api/mcp/servers/{id}DELETE /api/mcp/servers/{id}POST /api/mcp/servers/{id}/testGET /api/mcp/tools
9.3 MCP server 返回结构建议
{
"id": "github",
"name": "github",
"transport": "http",
"url": "http://localhost:3001/mcp",
"command": "",
"args": [],
"enabled": true,
"tool_timeout": 30,
"headers": {},
"status": "connected",
"tool_count": 12,
"tool_names": ["search_repos", "list_prs"],
"last_error": null
}
9.4 页面布局建议
上半区:MCP servers
- 卡片或表格
- 编辑 / 删除 / 测试连接
下半区:Discovered tools
- 按 server 分组
- 展示工具名、说明、schema 摘要
10. 建议的前端实现顺序
按这个顺序做最稳。
Phase 1: 先做前端数据结构重构
- 扩
types/index.ts - 扩
lib/store.ts - 扩
lib/api.ts的 ws event 类型 - 把
app/page.tsx拆出ChatWorkbench
这一步即使后端结构化事件还没补,也可以先用 mock data 跑布局。
Phase 2: 落三栏工作台 UI
- 中间主聊天区保留现有 message bubble
- 加
ProcessLane - 加
ArtifactSidebar - 支持选中某个 run
Phase 3: 接后端 process events
- 给
wsManager.onMessage()加 process 事件分发 - store 按 event 更新 process state
- 卡片流式刷新
Phase 4: 新增 Agent 管理页
app/agents/page.tsxlib/api.ts增 Agent APIHeader.tsx增导航
Phase 5: 新增 MCP 管理页
- 后端先补接口
- 前端
app/mcp/page.tsx - 管理 + 测试连接 + 工具查看
11. 为什么我建议最好由同一个 Codex 连前后端一起改
如果只是做视觉壳子,另一个 Codex 在前端仓库里单独改也可以。
但如果目标是你描述的完整体验:
- 每个 agent / MCP 弹出独立框
- 展示过程中的一问一答
- 展示 MCP 产物
- 最后再统一总结
那就不是纯前端问题,而是“后端事件模型 + 前端状态模型”联动问题。
结论:
- 只写前端:可以先做静态布局和 store 重构。
- 真正做成:最好同一个人连续改 backend + frontend,避免事件协议和 UI 状态设计脱节。
12. 给另一个 Codex 的明确施工指令
如果你把这份文档交给另一个 Codex,建议直接给它下面这段要求:
- 先阅读:
/home/ivan/xuan/steven_project/nanobot-fronted/app/page.tsx/home/ivan/xuan/steven_project/nanobot-fronted/lib/store.ts/home/ivan/xuan/steven_project/nanobot-fronted/lib/api.ts/home/ivan/xuan/steven_project/nanobot-fronted/types/index.ts/home/ivan/xuan/steven_project/nanobot-fronted/app/plugins/page.tsx/home/ivan/xuan/steven_project/nanobot-fronted/app/skills/page.tsx
- 先把聊天页拆成三栏工作台,不要继续把复杂逻辑堆在
app/page.tsx。 - 先做
processRuns / processEvents / artifacts的前端数据模型。 - 先接
/api/agents做 Agent 管理页。 - MCP 管理页先按文档搭 UI 壳子,但要显式标记“依赖后端 MCP API”。
- 如果要做真实过程可视化,不要拿普通 markdown 消息硬解析,必须等结构化 WebSocket process events。
13. 最小可交付版本
如果要先做一个能看的版本,建议这样收敛:
- 聊天页先做三栏布局。
- 用当前
_progress文本先临时映射成 Agent 卡片日志。 - 先接
/api/agents做管理页。 - MCP 页先做只读占位页,提示“等待后端 MCP API”。
- 第二轮再补真正结构化 process events。
这条路径的好处是:
- UI 先起来
- 后端协议第二轮再精修
- 不会一开始就卡死在全链路联调上
14. 推荐文档结论
最合适的落地方式是:
- 前端先重构成“聊天消息”和“过程运行”两套状态。
- 聊天页改成三栏工作台。
- 先接现有
/api/agents做 Agent 管理页。 - MCP 管理页需要后端先补接口。
- 真正的过程可视化必须补结构化 WebSocket process events,核心后端插入点是:
nanobot/agent/delegation.pynanobot/a2a/client.pynanobot/agent/tools/mcp.pynanobot/web/server.py