生成式 UI 与 Just-in-Time UI
从对话卡片到 Agent 运行时与开放协议
证据快照:2026-08-31。本文依据公开文档、规范与产品公告编写;协议、Host 支持和产品能力变化很快,实际实施前须重读原始链接。本文不把厂商宣称、研究原型或实验功能写成已被大规模验证的行业结论。
如果只读一页
**生成式 UI(Generative UI)**描述“界面内容、组件选择或布局有多少由模型/Agent 决定”;**Just-in-Time UI(JIT UI)**进一步描述“它应当在什么任务、什么情境、什么时机出现,又何时退出”。前者是生成机制,后者是面向人的产品交互范式;两者相关但不能互换。
这个方向并非从 coding agent 才开始。至少在 2023 年,Vercel 已将用自然语言生成界面代码称为 Generative UI;近年的变化是,模型不再只生成一次性页面代码,而开始在运行中的对话、语音、Agent 工作流和第三方工具之间,持续提供可交互的临时表面。Vercel 2023 v0 公告 与 AI SDK UI 是这条早期开发者脉络的代表。2025 年 Andrew Sims 用 JIT UI 概括“对的界面在对的时刻出现”的产品观;同年 Google 公开了为单次提示即时生成交互体验的研究与产品实验。Just-in-Time Interfaces、Google Generative UI
截至证据快照,不存在一个覆盖所有层的“JIT UI 标准”。正在形成的是可组合的分层:
| 层 | 它解决什么 | 代表 |
|---|---|---|
| Agent ↔ 用户运行时 | 流式状态、工具事件、中断、共享状态、前端动作怎样双向传递 | AG-UI |
| Agent ↔ UI 描述 | Agent 怎样在可信组件目录内表达一个动态界面 | A2UI |
| MCP 工具 ↔ 嵌入式界面 | 第三方 MCP Server 怎样携带可交互 UI 给 Host | MCP Apps |
| 应用内实现框架 | 应用怎样把模型输出、tool call、stream 和既有组件接进前端 | Vercel AI SDK、CopilotKit |
因此,AG-UI 不与 A2UI 竞争:前者是 Agent—用户的事件运行时,后者是可渲染 UI 的声明式载荷。MCP/A2A 也不是 JIT UI 标准:MCP 解决 Agent 接工具与数据,A2A 解决 Agent 间协作;MCP Apps 才是 MCP 上承载交互 UI 的可选扩展。AG-UI 协议定位
1. 从固定“信息架构”到临时“行动表面”
传统产品把能力预先压缩为导航、页面、表单和固定流程。它适合高频、稳定、可枚举的任务;但用户带来的往往是“我现在要完成什么”,而非“我要访问哪个功能”。当一个任务跨越搜索、理解、比较、确认和写回,用户必须自己在多个房间里搬运上下文。
JIT UI 的承诺不是消灭固定 UI,而是把下列输入编译成一个最小且可退出的行动表面:

用户模型 + 当前目标 + 任务状态 + 时间/环境 + 权限与风险策略
↓
受约束的 UI 决策与组合
↓
临时界面 → 用户行动/确认 → 业务结果 → 状态回写
↓
退出或降级到固定 UI它应解决四类问题:
- 能力发现成本:用户不必先学会菜单结构,系统在判断足够可靠时提供与目标相符的动作与证据。
- 长尾任务的界面组合成本:不为每一种低频组合预建一条完整流程,而从已有可信部件拼出临时工作面。
- 对话的低带宽问题:聊天适合意图澄清,但比较、编辑、审批、可视化与多状态选择常需要结构化表面。
- Agent 可见性与可控性:运行中的 Agent 需要把工具过程、候选、风险、进度和可中断点投影给人,而不是只在最后输出一段文字。
但“即时”不等于“随时主动”。出现时机本身是一个需要证明的决策:低置信、不可逆、高风险或强打扰场景应保持静默、请求确认,或回退到固定、可预测的界面。JIT UI 的成功指标不能只看生成次数,还要看任务完成、采纳、误触、撤销、打扰和用户为何能理解此刻出现它。
2. 概念边界:别把四件事混为一谈
| 名称 | 核心问题 | 生成/变化对象 | 必要边界 |
|---|---|---|---|
| 生成式 UI | Agent 决定多少 UI 表达 | 组件、数据、布局或 HTML | 组件契约、设计系统、安全和无障碍 |
| JIT UI | 为什么此刻为这个人出现这个表面 | 时机、范围、动作和退出 | 用户/任务状态、权限、解释、fallback |
| Agentic UI | 人与长运行 Agent 怎样共同工作 | 状态、工具事件、审批、干预 | 生命周期、取消、状态一致性、审计 |
| UI code generation | 怎样把自然语言变成前端代码/原型 | 源码与页面 | 代码审查、测试、设计还原与发布链路 |
例如,v0 的“描述界面→生成代码”更接近 UI code generation;Vercel AI SDK 的 tool-result card 更接近受控生成式 UI;ChatGPT Voice 在语音中出现天气、股票、体育等视觉卡片是产品内的情境化 UI;真正的 JIT UI 还要求它基于任务状态恰时出现、支持完成动作、把结果写回并在任务完成后退出。OpenAI 已公开说明 GPT-Live 的 Voice 体验会呈现这些富视觉卡片,但这不等于它公开了一个供开发者编程的 JIT UI API。OpenAI GPT-Live 公告

3. 现实不是二元选择:三种生成强度
CopilotKit 的分类很适合成为工程判断的共同语言:
| 形态 | Agent 能做什么 | 客户端掌握什么 | 典型适用面 | 主要风险 |
|---|---|---|---|---|
| 受控(Controlled) | 在预建组件中选择,填充类型化数据 | 布局、风格、交互、权限 | tool card、审批、表单、业务动作、关键路径 | 能力扩张时组件建设量增加 |
| 声明式(Declarative) | 输出受 schema 约束的组件树与绑定 | 组件目录、映射、验证、设计 token | 长尾表单、动态工作台、跨端 UI | schema 与组件目录设计不足会限制体验或失控 |
| 开放(Open) | 输出任意 HTML/iframe 或代码生成体验 | sandbox、CSP、审查与 fallback | 教学模拟器、探索型可视化、第三方丰富工具 | 安全、无障碍、品牌一致性、延迟与可复现性 |
大多数生产功能会从受控模式起步:模型只负责判断“何时显示哪个已验证组件以及其数据”,业务系统仍是状态与副作用的权威。声明式模式扩展组合空间;开放模式适合探索,但不能以“模型能写网页”替代安全策略。CopilotKit 对这三种模式及 MCP Apps 的区分见其生成式 UI 概览。

4. 协议地图:先把“协议在管什么”分开
如果没有读过原始规范,最容易误解的是把三者都当作“AI 生成 UI 的 JSON 标准”。它们其实处于三条不同的合同上:AG-UI 管一次 Agent run 如何让前端看得见并能介入;A2UI 管一个临时界面如何用安全的描述被 renderer 画出来;MCP Apps 管一个第三方工具如何把它自己预建的 Web App 带进聊天 Host。
| 协议 | 可以把它想成 | 发送的主要东西 | 它故意不规定什么 |
|---|---|---|---|
| AG-UI | Agent 的“过程直播 + 协作遥控器” | run、消息片段、工具生命周期、状态快照/增量、前端动作 | 组件树、CSS、业务授权规则 |
| A2UI | 受限的“临时界面描述文件” | surface 生命周期、可信组件树、数据绑定、action | 传输方式、任意 JS/HTML、领域副作用 |
| MCP Apps | 工具随身携带的“沙箱小应用” | ui:// 预声明资源、tool result、iframe ↔ Host JSON-RPC | UI 由模型临时设计、所有 Host 都支持它 |
下面不从术语,而从一个用户真正会遇到的链路解释:研究 Agent 检索五分钟后,需要你在“保守方案 / 激进方案”之间作选择并批准一次真实写入。
AG-UI:让前端跟上一次正在进行的 Agent run
AG-UI 的对象不是“一个卡片”,而是一次运行中的协作过程。用户应用向 Agent 发起 run;Agent 返回的是有类型、按时间到达的一串 event。前端消费这串 event,才知道现在该显示“正在检索”、逐字文本、某个工具的参数、等待批准,还是失败/完成。threadId 代表对话/任务上下文,runId 代表这一次执行;两者使前端不会把旧 run 的迟到事件误贴到新的任务上。AG-UI 的核心接口可概括为:输入一次 RunAgentInput,订阅一个 BaseEvent 流;传输可以是 SSE、HTTP binary、WebSocket 等,协议本身不绑定其中之一。AG-UI Core architecture
把它套进上例,事件流会像这样:
RUN_STARTED(threadId, runId)
→ STEP_STARTED("检索政策")
→ TOOL_CALL_START("search") → TOOL_CALL_ARGS(...) → TOOL_CALL_END
→ STATE_DELTA(候选方案、风险、进度)
→ TEXT_MESSAGE_CONTENT("我找到了两种可行方案…") …
→ 前端展示“批准写入”受控组件,用户点击/填写
→ 前端动作或 tool result 回到 Agent
→ TOOL_CALL_RESULT / STATE_DELTA(已写入的事实)
→ RUN_FINISHED (或 RUN_ERROR / 用户中断)这里有两组容易混淆但很关键的消息。第一组是显示过程:TEXT_MESSAGE_START/CONTENT/END 是文本流;TOOL_CALL_START/ARGS/END/RESULT 是工具调用从“准备参数”到“得到结果”的过程;RUN_*、STEP_* 是 run/步骤的边界。它们让前端不必从自然语言猜“工具是否已经跑完”。第二组是同步可共享状态:STATE_SNAPSHOT 给某一时刻的完整状态,STATE_DELTA 用 JSON Patch 发小改动,MESSAGES_SNAPSHOT 给可恢复的消息历史。前端可以把 snapshot 当作重连后的基线,再按 delta 重放;它不意味着这个 state 自动就是订单、审批记录等业务事实。AG-UI Events
因此,AG-UI 的前端实现通常要维护两本账:一份是可丢弃或可重放的 run/UI state(进度、草稿、当前候选);另一份是业务系统确认后的领域事实。批准按钮的视觉出现可以由 AG-UI event 驱动,但真正的“创建发布记录”仍要走受权服务、幂等键与审计。AG-UI 解决的是“人何时看到并介入 Agent 过程”,不是替业务系统执行副作用,也不规定组件究竟是 React 卡片、原生 iOS 控件还是 A2UI renderer。

A2UI:让 Agent 传递“要画什么”,而不是“要执行什么代码”
若 AG-UI 是过程直播,A2UI 就是其中可能携带的一种界面说明书。它把一个暂时存在的 UI 区域叫作 surface:例如 comparison_42。Agent/Server 不把 React、DOM 或任意 JavaScript 发给客户端,而是发版本化 JSON envelope;renderer 只从自己本地已登记、已验证的 Component Catalog 中找组件来解释它。换言之,模型能够组合 Card、Text、ChoicePicker、Button 及其已声明字段,却没有获得“在宿主里运行一段任意脚本”的权力。A2UI v0.9 specification
一个 surface 的完整生命周期并不复杂,但它解释了 A2UI 为什么能支持 JIT UI 的出现、变化和退出:
createSurface(surfaceId, catalogId, …) # 先声明临时区域和可用目录
updateComponents(surfaceId, components) # 再给组件结构(每个组件有 ID、类型、引用)
updateDataModel(surfaceId, path, value) # 单独填入或局部替换显示数据
… 多次 updateComponents / updateDataModel # 流式或用户交互后增量更新
deleteSurface(surfaceId) # 任务结束,移除这块临时界面及其本地数据这不是把一棵完整 UI 树每次重传。components 是带 ID 的扁平邻接表:容器引用子组件 ID,renderer 从 root 组装树;data model 是另一份 JSON,组件属性以 JSON Pointer(例如 /options/0/title)绑定其中的数据。于是“换候选方案的名称”只需更新 data model,不必重发整个布局;“从二选一改成三选一”才更新组件结构。前提是消息必须有序送达:若先收到 updateDataModel、后收到 createSurface,客户端状态就可能损坏,所以 A2UI 需要可靠顺序、明确消息分帧;交互时还需一条 Client → Server 的回程。A2UI 可走 AG-UI、A2A、MCP、SSE 或 WebSocket,它描述的是 payload 语义而不是传输层。A2UI Protocol: flow and transport
最值得掌握的是输入的本地写、显式回传合同。用户在 TextField 输入“周五 19:00”时,renderer 先把 /reservationTime 写入该 surface 的本地 data model,因此没有逐字网络请求;用户点击“提交”时,Action 才把指定 context 从当前 model 解析出来,带上 surfaceId 和来源组件 ID 发给 Agent。Agent 收到的是“用户在哪个 surface 的哪个按钮发起了什么 action,以及被允许随 action 传回的字段”,然后才可以请求业务服务。它甚至可以把 sendDataModel: true 打开,使完整 local model 以 metadata 随后续文字/语音动作同行;这能支持用户说“就按这个提交”,也意味着 orchestrator 必须按 surfaceId 做归属路由并剥离不该交给下游 Agent 的 model。A2UI Actions
所以 A2UI 的安全不是“组件目录存在”就完成了:renderer 必须拒绝不认识的 catalog/组件或无效 payload,并把 VALIDATION_FAILED 回给 Agent;但服务端仍必须重做权限、字段合法性、领域约束与副作用保护。A2UI local data model 是交互草稿,不是业务真相。

MCP Apps:不是“模型画 UI”,而是“工具带着已写好的 UI 进来”
MCP Apps 回答的不是“如何描述一个临时组件树”,而是一个 MCP tool 怎样带来自己的完整交互 View。工具 Server 在 tool 定义的 metadata 中指向预先声明的 ui:// 资源;当模型选择该 tool 后,Host 取回 HTML(初始规范的主内容类型)、在聊天内的 sandboxed iframe 里渲染,再把 tool result 交给这个界面显示。换句话说,地图 tool 可以带一张已开发好的可缩放地图,部署 tool 可以带一套已开发好的多字段配置流程;模型主要选择、填参或读取结果,并不是此时临场设计它们的 DOM。MCP Apps overview
把它套进同一例子,MCP Apps 的时序是:
Tool 定义中声明 _meta.ui.resourceUri = ui://comparison/app
→ Host 可在 tool 真正被调前预取 / 缓存 / 审查资源
→ 模型调用 compare_options tool,Server 返回数据
→ Host 在 sandbox iframe 打开预建 View,并将数据交给它
→ 用户在 View 中筛选、翻页或点击提交
→ iframe 通过 postMessage 上的 MCP JSON-RPC 请求 Host 调用允许的 tool / 更新对话上下文
→ Host 按权限、用户同意和 tool visibility 决定是否执行“预声明资源”是它最重要的治理选择:表现模板与 tool result 数据分离,Host 可以在执行前发现、缓存和审查 HTML;视图与 Host 的双向通信复用 JSON-RPC,Host 可以限制它能叫哪些工具、是否能打开链接或请求设备权限。sandbox iframe 隔离父页面 DOM、cookie 和 local storage,但不能替代对外链 CSP、iframe permissions、用户同意、工具结果校验的具体策略。该扩展也是可选且需能力协商的;Host 兼容度应按目标产品实际验证,不能把“一个 MCP Server 有 UI”误解为所有聊天客户端都会显示。MCP Apps SEP-1865

它们可以怎样组合
一项产品可用 AG-UI 流转整个 Agent 运行状态;在某个 STATE_DELTA 表明“需要用户选择”时,采用 A2UI 生成一个受限选择 surface;当 Agent 调到第三方地图或复杂编辑器时,再让 MCP Apps 作为预建 iframe View 出现。反过来,A2UI 也可以由 AG-UI 作为传输承载。这是层间组合而非互斥选型;唯一不能省略的是业务系统对副作用的最终授权与审计。
一条组合路径
Agent Runtime --(AG-UI events)--> 应用前端
├─ 预建组件:直接渲染
├─ A2UI JSON:目录校验后原生渲染
└─ MCP App:预声明 HTML 在 sandbox iframe 中渲染
用户输入/确认 <------------------ 事件、状态与受控工具调用回流这也是“有标准”最准确的表述:有多个相邻的开放契约,覆盖不同边界;尚没有一个从用户模型、时机判断、组件语法、跨端渲染、权限、审计到效果评估的统一 JIT UI 总规范。
4.5 JIT UI 还缺的一层:时机与退出状态机
协议让界面能够传输和渲染,却不回答“为何现在显示给这个人”。这部分必须作为产品状态机建模,而不能藏在 prompt 里:
| 状态 | 进入条件 | 用户看到什么 | 必须验证的退出 |
|---|---|---|---|
| Dormant | 无明确任务或置信不足 | 不打扰;保留固定 UI | 不因弱相关信号误触发 |
| Candidate | 识别到任务、信息缺口或需要确认 | 最多显示一个可解释提议 | 拒绝、忽略、超时皆可回退 |
| Proposed | Agent 提供证据与可选动作 | 预览、依据、风险与选择 | 用户能撤销或改写目标 |
| Active | 用户开始填写/审阅/协作 | 临时工作面与实时状态 | 断线恢复不丢输入,不混入其他任务 |
| Committing | 需要真实副作用 | 明确确认、权限和幂等键 | 成功/失败来自领域服务,不是模型文本 |
| Resolved / Expired | 任务完成、取消或过期 | 结果回执;表面收起或转固定页面 | 不再接收旧流和旧 action |
最实用的 JIT UI 不是最大化主动性,而是把 Candidate → Proposed 的阈值设得保守。出现理由、来源事实、操作影响和 fallback 必须同时可见。否则系统只是把固定导航的迷路,替换成模型驱动的随机打扰。
5. 重点实现方案
Vercel AI SDK:让既有前端快速承接模型流与工具 UI
AI SDK UI 的核心价值是把模型 stream、消息、对象与 tool call 统一成前端可消费的 UI 流,支持多种主流 Web 框架。它尤其适合“已有 Web 产品 + 后端已经能可靠调用工具”的路线:模型/Agent 发出结构化 tool invocation,前端把它映射为自己已写好的卡片、表单、进度和结果组件。其意义不在于让模型直接拥有 DOM,而在于把 UI message 的流式与类型边界处理掉,使团队把精力放在交互与业务事实上。AI SDK 文档、AI SDK 开源仓库
一个值得注意的演进信号是:曾以 streamUI 流式下发 React Server Components 的 AI SDK RSC 示例当前标记为“开发暂停”;这说明早期“服务器把组件直接流进客户端”的路线并不是唯一收敛方向。对新项目,更稳妥的抽象是持久的消息/事件协议、明确的 tool schema 与客户端受控渲染,而不是把某一 RSC 实验 API 当成通用 JIT UI 标准。AI SDK RSC 示例说明
AI SDK 的真实核心:UIMessage 不是聊天文本,而是渲染状态
AI SDK 的关键抽象是 UIMessage:它保存 id、role、metadata 和 parts,作为前端渲染与恢复所需的完整消息状态;它不同于送入模型的 ModelMessage。这一区分很重要:UI 可能包含工具调用、来源、文件、临时进度和客户端交互状态,而模型上下文应只接收经过校验、转换和权限裁剪后的内容。UIMessage 参考
一次受控 tool UI 的生命周期可拆成:
用户消息
-> 后端 streamText / Agent stream
-> UIMessageChunk(SSE)
-> useChat 聚合为 UIMessage.parts
-> Text | Data | Tool input | Tool result 等类型化 part
-> 应用组件按 part 渲染 loading / approval / result
-> 用户确认或客户端工具 addToolOutput
-> 必要时自动续交给 Agent 的下一步这不是概念性的“LLM 调用函数”。AI SDK 明确区分三类工具:服务端自动执行、客户端自动执行、以及必须由人操作的客户端工具。对于最后一类,工具调用先作为 assistant message 的 typed part 出现在 UI 中;用户完成表单或确认后,前端调用 addToolOutput 写回结果,才可能由 sendAutomaticallyWhen 触发下一轮。这正是将“模型提出动作”与“用户/系统批准并完成动作”分开的实现位置。AI SDK Chatbot Tool Usage
因此,一个可靠的 AI SDK 组件不应只读 toolName 和一次性 args。它至少要根据 part 的生命周期处理:输入开始和增量、等待确认、执行中、成功、失败、取消/断线,并按稳定 ID 更新同一个局部视图。对于进度、来源、临时卡片等不必成为对话历史的内容,可以用带 ID 的 data-* part 做合并/更新,并显式标记 transient;不要把每一个 token 或进度点都写成新的业务事实。UI Message Stream Protocol、Streaming Custom Data
useChat 还暴露 submitted、streaming、ready、error 等交互状态,以及 abort、disconnect、error 的完成原因。JIT UI 若忽略它们,就会把网络中断误画成“任务已经完成”。实现上,持久化的对象应至少拆为三层:conversation/UI projection(可重放)、agent run trace(解释发生了什么)与business truth(订单、审批、文档等最终事实)。它们可以互相引用,但绝不能互相冒充。useChat 参考
CopilotKit:把生成式 UI 放回 Agent 运行时
CopilotKit 的重点不是只提供一个聊天窗,而是将 Agent runtime、React 前端、共享状态、人类介入与多种生成式 UI 放到同一条运行链路。其六类原语清楚地覆盖了渐进路线:
- Components as Tools:把已有应用组件注册为前端工具,Agent 用类型化参数调用;
- Tool Call Rendering:为已有后端工具映射实时状态、参数和结果卡片;
- State Rendering:订阅 Agent 流式状态,并随之重绘工作台;
- A2UI:从动态或固定 schema 渲染组件目录;
- MCP Apps:嵌入 MCP Server 随工具提供的 sandbox UI;
- AG-UI:用同一事件运行时连接不同 Agent backend。
这使 CopilotKit 特别适合需要“Agent 在运行中不断展示进度、请求确认、修改共享工作面、被人打断或重定向”的产品。它并不要求每个功能都进入开放生成:同一应用可同时使用受控组件、声明式 A2UI 与 MCP Apps。其文档将这种选择明确定位为按功能而不是按产品二选一。CopilotKit Generative UI、AG-UI Overview

AG-UI 把“Agent 正在做事”拆为可渲染事件,而不是一条长文本
AG-UI 的价值在于把一个 run 表示为 typed event stream。除了 run 开始/结束、消息生命周期和文本增量,它还有 TOOL_CALL_START → TOOL_CALL_ARGS → TOOL_CALL_END → TOOL_CALL_RESULT 的工具调用序列;前端据此能在参数尚未完整时显示“正在准备”,而不是等最终结果后再伪造过程。对长任务,它提供 STATE_SNAPSHOT(某一时刻完整状态)与基于 JSON Patch 的 STATE_DELTA(增量);前端需要按 run/thread 与状态版本将 delta 应用到正确的共享工作面。AG-UI core architecture、AG-UI events
这带来一个比聊天 UI 更严格的状态纪律:
| 状态域 | 谁是权威 | 前端怎样使用 | 典型错误 |
|---|---|---|---|
| Agent working state | 当前 run / runtime | 显示草稿、计划、进度、候选内容 | 将其直接当作已提交业务结果 |
| 共享 UI state | 应用与 runtime 的明确契约 | 用 snapshot/delta 维护可协作工作面 | 旧 run 的 delta 覆盖新 run |
| Tool / action result | 受控执行器 | 以状态卡和证据呈现 | 只显示 model 的“已完成”文本 |
| Business truth | 领域服务/数据库 | 回读并投影最终事实 | 用 UI 组件本地状态代替它 |
CopilotKit 的 Components as Tools 与 Tool Call Rendering 分别对应“前端提供可调用组件”和“后端已有 tool 在前端如何呈现”;State Rendering 则消费上面的 state stream。由此可见,它的难点不在于注册一个 React 组件,而在于明确状态归属、run 生命周期、取消语义和人类修改怎样回到 Agent。当人类暂停、编辑、拒绝或改变方向时,应写入同一 run 的显式事件/状态契约;不能只在浏览器内静默改画面,否则下一轮 Agent 仍会基于旧世界继续工作。
Google Generative UI:开放式“按提示生成完整体验”的上界实验
Google 2025 年公开的 Generative UI 研究与 Gemini/AI Mode 实验,目标是让模型为每一个 prompt 动态设计并编码整套交互体验,例如学习、计划、模拟器或小游戏。它代表开放生成的能力上界:个性化与表达空间最大,但对质量、速度、安全、无障碍、数据访问和可重复性的要求也最大。Google 的公开表述是实验性 rollout,且其论文评估提到在忽略生成速度时的用户偏好;这不能直接推出一般产品的端到端可用性。Google Research 公告
四种工程机制:不要只按“开放程度”分类
“受控 / 声明式 / 开放”描述的是生成自由度;真正影响架构、测试和锁定风险的,是模型向 renderer 交付什么。截至 2026-08-31,开源生态已经出现四种可区分的机制:
| 机制 | 模型输出合同 | 主案例 | 状态与副作用的正确归属 | 适合什么 |
|---|---|---|---|---|
| 组件即工具(component-as-tool) | 在注册组件中选择一个,并生成受 schema 限制的 props | Tambo | 组件 props / thread state 用于交互;业务写入仍由显式 tool 或领域服务完成 | 在既有 React 产品里,让 Agent 恰时选择图表、表单、任务板等可信组件 |
| UI spec / patch | 组件树、binding、受限 action 与增量 patch | json-render、A2UI | renderer state 可本地更新;跨设备、审批与业务事实仍须有独立权威 | 长尾组合、渐进渲染、希望复放/验证 spec 的工作面 |
| UI DSL | 面向模型的紧凑语言,由 parser 流式编译为组件树 | OpenUI | DSL 内可声明本地变量和 action;mutation 必须映射到受控后端能力 | token / 流式语法是主要约束,且需要更丰富的表单、查询与交互 |
| 工具携带 view | MCP tool 预先绑定的 ui:// 资源或 React View | MCP Apps、mcp-use | iframe/View 的局部状态与 tool result 双向同步;Host 和 server 决定权限 | 第三方工具带来独立的地图、编辑器、审批流,而不是由当前 Agent 发明界面 |
这也澄清一个常见混淆:组件库本身不在本报告的实现范围。它只是上述前三种机制所依赖的可信目录;普通聊天 UI 则只是消费这些机制的宿主。只有当模型或 Agent 能根据上下文选择、实例化、更新或交付一个行动表面时,项目才进入本文主图谱。
6. 应纳入观察范围的项目、实现与对照案例
星标只是社区关注信号,并非质量或生产可用性的证明;下表的数字为 2026-08-31 GitHub API 快照。项目按机制角色分组,而不是做总排名。
6.1 主案例:模型如何表达并更新 UI
| 对象 | Stars | 直接机制 | 为什么应作为主案例 |
|---|---|---|---|
| Tambo | 11.2k | 注册 React 组件的 schema 成为 Agent 可调用能力;模型选组件并流式生成 props | 最完整地展示 component-as-tool:一次性 Generative Component 与可持续更新的 Interactable Component 有不同生命周期 |
| json-render | 16.1k | catalog + JSON spec + JSONL/RFC 6902 风格 patch + action | 把“可信组件目录、状态 binding、增量渲染、调试”做成可复用 runtime,覆盖 React、Vue、Svelte、Solid、React Native 等 renderer |
| A2UI | 16.2k | 可更新的声明式 JSON surface / component / data-model 协议 | 不绑定单一应用或 Agent;强调跨 trust boundary 的可信组件目录与跨端 renderer,是标准化方向的主样本 |
| OpenUI | 8.5k | 流式、行式 OpenUI Lang + parser + renderer | 把 UI grammar 作为一等问题:library 生成 prompt,parser 处理部分/无效输出,renderer 管理表单与 action 回传 |
Tambo 的特殊价值在于它不要求模型直接写 UI tree。开发者把组件名、用途和 Zod props schema 注册给 runtime;模型据此选择组件,并流式填充 props。它的 Generative Component 是响应某条消息新建的临时实例;Interactable Component 则由开发者预置在页面上、由 Agent 读取当前 props 并原位更新。后者很接近 JIT UI 的“稳定工作面被上下文重新配置”,但其远程 thread state 仍是交互上下文,不能替代订单、文档或审批等业务真相。Tambo Generative Components、Tambo Interactable Components、Tambo Component State
json-render 和 A2UI 同属 spec 路线,却不应混为一个标准:前者是面向应用开发的 catalog/runtime,支持 inline chat 与 patch 流;后者是 Agent 向客户端传递 UI 的开放协议,重点是 surface、数据模型和跨 renderer 的可移植性。OpenUI 则把模型输出改为紧凑 DSL:component library、prompt generator、parser 和 renderer 是不可分割的四件套;它可以使表单 interaction 继续对话或原地更新,也可以选择以 sandbox iframe 承载开放 HTML。三者的共同安全前提是:模型得到的是可用能力集合,renderer 只实例化已注册的实现,而不是把模型 token 当作可执行 UI 代码。json-render README、json-render generation modes、OpenUI architecture、OpenUI interactivity
6.2 MCP Apps:工具视图层的实现生态
MCP Apps 不是一条与 Tambo/A2UI 直接竞争的“生成 UI 协议”。它的核心是把某个工具的独立 View 预先带到 Host;因此下列项目应放在工具嵌入层,并以 Host 支持、sandbox、tool visibility、上下文同步和工具结果校验为主要评价维度。
| 对象 | Stars | 角色 | 观察重点 |
|---|---|---|---|
MCP Apps ext-apps | 2.8k | 官方规范与 SDK | 规范实现和 Host/Server 交互的基线,不等于高层应用框架 |
| MCP-UI | 5.1k | SDK 与 Host adapter | 将 MCP Apps 的 UI resource / renderer 接到多种 Host;适合研究兼容层而非把它误称为新 UI 描述标准 |
| mcp-use | 10.5k | 全栈 MCP / View 框架 | 从 Zod tool schema 推导到 React View 与 inspector,代表“tool 绑定 type-safe view”的开发体验 |
| Skybridge | 2.0k | React-first MCP Apps 框架 | 侧重 ChatGPT、Claude 等多 Host 的本地模拟、HMR、端到端类型与部署链路 |
| Prefab | 604 | Python declarative UI / MCP Apps 框架 | Python DSL 可人工编写也可由 Agent 生成,编译为 JSON protocol 后用内置 React renderer 展示;是非 TypeScript 路线的有用对照 |
6.3 不只看框架:真实应用与必要反例
| 对象 | Stars | 为什么保留 | 不能从它推导什么 |
|---|---|---|---|
| Morphic | 9.1k | 搜索回答将流式 JSON spec 投影为带来源图片、网格、标题等 inline UI;是“研究任务触发临时认知工作面”的可读案例 | 它是应用而非通用协议或 SDK,不能代表所有生成式 UI 的状态模型 |
| OpenGenerativeUI | 1.5k | Agent 生成 HTML/SVG/JS,在 sandbox iframe 中流式预览,是开放生成的能力上界和风险样本 | README 明确要求强模型;布局破损、交互缺失与不可复现性仍是该路线成本,不能与受控 schema 等量齐观 |
| pi-generative-ui | 1.2k | 用 show_widget 工具在解释/可视化请求时流式打开原生 HTML widget,清楚展示“何时 widget、何时文本”的 JIT 决策 | widget 对 Agent 缺少通用的点击/输入回传,因此更像解释型 JIT UI,不是可完成业务写入的通用工作流 |
| Excalidraw MCP App | 5.2k | 流式、可全屏编辑的 MCP App,是 tool-with-view 的强产品样本 | 它交付的是预建编辑器,不是模型即时生成 UI;恰好可作为 MCP Apps 与 Generative UI 的边界反例 |
| Flutter GenUI / AGenUI | 1.8k / 1.1k | 分别将 A2UI 接入 Flutter 与 iOS/Android/HarmonyOS native renderer,证明协议/renderer 方向并非 React-only | stars 尚低、协议快速演进,不应据此断言移动端互操作已经成熟 |
| OpenTiny GenUI SDK | 157 | Vue / Angular 的 schema 驱动生成 UI、动作和 MCP 接入实现 | 规模仍早期;保留为生态覆盖,不作为成熟度结论 |
开放生成的实用判断:OpenGenerativeUI 和 pi-generative-ui 都让模型输出 HTML/JS,并把最终体验隔离在 iframe 或原生 webview。它们适合教学模拟器、一次性解释图、数据探索和创意表达;但在可写业务、隐私字段、品牌一致性、无障碍或必须重放的流程中,应优先回到 component-as-tool 或 spec/DSL 路线。Excalidraw MCP App 的对照尤其重要:复杂体验可以是完整可编辑的 View,却并不需要由模型即时发明其界面。OpenGenerativeUI、pi-generative-ui、Excalidraw MCP App
此外,Open JSON UI仍可作为声明式 schema 的相邻研究对象:它在 CopilotKit 的生态图中与 A2UI 并列,但本报告未对其规范、实现成熟度或跨 Host 互操作性作独立验证,因此不把它纳入本文的实施事实。CopilotKit 生态映射
7. 落地不是“选一个库”,而是先定四个合同
无论采用 AI SDK、CopilotKit 或自建运行时,先明确以下合同,才能让 JIT UI 从炫技变成可维护的产品能力。
| 合同 | 必须先回答的问题 | 最小可验证物 |
|---|---|---|
| 状态合同 | 用户、任务、业务对象与 Agent run 的权威事实分别在哪里?界面是投影还是事实源? | 一个可重放的状态/事件样例与断线恢复测试 |
| 组件合同 | Agent 可调用的组件、字段、动作、无障碍语义和设计 token 是什么? | 类型/JSON Schema + 组件目录 + 无效 payload fallback |
| 行动合同 | 哪些动作只改变本地 UI,哪些进入真实业务?确认、幂等、撤销和审计怎样处理? | tool schema + 授权/确认路径 + 副作用测试 |
| 生命周期合同 | UI 何时出现、更新、过期、退出与降级?用户如何中断、改写或拒绝? | 典型任务时序 + cancel/retry + 固定 UI fallback |
建议从一个可观测、可撤销的单场景开始,例如“研究 Agent 完成检索后生成来源对比与确认结论卡”“语音任务进入需要选择时展示两到三个候选动作”“后台任务运行时显示状态与安全中断入口”。首先采用受控组件 + 类型化 tool/state 流;只有当长尾组合确实超过预建组件承载力时,再引入 A2UI 一类声明式层;当接入第三方工具的独立体验时,再评估 MCP Apps。这是架构分层顺序,不是对任何项目或产品的优劣排名。
8. 验收:UI 看起来生成了还不够
- 恰时性:出现是否有可解释的任务触发;低置信场景是否不打扰。
- 任务闭环:用户是否能在界面中理解证据、作出选择并看到真实结果回写。
- 受控性:Agent 不可调用目录外组件;无效 schema、过期状态或 Host 不支持 UI 时有文本/固定 UI fallback。
- 副作用安全:高风险操作需明确确认;调用幂等、可追踪、可撤销或清楚说明不可撤销。
- 一致性:同一任务的状态在聊天、工作面与业务系统之间不会互相矛盾;取消后旧流/旧 UI 不会复活。
- 可访问与跨端:键盘、读屏、窄屏、深浅主题、加载/失败状态不是最后补丁。
- 可学习性:用户可追溯“它为何出现、来自哪些事实、我如何回到熟悉界面”。
结论
生成式 UI 正从“模型替人写页面”扩展为 Agent 产品的交互层:让文本、工具、状态、审批和结果以合适的结构进入人的注意力。JIT UI 则给这件事加上最重要的约束——不是任何时刻都生成更多界面,而是在可信上下文中出现最小行动表面,并在结束后让它消失。
当前生态已经具备相邻而可组合的积木:AI SDK 解决应用 UI 流,CopilotKit/AG-UI 解决 Agent—用户运行时;Tambo 代表 component-as-tool,json-render/A2UI 代表 spec/patch,OpenUI 代表 DSL,MCP Apps 代表第三方预建 View。它们的共同点是把模型限制在可审计的交互合同中;真正尚未标准化、也最需要产品判断的部分,是用户模型、时机、权限、解释、跨端一致性与效果验证。
Source Manifest
Sources
- 用户指令,2026-08-30:本报告的范围、重点(Vercel AI SDK、CopilotKit、AG-UI)及初始资料清单。
- Vercel AI SDK Generative User Interfaces 与 AI SDK UI — AI SDK UI 的公开入口。
- CopilotKit Generative UI、CopilotKit Generative UI overview、AG-UI overview — 三种生成强度、CopilotKit 原语与 AG-UI 定位。
- Google Research: Generative UI — Google 的开放式生成 UI 研究/实验范围和证据边界。
- Andrew Sims: Just-in-Time Interfaces — JIT UI 的产品/设计论述(2025-09-20)。
- A2UI project — 声明式 JSON、组件目录、传输和 renderer 边界。
- A2UI v0.9 specification 与 A2UI Actions — surface、组件/数据模型更新、本地 read/write、action 与 data-model sync 的机制和安全边界。
- MCP Apps specification、MCP Apps overview、MCP-UI —
ui://资源、sandbox、JSON-RPC 与 Host 扩展边界。 - MCP Apps API Overview 与 MCP Apps Patterns — UI resource、app-only tool 与 Host/iframe 通信边界。
- AI SDK
UIMessage、stream protocol、tool usage、useChat— UI state、typed part、客户端确认与断线/取消语义。 - AG-UI core architecture 与 AG-UI events — run、tool lifecycle、snapshot 和 JSON Patch delta。
- OpenAI GPT-Live announcement — ChatGPT Voice 的视觉卡片这一公开产品事实。
- Vercel v0 Generative UI announcement、AI SDK RSC GenUI example — 2023 的术语使用及 RSC 路线状态。
- Tambo repository、Generative Components、Interactable Components、Component State — component-as-tool、按消息新建与按 ID 原位更新、thread state 回传/重建的公开机制。
- json-render repository、generation modes — catalog、schema、action、JSONL patch 与 inline chat 的实现路线。
- OpenUI repository、OpenUI Lang introduction、interactivity — DSL、library prompt、流式 parser、renderer、form state 与 action 回传;token 效率数据仅作为项目自述。
- MCP Apps
ext-apps、MCP-UI、mcp-use、Skybridge、Prefab — MCP Apps 规范 SDK、兼容 adapter、type-safe View 框架及 Python declarative UI 路线。 - Morphic、OpenGenerativeUI、pi-generative-ui、Excalidraw MCP App、Flutter GenUI、AGenUI、OpenTiny GenUI SDK — 真实应用、开放 HTML/widget、MCP View 对照与跨端 renderer/SDK 的公开仓库说明。
- Just-in-Time UI、Agent 认知界面 — 本 wiki 中关于情境界面、注意力与人机反馈的已有综合。
Produced artifacts
- 本报告:[生成式 UI 与 Just-in-Time UI](/reports/20260830_生成式 UI 与 Just-in-Time UI:从对话卡片到 Agent 运行时与开放协议/)。
- 关联综合页:生成式 UI、JIT UI 与 Agent 交互协议。
Key decisions
- 将 Generative UI(生成机制)与 JIT UI(时机与任务范式)明确拆分。
- 将 AG-UI、A2UI、MCP Apps 置于不同协议层,不叙述为互斥或一个单一标准。
- 以 CopilotKit 为 Agentic UX/运行时重点,以 Vercel AI SDK 为应用内 UI 流重点;Google 开放生成、MCP Apps 和 OpenAI Apps SDK 为相邻生态观察对象。
- 将“时机与退出”建模为 JIT UI 自己的状态机,不将其错误归入协议或单一框架能力。
- 将开源项目按“模型输出合同”而非仅按 star 或“是否有 AI 聊天界面”分类;明确排除纯组件库、普通聊天 UI 与只消费工具输出的前端壳。
- 以 Tambo、json-render、A2UI、OpenUI 作为主实现案例;将 MCP Apps 框架和真实产品示例置于工具嵌入/对照层,避免将预建工具 View 错写为模型生成 UI。
Verification evidence
- 2026-08-30:逐页读取上述公开文档/项目页;网页证据快照见本会话的 web 检索记录。
- 2026-08-30:已完成本文件存在、内部 wikilink、索引注册、日志记录与
git diff --check检查;三张初始 ImageGen 信息图均已逐张原始分辨率检查并记录 SHA-256;未运行代码或访问需要登录的产品环境。 - 2026-08-31:新增概念边界、生成强度与 AG-UI/A2UI 合同三张 ImageGen 信息图,均以原始 1672×941 分辨率逐张检查,并在 ImageGen Manifest 记录完整 prompt、SHA-256 与证据边界。
- 2026-08-31:将合并的 AG-UI/A2UI 图改为两张各自独立、中文标注的机制图;按 AG-UI/A2UI/MCP Apps 原始规范重写协议地图,补充事件类型、surface 生命周期、数据读写合同、资源预声明、Host sandbox 与业务副作用边界;两张新图均完成原始分辨率视觉检查。
- 2026-08-31:通过 GitHub API 读取主项目 star、fork、issue、最近推送、license 与最新 release 快照;逐页复核各项目 README / 官方文档。星标仅作生态关注信号,未执行任一项目的运行态 PoC。
Open questions / risks
- AG-UI、A2UI 和 MCP Apps 都在快速演进,互操作范围与 Host 支持必须在实际接入前重新验证。
- 本报告未对 CopilotKit、AI SDK、A2UI 或 MCP Apps 做运行态 PoC、性能/无障碍测试或安全渗透测试。
- Tambo、json-render、OpenUI、MCP Apps 框架和跨端 renderer 的兼容性、性能、升级路径及 Host 行为只来自公开说明与代码仓库快照;实施前必须以目标框架、Host、权限模型和业务副作用做 PoC。
- JIT UI 的“恰时出现”依赖用户模型与任务事实;这部分没有可移植的统一标准,也不应被模型生成能力替代。
- 生成图仅为机制解释,不验证 AI SDK、CopilotKit、A2UI、AG-UI 或 MCP Apps 的实际运行行为。