workspace/ files existed on disk but were not included in previous incremental commit, causing git to record them as deleted. Re-adding all workspace card components, AgentWorkspace, ActivityTimeline, and WorkspaceCardRenderer to properly track them. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
19 KiB
SOC Generative UI 产品方案(uigoto)
1. 目标结论
本方案不再把当前前端的 trace panel 视为最终形态,而是将其定义为过渡能力。
本阶段产品目标明确为:
- 基于当前 SOC 前端代码继续演进
- 不切换主工程,不直接迁移到
langgraphjs-gen-ui-examples - 以现有
GeminiChat/GeminiMessage/TracePanel/api.ts为基础重构交互 - 目标交互不是“消息下方的工具折叠区”
- 而是“聊天主线程 + agent 活动层 + 结构化 UI 承接区”
- 最终要求:在当前项目约束下,无限接近
langgraphjs-gen-ui-examples的交互体验
一句话定义:
当前项目从
chat + trace升级为chat + activity + generative UI workspace。
2. 基于当前代码的现状判断
当前前端已经具备以下基础:
2.1 已有能力
- 页面入口极简,
frontend/app/page.tsx直接挂GeminiChat GeminiChat.tsx已经是主控容器:- 负责 sidebar / topbar / message list / input / extensions panel
- 已接入流式聊天
streamChat(...) - 已接收
status / tool_start / tool_end / tool_error / token
GeminiMessage.tsx已支持:- assistant message 渲染
traceItems绑定到单条 assistant messageTracePanel插入正文前
TracePanel.tsx已支持:- 工具摘要
- 工具列表展开
- 成功/失败/运行中状态
api.ts已有前后端流协议类型:ChatStreamEventTraceItem
- 页面整体骨架已经是聊天产品,不需要推倒重做
2.2 当前不足
当前代码的交互层级仍然偏低,主要问题如下:
问题 A:trace 仍然附属于 message,而不是独立 UI 层
当前 TracePanel 只是 assistant message 上方的一块折叠区域。
这意味着:
- tool activity 只是“消息补充信息”
- 不是可持续存在的 agent workspace
- 用户注意力仍然集中在文本回复,不是结构化交互本身
问题 B:status 虽然收到了,但没有成为真正可见 UI
当前 GeminiChat.tsx 接了 status 事件,但 TracePanel.tsx 会过滤掉非 tool 项。
这意味着:
- 后端的 status 没有变成产品层交互
- 用户看不到 agent 当前处于哪个阶段
- 还没有形成真正的 activity timeline
问题 C:没有独立的 generative UI 承接区
当前页面结构只有:
- 左侧 sidebar
- 中间 chat
- 扩展面板
ExtensionsPanel
没有一个与 agent 执行结果强绑定的右侧 workspace / side panel / dynamic card panel。
这和 langgraphjs-gen-ui-examples 的交互差距最大。
问题 D:tool 结果还是“摘要文本”,不是“组件状态”
当前 tool_end/tool_error 最终只是写入:
outputSummaryerrorSummary
也就是说:
- tool 结果只被当成 message 附属文本
- 不能驱动卡片、详情面板、结果区块、交互组件
问题 E:页面是“消息流 UI”,不是“agent 工作台 UI”
现在用户是在看聊天。 不是在看一个 agent 正在构造、更新、切换多个结果视图。
而用户现在明确偏好的是后者。
3. 产品目标:必须完成的范围
下面是本轮必须完成的范围。这个范围一旦确认,就不能做成“弱化版”。
3.1 最终交互目标
必须完成的目标交互如下:
目标 1:对话区仍保留,但不再是唯一主角
中间聊天区仍然保留,用于:
- 展示用户输入
- 展示 assistant 文本回答
- 展示简洁的 agent 活动摘要
但是:
- 详细工具过程
- 结构化结果
- 中间态 UI
- 后续可点击视图
都不能只塞在 message 里。
目标 2:新增独立的 Agent Workspace 区域
必须新增一个独立 UI 区域,位置优先级如下:
- 首选:右侧固定 workspace panel
- 次选:中间 chat 区下方的持续存在 workspace
- 不接受:仍然只挂在 message 气泡里作为折叠面板
这个 workspace 的职责是:
- 承接 agent 的结构化执行过程
- 承接 tool 返回的可视结果
- 在同一轮对话中持续更新
- 在回答结束后保留结果视图
目标 3:status 必须成为第一层可见交互
status 不能再只存在于后端事件和前端状态变量中。
必须在 UI 里直接可见。
必须具备以下阶段表达:
- 已接收问题
- 正在分析
- 正在调用某个工具
- 正在汇总结果
- 已完成
- 失败 / 中断
要求:
- 用户在不展开任何调试视图的前提下,也能看到 agent 当前阶段
- status 不得埋在细节抽屉里
目标 4:tool 调用必须既有摘要,也有实体卡片
每个重要工具调用,不仅要有 timeline 行,还要能够驱动结果卡片。
例如:
- 知识库检索 -> “知识卡片 / 命中条目列表”
- web 搜索 -> “来源列表卡片”
- ticket 工具 -> “工单摘要卡片 / 工单详情卡片”
- 文档生成 -> “文档卡片 / 下载入口”
- sandbox -> “执行结果卡片 / 输出块”
也就是说:
- tool trace 是“过程层”
- tool result card 是“结果层”
- 两层必须同时存在
目标 5:每一轮回答要形成完整闭环
每次一次完整请求,前端必须形成一轮完整可见闭环:
user message -> status -> tool activity -> structured result cards -> assistant answer -> completed state
不能只剩下:
- 有 token
- 有 trace
- 但没有结果区承接
目标 6:结果区要持续存在,不随消息滚动立即消失
用户喜欢的交互,本质上不是“看完就过去”,而是 agent 在右侧/固定区域留下工作结果。
因此必须做到:
- 当前轮次结果在回答结束后仍然可见
- 点击历史消息时,可以重新激活该轮对应 workspace
- workspace 与 conversation / message 建立明确绑定
4. 本轮不允许模糊的实现边界
为了保证“必须完成”,这里明确哪些属于本轮范围,哪些不属于。
4.1 本轮必须完成
A. 页面布局升级
必须把当前页面从:
- sidebar + main chat + extensions panel
升级为:
- sidebar + chat main + agent workspace panel
要求:
ExtensionsPanel不再承担 generative UI 主职责- workspace 是主产品结构,不是弹窗附属物
B. activity timeline 升级
必须把当前 TracePanel 升级为真正的 ActivityPanel:
- 支持 status 节点
- 支持 tool 节点
- 支持完成/失败节点
- 支持当前轮次高亮
- 支持点击节点联动结果卡片
C. result cards 体系
必须定义并实现第一批可交付卡片类型。 本轮最少要完成以下卡片:
- SearchResultCard
- KnowledgeResultCard
- TicketSummaryCard
- TicketDetailCard
- DocumentResultCard
- SandboxResultCard
- ErrorCard
- EmptyStateCard
这些卡片不要求一次做到极复杂,但必须是“真实组件”,不是把 JSON dump 出来。
D. chat 与 workspace 联动
必须实现:
- 某条 assistant message 对应一个 workspace session
- 点击该 message,可重新展示它那一轮的 activity + result cards
- 正在生成时,workspace 实时更新
- 完成后,workspace 固化为当前轮结果
E. 事件协议升级
必须在当前 SSE 事件协议上增加一层 UI 事件语义。
后端不一定一开始就一次发完整 UI schema,但前端必须按这个目标设计:
- activity 事件
- result card 事件
- workspace patch 事件
即使第一版是由前端根据 tool_end 映射卡片,也必须保留后续升级为后端直接下发 UI schema 的位置。
4.2 本轮明确不做
为了保证“无限接近目标交互”而不是分散精力,本轮先不做:
- 多标签 workspace 管理
- 拖拽式布局编辑
- 用户自定义卡片布局
- 通用低代码 schema 编辑器
- 全量历史 workspace 持久化版本管理
- 复杂多人协作 UI
这些都不是当前用户最核心的“像那个项目的交互”诉求。
5. 交互方案:必须实现到的细节
这是本方案最核心部分,重点是交互细节,不允许只停留在“有个右侧栏”。
5.1 总体布局
页面结构必须调整为三栏心智模型:
左栏:Conversation / Navigation
保留现有 GeminiSidebar,只做轻量微调。
职责不变:
- 新建会话
- 会话切换
- 会话管理
- 扩展入口
中栏:Chat Thread
保留聊天主线程,但要减轻其“承载所有信息”的职责。
中栏只负责:
- 用户消息
- assistant 文本输出
- 精炼版 activity 摘要
- 当前轮生成状态
中栏不再承担:
- 大量工具明细
- 详细结构化结果
- 复杂工具结果交互
右栏:Agent Workspace(本轮核心)
新增固定 workspace,默认始终可见。
必须具备:
- 标题区
- 当前阶段状态区
- activity timeline
- 结果卡片区
- 空状态 / 错误状态 / 完成状态
建议结构:
- Header
- 当前轮标题
- 当前状态 badge
- collapse / expand 能力(可选)
- Activity 区
- 展示 status + tool 节点
- Result 区
- 展示当前轮生成的 card stack
- Footer / meta 区
- 时间、完成状态、重试入口(可选)
5.2 Chat 区具体交互要求
交互要求 1:assistant message 上方只保留轻摘要
当前 TracePanel 的详单不应该继续作为主交互。
改造后:
- message 上方只保留一行 activity summary
- 文案例如:
- 正在分析问题
- 已查询知识库与外部信息
- 已生成工单摘要
- 已完成文档生成
不再默认把完整工具列表塞进 message 气泡区域。
交互要求 2:点击 assistant message 可聚焦右侧 workspace
每条 assistant message 都必须可触发右侧 workspace 聚焦。
行为定义:
- hover 时出现“查看工作区”提示或高亮
- 点击 assistant message,右侧显示它对应那一轮的 workspace
- 当前活跃 message 在聊天流中有弱高亮
交互要求 3:生成期间聊天区与 workspace 同步流动
生成中:
- 中间 message 逐步吐文本
- 右侧 activity / cards 同时更新
用户应感知到:
- 不是“等回答完再展示工具过程”
- 而是“回答和工作区同步生长”
5.3 Workspace 区具体交互要求
交互要求 4:workspace 默认固定显示,不是弹窗
这是硬约束。
不接受:
- 抽屉点击后才看见
- modal 弹窗式承接
- 工具面板必须展开才看到
必须默认可见。
交互要求 5:workspace 有明确状态头部
顶部必须显示:
- 当前轮标题(自动从用户问题摘要生成)
- 当前状态 badge
- 当前阶段短文案
例如:
- 分析中
- 调用知识库
- 汇总工单结果
- 生成完成
- 执行失败
交互要求 6:ActivityTimeline 必须是真正的时间线
ActivityTimeline 不是现在 TracePanel 那种折叠列表。
必须具备:
- 顺序节点
- 节点状态图标
- 当前节点高亮
- 完成节点保持可见
- 错误节点可单独标红
- 点击节点可联动结果区滚动/高亮
节点类型至少包括:
- status node
- tool node
- done node
- error node
交互要求 7:结果卡片区必须有“主卡片”概念
不是简单 list。
要求:
- 最新 / 当前最关键结果卡片优先显示在上方
- 次级结果按时间或重要性排列
- 当前高亮的 activity 节点对应的 card 自动高亮
交互要求 8:无结果时不能空白
在 agent 正在运行但还没产出 card 时,workspace 结果区必须有占位状态:
- 正在准备结果…
- 正在等待工具返回…
- 暂无结构化结果
不能出现大面积空白让用户以为没工作。
交互要求 9:回答完成后 workspace 要进入“已完成态”
回答完成后:
- timeline 固化
- 最终状态变为 completed
- 结果卡片保留
- message summary 从“进行中”切换为“已完成摘要”
5.4 卡片层交互要求
交互要求 10:卡片必须像产品组件,不像调试面板
卡片 UI 原则:
- 标题明确
- 信息分组清楚
- 可扫读
- 有主次层级
- 不直接暴露原始 JSON
交互要求 11:卡片内容要有“用户可读摘要 + 结构化字段”双层
例如搜索卡片:
- 顶部:找到 5 条高相关结果
- 下方:来源列表、标题、摘要、链接
例如 ticket 卡片:
- 顶部:共 12 条工单,P0 2 条
- 下方:按状态/优先级分组
交互要求 12:失败也要有失败卡片
如果工具失败:
- timeline 有错误节点
- 结果区同步出现 ErrorCard
- assistant 文本可继续回答,但 workspace 必须保留失败证据
交互要求 13:同一轮允许多卡片叠加
例如一次请求可能触发:
- KnowledgeResultCard
- SearchResultCard
- TicketSummaryCard
- FinalDocumentCard
这些都必须能在一轮 workspace 中共存。
6. 信息架构与前端状态模型
为了避免方案空泛,这里直接给前端目标状态模型。
6.1 当前 message 模型的问题
当前 Message 结构大致是:
- id
- role
- content
- attachments
- traceItems
这不够支撑 generative UI。
6.2 目标模型
前端状态必须增加“workspace session”概念。
建议新增:
interface WorkspaceSession {
id: string;
conversationId: string;
messageId: string;
title: string;
status: "idle" | "running" | "completed" | "error";
stageLabel: string;
timeline: ActivityNode[];
cards: WorkspaceCard[];
startedAt: number;
finishedAt?: number;
}
interface ActivityNode {
id: string;
type: "status" | "tool" | "done" | "error";
label: string;
detail?: string;
tool?: string;
callId?: string;
status: "running" | "success" | "error" | "info";
ts: number;
linkedCardIds?: string[];
}
interface WorkspaceCard {
id: string;
kind:
| "search-results"
| "knowledge-results"
| "ticket-summary"
| "ticket-detail"
| "document-result"
| "sandbox-result"
| "error"
| "empty";
title: string;
priority: number;
data: Record<string, unknown>;
sourceCallId?: string;
}
6.3 关键绑定关系
必须建立以下绑定:
assistant message->workspaceSessiontimeline node->workspace cardtool call_id->activity node->card sourceCallId
这一步是整个交互能否稳住的关键。
7. 事件协议升级要求
7.1 当前协议可复用部分
当前已有:
- token
- status
- tool_start
- tool_end
- tool_error
- done
- error
这个基础可以继续用。
7.2 必须补的语义层
虽然第一版可以前端自行从 tool_end 推导卡片,但协议设计必须预留为以下方向:
事件层 1:Activity Event
用于更新 timeline。
事件层 2:Workspace Card Event
用于插入或更新结果卡片。
建议未来协议形态:
type ChatStreamEvent =
| TokenEvent
| StatusEvent
| ToolStartEvent
| ToolEndEvent
| ToolErrorEvent
| WorkspaceCardEvent
| DoneEvent
| ErrorEvent
其中 WorkspaceCardEvent 应允许:
- append card
- update card
- mark card done
事件层 3:Workspace Meta Event
用于更新:
- session title
- stage label
- overall status
第一版即使后端不直接下发,也必须在前端 store 设计上预留。
8. 组件改造建议(基于现有文件)
8.1 必改组件
1. frontend/components/gemini/GeminiChat.tsx
这是主改造中心。
必须负责:
- 新增 workspace state
- 维护 active workspace session
- 接收 SSE 事件后同时更新:
- message content
- activity timeline
- workspace cards
- 管理 chat 与 workspace 联动
- 页面布局从双主区变三主区
2. frontend/components/gemini/GeminiMessage.tsx
必须改为:
- 弱化当前
TracePanel - 增加
message summary bar - 增加 “查看工作区”/高亮态
- assistant message 点击后切换 active workspace
3. frontend/components/gemini/TracePanel.tsx
不建议继续保留原职责。
建议:
- 要么升级重命名为
ActivityTimeline.tsx - 要么拆成:
MessageActivitySummary.tsxWorkspaceActivityTimeline.tsx
当前这个文件的“折叠工具列表”心智不够用了。
4. frontend/lib/api.ts
必须升级类型:
- 增加 workspace card event 类型预留
- 增加 UI card 数据结构类型
- 增加 session / activity / card 的类型定义
8.2 新增组件建议
至少新增:
AgentWorkspace.tsxWorkspaceHeader.tsxActivityTimeline.tsxWorkspaceCardRenderer.tsxcards/SearchResultCard.tsxcards/KnowledgeResultCard.tsxcards/TicketSummaryCard.tsxcards/TicketDetailCard.tsxcards/DocumentResultCard.tsxcards/SandboxResultCard.tsxcards/ErrorCard.tsxcards/EmptyStateCard.tsxMessageActivitySummary.tsx
9. 分阶段交付要求(但每阶段都有硬结果)
为了降低风险,允许分阶段做,但每阶段都必须是完整可见结果,不接受“先埋代码,UI 后补”。
Phase 1:布局与状态层完成
必须交付:
- 页面三栏结构完成
- 右侧 workspace 固定出现
- status 在 workspace 顶部真实可见
- assistant message 可与 workspace 绑定
- 当前 trace panel 不再承担主展示职责
这是最低可验收版本。
Phase 2:timeline 完成
必须交付:
- status/tool/done/error 节点都能显示
- timeline 可高亮当前节点
- timeline 与 message / workspace 联动
- 当前轮完整活动闭环可见
Phase 3:第一批结果卡片完成
必须交付:
- 至少实现 4 类真实结果卡片
- 正在生成时能增量更新
- 失败时能显示 ErrorCard
- 完成后 workspace 保留结果
Phase 4:接近目标项目交互的收口
必须交付:
- message 区与 workspace 的视觉关系收敛
- summary 文案收敛
- 动效和状态切换自然
- 当前交互整体无限接近目标项目的观感与操作路径
10. 我的方案选择
结合当前 SOC 项目现状,我明确选择:
- 不直接改
langgraphjs-gen-ui-examples为主工程 - 以它为交互参考
- 在当前 SOC 前端基础上完成 generative UI 升级
理由:
- 当前项目前端骨架已成型
- SSE 聊天链路已接通
- trace / status / tool 事件已具备基础
- 改当前项目比反向适配示例仓库更稳、更贴当前后端
所以这份方案不是概念探索,而是当前项目的明确产品实现方向。
11. 最终硬性验收标准
只有同时满足以下条件,才算本方案完成:
验收 1
页面存在固定可见的 agent workspace,不再只是 message 下方 trace 折叠区。
验收 2
status / tool / done / error 都能在 UI 中形成可视 timeline。
验收 3
至少 4 类结构化结果卡片真实落地,并与时间线/工具调用绑定。
验收 4
聊天区与 workspace 双向联动:
- 点击消息可切换 workspace
- 生成中同步更新
- 完成后保留结果
验收 5
最终交互观感明显不再是“chat + 调试 trace”,而是“chat + agent workspace”。
验收 6
用户主观体验上,必须明显无限接近 langgraphjs-gen-ui-examples 的交互方向,而不是只做一个右侧栏凑数。