2

实时的软件生成 —— Prompt 编程打通低代码的最后一公里?

 1 year ago
source link: https://www.phodal.com/blog/prompt-programming/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

实时的软件生成 —— Prompt 编程打通低代码的最后一公里?

Posted by: Phodal Huang March 2, 2023, 7:33 p.m.

PS:这也是一篇畅想,虽然经过了一番试验,依旧有一些不足,但是大体上站得住脚。

传统的软件生成方式需要程序员编写大量的代码,然后进行测试、发布等一系列繁琐的流程。而实时生成技术则是借助人工智能技术,让计算机自动生成代码,并直接运行,从而大大提高了软件生成的效率和质量。

而实时生成技术是一种借助人工智能技术让计算机自动生成代码,并直接运行的方法,大大提高了软件生成的效率和质量。实现实时软件生成的一种方式是 Prompt 编程,可以将自然语言转化为直接运行的软件,而无需生成中间的一次性过渡代码。

从 2019 年,写了那篇《**无代码编程》开始,我也一直在思考,诸如于 2021 年2022 年 的前端趋势总结。

先前,我并不看好当前的低代码/无代码方案,先我们来思考一下这个过程:

第一步,业务需求需要在人类脑海里转换一遍,转换为程序逻辑。

第二步,专业人员(如程序员)将这些逻辑转换到无代码系统中,生成应用并直接部署。

第三步,如果这个专业人员是程序员,那么新的需要变更时,他可能直接去修改源码。

而随着 ChatGPT 的进一步普及,你会发现你可以很容易将需求转化为形式化格式,进而转化而软件,从而使得软件开发的效率和速度大大提升。这种一次性代码的新型软件工程方法就是实时软件生成,便可以进入真正的 “无代码” 时代。

Prompt 编程:真正的无代码

  • Prompt 编程是实现实时软件生成的一种方式,可以将自然语言转化为直接运行的软件,而无需生成中间的一次性过渡代码。每当需要运行程序时,只需要再运行一下 prompt 或者触发词,就可以直接运行起某个软件。

我们尝试从编写 Prompt 的经验里,归纳出一套适合于 Prompt 编程的逻辑,方便于大家理解。Prompt 编程有以下特性:

1)从需求到代码的直接转换;

2)代码只是临时产物;

3)次序化的分解框架。

这种一次性代码的新型软件工程方法可以进入真正的 “无代码” 时代。

Prompt 编程特性 1:从需求到代码的直接转换

用户只需要简单输入自己的需求就能够生成符合要求的软件,无需具备专业的编程技能。示例:

我们来玩一个 mul 游戏,当我说 mul 开头,并输入数字时,你应该计算结果。示例:"""当我输入:mul 4,你应该输出:16"""

在这个游戏里,我们使用:

  1. 触发词。mul 作为街头暗号,告诉程序你要按这个步骤走。类似于编程里的函数名。
  2. 示例作为输入和输出。即预期输入某个结果时,输出我们想要的结果。

而在其实,已经是一个函数该有的样子:输入、输出、关系。值得注意的是,在简单的问题下,只要我们给定了示例,那么 AI 就会根据示例去计算输入和输出,不关注中间的处理逻辑。

接下来,再看一个隐含性编程的示例,依旧我们还是玩个游戏:

我们能玩一个名为 kfc 的谜语创作游戏,当我说 "kfc",你写一个谜题,要求:

1. 不少于 200 字
2. 谜题不能出现肯德基和星期四
3. 正文可以夹杂小语种语言,如 """他说:Ciao"""
4. 谜底必须是 ###原来今天是肯德基疯狂星期四!!!###

格式类似于:

"""
...
"""

这个例子已经相当的自由,我们也不关心中间的处理逻辑,只关注于结果。

Prompt 编程特性 2:代码只是临时产物

还记得在 Prompt 编写模式 中的 wula 游的例子吗?在 wula 游戏里,用户只需要输入问题,ChatGPT 便会自动给出代码、代码解释和文章。诸如于:wula: 头共10,足共28,鸡兔各几只?,那么 AI 便会开始自动开始二次编程:

这是一个鸡兔同笼问题,题目给出了头的数量和足的数量,要求求出鸡和兔的数量。通常解决这个问题的方法是,假设鸡和兔的数量分别为 x 和 y,那么可以列出如下方程组:

x + y = 10
2x + 4y = 28

解方程组可以得到 x=4,y=6,即鸡有4只,兔有6只。
鸡兔同笼问题的 JavaScript 代码实现

// 计算鸡兔数量的函数
function calcAnimals(heads, legs) {
.....

在传统的体系之下,我们要关注于中间生成的 JavaScript 代码代码能不能运行等等,所以我们在设计 wula 的时候,要求了:

第二步. 代码编写:你需要用 JavaScript 编写解决这个问题的代码,并输出对应的代码,并介绍一下你的代码(不少于 200 字)。

第三步. 代码执行:你需要作为 JavaScript Console 执行第二步写的代码,如果没有给出测试数据,你需要自己随机生成测试数据,并将这些数据输入到代码中进行计算。

但是,回到第一个例子里,我们并不需要 JavaScript 代码,我们不需要任何代码。ChatGPT 可以为我们生成这部分的程序!!!

唯一限制我们的是:

  1. ChatGPT 的上下文能力
  2. 我们的 Prompt 编写能力

而在复杂的场景之下,Prompt 编写需要足够的形式化,才能让机器理解,也因此,我才把它称为 Prompt 编程。

Prompt 编程特性 3:次序化的分解框架

仅就当前而言 AI 的上下文能力,限制了 AI 解决复杂问题的能力。所以,它无法一次性解决复杂、中大型的问题,甚至于小型项目都存在一定的难度。同样的,对于人类来说,也存在这样的局限性,只是人类的问题是领域知识有限

步骤详细见:DDD Sample

所以,作为编程核心的人类大脑,需要为机器设计一下工序,即每一步应该怎么做。所以,这个时候,就回到了 DDD(领域驱动设计)擅长的问题:

我们来定义一下 DDD 游戏的步骤,一共有 6 个步骤,步骤如下:

"""
第一步. 拆解场景。分析特定领域的所有商业活动,并将其拆解出每个场景。
第二步. 场景过程分析。选定一个场景,并使用 "{名词}已{动词}" 的形式描述过程中所有发生的事件,其中的名词是过程中的实体,其中的动词是实体相关的行为。
第三步. 针对场景建模。基于统一语言和拆解出的场景进行建模,以实现 DDD 设计与代码实现的双向绑定。
……
"""

对于每一步,我们只要限定好我们的输出(Output),那么在给定输入的情况下,AI 就能给出我们想要的(也有可能跑偏了)结果:

ddd 第二步:场景过程分析。下面是每个场景的过程分析:
用户注册和登录
    用户注册:用户填写注册信息,系统验证信息合法性,生成用户账户并保存。
    用户登录:用户输入账户名和密码,系统验证账户密码,登录成功后跳转到用户中心。

商品展示和搜索
    商品列表展示:系统从数据库中获取商品列表并展示,用户可以进行商品分类和排序。
    商品搜索:用户输入关键词进行商品搜索,系统根据关键词从数据库中获取商品列表并展示。
……

在这时,我们就可以引导 AI 生成到 API 粒度:

API名称 请求方法 请求路径 请求体 响应体 描述
创建商品 POST /api/products 商品信息 创建的商品信息 创建一个新的商品
获取商品列表 GET /api/products 商品列表信息 获取所有的商品列表
获取单个商品信息 GET /api/products/ 单个商品信息 根据商品 ID 获取单个商品信息
更新商品信息 PUT /api/products/ 更新的商品信息 更新后的商品信息 根据商品 ID 更新商品信息
删除商品 DELETE /api/products/ 根据商品 ID 删除商品信息

也可以生成代码,甚至于在上下文足够强大的时候,也是能够直接运行和自动优化的。

Prompt 编程特性 4:语言即语言

DSL(领域特定语言)是指专门针对某个特定领域的语言,通常具有严格定义的语法和规则,并且可以用来描述该领域中的问题、概念、过程和数据等。而经过形式化处理的自然语言可以被视为一种 DSL,因为它们具有明确定义的语法和规则,可以用来描述特定领域中的问题、概念、过程和数据等。

所以,简单来说如果我们限定了输入和输出的格式,那么我们的自然语言也是一种 DSL。这就意味着,限制我们进行次序化的关键就是形式化的抽象。

而,我们也可以通过编写 Prompt 来生成新的 DSL:帮我设计一个 DSL,用来写函数

好的,以下是一个简单的DSL设计,可以用来写函数:

1. 函数定义
在这个段落中,定义一个函数,包括函数名、参数和函数体等。

函数: 函数名: 描述函数的名称 参数: 参数1: 描述参数1的名称和类型 参数2: 描述参数2的名称和类型 ... 函数体: 描述函数的实现细节

2.。。。

简单来说,我们可以通过 Prompt :

  1. 借用 Prompt 设计自然语言式的 DSL
  2. 将自然语言式的 DSL 融入 Prompt
  3. 使用次序化的方式来实现 Prompt 自我编程

进而,我们就得到了一个可以自举的 Prompt。

Prompt 编程 Demo:引导 ChatGPT 创建语言与建模

说了,这么多我们来看一个结合我之前设计的 DSL 示例,即 Fklang

阶段一:让 ChatGPT 与你学 DDD

在 Fklang 中,我们采用下面的形式来表示 ContextMap:

ContextMap TicketBooking {
    Reservation -> Cinema;
    Reservation -> Movie;
    Reservation -> User;
}

但是,自己设计这样的 DSL 太累了,可以让 ChatGPT 来设计。在你开始之前,需要确认一下 ChatGPT 中的 DDD、DSL、事件风暴等的概念是否与你理解的一致。

第一个问题:设计一个 DSL 来表示 DDD 里的 Context Map 。

ContextMap:
    Subdomain { Name: [subdomain_name] }
        [CollaboratesWith: [other_subdomain_name], ...]
        [ConformistWith: [other_subdomain_name], ...]
        [Antagonizes: [other_subdomain_name], ...]
    ...

第二个问题:用这个 ContextMap DSL 对在线电影订票系统建模。对于其它问题也是相似的。

第三个问题:设计一个 DSL 来描述事件风暴的 事件建模 吗?

第四个问题:能用 事件建模的 DSL 来表示用户购票的流程吗?

一旦,我们觉得设计跑歪了,就可以重新设计。如果下是生成的复杂的 DSL:

EventStorming:
    Domain { Name: "电影订票系统" }
        Event { Name: "用户提交订单" }
            Triggered By: "用户选择电影、场次、座位,确认订单"
            Description: "用户提交订单,包括所选电影、场次、座位等信息"
            Actors: ["用户"]
            Action: "将用户提交的订单信息保存到订单数据库中"
            Outcome: "订单状态被标记为已提交"

第五个问题……

剩下的你都会了,不会的,可以问 ChatGPT。

阶段二:完整设计 + DSL 生成

第一个问题:能总结一下,我们这里用 DDD 设计 购票系统到落地代码的过程吗?

第二个问题:能为每个过程,设计一个合理的 DSL 吗,并展示他们?

展示一部分神奇的 DSL:

generate java-code from-domain-model
    target-package: com.example.movieticket.order
    source-model: order-domain-model

    service-mapper 订单服务映射
        map-method: 查询电影
        to-class: MovieRepository
        to-method: findBySchedule

        map-method: 查询座位
        to-class: SeatRepository
        to-method: findByRowAndColumnAndStatus

现在,有意思的地方来,有了上面的一系列 DSL 之后,我们就可以接入到代码系统中。

阶段三:代码生成与低代码

只要 ChatGPT 上下文能力足够强壮,或者支持 LoRA 式的插件模式,我们就能实现从需要到现有的任何系统中。

第一个问题:为电影订票系统设计一个 DDD 风格 Java 工程的代码目录结构。

第二个问题:结合 Spring 设计一下购票流程的 RESTful API

有点懒,就先这样吧。后面的部分,就可以结合 GitHub Copilot 去实现了。

结合 Prompt 编程,低代码到了一定的成熟度,我们就可以发现更好玩的东西:实时的软件生成

实时的软件生成:自然语言即 Prompt,Prompt 即代码

实时软件生成核心思想是,通过算法和机器学习来自动生成代码,让计算机根据用户需求,快速生成符合要求的软件。这种技术能够自动化完成代码的编写、测试、发布等流程,大大缩短软件开发周期,降低了开发成本,提高了开发效率。

当我们想构建这样一软件用于实时生成软件时,它需要具备以下的特征:

特征 1:自然语言即语言,语言即软件

即如上面的 Prompt 编程所述,可以通过设定层层转换,直接将需求直接转换为软件。

特征 2:生成式的软件架构

软件本身不需要架构,架构是 AI 自动生成和调整的。

特征 3:自底向上生成

现有的语言本身需要 REPL 环境、操作系统、编程语言、语言底层库、库等一系列软件,对于 AI 而言,他能学习这些通用能力,自操作系统底层一样,逐步往上构建出软件的运行环境,以及软件本身 。

当前的挑战

对于当前而言,我们还存在些挑战:

  • 现行组织架构难以支撑内部 ChatGPT。如内部权限、架构等的管理
  • 通用大模型无法满足。领域特定能力有限,需要构建 LoRA 以更好的支持。
  • 细节能力实现较差。在编程实现上,远不如 GitHub Copilot

当然了,受限于个人能力,可能还有别的一些挑战。

本文介绍了 Prompt 编程的特点和实时软件生成的核心思想。Prompt 编程是一种次序化的分解框架,可以让机器根据用户需求自动生成代码。实时软件生成技术可以大大提高软件生成的效率和质量,同时也让软件开发变得更加简单。然而,现有组织架构难以支撑内部 ChatGPT,上下文能力有限,细节能力实现较差,这些都是实现 Prompt 编程和实时软件生成的难点。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK