The UI
openInula 开源项目贡献赛 「开发基于 LLM 的创新应用,让 AI 赋能 openInula 框架」赛题参赛作品。
The UI 是一个基于 AI 的 UI 的工具,开发者指定数据结构后,The UI 就可以为最终用户动态生成收集数据与展示数据的 UI,是为「直接解决用户需求」而设计的 AI UI。
演示视频
与已有项目的对比
在参考赛题中,我们看到了「赛题二:openInula AI 代码生成器(基于图片生成代码)」。
在对应的 Issue 中,链接了之前比赛的一个获奖项目。从该项目的 system prompt 来看,作者应该也是参考了我之前实现的一个 AI UI 项目的思路(相同的 system prompt)。
这一思路比较流行的商业化产品包括 Vercel 的 v0.dev、wandb 的 OpenUI、Claude 内置的 Artifacts 功能等,实现大同小异,具体实现的详细解析在我的博客中进行了记录,不再这里展开。
但再一次准备开发一个 AI UI 项目时,我希望不只是在已有思路上应用更强的模型、优化 prompt、完善交互体验,而是希望从使用流程上真正进入「下一代」。
因此 The UI 的设计从面向的使用者就与之前项目有所不同。我们可以将 AI UI 工具的使用者分为三类:
- 设计师:有设计能力、无 UI 代码能力。
- 前端工程师:无设计能力,有 UI 代码能力。
- 非前端工程师:无设计能力,无 UI 代码能力,有非 UI 代码能力。
The UI 希望为第三类使用者服务,作为非前端工程师,可能为用户的业务需求开发了几个 API。此时不再需要设计师和前端工程师配合,使用 The UI 就可以直接在运行时为 API 生成 UI,收集用户输入,调用 API,将结果反馈至用户。
设计
The UI 界面示意图

整体交互逻辑如下:
- 开发者设置阶段
- 将 API 的 input schema 和 output schema 传入 The UI
- 将 callAPI 方法传入 The UI,通常是一个 fetch 的封装。The UI 会将收集的用户数据(预期与 input schema 一致)传入 callAPI,并预期 callAPI 返回与 output schema 一致的返回值。
- 用户使用阶段
- 加载开发者为特定 API 配置的 The UI
- 进入
generate-form
LLM 生成阶段。根据 input schema 和 The UI 中的 UI 生成最佳实践,为用户生成示意图中的绿色 Form
区域,用于收集用户填写的数据。
- 进入
generate-chatbox-prompt
LLM 生成阶段。根据 input schema、当前用户在表单中已经填入的值,分析还有哪些未填入的字段,并给出填写建议,输出在示意图中的灰色 Chatbox Prompt
区域,用于帮助用户更好的填写表单。
- 用户可以在
Form
区域通过生成的精细表单控件填入数据,也可以在黄色的 Chatbox
区域通过自然语言描述自己想要填写的内容。在 Chatbox
输入自然语言之后点击识别,通过 parse-user-input
LLM 生成阶段,会提取自然语言中与 input schema 相关的信息,填入表单中。自然语言输入和表单控件输入灵活结合,最大化用户输入效率。
- 用户完成输入之后点击提交,The UI 会将实际输入的数据与 input schema 进行 ajv JSON schema 校验,这一步程序输出的 JSON schema 错误较难阅读,因此通过
format-error
LLM 生成阶段,将程序化的错误信息优化为用户可读的自然语言,反馈在示意图中的红色 error message
区域。
- 当用户输入通过所有校验之后,执行 callAPI,通过
generate-display
LLM 生成阶段,在示意图中的蓝色 Display
区域生成一个符合 output schema 和 The UI 中的 UI 生成最佳实践的展示 UI,并将 API response 输入其中,给用户进行展示。
src 文件目录结构
- App.tsx 和 main.tsx 是开发环境的应用入口文件。
- TheUI.tsx 是 The UI 的核心入口组件。
- components 目录中包含 business 和 ui 两个分类。ui 是 The UI 生成会使用到的组件,源于
@shadcn/ui
,business 是 TheUI 业务逻辑相关的组件。
- lib
- machine.ts。TheUI 核心状态机逻辑。
- llm.ts。封装了各个 LLM 生成阶段的调用方法。
- ast.ts。对 LLM 生成结果中的一些常见错误进行纠正,提高生成成功率。
- cache.ts。对 LLM 生成结果进行缓存,重复的请求使用缓存结果。
- prompts 目录中包含了上述每个 LLM 生成阶段的 prompt。每个阶段分为 system 和 user 两类 prompt,文件名中加以区分。
状态机
+-------------------+
| init |
+--------+----------+
|
v
+------------------------+
| generateInputForm |
+--------+----------------+
|
v
+------------------------+
| waitingForInput |
| |
| +-------------------+ |
| | loadingPrompt | |
| +---------+---------+ |
| | |
| v |
| +-------------------+ |
| | idle | |
| +---------+---------+ |
| | |
| USER_INPUT | SUBMIT_FORM|
| v |
+------------+------------+
|
v
+------------------------+
| parsingUserInput |
+--------+----------------+
|
v
+------------------------+
| validatingFormData |
+--------+----------------+
|
v
+------------------------+
| callingAPI |
+--------+----------------+
|
v
+------------------------+
| handlingAPIResponse |
+--------+----------------+
|
v
+------------------------+
| generateOutputDisplay |
+--------+----------------+
|
v
+------------------------+
| displayingResult (final)|
+--------------------------+
+------------------------+
| errorHandling |
+------------------------+
| RETRY |
+------------------------+
OpenInula 优势
由于 OpenInula 与 React 兼容,所以 React 生态中的绝大部分方案都可以直接使用。在 The UI 中,仅对 React.useId
API 进行了额外处理,其余均由 OpenInula 直接兼容,在 Vite 配置中将 React 动态替换为 OpenInula。
运行时动态渲染 React JSX string
在 RenderGeneratedComponent.tsx 中实现,通过 babel 转移后执行代码。此处也可以实现为一个后端 API,在服务端完成相关工作。
本地运行
首先创建 .env
文件,填入以下内容:
VITE_LLM_API_KEY=$API_KEY
VITE_LLM_MODEL=gpt-4o-mini
$API_KEY 为 OpenAI 的 API key。
之后运行 yarn
安装依赖。
最终运行 yarn dev
启动本地开发环境。
迭代 Roadmap
- 支持 API 编排,连续调用多个 API,中途由用户输入辅助信息。
- 从 JSON schema 中读取更多信息,优化生成结果。
- Chatbox 区域支持上下文。
- 优化各阶段 prompt。
- cache as a service & render as a service。
The UI
The UI 是一个基于 AI 的 UI 的工具,开发者指定数据结构后,The UI 就可以为最终用户动态生成收集数据与展示数据的 UI,是为「直接解决用户需求」而设计的 AI UI。
演示视频
与已有项目的对比
在参考赛题中,我们看到了「赛题二:openInula AI 代码生成器(基于图片生成代码)」。
在对应的 Issue 中,链接了之前比赛的一个获奖项目。从该项目的 system prompt 来看,作者应该也是参考了我之前实现的一个 AI UI 项目的思路(相同的 system prompt)。
这一思路比较流行的商业化产品包括 Vercel 的 v0.dev、wandb 的 OpenUI、Claude 内置的 Artifacts 功能等,实现大同小异,具体实现的详细解析在我的博客中进行了记录,不再这里展开。
但再一次准备开发一个 AI UI 项目时,我希望不只是在已有思路上应用更强的模型、优化 prompt、完善交互体验,而是希望从使用流程上真正进入「下一代」。
因此 The UI 的设计从面向的使用者就与之前项目有所不同。我们可以将 AI UI 工具的使用者分为三类:
The UI 希望为第三类使用者服务,作为非前端工程师,可能为用户的业务需求开发了几个 API。此时不再需要设计师和前端工程师配合,使用 The UI 就可以直接在运行时为 API 生成 UI,收集用户输入,调用 API,将结果反馈至用户。
设计
The UI 界面示意图
整体交互逻辑如下:
generate-form
LLM 生成阶段。根据 input schema 和 The UI 中的 UI 生成最佳实践,为用户生成示意图中的绿色Form
区域,用于收集用户填写的数据。generate-chatbox-prompt
LLM 生成阶段。根据 input schema、当前用户在表单中已经填入的值,分析还有哪些未填入的字段,并给出填写建议,输出在示意图中的灰色Chatbox Prompt
区域,用于帮助用户更好的填写表单。Form
区域通过生成的精细表单控件填入数据,也可以在黄色的Chatbox
区域通过自然语言描述自己想要填写的内容。在Chatbox
输入自然语言之后点击识别,通过parse-user-input
LLM 生成阶段,会提取自然语言中与 input schema 相关的信息,填入表单中。自然语言输入和表单控件输入灵活结合,最大化用户输入效率。format-error
LLM 生成阶段,将程序化的错误信息优化为用户可读的自然语言,反馈在示意图中的红色error message
区域。generate-display
LLM 生成阶段,在示意图中的蓝色Display
区域生成一个符合 output schema 和 The UI 中的 UI 生成最佳实践的展示 UI,并将 API response 输入其中,给用户进行展示。src 文件目录结构
@shadcn/ui
,business 是 TheUI 业务逻辑相关的组件。状态机
OpenInula 优势
由于 OpenInula 与 React 兼容,所以 React 生态中的绝大部分方案都可以直接使用。在 The UI 中,仅对
React.useId
API 进行了额外处理,其余均由 OpenInula 直接兼容,在 Vite 配置中将 React 动态替换为 OpenInula。运行时动态渲染 React JSX string
在 RenderGeneratedComponent.tsx 中实现,通过 babel 转移后执行代码。此处也可以实现为一个后端 API,在服务端完成相关工作。
本地运行
首先创建
.env
文件,填入以下内容:$API_KEY 为 OpenAI 的 API key。
之后运行
yarn
安装依赖。最终运行
yarn dev
启动本地开发环境。迭代 Roadmap