核心思路是大模型流式输出时嵌入结构化UI指令(如A2UI JSON),前端实时解析并安全渲染。主流方案为SSE事件区分或自定义分隔标记(如---UI-BLOCK---),需校验字段、白名单组件、JSON Pointer路径有效性,并预留占位符保障滚动连续性。

核心思路是让大模型在流式输出文本的同时,按约定格式插入结构化 UI 指令(如 A2UI JSON 片段),前端解析并动态渲染,而非等待全部响应完成。
明确混合流的数据格式规范
不能随意混入 JSON,需定义清晰的边界与标识。主流做法有两种:
-
基于 SSE 的事件类型区分:后端用
event: text推送普通文本,用event: ui推送 JSON 指令,前端通过eventSource.addEventListener('ui', ...)单独捕获并解析 -
自定义分隔标记:例如用
---UI-BLOCK---包裹 JSON 内容,前端用正则或字符串分割识别,再JSON.parse()解析。需确保标记不会出现在自然语言中,建议加校验字段(如"type": "a2ui-v0.9")
前端实时解析与安全渲染
收到 UI 指令后不直接执行,而是走可控流程:
- 先做基础校验:检查必填字段(
id、component)、组件名是否在白名单内(如Text、Button、Chart) - 使用 JSON Pointer 路径绑定数据时,确认路径指向的数据已在本地状态中存在,避免渲染异常
- 对动态生成的组件,统一挂载到预设容器(如
<div id="a2ui-mount"></div>),避免 DOM 泄漏或重复插入
后端生成时的协同要点
大模型不是自由发挥,需在 prompt 和推理阶段约束输出行为:
- 在 system prompt 中明确指令格式,例如:“当需要展示交互控件时,请在独立行输出以 ---UI-BLOCK--- 开头和结尾的合法 JSON,仅包含 A2UI Basic Components 支持的字段”
- 调用模型 API 时启用
response_format: { "type": "json_schema" }(如 OpenAI 2024 年后支持),强制模型输出结构化内容 - 服务端接收到流式 chunk 后,先做轻量级模式匹配(如检测
---UI-BLOCK---),再交由专用解析器处理,避免阻塞主响应流
处理 UI 与文本的交织逻辑
用户看到的是连贯界面,不是“一段文字 + 一个弹窗”的割裂感:
- 文本流中插入 UI 指令时,对应位置应预留占位符(如
[UI:chart-123]),等 UI 渲染完成再替换,保持滚动锚点稳定 - 若 UI 组件需用户操作(如点击按钮触发下一步),其回调应能向同一会话上下文提交新消息,形成闭环,而非跳转新页面
- 对含表单类组件(如
Select、DatePicker),默认值应从当前对话上下文自动注入,例如 “预算区间” 组件可绑定{"path":"/user/budgetRange"}


















