本文是”Agent 基础设施与交互设计”系列的第二篇。第一篇《接口标准作为熵减》从 stateful container 出发,讨论了 skill 架构、环境隔离,以及为什么接口标准是 agent 时代最重要的设计工作。本篇聚焦于 generative UI——它到底是什么、它引入了哪些新问题、以及它在整个 agent 体系中应该扮演什么角色。
后续文章将对 MCP Apps、Google A2UI 等具体的 generative UI 框架进行技术分析和实践分享。
Token 不够用了
最近看到一个让我觉得很准确的类比:现在的 token 就像 2009 年的流量。
2009 年,移动互联网刚起步,大家用着 2G/3G 网络,每个月几百 MB 的流量包捉襟见肘。当时所有的产品设计都围绕一个约束展开——怎么在有限的带宽里传递尽可能多的信息。图片要压缩,视频想都别想,网页要做移动适配。流量是稀缺资源,而整个行业的创新方向就是在这个约束下做到最好。
今天的 AI 领域处在一个类似的阶段。Token 是当前最核心的稀缺资源——context window 有上限,每次推理都有成本,信息的输入和输出都受到 token 数量的约束。而自然语言作为人与 AI 之间几乎唯一的交互通道,效率其实很低:你需要用大量文字去描述一个问题,AI 也需要用大量文字去解释它的分析。
但回看移动互联网的历史,流量约束最终被技术进步消解了——4G、5G、WiFi 普及之后,带宽不再是瓶颈,产品形态从图文为主演变为短视频、直播、实时交互。约束消失的时候,被约束压制的需求会爆发。
Token 的约束也在快速消退。Context window 在过去两年从 4K 扩展到了百万级,推理成本在持续下降。当 token 不再是瓶颈,AI 和人之间的交互形式也会突破纯文本的限制。
这就是 generative UI 被提出的时代背景。但在讨论它的技术形态之前,需要先回答一个更根本的问题:当 AI 可以用更丰富的方式跟人交互,用户到底在消费什么?
从消费信息到消费智能
在传统 App 时代,用户消费的是信息。世界上存在天气数据、新闻、商品、社交动态,App 帮你找到它、组织它、呈现给你。App 是信息的搬运工和整理师。传统 App 之间竞争的是信息的获取能力、组织方式、呈现质量。整个 UI 设计的命题也围绕于此——如何把信息清晰、美观、高效地展示给人。
在 Agent 时代,信息的获取和组织被 AI 接管了。用户不再需要自己去翻、找、筛选。这时候用户真正在消费的不是信息——信息是原材料——而是 AI 对信息的理解、判断和行动能力。
用户消费的是智能本身。
这个转变对界面的意义是根本性的。如果用户消费的是信息,界面的核心任务是呈现。如果用户消费的是智能,界面的核心任务变了——它需要让用户感知、理解、校验和信任 AI 的智能输出。你不只是在看一个数据图表,你是在评估 agent 对数据的理解是否靠谱。你不只是在读一段分析,你是在判断 agent 的推理是否值得采纳。
当你消费信息时,对错相对容易验证——数据准不准、事实对不对。当你消费智能时,你面对的是概率性的、有解释空间的输出,验证变得困难得多。
纯文本对话作为唯一的交互通道,不足以承载”帮助用户校验智能”这个任务。我们需要第二条通道。这就是 generative UI 的深层动因。
什么是 Generative UI
简单说,generative UI 是指 AI 在对话过程中动态生成界面元素,而不是让用户跳转到一个预先设计好的页面。
传统的 AI 对话产品只能输出文字。你问 agent 一个问题,它回一段 markdown。但文字的表达力是有限的——你让 agent 分析一组数据,它只能用文字描述”呈上升趋势,二月有异常”。Generative UI 让 agent 可以在回复中直接嵌入一个图表、一张地图、一个可点击的选项卡片,甚至一个小型的交互式应用。
目前已经有一些产品在探索这个方向。Vercel 的 AI SDK 支持在聊天流中渲染 React 组件;Claude 的 artifacts 让 AI 可以生成完整的交互式应用;Google 的 A2UI 协议和 MCP Apps 也在定义 agent 输出富媒体的标准方式。
这些实现方式各有不同,但核心思路一致:AI 的输出不再局限于文本流,而是可以包含结构化的、可交互的视觉元素。 后续的文章会对这些框架逐一做技术分析。本篇先讨论一个更基础的问题:为什么我们需要这个东西,以及它在 agent 体系中到底应该扮演什么角色。
为什么需要第二信息通道
了解了 generative UI 的基本形态之后,我们可以从一个更抽象的层面来理解它的价值。
人和 AI 之间最原始的交互形式是自然语言。你说一句话,AI 回一段文字,你读完理解。这个通道是一维的、顺序的、靠人脑线性解码的。Generative UI 开辟的是一条本质上不同的信息通道——AI 不用语言描述,而是把理解编码成视觉结构:图表、交互组件、空间布局。
这条通道比自然语言的链路更长:

链路每长一步都可能引入偏差。但它的价值来自于三个层面:
第一,带宽。 视觉通道的信息密度远高于文字。一张图能在一瞬间传达的信息量,可能需要上千字才能说清楚。而且视觉信息的接收方式是整体感知、按需深入,不是线性扫描。
第二,精确性。 这可能比带宽更重要。自然语言本质上是模糊的。Agent 说”二月销售显著下降”——“显著”是什么意思?5%?50%?跟什么基线比?这些信息在自然语言里是隐含的、可解释的。两个人读同一句话,脑子里构建的数量级可能完全不同。但当这个信息被渲染成图表的时候,背后必须有一个精确的数据模型——具体的数值、明确的轴定义、确定的时间范围。这个数据模型是无歧义的。Generative UI 的真正优势不是”好看”,而是它强制 AI 把模糊的理解转化为精确的数据结构。 自然语言允许 AI 含糊——它可以说”大概”、“可能”、“显著”。而当 AI 需要生成一个 UI 组件的时候,它必须输出结构化数据。如果 AI 对一件事的理解是模糊的,它在生成数据模型的时候就会暴露出来。
第三,可校验性。 正因为有了精确的数据模型,用户对 AI 输出的校验有了锚点。你可以对着图表上的具体数字问”这个值对吗”,但你很难对着一句”显著下降”问同样的问题。在”消费智能”的语境下,这一点尤其关键——可视化让用户能自主判断 agent 的结论是否合理,而不只是选择信或不信。
所以 generative UI 本质上是一个带宽换保真度的 trade-off。自然语言窄但可靠,视觉宽但链路长、失真风险高。在”消费智能”的语境下,这个 trade-off 是值得的——高带宽通道让用户获得了校验智能的能力,精确的数据模型让校验有了锚点。
但这里有一个诚实的问题需要面对:generative UI 是实现这些价值的唯一方式吗?
GenUI 的竞态
事实上,在 agent 时代让界面承载智能输出,至少有三条不同的路线:
路线一:传统 GUI + Agent 后端化。 界面还是设计师提前设计好的,用户操作方式跟今天的 SaaS 没区别。只是后端的逻辑从规则引擎换成了 agent。用户可能根本感知不到 AI 的存在——他点了”生成报告”,背后是 agent 在跑,但前端就是一个按钮和一个结果页面。Notion AI、Figma AI 走的是这条路。优势是确定性高,用户熟悉,经过充分的设计和测试。劣势是灵活性低——界面只能呈现设计师预设的那些场景,agent 的能力被 GUI 的边界卡死。
路线二:数据模型驱动,UI 和对话流解耦。 Agent 不直接生成界面,而是通过 MCP 等协议操作一个外部的结构化数据模型。UI 层独立地监听数据模型的变化,自行决定怎么渲染。对话归对话,界面归界面,两者通过共享的数据模型间接联动。优势是架构干净,数据的精确性天然保证。劣势是需要预先定义数据 schema,而且对话体验和界面体验是割裂的。
路线三:Generative UI。 Agent 在对话流中动态生成界面组件。界面是对话的一部分,最灵活、最自然,但也最不可控。
这三条路线不是互斥的。在同一个产品里,高频确定的操作走路线一,需要持久化协作的数据走路线二,偶发的、探索性的呈现走路线三。
但这引出了一个尖锐的问题:如果路线一和路线二已经覆盖了大部分场景,generative UI 到底还剩下什么独占的领地?
GenUI 的真正领地
回答这个问题之前,需要注意到一个正在发生的趋势:工作空间和对话流的关系正在反转。
Cursor 的模型是 workspace 为主体,对话框是辅助。你盯着代码编辑器,agent 在侧边栏帮忙。
但 Claude Code、Claude Cowork 走的是另一条路——对话流是主体,workspace 退到后台。你描述意图,agent 执行,执行的结果作为对话流的一部分回来给你看。你的注意力焦点不再是代码编辑器或者数据面板,而是对话本身。
如果后者成为越来越多场景的主流交互模式,那对话流里就需要承载远超纯文本的内容。Agent 说”我改了三个文件”,你需要看到 diff;agent 说”分析结果如下”,你需要看到图表;agent 说”这里有两个方案”,你需要看到对比视图。这些东西必须出现在对话流里,因为对话流就是你的注意力焦点。
在这个模式下,agent 的交互自然分成三个层:
严肃的、需要确定性的工作场景。 即使对话流成为主要入口,真正的重度操作(写代码、做设计、编辑文档)仍然需要专业的 workspace。但入口和调度从对话流发起。
嵌入对话流的富媒体交互。 这才是 genUI 的家。你在跟 agent 讨论去哪吃饭,它在对话里嵌一个地图标注了几家推荐的餐厅;你在讨论数据趋势,它嵌一个可交互的图表;你在规划旅行,它嵌一个日程卡片。
自然语言承接大部分长尾。 “帮我总结一下这个文档”、“这段代码什么意思”——回一段文字就够了,不需要生成任何界面。
这意味着 genUI 的定位不是”AI 生成应用”,而是**“对话流中的富媒体嵌入”**。它的粒度是组件级别的,不是应用级别的。它的生命周期是对话上下文内的,不是持久化的。它的交互深度是轻量的——看一看、点一点、选一选——不是复杂工作流。
重新定义 Generative UI
定位清楚之后,genUI 本身的含义也需要重新审视。
一个常见的误解是 generative UI 意味着”AI 从零生成一个完整的界面组件”。但回看实际场景,大量的 UI 呈现是和工具本身绑定的——地图组件来自 Maps MCP,绘图来自 Excalidraw,代码 diff 来自代码工具。这些 UI 不是 agent 动态生成的,而是工具自带的。Agent 做的只是决定调用哪个工具。
那 agent 真正在做的”生成性”决策是什么?是在对话流的这个位置,用什么方式呈现信息——调用哪个工具、选择哪种组件、填充什么数据、按什么方式组合。生成的是呈现策略,不是 UI 代码。
这样理解的话,整个 genUI 的实现其实是一个光谱:

左端是专用交互工具。 每个工具有自己完整的数据模型、交互范式、渲染逻辑。AI 只需要知道什么时候调用它们、往里传什么数据。它们的优势是确定性强、交互质量高。Maps MCP、Excalidraw MCP 就是这类。
右端是通用 canvas。 AI 可以在上面自由组合、渲染任何内容。Claude 的 artifacts 就是雏形——AI 现场生成一个 React 组件,什么都能画,但每次都不一样,质量不可控。
中间是参数化组件。 有固定的交互范式,但内容和配置是灵活的。图表库、表单生成器、对比卡片。AI 选择模板、填充数据、调整参数。不是从零生成,但也不是完全预设。
大部分实际场景被左端和中间覆盖。通用 canvas 是长尾兜底。而且有一个自然的演化路径——东西从右往左迁移。一开始某种呈现需求只能在 canvas 上自由渲染,当这种需求反复出现,就被抽象成参数化组件。当它进一步稳定,就固化成专用工具。Canvas 是实验场,专用工具是终态。
所以,generative UI 的核心不是”生成 UI”,而是 agent 根据语境在这个光谱上做出呈现决策的能力。 它调用专用工具是 genUI,它配置参数化组件是 genUI,它在 canvas 上自由渲染也是 genUI。“Generative”描述的是决策过程,不是生产过程。
Skill 与对话流的通信
明确了 genUI 的定位和实现光谱之后,一个基础设施问题浮出水面:skill 的执行进程如何与对话流交互?
在上一篇文章中,我们讨论了 skill 运行在 serverless container 里的架构。当前 CLI 模型是单向的——agent 调用一个命令,命令跑完返回结果。但如果 skill 要在对话流中嵌入富媒体组件,并且能够响应用户在组件上的操作,它就需要和对话流之间建立一个双向的、结构化的消息通道。
这个通道需要承载的消息类型远超传统的 stdin/stdout:

在 skill 的代码里,它可能长这样:
from skill_sdk import dialog
# 推送一个交互式图表到对话流
dialog.emit_surface(
component="chart",
data={"x": dates, "y": values},
interactive=True
)
# 等待用户操作
action = dialog.wait_for_interaction()
# 基于用户操作继续处理
if action.type == "click":
dialog.emit_surface(
component="detail_card",
data=get_details(action.point)
)
这个模型下,之前作为独立概念存在的 interactive MCP 不再特殊——它只是一个普通的 skill,碰巧 emit 了 interactive 的 surface 组件,并且在 wait 用户的 interaction 事件。Maps MCP 不是一种特殊的工具协议,而是一个 skill,它的 surface 是地图组件,它等待的 interaction 是用户在地图上的操作。
Skill、CLI、interactive tool、genUI 在这个模型下统一了。
半双工与操作意图
但这里有一个根本性的架构问题:生成出来的 surface 既是 agent 的表达,又是用户可操作的空间。如果两个方向同时活跃,就会冲突——用户正在图表上拖动筛选器,agent 同时想更新图表加一条趋势线,谁优先?
好在对话流本身提供了一个天然的答案:对话就是半双工的。你说一句,我说一句。GenUI 作为对话流中的嵌入,天然继承这个节奏。Agent 推送一个 surface,控制权交给用户。用户操作完或继续说话,轮到 agent 回应。

每个时刻只有一方在”说话”,不存在并发冲突。
但这里有一个微妙的问题:用户在 surface 上的操作,哪些应该立刻发送给 agent,哪些是用户自己在探索?
用户在地图上缩放、在图表上 hover 看数值、在表格里滚动——这些是探索性的,用户还在想,不希望每一次操作都触发 agent 的回应。但用户在决策卡片里点了”选 A”、在 ask_user_input 里选了一个选项——这些是明确的决策,应该立刻传回。
如果把所有操作都立刻发给 agent,用户会疯。如果所有操作都不发,agent 就是瞎的。
合理的模型是:默认本地,发言时附带快照。
Surface 上的大部分操作是本地的——用户自己看、自己探索,agent 不介入。只有少数明确的决策操作(声明为 emit_immediately 的按钮)会立刻传回给 agent。
当用户主动在对话框输入文字的时候,surface 的当前状态——用户筛选到了什么范围、选中了哪些数据点、停留在什么视图——作为快照自动附带在用户的消息里。Agent 不需要追踪用户的每一次操作,但当用户决定”说话”的时候,agent 能看到用户当时看到的、关心的状态。
这就像人类协作:你同事在自己电脑上翻了半天数据,你不需要知道他翻的过程。但他跟你说话的时候,会把屏幕转过来让你看。
三方对齐
以上是 genUI 的定位和基础设施。接下来讨论它引入的核心设计难题。
传统 GUI 的设计只需要对齐两方:人和系统。设计师画了一个按钮,系统知道点击它会触发什么,人知道点击它意味着什么。两边理解一致,就是好设计。
Agent 时代多了一个角色。当 surface 被引入对话流,信息的生产者(agent)、渲染者(系统)和消费者(人)变成了三方,而三方对同一个 surface 可能有不同的”理解”:
人看到一个图表,理解的是”销售在下降,二月最差”。
Agent 持有的是生成这个图表时的底层数据和分析逻辑,它的理解可能是”销售在下降,但季节性因素调整后其实持平”。
系统看到的是一组 JSON + 渲染指令,它不理解任何语义,只是忠实地把数据变成像素。
这个不一致是隐性的——大家都在看同一个东西,但各自脑子里的模型不同,没人意识到分歧的存在。
不过,前面讨论的数据模型的精确性其实为三方对齐提供了一个锚点。如果有一个精确的结构化数据模型作为中间层,系统从它渲染,agent 从它生成,人从它的视觉投影理解——对齐的锚点不再是模糊的文字,而是精确的数据结构。
在交互式 surface 中,对齐问题有另一个维度。当用户在图表上拖动了一个筛选器,这个操作的语义对三方可能不同。用户觉得”我在看二月的数据”,系统执行的是 filter where month=2,agent 可能不知道用户做了这个操作。前面讨论的”快照附带”机制部分解决了这个问题——用户发言时,agent 能看到 surface 的当前状态,但这也只是一个近似的对齐,不是完美的同步。
Surface 不只是呈现层,它是人、agent、系统三方共享认知的媒介。 在”消费智能”的语境下,如果用户对智能输出的理解和 agent 的实际理解之间存在隐性偏差,用户可能在错误的基础上做出决策,而且完全没有意识到。
双通道互校验
三方对齐的风险怎么缓解?
自然语言对话有一个天然的兜底机制——你说了一句话我没听懂,我说”什么意思”,你换个方式再说一遍。这个修复循环是内建在对话结构里的。
Generative UI 没有这个循环。界面生成出来就摆在那里,不会主动问”你看懂了吗”。如果信息在链路中失真了——渲染错了、用户误读了——没有机制能检测到。
所以一个关键的设计原则是:genUI 永远不应该脱离自然语言通道独立存在。
每一个视觉输出都应该有一个自然语言的”影子”——agent 用文字描述”我生成了什么、我想表达什么”。
它是对齐校验:如果用户看到图表理解的是 A,但 agent 的文字描述说的是 B,分歧立刻可见。失真从隐性变成显性。
它是回退通道:当视觉通道失败——渲染出错、用户读不懂、设备不支持——自然语言通道还在,用户至少能通过文字理解 agent 想传达什么。
在上一篇文章中,我们提出了 skill 的 surface 分层模型。在这个框架下,Level 0 的自然语言叙述不只是”客户端能力不足时的降级方案”,它是整个 genUI 体系的语义锚点:

对于 skill 的规范设计,这意味着 Level 0 不是 optional 的增强,而是强制要求:任何 skill 如果提供了 Level 1 或 Level 2 的 surface,就必须同时提供一个 Level 0 的语义描述,且这个描述必须足以独立传达核心信息。
Affordance 的可靠性
关于 genUI 还有一个常见担忧:UI 元素是动态的,用户无法形成操作习惯。每次出现新的 component,用户可能不知道该怎么操作。
这个担忧真实但被高估了。Google 的 rich results 已经在大规模验证这个模式——搜航班出航班卡片,搜食谱出步骤富结果,搜数学公式出计算器。每次 UI 都不一样,但没有人抱怨不会用。因为每个组件的 affordance 是自解释的。
人对 UI 的理解不依赖于”我之前见过完全一样的界面”,而是依赖于视觉语言的一致性。只要组件遵循通用设计惯例——按钮长得像按钮、输入框长得像输入框——用户就能理解。
真正会出问题的不是组件可变,而是交互模式不可预期——看起来像按钮但触发了不可逆操作,看起来是展示信息的卡片但其实可编辑。
所以规范约束不应该放在”限制可变性”上,而应该放在保证 affordance 的可靠性上。具体到 spec 设计,skill 生成的 UI 组件需要声明自己的交互类型——display only、clickable、editable、destructive。客户端根据声明统一处理视觉和行为。Skill 开发者不需要自己设计按钮样式,只需要标注”这个操作是破坏性的”,客户端自动渲染成带确认的红色按钮。
这把设计一致性的责任从 skill 开发者转移到了客户端 runtime。就像 HTML 只声明”这是一个 button”,浏览器负责让它看起来像按钮、行为像按钮。
从 Accessibility 到 Agent Accessibility
回顾以上讨论——语义与呈现的分离、多通道可达性、progressive enhancement、在动态输出上保证可预期性——这些原则并不新。它们是 web accessibility 几十年来的核心设计理念。
Accessibility 的核心前提是:你不能假设用户通过什么通道接收信息。有人用眼睛看,有人用屏幕阅读器听,有人用盲文触摸。所以必须把内容和呈现分离——内容是语义化的,呈现根据用户的能力和设备动态适配。
Agent 时代面对的是同一个结构性问题,只是维度变了。你不能假设谁在接收信息——可能是人用眼睛看,可能是 agent 在解析,可能是另一个系统在消费。而 generative UI 再推了一层:你不能假设信息以什么形态被生成——界面本身是动态的,需要在不确定的输出上保证多通道可达性。
WCAG 的 POUR 原则可以直接迁移:
Perceivable(可感知):skill 的输出必须能被人和 agent 同时感知——语义标注解决这个。Operable(可操作):交互组件的 affordance 必须可靠——交互类型声明 + 客户端统一渲染。Understandable(可理解):三方认知对齐——Level 0 narrative shadow + 快照机制。Robust(健壮):跨客户端兼容——progressive enhancement 的分层架构。
Level 0 narrative 的角色就像 alt text——不是降级方案,是语义锚点,确保任何呈现形式失败时信息仍然可达。
这个领域的设计哲学不需要从零发明。适用对象从”不同能力的人”扩展到了”人 + agent + 系统”的三方关系。我们可以称之为 Agent Accessibility。
缺失的规范
综合以上讨论,我们可以定位 generative UI 在 agent 体系中的位置,以及当前规范图谱中一个明确的空白。
能力层已经有人在定义——Anthropic 的 skill spec、MCP 定义了 skill 怎么打包和工具怎么调用。呈现层也有人在做但碎片化——Google A2UI、Vercel JSON schema、MCP Apps 各自一套方案。
中间那一层——能力层和呈现层之间的接口——没有人在定义。

这个中间层——Skill-Surface Interface Spec——需要覆盖五个层面:
语义层:skill 输出数据的语义标注,包括 confidence/uncertainty 元数据,让数据模型的精确性可被三方共享。
呈现层:skill 在光谱上的定位声明——它的输出适合由专用工具渲染、参数化组件配置、还是需要通用 canvas。Level 0/1/2 的 progressive enhancement,Level 0 作为强制的语义锚点。
交互层:组件的交互类型声明(display only / clickable / editable / destructive),affordance 约束,确保动态生成的界面可预期。
通信层:skill 执行进程和对话流之间的 dialog channel 协议——emit(surface / progress / ask / result)和 receive(user_input + snapshot / interaction / abort)的消息类型定义。
对齐层:Level 0 narrative shadow 作为双通道校验机制,surface 快照作为用户操作状态的传递手段,三方认知同步的基础设施。
它的设计哲学根植于 accessibility 的传统:语义与呈现分离,多通道可达,progressive enhancement,在不确定的输出上保证可预期性。它不需要管光谱的两端——专用工具自己定义一切,通用 canvas 太自由管不住。它管的是中间地带——参数化组件的数据契约,以及 skill 和对话流之间的通信标准。
这个规范的生态位之所以独特,是因为做能力层的人不会去想呈现问题,做呈现层的人不会去想 skill 执行语境。而这个中间层的缺失,正是当前 skill 和 generative UI 两条线无法整合的根本原因。
下一篇将从具体的技术框架出发——MCP Apps、Google A2UI 等——分析它们各自的实现方式、设计取舍和适用边界,为这个 Skill-Surface Interface 的设计提供更具体的参照。
2026.03
