关于前端:低代码与大语言模型的探索实践

64次阅读

共计 11388 个字符,预计需要花费 29 分钟才能阅读完成。

低代码系列文章:

  • 可视化拖拽组件库一些技术要点原理剖析
  • 可视化拖拽组件库一些技术要点原理剖析(二)
  • 可视化拖拽组件库一些技术要点原理剖析(三)
  • 可视化拖拽组件库一些技术要点原理剖析(四)
  • 低代码与大语言模型的摸索实际

低代码相干仓库:

  • 一个低代码(可视化拖拽)教学我的项目
  • 低代码与大语言模型的联合实际 demo

前言

ChatGPT,作为一个先进的自然语言解决工具,能够了解和生成人类语言,提供智能编程倡议,自动化代码生成,以及提供交互式编程教学。这些性能为开发者提供了前所未有的便当,大大减少了编程的工夫和复杂性。

低代码平台则容许用户通过图形界面来构建利用,缩小了对业余编程常识的依赖,在 特定业务场景下 可能晋升开发效率。用户能够通过拖放组件和模型驱动的逻辑来疾速地创立应用程序,而无需编写大量代码。

如果能够把 ChatGPT 和低代码平台联合起来应用,那么用户就能够通过对话来疾速地创立应用程序,从而简化了搭建应用程序的过程,并且晋升了用户体验。

可行性

低代码平台通常应用 JSON 格局的 DSL(畛域特定语言 domain-specific language 指的是专一于某个应用程序畛域的计算机语言)来形容一个页面。用户拖拽组件、编辑页面,实际上是在和页面的 JSON 在进行交互。低代码平台通过渲染引擎把 JSON 数据渲染成为页面,至于页面要渲染成为 Vue、React 或者是纯正的 HTML 页面,就得看各个低代码平台本人的实现了。一个应用程序个别会蕴含多个页面,而后通过路由来决定各个页面的跳转逻辑。

因而,咱们能够向 ChatGPT 提出生成页面的需要,ChatGPT 再依据咱们提供的 prompt 来生成一份合乎低代码平台数据格式的 JSON。实践上,这是可行的,当初来看一下怎么实现这个性能。

应用 ChatGPT 进行页面生成

首先,咱们须要注册一个 openai 或者 azure 账号,在下面开明 api 服务(如何申请账号请自行搜寻,网上有很多教程)。而后就能够应用这个 api 来和 ChatGPT 进行交互了。

另外,咱们还须要一个低代码平台,因为生成的 JSON 须要一个低代码平台来验证生成 JSON 是否实在可用。刚好前几年我写了一个低代码平台教学我的项目,当初刚好能够用上。

低代码平台组件 DSL

首先,咱们要晓得每一个组件的 DSL 形容,上面的代码是一个文本组件的 DSL 形容:

{"animations": [], // 动画属性
    "events": {}, // 事件
    "groupStyle": {}, // 组合组件款式
    "isLock": false, // 是否锁定
    "collapseName": "style",
    "linkage": { // 联动组件
        "duration": 0,
        "data": [
            {
                "id": "","label":"",
                "event": "","style": [
                    {"key": "","value":""}
                ]
            }
        ]
    },
    "component": "VText", // 组件类型
    "label": "文字", // 组件名称
    "propValue": "双击编辑文字", // 组件值
    "icon": "wenben", // 组件图标
    "request": { // 组件 API 申请
        "method": "GET",
        "data": [],
        "url": "","series": false,"time": 1000,"paramType":"",
        "requestCount": 0
    },
    "style": { // 组件款式
        "rotate": 0,
        "opacity": 1,
        "width": 200,
        "height": 28,
        "fontSize": "","fontWeight": 400,"lineHeight":"",
        "letterSpacing": 0,
        "textAlign": "","color":"",
        "top": 157,
        "left": 272
    },
    "id": "07l4byRWvsphAPo2uatxy" // 组件惟一 id
}

每一个组件就是一个 JSON 数据,那么整个页面就是一个 JSON 数组,外面蕴含了多个组件:

// 页面 JSON
[{ ...}, // 组件 1
 {...}, // 组件 2
 {...}, // 组件 3
]

prompt 编写

要让 ChatGPT 来生成页面,那么咱们要让 ChatGPT 晓得页面、组件的数据结构,并且要给它提供示例。而后再向它提出页面生成的需要,从而为咱们生成符合要求的页面。这个 prompt 的格局如下:

我有一个低代码平台我的项目,它能够依据符合规范的 JSON 数据生成页面,这个 JSON 数据是一个数组,外面的每一项都是一个 JSON 对象,每个 JSON 对象都对应着一个组件。上面用 ### 包含起来的代码就是所有的组件列表。###
--- 所有组件的 JSON 数据结构 ---
###

如果一个页面蕴含了一个文本和按钮组件,那么这个页面的 JSON 代码如下:###
--- 示例页面 JSON 数据结构 ---
###

你作为一个技术专家,当初须要依照下面的规定来为我生成页面,并且生成的页面中每一个组件的属性都不能疏忽,也不须要解释,只须要返回 JSON 数据即可。要留神的是,有些数值的单位是没有 px 的。当初我须要生成一个海报页面,次要用于宣传编程有什么用。

因为篇幅无限,下面只展现了这个 prompt 的纲要,JSON 数据都省略了。残缺的 prompt 请在 lowcode-llm-demo 上查看。

prompt 筹备好了,当初咱们须要调用 ChatGPT 的 api 来生成页面,示例代码如下:

import {AzureChatOpenAI} from '@langchain/azure-openai'
import 'dotenv/config'
import {readFileSync} from 'fs'
import {resolve, dirname} from 'path'
import {fileURLToPath} from 'url'

const model = new AzureChatOpenAI({
    modelName: process.env.AZURE_OPENAI_API_MODEL_NAME,
    azureOpenAIEndpoint: process.env.AZURE_OPENAI_API_ENDPOINT,
    azureOpenAIApiKey: process.env.AZURE_OPENAI_API_KEY,
    azureOpenAIEmbeddingsApiDeploymentName: process.env.AZURE_OPENAI_API_EMBEDDING_DEPLOYMENT_NAME,
    azureOpenAIApiVersion: process.env.AZURE_OPENAI_API_VERSION,
})

const dirName = dirname(fileURLToPath(import.meta.url))
const prompt = readFileSync(resolve(dirName, '../prompts/prompt-compress.md'), 'utf-8')
const response = await model.invoke(prompt)
console.log(JSON.stringify(response)) // 返回 ChatGPT 的后果

下面的代码执行后就能失去 ChatGPT 返回来的页面 JSON 数据。不过这个数据不能间接应用,还须要额定写点代码解决一下能力应用。上面的代码就是解决后的页面 JSON 数据结构:

[
    {"animations": [],
        "events": {},
        "groupStyle": {},
        "isLock": false,
        "collapseName": "style",
        "linkage": {
            "duration": 0,
            "data": [
                {
                    "id": "","label":"",
                    "event": "","style": [
                        {"key": "","value":""}
                    ]
                }
            ]
        },
        "component": "Picture",
        "label": "背景图片",
        "propValue": {"url": "img/programming_poster_bg.jpg" // 替换为本人的图片},
        "style": {
            "rotate": 0,
            "opacity": 1,
            "width": 500,
            "height": 700,
            "top": 0,
            "left": 0,
            "position": "absolute",
            "zIndex": 0
        },
        "id": "backgroundImage"
    },
    {"animations": [],
        "events": {},
        "groupStyle": {},
        "isLock": false,
        "collapseName": "style",
        "linkage": {
            "duration": 0,
            "data": [
                {
                    "id": "","label":"",
                    "event": "","style": [
                        {"key": "","value":""}
                    ]
                }
            ]
        },
        "component": "VText",
        "label": "题目文字",
        "propValue": "编程扭转世界",
        "icon": "wenben",
        "style": {
            "rotate": 0,
            "opacity": 1,
            "width": 450,
            "height": 100,
            "fontSize": "32px",
            "fontWeight": 700,
            "textAlign": "center",
            "color": "rgba(16, 15, 15, 1)",
            "top": 50,
            "left": 25,
            "position": "absolute",
            "zIndex": 10
        },
        "id": "titleText"
    },
    {"animations": [],
        "events": {},
        "groupStyle": {},
        "isLock": false,
        "collapseName": "style",
        "linkage": {
            "duration": 0,
            "data": [
                {
                    "id": "","label":"",
                    "event": "","style": [
                        {"key": "","value":""}
                    ]
                }
            ]
        },
        "component": "VText",
        "label": "形容文字",
        "propValue": "通过编程,咱们能够创立软件来解决问题、剖析数据,甚至改善人们的生存。",
        "icon": "wenben",
        "style": {
            "rotate": 0,
            "opacity": 1,
            "width": 400,
            "height": 200,
            "fontSize": "18px",
            "fontWeight": 400,
            "lineHeight": "1.5",
            "textAlign": "center",
            "color": "rgba(33, 31, 31, 1)",
            "top": 180,
            "left": 50,
            "position": "absolute",
            "zIndex": 10
        },
        "id": "descriptionText"
    },
    {"animations": [],
        "events": {},
        "groupStyle": {},
        "isLock": false,
        "collapseName": "style",
        "linkage": {
            "duration": 0,
            "data": [
                {
                    "id": "","label":"",
                    "event": "","style": [
                        {"key": "","value":""}
                    ]
                }
            ]
        },
        "component": "VButton",
        "label": "口头按钮",
        "propValue": "开始学习编程",
        "icon": "button",
        "style": {
            "rotate": 0,
            "opacity": 1,
            "width": 200,
            "height": 50,
            "borderRadius": "25px",
            "fontSize": "20px",
            "fontWeight": 500,
            "textAlign": "center",
            "color": "#FFF",
            "backgroundColor": "#f44336",
            "top": 420,
            "left": 150,
            "position": "absolute",
            "zIndex": 10
        },
        "id": "actionButton"
    }
]

将 JSON 导入到低代码平台后,生成的页面如下所示:

能够看到 ChatGPT 输入了一个半成品页面,背景图片的地址须要咱们手动批改。ChatGPT 每次输入的页面都是随机的,上面是生成的另外一个页面。

节省成本

ChatGPT 很好用,然而有一个毛病,太贵了。所以咱们须要想一些方法来降低成本,上面是几个比拟可行的方法:

  1. 精简 prompt
  2. 微调(Fine-tuning)
  3. 应用模板、分类标签

    精简 prompt

    ChatGPT 的 api 是通过 token 来免费的,所以最简略间接的办法就是优化 prompt。上面是一个未优化的 prompt 示例:

我须要一个用户管理系统的页面。在页面顶部,我须要一个增加用户的按钮。上面是一个表格,列出了所有用户的姓名、邮箱和注册日期。点击任何一个用户,将会关上一个蕴含残缺用户信息的新页面,其中蕴含姓名、邮箱、注册日期、最初登录工夫和用户角色。还须要有一个搜寻栏,能够通过姓名或邮箱搜寻用户。请基于这些要求为我的低代码平台生成代码。

当初将这个 prompt 优化一下:

生成页面:用户治理
组件:增加按钮,用户表格(姓名,邮箱,注册日期),用户详情(姓名,邮箱,注册日期,最初登录,角色),搜寻栏(姓名,邮箱)

在这个例子中,咱们简化了形容页面的需要,从而缩小了 token 的数量。

微调(Fine-tuning)

在文章的结尾,我展现了一个生成页面的 prompt 示例,并且能够看到这个 prompt 耗费的 token 数量十分大,因为它须要通知 ChatGPT 每个组件的 JSON 数据结构是什么,以及一个残缺的示例页面 JSON 数据结构是什么样的,这些示例都须要耗费大量的 token。

为了精简 prompt,同时又能达到未精简前的成果,这能够应用微调来实现。

微调是一种机器学习技术,它能够让你自定义机器学习模型以适应特定的工作或数据集。通过微调,您能够在一个预训练的模型(如 ChatGPT)的根底上进一步训练它,使其更好地了解和执行特定的工作。这样,您能够创立一个专门为您的低代码平台生成页面的模型。

咱们能够给 ChatGPT 提供大量的数据集进行微调训练,比方大量的低代码页面示例。这样你再让它生成一个“用于宣传编程的海报页面”,就不须要提供每个组件的数据结构了,因为这些数据 ChatGPT 曾经通过微调学会了。

当初来看一下用于微调训练的数据集是什么样的:

{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}

下面是数据集的格局,当初我要提供大量的低代码平台数据集:

{"prompt":"生成一个带有矩形组件的页面","completion": "[{\"animations\":[],\"events\":{},\"groupStyle\":{},\"isLock\":false,\"collapseName\":\"style\",\"linkage\":{\"duration\":0,\"data\":[{\"id\":\"\",\"label\":\"\",\"event\":\"\",\"style\":[{\"key\":\"\",\"value\":\"\"}]}]},\"component\":\"RectShape\",\"label\":\" 矩形 \",\"propValue\":\" 矩形 \",\"icon\":\"juxing\",\"style\":{\"rotate\":0,\"opacity\":1,\"width\":200,\"height\":200,\"fontSize\":\"\",\"fontWeight\":400,\"lineHeight\":\"\",\"letterSpacing\":0,\"textAlign\":\"center\",\"color\":\"\",\"borderColor\":\"#000\",\"borderWidth\":1,\"backgroundColor\":\"\",\"borderStyle\":\"solid\",\"borderRadius\":\"\",\"verticalAlign\":\"middle\",\"top\":143,\"left\":379},\"id\":\"j3i41NnZw8Zcxu3BfbXwv\"}]"}
{"prompt":"生成一个带有文本组件的页面","completion": "[{\"animations\":[],\"events\":{},\"groupStyle\":{},\"isLock\":false,\"collapseName\":\"style\",\"linkage\":{\"duration\":0,\"data\":[{\"id\":\"\",\"label\":\"\",\"event\":\"\",\"style\":[{\"key\":\"\",\"value\":\"\"}]}]},\"component\":\"VText\",\"label\":\" 文字 \",\"propValue\":\" 双击编辑文字 \",\"icon\":\"wenben\",\"request\":{\"method\":\"GET\",\"data\":[],\"url\":\"\",\"series\":false,\"time\":1000,\"paramType\":\"\",\"requestCount\":0},\"style\":{\"rotate\":0,\"opacity\":1,\"width\":200,\"height\":28,\"fontSize\":\"\",\"fontWeight\":400,\"lineHeight\":\"\",\"letterSpacing\":0,\"textAlign\":\"\",\"color\":\"\",\"top\":145.3333282470703,\"left\":195},\"id\":\"WKqULBX4bKcmREgPJef3D\"}]"}
{"prompt":"生成一个带有按钮组件的页面","completion": "[{\"animations\":[],\"events\":{},\"groupStyle\":{},\"isLock\":false,\"collapseName\":\"style\",\"linkage\":{\"duration\":0,\"data\":[{\"id\":\"\",\"label\":\"\",\"event\":\"\",\"style\":[{\"key\":\"\",\"value\":\"\"}]}]},\"component\":\"VButton\",\"label\":\" 按钮 \",\"propValue\":\" 按钮 \",\"icon\":\"button\",\"style\":{\"rotate\":0,\"opacity\":1,\"width\":100,\"height\":34,\"borderWidth\":1,\"borderColor\":\"\",\"borderRadius\":\"\",\"fontSize\":\"\",\"fontWeight\":400,\"lineHeight\":\"\",\"letterSpacing\":0,\"textAlign\":\"\",\"color\":\"\",\"backgroundColor\":\"\",\"top\":126.33332824707031,\"left\":224},\"id\":\"6wgvR1wyRyNqIl37qs1iS\"}]"}
...

通过微调训练后,ChatGPT 就变成了一个专门的低代码模型,它会更好地了解低代码的需要。前面咱们再让 ChatGPT 生成页面就不须要大量的 prompt 了,能够间接让它生成一个“用于宣传编程的海报页面”。记住,微调是一个须要精心设计和执行的过程,须要咱们不停的校对,能力达到最好的成果

应用模板、分类标签

一个胜利的低代码平台,肯定会内置大量的模板,包含但不限于页面模板、利用模板等等。其实在大多数时候,用户提出生成页面的需要时,咱们能够提取关键词,依据关键词找到合乎用户需要的模板,再展现给用户抉择。如果没有找到符合要求的模板,才应用 ChatGPT 来生成页面,这样不仅能节省成本,还防止了 ChatGPT 随机生成页面并且有可能生成谬误页面的弊病。

当初咱们来看看怎么做。首先,除了给模板命名,还须要给模板归类,比方打上几个相似于“医疗”、“后盾管理系统”之类的标签。

当用户提出一个”生成用于宣传编程的页面“需要时,咱们能够应用自然语言解决(NLP)库,如 natural 或者 compromise 进行关键词提取,而后再通过 Elasticsearch 来进行搜寻,最初把搜寻到的模板返回给用户。上面是代码示例:

const {Client} = require('@elastic/elasticsearch');
const {NlpManager} = require('node-nlp');

// 初始化 Elasticsearch 客户端
const client = new Client({node: 'http://localhost:9200'});

// 初始化 NLP 管理器
const nlpManager = new NlpManager({languages: ['en'], nlu: {useNoneFeature: false} });

// 假如咱们有一些模板数据
const templates = [{ name: 'Medical Service Promotion Page', tags: ['medical', 'promotion'] },
    {name: 'Programming Education Poster', tags: ['education', 'programming', 'poster'] },
    {name: 'Backend Management System Dashboard', tags: ['backend', 'management', 'system'] }
];

// 创立 Elasticsearch 索引
async function createIndex(indexName) {// 省略创立索引代码}

// 索引模板数据到 Elasticsearch
async function indexTemplates(indexName, templates) {// 省略索引数据代码}

// 提取关键词
async function extractKeywords(text) {const result = await nlpManager.extractEntities(text);
    const keywords = result.entities.map(entity => entity.option || entity.utteranceText);
    return keywords;
}

// 应用 Elasticsearch 进行搜寻
async function searchTemplates(indexName, keywords) {const { body} = await client.search({
        index: indexName,
        body: {
            query: {
                bool: {
                    should: [{ match: { name: { query: keywords.join(' '), boost: 2 } } },
                        {terms: { tags: keywords} }
                    ]
                }
            }
        }
    });

    return body.hits.hits.map(hit => hit._source);
}

// 主程序
async function main() {
    const indexName = 'templates';

    // 创立索引并索引数据
    await createIndex(indexName);
    await indexTemplates(indexName, templates);

    // 用户输出
    const userInput = "I want to create a poster page for programming promotion";

    // 提取关键词
    const keywords = await extractKeywords(userInput);

    // 执行搜寻
    const results = await searchTemplates(indexName, keywords);

    // 输入后果
    console.log(results);
}

main().catch(console.error);

应用开源大语言模型 ChatGLM-6B 进行页面生成

对于无奈应用外网或估算无限的我的项目,咱们能够思考应用开源的大语言模型。本文选了 ChatGLM-6B 开源模型来做演示。

装置

ChatGLM-6B 本地部署的教程网上有很多,因为我的电脑是 Windows,并且没有 N 卡,所以我参考了这篇文章手把手教你本地部署清华大学 KEG 的 ChatGLM-6B 模型来部署 ChatGLM-6B。

这篇文章讲得很粗疏,依照流程走下来只呈现了两个小问题,解决后就跑通了。这里也记录一下这两个问题及相应的解决办法。

TDM-GCC 编译谬误

依照文章中的要求装置了 TDM-GCC 后发现编译 quantization_kernels_parallel.c 文件谬误,卸载 TDM-GCC 后换了 MinGW-w64 就好了,编译顺利通过。

执行 python 脚本偶然没反馈

这个问题排查了很久,通过一直的调试和重启,最初发现是系统资源有余(我的电脑 CPU 是 6800H,32G 内存,没有显卡)。在关掉无关程序后,只保留一个终端用于启动脚本后,就没有问题了。

应用

ChatGLM-6B 的相干代码曾经上传到了 Github,大家能够把我的项目下载下来,而后依照仓库文档中的阐明批改目录地位后,就能够执行 cli-demo.py 或者 web-demo.py 脚本和 ChatGLM-6B 进行交互了。上面的几张图片就是部署在我电脑上的 ChatGLM-6B 应用示例:

因为电脑配置不是特地好,ChatGLM-6B 在我电脑上运行起来比较慢,一个问题答复起来要花几分钟。像生成低代码页面的这个需要,就跑了十几分钟,最初程序间接崩了,只给我输入了一半的 JSON,不过数据结构是对的,所以换个好点的显卡后应该不是问题。

总结

其实,大语言模型不仅能和低代码畛域配合应用,经过训练后的模型能够和任何畛域联合,从而生成该畛域的专门模型。例如 Figma、即时设计、MasterGo 这种设计工具,它们存储的也是一份 JSON 数据。所以实践上也能够通过对话来生成设计页面。

还有其余的相似于 AI 客服、催收机器人都能够通过这种办法训练进去。

参考资料

  • 手把手教你本地部署清华大学 KEG 的 ChatGLM-6B 模型
  • ChatGLM-6B

求职

我是一名有 7 年工作教训的前端,学历是 非全大专 ,目前正在看机会。我的冀望工作地点是 北京 / 天津 / 近程 ,冀望的岗位是 前端 / 全栈

以下是我把握的一些技能:

  1. 前端有做过低代码、监控、脚手架、前端工程化、性能优化,业余时间有钻研过微前端、浏览器渲染原理、编译原理等
  2. 后端能用 nodejs 写业务,懂点 docker k8s
  3. 有带团队教训(团队规模 15 +)
  4. 理解 Rust、LLM 利用相干常识,做过一些练手我的项目

我的 Github: https://github.com/woai3c 和微信号:qq411020382,有趣味的大佬请加我微信分割。

正文完
 0