Files
socweb/doc/start/uigoto.md
T
gongzhiyongandClaude Sonnet 4.6 c6ca9dc126 fix: restore workspace components accidentally dropped from git index
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>
2026-04-10 03:09:41 +08:00

19 KiB
Raw Blame History

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 message
    • TracePanel 插入正文前
  • TracePanel.tsx 已支持:
    • 工具摘要
    • 工具列表展开
    • 成功/失败/运行中状态
  • api.ts 已有前后端流协议类型:
    • ChatStreamEvent
    • TraceItem
  • 页面整体骨架已经是聊天产品,不需要推倒重做

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 最终只是写入:

  • outputSummary
  • errorSummary

也就是说:

  • 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
  • 结果卡片区
  • 空状态 / 错误状态 / 完成状态

建议结构:

  1. Header
    • 当前轮标题
    • 当前状态 badge
    • collapse / expand 能力(可选)
  2. Activity 区
    • 展示 status + tool 节点
  3. Result 区
    • 展示当前轮生成的 card stack
  4. 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 -> workspaceSession
  • timeline node -> workspace card
  • tool 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.tsx
    • WorkspaceActivityTimeline.tsx

当前这个文件的“折叠工具列表”心智不够用了。

4. frontend/lib/api.ts

必须升级类型:

  • 增加 workspace card event 类型预留
  • 增加 UI card 数据结构类型
  • 增加 session / activity / card 的类型定义

8.2 新增组件建议

至少新增:

  • AgentWorkspace.tsx
  • WorkspaceHeader.tsx
  • ActivityTimeline.tsx
  • WorkspaceCardRenderer.tsx
  • cards/SearchResultCard.tsx
  • cards/KnowledgeResultCard.tsx
  • cards/TicketSummaryCard.tsx
  • cards/TicketDetailCard.tsx
  • cards/DocumentResultCard.tsx
  • cards/SandboxResultCard.tsx
  • cards/ErrorCard.tsx
  • cards/EmptyStateCard.tsx
  • MessageActivitySummary.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 的交互方向,而不是只做一个右侧栏凑数。