侧边栏壁纸
博主头像
HHShare 博主等级

行动起来,活在当下

  • 累计撰写 234 篇文章
  • 累计创建 36 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

ChatGPT 新 UI 不到 24 小时被拆开:三层协议,和一份能本地跑的复刻

晖晖分享
2026-10-09 / 0 评论 / 0 点赞 / 1 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我删除。

OpenAI 的 Intelligent UI 随 GPT-6 在 10 月 7 日推给全部用户,不到一天,外面就出了两份拆解。

一份来自 OpenUI 背后的 Thesys 工程团队,长文把实现拆到底,连服务端编译器都重写了一遍,输出和 OpenAI 的做到字节级一致。

另一份是个独立开发者的仓库,直接把复刻写成了能跑的东西,一条命令就能看。

两份拆解彼此独立,结论对得上:模型写的既不是 HTML,也不是 Markdown。

自制:模型写界面,一共三段接力

对话里那张界面,是三段接力画出来的

官方给的说法是,他们训练 GPT-6 判断什么时候该给交互式视觉而不是纯文字,以及怎么把它排版出来。

官方演示里的例子包括:一台七速自行车的剖视图,带可以点选的按钮;一副麻将牌,按花色排成可滑动的分组;还有退休金计算器、复古小游戏、AA 分账这类小工具,直接在回答里生成。

要做到这件事,一次回答要过三关。

第一关在模型这边。 它写的是一门叫 DIL 的语言:Markdown 负责正文,JSX 式的标签负责叫组件,JavaScript 负责状态和逻辑。拆解里举的例子是个报价滑块,模型用两行语句声明了座位数和单价,滑块一动,价格跟着变。

第二关在服务端。 模型是一个字一个字往外吐的,所以服务端每隔几百毫秒就把已经写出来的部分重新编译一遍:没写完的语句直接丢掉,元素有内容就自动闭合、没内容就丢弃,静态文字搬进一张常量表,状态各自带上 key 以便反复重编译时值不丢。产出是两样东西,一段 JavaScript 程序,加一份装着文本和数据的 JSON。属性还要过一遍校验,组件上不存在的属性会被删掉,并记成一条诊断。

第三关在客户端。 程序不在 ChatGPT 的页面里跑,而是丢进一个隐藏 iframe 里的 Web Worker,跑出来的不是画面,是一串「操作」。页面拿着这串操作,用 ChatGPT 自己的原生组件画出来。

组件不是随便挑的。拆解里数到,ChatGPT 客户端的组件登记表里约 70 个原生组件,实际见到的有 39 个,样式只能用设计 token 里的取值。模型能挑,但不能自己造标签、塞样式。

两道防线:编译放在服务端,代码关进沙箱

这套设计里最讲究的是「模型写的代码谁来跑」。

那个 Worker 的沙箱是硬做的:iframe 只开 allow-scripts,内容安全策略是 default-src 'none'。程序在求值之前,先做一轮清理,把网络、定时器、消息通道和动态求值从全局里摘掉,再把剩下的全局冻住。跑得没反应的程序会被隔离,Worker 重启。

程序跑完输出的操作有 CREATE、SET、PLACE 这几种,在传输时编码成二进制整数串,字符串单独放一张表。函数根本不出 Worker,滑动条的处理函数只传一个标识符过去。

交互也不惊动模型。 拖动滑块只改 Worker 里的状态,回给页面一串新的操作,不产生任何模型调用。

唯一能回到模型的是 issueNewTurn。按钮或表单提交时,界面上拼出一条新消息发给模型,存储方式和手打的消息一模一样。

原生组件做不了的东西,还有一条逃生舱:模型可以写一整块 HTML、CSS、JavaScript 的小应用塞进回答里(拆解里抓到的例子是一个能出声的鼓机),跑在单独域名的 iframe 里,和 ChatGPT 的设计系统隔开。

拆解里记下的毛病,比功能更值得看

两拨人的文章里都写了限制,这部分反而是全文最有信息量的地方。

刷新就忘。 你调过的值在页面重载后丢失,每次追问会生成一张新界面,而不是改现有的那一张。

模型看不见界面状态。 它只拿到 issueNewTurn 发出去的文字,被问到也说不出用户刚才把滑块拖到了几。

重发的代码占大头。 拆解里抓的一次回答有 6,341 个字符,流了 18.7 秒、84 次更新;编译结果每次重编译都要整体替换,重发的代码占了约 275KB 补丁的 83%。

自制:拆解里量出来的四个数字

操作数虚高。 一个价格组件里点一下,产生 158 条操作,其中只有 4 条真的改变了东西。

报错是静默的。 表达式抛异常就什么都不画,逻辑错也不报错——某个仪表盘里切换指标时,营收数字从 6,930 跳成了 256,410。

无效属性没人管。 编译器删掉了它们并记了诊断,模型在后续回答里继续犯同样的错。

图片搜索会跑偏。 模型写查询词但看不到结果,一次查「变速杆特写」,回来的是电动自行车的整车照。

自制:官方没提、拆解里记下的边角

Hacker News 上的公告帖拿了 747 分、四百多条评论,反应分成两派。一派认为把聊天框变成可操作界面是迟早的事,还在自己的项目里照着实现;另一派嫌它不如纯文本好用,担心导出和二次加工变麻烦,最尖锐的一句问得很直接:为什么不干脆流式输出 HTML。

Thesys 工程团队公开的拆解(openui.com)

想自己跑一个:两条路,其中一条不需要密钥

复刻已经有人做出来了,两条路都能走。

一条是照着拆解重写的可运行复刻。 仓库里给了流式 DSL 编译器、iframe 加 Worker 沙箱、宿主渲染器和状态回环,附 98 个测试。npm start 起来的是一个回放抓包的 mock agent,不需要任何密钥就能看到完整链路;想接真模型,走任意 OpenAI 兼容接口,本地的推理服务同样能接。

另一条是现成的开放替代品。 它用图表、表单、计算器和实时 3D 场景回答,MIT 协议,已经发了 npm 包,仓库里写明支持任何 OpenAI 兼容模型,云端或者自己机器上跑都行;演示视频里作答的模型是 Kimi K3。

复刻仓库:拆解 + 可运行的 replica

两边的实现思路对得上:模型只负责描述界面和状态,编译、校验、沙箱执行交给宿主。这也是这套设计真正能复用的部分——它回答的不是「怎么让模型画图」,是「模型写的代码凭什么敢让它跑」。

  • 可运行复刻(拆解 + replica,98 个测试,Node 22+):https://github.com/Disdjj/intelligent-ui-demo
  • 开放替代品 AnswerUI(MIT,npm 包 answerui-app):https://github.com/0xcro3dile/answerui
0

评论区