【随想】低代码和大模型如何配合

前段时间无意中看到 vercel 已经推出了利用大模型根据用户语言生成页面,并且可以根据需求不断调整页面,思考了一下如果是我,我该怎么做完成这个事情。

本着能白嫖就不花钱的原则,没有调 GPT 的 API,因为 GPTs 能够存储 KnowLedge 作为上下文进行分析,所以打算写一个最简单的‘低代码’的 demo,只要能表达出意思就好了。

V1.0

准备代码

先用了 js,发现效果不好,GPT4 无法直接通过“不自洽”代码猜到我的一些意图,可能 GPT 没有联想和想象的能力(也可能是这个能力不成熟所以没放出来),不纠结这个问题,改成 ts,写好注释。

interface Container {
  /** 容器名称 */
  containerName: string;
  /** 容器包含组件 */
  components: {
    /** 组件名称 */
    text: string;
    /** 组件类型 */
    component: string;
  }[];
  /** 子容器 */
  children?: Container[];
}

const Login: Container[] = [
  {
    containerName: "Form",
    components: [
      {
        text: "用户名",
        component: "Input",
      },
      {
        text: "密码",
        component: "Password",
      },
    ],
    children: [
      {
        containerName: "Action",
        components: [
          {
            text: "登录",
            component: "Button",
          },
          {
            text: "忘记密码",
            component: "Button",
          },
        ],
      },
    ],
  },
];

const BaseComponents = [
  {
    type: "Input",
    cnName: "输入框",
    html: "<input></input>",
  },
  {
    type: "Password",
    cnName: "密码输入框",
    html: '<input type="password"></input>',
  },
  {
    type: "Select",
    cnName: "密码输入框",
    html: "<select></select>",
  },
  {
    type: "Button",
    cnName: "按钮",
    html: "<button></button>",
  },
];

生成注册页

ME: 你好,根据我的 Login 的配置,生成一个注册表单

GPT:

根据您的配置文件,登录表单(Login)包含以下元素:

容器名称为”Form”,包含两个组件:
用户名(Input 类型)
密码(Password 类型)
子容器名称为”Action”,包含两个按钮:
登录(Button 类型)
忘记密码(Button 类型)
为了创建一个注册表单,我们可以基于登录表单的配置,加入额外的必要字段。通常,注册表单会包含用户名、密码、确认密码、邮箱等字段。下面是一个基于您现有配置修改的注册表单:

interface Container {
  /** 容器名称 */
  containerName: string;
  /** 容器包含组件 */
  components: {
    /** 组件名称 */
    text: string;
    /** 组件类型 */
    component: string;
  }[];
  /** 子容器 */
  children?: Container[];
}

const Registration: Container[] = [
  {
    containerName: "Form",
    components: [
      {
        text: "用户名",
        component: "Input",
      },
      {
        text: "密码",
        component: "Password",
      },
      {
        text: "确认密码",
        component: "Password",
      },
      {
        text: "邮箱",
        component: "Input",
      },
    ],
    children: [
      {
        containerName: "Action",
        components: [
          {
            text: "注册",
            component: "Button",
          },
          {
            text: "已有账号?登录",
            component: "Button",
          },
        ],
      },
    ],
  },
];

这个配置添加了确认密码和邮箱的输入框,并将子容器中的”登录”和”忘记密码”按钮替换为”注册”和”已有账号?登录”按钮,以适应注册场景的需求。请根据您的实际需求进一步调整或添加其他必要字段。


可以发现 GPT 能领会了我的意思,并且生成了一个结构类似的代码,继续

添加 Button

ME: OK,很好,现在我想在注册页面的左上角加一个返回登录页的按钮

GPT:

const Registration: Container[] = [
  {
    containerName: "BackButton",
    components: [
      {
        text: "返回登录",
        component: "Button",
      },
    ],
  },
  {
    containerName: "Form",
    components: [
      {
        text: "用户名",
        component: "Input",
      },
      {
        text: "密码",
        component: "Password",
      },
      {
        text: "确认密码",
        component: "Password",
      },
      {
        text: "邮箱",
        component: "Input",
      },
    ],
    children: [
      {
        containerName: "Action",
        components: [
          {
            text: "注册",
            component: "Button",
          },
          {
            text: "已有账号?登录",
            component: "Button",
          },
        ],
      },
    ],
  },
];

为了精简内容只展示GPT回复的代码部分,后续保持一致

GPT 完全明白 Container 的作用,并且可以借此完成想要的功能,虽然命名上和我想要的有点不一样,但是应该可以通过增加约定来进行优化。

添加 Logo

ME: 我发现返回登录已经有了,左上角应该放置一个 Logo 图片

GPT:

const Registration: Container[] = [
  {
    containerName: "Logo",
    components: [
      {
        text: "Logo", // 这里的text属性可以用于辅助标识,实际展示的是图片
        component: "Image",
        imagePath: "path/to/your/logo.png", // 假设的Logo图片路径
      },
    ],
  },
  {
    containerName: "Form",
    components: [
      {
        text: "用户名",
        component: "Input",
      },
      {
        text: "密码",
        component: "Password",
      },
      {
        text: "确认密码",
        component: "Password",
      },
      {
        text: "邮箱",
        component: "Input",
      },
    ],
    children: [
      {
        containerName: "Action",
        components: [
          {
            text: "注册",
            component: "Button",
          },
          {
            text: "已有账号?登录",
            component: "Button",
          },
        ],
      },
    ],
  },
];

如果没有定义 interface 和注释(主要应该是注释),GPT 还是不能理解 BaseComponents 中的内容进行联想,但是他会尝试采用一些行业比较通用的方法去解决问题。现在先完善 BaseComponents 的类型定义和注释。

V2.0

准备代码

interface Container {
  /** 容器名称 */
  containerName: string;
  /** 容器包含组件 */
  components: {
    /** 组件名称 */
    text: string;
    /** 组件类型 */
    component: string;
  }[];
  /** 子容器 */
  children?: Container[];
}

const Login: Container[] = [
  {
    containerName: "Form",
    components: [
      {
        text: "用户名",
        component: "Input",
      },
      {
        text: "密码",
        component: "Password",
      },
    ],
    children: [
      {
        containerName: "Action",
        components: [
          {
            text: "登录",
            component: "Button",
          },
          {
            text: "忘记密码",
            component: "Button",
          },
        ],
      },
    ],
  },
];

interface Component {
  /** 组件名称 */
  name: string;
  /** 组件中文 */
  cnName: string;
  /** 组件对应html代码 */
  html: string;
}

const BaseComponents: Component[] = [
  {
    name: "Input",
    cnName: "输入框",
    html: "<input></input>",
  },
  {
    name: "Password",
    cnName: "密码输入框",
    html: '<input type="password"></input>',
  },
  {
    name: "Select",
    cnName: "密码输入框",
    html: "<select></select>",
  },
  {
    name: "Button",
    cnName: "按钮",
    html: "<button></button>",
  },
];

重新生成

ME: 我重新修改了 Knowledge,希望你根据新的 Knowledge 重新生成一个左上角带 Logo 的注册页

GPT:

interface Container {
  /** 容器名称 */
  containerName: string;
  /** 容器包含组件 */
  components: {
    /** 组件名称 */
    text: string;
    /** 组件类型 */
    component: string;
  }[];
  /** 子容器 */
  children?: Container[];
}

const RegistrationPage: Container[] = [
  {
    containerName: "Header",
    components: [
      {
        text: "Logo",
        component: "Image",
      },
    ],
  },
  {
    containerName: "Form",
    components: [
      {
        text: "用户名",
        component: "Input",
      },
      {
        text: "电子邮件",
        component: "Email",
      },
      {
        text: "密码",
        component: "Password",
      },
      {
        text: "确认密码",
        component: "Password",
      },
    ],
    children: [
      {
        containerName: "Action",
        components: [
          {
            text: "注册",
            component: "Button",
          },
        ],
      },
    ],
  },
];

export default RegistrationPage;

ME: Image 的组件没有定义,帮我定义一下
GPT:

interface ImageComponentProps {
  /** 图片源地址 */
  src: string;
  /** 图片的替代文本 */
  alt: string;
  /** 应用于图片的CSS类 */
  className?: string;
}

/** Image组件 */
const ImageComponent: React.FC<ImageComponentProps> = ({ src, alt, className }) => {
  return <img src={src} alt={alt} className={className} />;
};
{
  containerName: "Header",
  components: [
    {
      text: "Logo",
      component: "ImageComponent",
      props: {
        src: "logo的URL地址",
        alt: "公司Logo",
        className: "logo-class"
      }
    },
  ],
}

ME: 我还是希望你根据我的 Knowledge 去定义

GPT:

interface ImageProps {
  /** 图片地址 */
  src: string;
  /** 图片替代文本 */
  alt: string;
}

const Image: React.FC<ImageProps> = ({ src, alt }) => {
  return <img src={src} alt={alt} style={{ maxWidth: "100%", height: "auto" }} />;
};
const RegistrationPage: Container[] = [
  {
    containerName: "Header",
    components: [
      {
        text: "Logo",
        component: "Image",
        props: {
          src: "path/to/your/logo.png",
          alt: "Website Logo",
        },
      },
    ],
  },
  // 其他容器和组件的定义...
];

和图片一样只要涉及重新生成,必然会有些问题,把“已有账号?登录”给搞丢了

聊天中没有指明 BaseComponents 是定义组件的,并且代码其实没有实际关联上,导致 GPT 无法做这样的思考(GPT 的思考方式还是比较死板的,缺乏一些想象力),不过在实际代码中肯定不会这样去写,这里继续优化一下代码吧。

V3.0

准备代码

interface Component {
  /** 组件名称 */
  name: string;
  /** 组件中文 */
  cnName: string;
  /** 组件对应html代码 */
  html: string;
}

const Input: Component = {
  name: "Input",
  cnName: "输入框",
  html: "<input></input>",
};
const Password: Component = {
  name: "Password",
  cnName: "密码输入框",
  html: '<input type="password"></input>',
};
const Select: Component = {
  name: "Select",
  cnName: "密码输入框",
  html: "<select></select>",
};
const Button: Component = {
  name: "Button",
  cnName: "按钮",
  html: "<button></button>",
};

interface Container {
  /** 容器名称 */
  containerName: string;
  /** 容器包含组件 */
  components: {
    /** 组件名称 */
    text: string;
    /** 组件类型 */
    component: Component;
  }[];
  /** 子容器 */
  children?: Container[];
}

const Login: Container[] = [
  {
    containerName: "Form",
    components: [
      {
        text: "用户名",
        component: Input,
      },
      {
        text: "密码",
        component: Password,
      },
    ],
    children: [
      {
        containerName: "Action",
        components: [
          {
            text: "登录",
            component: Button,
          },
          {
            text: "忘记密码",
            component: Button,
          },
        ],
      },
    ],
  },
];

重新生成

ME: 很抱歉,我的代码写的不太好,请你根据我刚刚的要求再重新生成一个注册页

GPT:

interface Component {
  /** 组件名称 */
  name: string;
  /** 组件中文 */
  cnName: string;
  /** 组件对应html代码 */
  html: string;
}

const Logo: Component = {
  name: "Logo",
  cnName: "标志",
  html: '<img src="logo路径" alt="Logo"></img>',
};

const Input: Component = {
  name: "Input",
  cnName: "输入框",
  html: "<input></input>",
};

const Password: Component = {
  name: "Password",
  cnName: "密码输入框",
  html: '<input type="password"></input>',
};

const Email: Component = {
  name: "Email",
  cnName: "邮箱输入框",
  html: '<input type="email"></input>',
};

const Button: Component = {
  name: "Button",
  cnName: "按钮",
  html: "<button></button>",
};

interface Container {
  /** 容器名称 */
  containerName: string;
  /** 容器包含组件 */
  components: {
    /** 组件名称 */
    text: string;
    /** 组件类型 */
    component: Component;
  }[];
  /** 子容器 */
  children?: Container[];
}

const PageLayout: Container[] = [
  {
    containerName: "Header",
    components: [
      {
        text: "Logo",
        component: Logo,
      },
    ],
  },
  {
    containerName: "Form",
    components: [
      {
        text: "用户名",
        component: Input,
      },
      {
        text: "密码",
        component: Password,
      },
      {
        text: "确认密码",
        component: Password,
      },
      {
        text: "邮箱",
        component: Email,
      },
    ],
    children: [
      {
        containerName: "Action",
        components: [
          {
            text: "注册",
            component: Button,
          },
        ],
      },
    ],
  },
];

关联上之后,GPT 立刻就聪明了,虽然定义方式和我设想的还是不太一样,但是借此可以推断只要上下文足够优秀,GPT 生成低代码产品就是工程化的问题。

总结

可以看到,当设计的代码能逻辑自洽,GPT 的分析能力完全可以生成一段‘低代码’的代码,而且从物料到页面(延续到其他层面)应该都没问题,但是如何不同场景下去限定作用范围(这个作用范围不只是指具体功能,也可以是抽象层面的)可能会是一个需要重点考虑的问题。

从我的对话中,GPT 和生成图片类似,一旦涉及到重新生成,就会真的重新生成。在 V2.0 里,GPT 把返回登录按钮给搞丢了,之前用过 Vercel 的低代码平台,发现也一样有这样的问题。尤其是后期功能调教的时候,AI 的目的是降低门槛,门槛降低势必会有大量的用户不具备程序员思维,不能理解我要只是觉得不好看要重新生成一个 ABCD,完事了就只剩 ABC 了,然后再说把 D 加回来,发现这个 D 和原来的 D 不一样了。所以,限定作用范围本身也是需要 GPT 去理解和决策做的事情,如果通过代码层面进行决策的干预,那很不 AI。

原文链接:https://juejin.cn/post/7340836136207745062 作者:徐小贱本尊

(0)
上一篇 2024年3月1日 上午10:11
下一篇 2024年3月1日 上午10:21

相关推荐

发表回复

登录后才能评论