生成式UI & A2UI
- 进一步搭建Server端
- [SSE 传输协议/网络协议](#SSE 传输协议/网络协议)
- Agent
进一步搭建Server端
- 把 测试接口,改为了 UI内发送键,并且搭建了基础的agent界面
- 把mock数据通过实际的接口返回(核心测试接口以及AGUI传输层是否正确)
- 将之前用于测试端上的stream数据,通过在服务




现在效果是无论输入什么,接口随机选择组件做流式模拟渲染

通过 AGUI 协议,第一个调用的时候,会将角色的内容放到里面去,role,message等

里面带的是AGUI的JSONL的chunk,拿到chunk,通过端上的缓冲区,将其缓冲下来,等拿到一个完整的jsonl的时候,就将其渲染到界面中去

buffer?怎么实现来的? Mcp / agent 基础 ,stream 读 chunk 拼接对应的LLM返回的数据块
核心是buffer需要知道什么时候返回的是一个完整的A2UI的部件
surfaceUpdate + 完整的A2UI协议组件 -> 送到parser解析-> treebuilder和renderer渲染出来
怎么判断完整的A2UI协议组件 ?
通过补全json 以及 try{JSON.parser(bufferJSONL); buffer中的协议,拼为jsonL发送给parser解析;buffer 清空} catch (err) {}
SSE 传输协议/网络协议
SSE 传输协议/网络协议,AGUI 应用协议
用户->server 发送的内容以及频率远远小于server到用户
除了SSE以外,常见的长链接和双工通道:
-
streamable http:本质上是SSE协议的升级,整体对于 nginx,运行环境,搭建成本都会高一些
streamable http和SSE需要按照场景去选用
-
P2P 双工通道 webSocket
-
视频流(流媒体服务) webRTC / 私有RTS / HLS
服务向客户端持续的发送消息使用SSE,比较契合agent这种形态的
SSE缺点:SSE有链接限制,但是同一时间基本只有一个agent 和用户端在通信,SSE需要 web server 支持
Agent
选型
公司内部,交易接口MCP,用户接口MCP => 选用支持mcp的agent环境,opencode SDK、iflow SDK、 cursorCLI
opencode SDK <=> 适合搭建自己的服务端运行的agent,但是成本和集成度来说都是比较原始的;类比:EMCAS,传统IDE的vim,开源的
iflow sdk,cursorCLI <=> 类比:IDE的vsCode,商业的
此时,a2ui-playground的对话界面不是agent用户端
Agent是:用户端 -> LLM(通过openAI)
而这里,a2ui-playground的对话界面实际上是,运行在你的a2ui-server上的openAI实例
三层架构:web端是a2ui-server的用户端,a2ui-server是web的服务端
a2ui-server和大模型供应商之间,a2ui-server是大模型的用户端
最终,还是使用 openAI 做最基础的服务agent
模型选型与接入测试
LLM model
- 多模态支持
- system prompt
- 定义agent的角色以及主要能力
- 注入定义好的 a2ui协议以及 catelog
- 可能需要一些调用接口获取数据/上下文的能力
provider: 百炼 + coding plan (我用的 minimax + token plan)
-
建立模型基础链接(通过chat接口测试)
告诉AI IDE 你的模型供应商(baseURL),以及apiKey,使用的模型
playground里面增加一个对话test
目的:测试基础模型链接没有问题
-
搭建a2ui-agent 通过(agent接口)
Const standardComponentProtocal = Readfile(standard组件的协议定义)



调错模型了,在这里复制模型名



对话将返回的模型也输出了


AI agent 支持选择模型
在百炼中可用的模型,将其模型复制下来搞一个列表,在每次请求的时候传入,当前用户选用的模型,就可以使用模型切换,使用不同模型
并且模型对话的响应也是流式输出的:

注入system prompt

在之前已经生成了三个关于A2UI协议的prompt,现在还缺少告诉我们现在A2UI agent 它是一个什么agent
将刚扩展的A2UI协议和现有支持的标准协议,以及其他东西给到system prompt




我们的agent是没有 tools 能力的,因此读不了对应的文件,现在能做的事情就是:通过工程的方法,readFile(standard组件的协议定义) 去拼接字符串
const standardComponentProtocal = readfile(standard组件的协议定义)
`当前支持的组件协议为${standardComponentProtocal)`





整体就是模板字符串拼接的一个逻辑






现在的情况是:模型返回了,但是渲染层报错,需要把模型返回替换到mock数据里面,然后通过之前保留的下拉列表来本地复现问题,然后再通过A2UI sdk里的问题输出的日志尝试调整出问题

mock下新增文件,将上述json内容复制下来:



现在列表切换后,本地模拟流渲染的内容都一样呢


现在发现,经过AI调整的协议,渲染是没有问题的,那就是agent返回的协议格式是有问题的,导致没有正确渲染






大概率问题是生成prompt的时候没有将原始的协议带进入,自然AI也不会按照符合要求格式的去生成和返回
引入了文件

prompt 其实就是 few shot,其实协议本身就是 few shot,在业务场景中让协议更稳定的生出a2ui json,可以将调好的a2ui json注入到模板中,基于已有的模板让AI生成,会稳定并且速度也会提升不少

确认AI生成的json是否符合A2UI规范

当前可以正常渲染了

beginRendering的root有问题,但是这里其实没用

现在的问题是按钮里没有渲染出来文案

问题可能:1. 解析的问题 2. 渲染的问题
按钮里 debugger 一下


这里text是传了个空进来



这里是大模型出现了幻觉,将root定位到 components 了,所以就自然而然的只能渲染出确认出来了



通过打断点看prompt





prompt写的很烂

A2UI agent 的核心 prompt
- 职责角色声明
- 需要说明A2UI的client-server协议是什么,支持的组件catelog是什么,以及私有扩展的协议是什么
现在还是有问题


这个文件之前是给到cursor用的,cursor是有我们的上下文的,因此内容写的都是我们本地的一些文件,但是给到LLM(百炼)模型是有大量的干扰的(包括supported-a2ui-standard-components-vo_8.md这个文件)





现在模型对话过程中的状态又没有了,需要加上

推荐的prompt生成方式:
- 通过cursor(AI IDE),结合当前renderer已经实现的组件,以及a2ui standard catelog生成目前支持的组件的catelog
- 通过其他AI agent(开一个空的ai ide工程,核心目的防止代码中已实现部分对AI IDE的上下文干扰),生成a2ui agent的基础prompt
- 通过Al IDE,实现对standard catelog 以及 client-server的a2ui的协议拼接



不让它生成 jsonl 而是完整的 json
还是有问题


还是解决不了 root 问题








模型返回的json:


这里看出模型生成是没有问题的,在于实现时候的问题


印证了cursor在做原子组件json的时候,没有按照协议生成,而是按照他自己组件实现的标准执行
json里的root是没问题的

但是playground的view json显示的就是有问题的


可以在谷歌中实验(失败了,谷歌输出的json不是想要的)


这里解决了
现在的问题是加入购物车文字没有渲染出来


将store内容复制下来给ai









整体和agent联调:
- 让Agent生成真实的U卡片(例如天气预报、购物、员工列表、todolist),测试真实的生成效果
- 联调的时候,如果发现问题,可以把Agent返回的协议,放在mock数据里面,通过在playground的回放能力,尝试获取错误信息
- 把原始协议以及错误信息,喂给AI IDE,尝试解决问题
- 重复2-3,直到整体表现稳定