24小时服务热线

18928448884 / 0755-2592 9959

24h咨询热线:18928448884

能否写出一个程序按照需求自动生成实现的代码? 能否写出一个程序按照需求自动生成实现的代码? 能否写出一个程序按照需求自动生成实现的代码?

自动化定制


    能否写出一个程序按照需求自动生成实现的代码?

    时间: 2024-04-01 19:44:34 |   作者: 打标自动化定制

  • 机型介绍



  如果我们能将需求与产物划上等号:需求即代码,那么我们只要找到两者之间的关联关系即可通过需求自动产出代码了,岂不是乐哉美哉(diao zha tian le)。

  ——————————————————————————————————————

  自然语言是及其抽象且强依赖上下文的,其整体表现为不精准,而代码是多维具象且有强相关性的,其整体要求为精准。这样两个不同概念的东西怎么找到他们之间的相关性呢?

  需求和代码之间没有一个标准的转换模式,通过标准转换器来实现是不可能的,唯一能够使用的方案就是运用机器学习,并通过大量的样本来增强之间的关联性。但正如前面所提到的,代码和需求都不是对局部的简单理解就能完成的,而是对一个整体的理解,因此对每一句话的理解都不能是独立存在的,而是相互交织在一起的,这就增高了对整个需要理解的纬度,据鄙人所了解这个难度是非常大的。

  但有时一个问题的难度大小也是由当下技术边界所决定的,比如3D打印的出现,就彻底将需求和产出物划上了等号,过去很多繁琐的工序都可以舍弃了,只需要一种实现方式就能让人们在家就可以下载设计稿并自己完成产品的实现。

  当然3D打印的出现并不能解决代码自动生成的问题,3D打印只是在生产的全部过程中运用了统一化的解决思路,而从需求到产出的过程依旧需要依靠设计图来对产出物的各项尺标数据做约束。所以设计稿的标准化一定是统一化的前提,3D打印更像是一个标准化出码的机器,而指挥这台机器如何生产的正式标准化下的设计稿,因此对我们来说需要思考两个问题:

  我把第二个问题看作和3D打印一样,是一个标准化的问题,而有了标准化的设计语言再转到AST是很简单的事情,困难的是第一个问题,如何将需求转为标准化的设计语言。这是我们应该核心思考的问题,并且这个课题对于运用机器学习来解决也同样是十分艰难的,那我们第一步是否应该来了解一下目前机器学习的边界呢,并怎样拆分成具体目标去实现它。

  电影中的小男孩大卫是个机器人,但是他被赋予了情感,他历经万险,为了一个注定幻灭的结局。"等我变成了真的小男孩,妈妈就会带我回家了"

  “当人工智能开始寻求自我认同时,他就已经和人类没区别了”。如果这样一个世界是虚拟的,造物主一定不会让我们得知丝毫,这也是当时这一部优秀的电影令人感同身受最恸哭内心的部分。这也正验证了人与机器的本质区别,即是否能感受自我的存在。

  回到当下,现实的AI 并不像电影里的那样,既没有情感也没有逻辑,更没有自我意识。比如知名的AI AlphaGo,从技术上讲,它之所以能够击败人类的围棋高手,是因为它具有由“小”变“大”的能力,人类将十几万的围棋博弈输入到它的“大脑”中,然后它就会进行自我“对战”,进而产生几百万甚至几千万的围棋博弈或者叫做棋谱,所以它在应付人类的围棋博弈时,就能够“从容不迫”。但他产生的模型的过程不能举一反三,当改变棋盘的尺度或改变规则时AI就再没办法做出有效应对了,它必须得进行重新的学习,而人类只一定要通过理解规则即可做出应对改变。

  与AI 相比,人类似乎能够解释和理解其所生活的环境,而计算机只是一台从事匹配工作的机器。哲学家约翰·塞尔(John Searle)很久以前就通过他的“中文房间”思维实验(Chinese Room thought experiment)指出了这种差异。在本实验中,他将自己关在密闭的房间中。

  这个实验是这样设计的:Searle 他既不会说也听不懂中文,但是在这个房间里有一本很大的手册,里面有一系列的假设陈述。通过门上的一个插槽,他可以接收汉字,查找手册中的字符串,并找到要通过插槽送出的字符串。显然,塞尔可能会让房间外的人相信他真的懂中文,但事实上他并不懂,他只是在匹配符号而已。

  虽然从外部无法区分房内的人到底是否“懂得”中文,但是实质上房内的人是不懂中文的。因此以“是否无法区分‘懂得中文’和‘表现得完全像懂得中文’这两个现象”而将其两者认为是等同的,这个观点是不能够成立的。

  AI 并不神奇,它预测的基础甚至和《易经》和 中医理论 都没有过大区别,如果要有,我觉得差在了灵魂和哲学的思考上。而对我们来说AI 是不是真的能产生情感还是是否能真正能够理解处理信息,对我们来说都不是重要的,我们只需要他看起来能做到准确预测即可,并不是特别需要一个真正的人工智能。

  用传统机器学习进行建模预测,其本质更接近于搜索,这是一个看起来会比较傻的弱人工智能,并且所有的预置算法都是由人类来写的,AI 只是一个按算法规则来进行分类/聚类的机器 ,比如对单个图形或句子进行预测,这一些数据都是相对结构化的数据,而对于整篇文章或全幅大图做分析则需要强人工智能来完成,一般我们会用到深度学习,并需要用多层处理单元的巨大神经网络利用强大计算能力和改进的训练技术来学习大量数据中的复杂模式。原理是计算机在学习特定问题时,需要大量输入这样的一个问题相关的学习材料也就是数据,然后在计算机通过算法和模型来构建对这个具体问题的认知,也就是总结出一个规律,那么在以后遇到相似问题时,计算机会把收集的数据转成特征值,如果这个特征值符合这前面规律里面的特征值,那么这个事物、行为或者模式,就可以被识别出来。

  P2C即通过 prd 自动产出 code,即是我们开头所讲的需求即代码的终极目标。

  在开发链路中耗时较长的两个环节是「沟通成本」和「编码成本」,「沟通」一般是需求明确的过程,一般体现在各种需求评审上。而前端的「开发」成本则主要可看作两个部分:视图代码与逻辑代码两个部分的开发工作。目前我们团队的 D2C产品(imgcook 设计稿到代码) 已经能够帮我们准确的生成大部分的视觉代码了,甚至还可以分析出部分简单的的业务代码,因此对前端开发来说在开发中的成本主要花在非通用的逻辑表达部分,即粘合剂。

  对于这些“粘合剂”逻辑,在产品的prd 中我们大家可以找到准确答案,但有时产品的prd 是不够结构化的,信息丢失也非常严重,这非常不利于机器学习进行学习和理解。因此我们应该一个平台来规范产品的需求,使产品能够根据相关要求进行结构化的录入。这就是我们做P2C 的初衷。

  前面我们对AI 的能力已经有所知之了,而现在我们要怎样一步步达成我们的终极目的“Auto Code”呢?

  我们知道AI 目前还不能够像人类一样来分析数据关系,而大部分prd 都是以文本为主的非结构化信息,这时候我们就需要利用 NLP技术对信息做处理并根据意图翻译为可进行转化的逻辑描述DSL,因此我们通过相对具有结构化文档的方式来进行需求的收集,从而简化机器学习的难度。

  虽然我们大家可以将原本海量信息的大文档进行结构化的信息表达,使局部信息清晰可解,但此降维操作也产生了新问题,就是关键点与关键点之间的联系变得更弱了。

  我们的初衷是希望能降低需求沟通成本,并在此过程中积累智能化出码的能力,所以我们只是设计了简单的结构化收集方式,并不强制改变pd原有的需求录入方式,因此需求文档内容有着非常高的不确定性,不仅存在上下文关系依赖,还有很多未描述的知识依赖,并且内容也都是允许其自由组合天马行空。

  知乎有一篇买苹果的例子,很好的诠释了一个简单的需求背后所牵涉的复杂的关联关系。因此可见单纯的通过需求来推导出产出物是非常难的工作。既然如此为啥不直接走向另一个极端:严格的结构化需求录入呢?虽然严格的结构化信息录入能够在一定程度上帮助更清晰的将一个开域问题收拢回一个闭域问题,但是会让需求产生的过程变得更困难更具专业化,这和我们服务pd 更好的进行需求录入的初衷是相违背的,另外我们也不希望能够通过标准化的方式去限制业务的创新。

  因此如何既能让 pd 录入需求的工作变得简单,又用能借此发展我们的“Auto Code”事业,是我们最大的一个难题。另外对于整个出码目标的技术链路我觉得目前也存在两个难点:

  既要让pd 录入需求时能录入的舒服,又得要求能按需出码,似乎两者是矛盾的,但是困难也都不可能是一朝就能解决掉的。

  所以我们打算分步骤实现目标,首先我认为短时间对需求的结构化信息分析还很难达到从局部到整体的突破,文本的灵活性也会带来诸多问题,比如模块信息的增删改造成的信息错位,因此我们觉得第一步要从以P2C为核心出码的逻辑变为以D2C(即Design2Code - imgcook),因为视觉是产出是最终产出物比较接近终态的一个阶段,通过视觉我们将会更容易分析缺失部分的内容,然后结合P2C内容从中寻找补全的关键信息,比如一个视图是否是ScrollView 单从视觉上很难辨认,需要结合从prd 中获取的信息,甚至prd 中没有详细描述时还需要跟俊产品属性做多元化的分析,例如这是一个音乐播放器的界面,那么其中应该包含什么功能组成,哪些功能组成一定会是ScrollView,这就需要一些知识依赖的输入,而这些宝贵数据资产都是需要脚踏实地不间断地积累的。

  我觉的D2C和P2C的结合一定是1+12的,对于D2C视觉出码有了知识依赖做背景,对于视觉稿的整体判断及组成可以有了很好的依据,另外P2C也能够基于准确的视觉做精准的逻辑补充。因此以视觉稿为主导出码,以prd为辅助出码的思想浮出水面。

  即我们第一阶段重修了目标:将原本的AutoCode目标先降低为NoCode = 通用逻辑组件 + ProCode(AI)目标。

  这个过程通俗来讲就是通用组件 + 配置信息的模式,配置信息即 ProCode 的部分,该部分即为需要 AI 自动产出的内容。因此想要完成自动出码,就需要对ProCode的部分进行样本制造和监督学习。

  即我们需建立要两个平台,我们叫做P2C 的 2.0 代 和 1.0 代。P2C 1.0 负责打标需求数据,并为 2.0的智能出码提供庞大准确的数据。而 P2C 2.0则主要进行需求的结构化收集并与1.0 的样本做关联学习,训练出码模型,最终达到创作和自动完成需求的目的。

  打标样本一定要从实践出发,并能在该阶段帮助需求真实的进行产出,即咱们提供的打标平台能真实的完成业务需求,因此我们决定开发一个可视化编排的平台,通过该平台来收集样本数据,并能顺手把需求也消化掉。

  我们通过调研发现运营的角色在可视化编排方向上,是很有高契合度的。为什么呢?其一,运营都具备模块搭建的能力。其二,很多运营的需求都不一定有机会能够落地,根本原因是开发资源不足导致的,这也是多年来存在的业务与技术矛盾,前端这十年来一直朝着工程化、规范化、模块化的方向发展,本意是为了更有效的重用业务能力以达到解放生产力,而产品却一直在朝着丰富化、精细化的方式来运作,各个业务方不再是单单为满足功能诉求而更讲求的是用户心智。最终致使现在对一个个性化需求的提出往往是用一个标准化方案来落地的。当业务方为资源不足妥协时,其业务整体感官也会慢慢的平庸化、趋同化,最后导致产品对用户的心智弱化。

  因此对于运营的诉求是希望能将创新和业务思考带入到自己的产品中,而不是简单的拆解为一个个的标准实现。如何拉大与竞争对手的运营差异、交互差异、创新差异、视觉差异才是对于运营真正的核心价值。

  在AI 的介绍篇中我们讲了对于复杂的逻辑关系我们依然能够使用抽象的组件化来实现,而这部分实现对比传统搭建体系的组件颗粒度更细,传统搭建一般是对模块的自定义配置,而在我们的编排体系里最小的组件应该是原子化的不可再被拆解的,比如一个Image 组件,而对组件的配置可以是一段编排好的逻辑实现,因此它能有着同代码一样的绝对灵活性。

  在前面3D打印的内容中我们提到,自动化统一化生产的前提一定是要有一个标准化的表达做支撑的,这个中间 DSL该如何设计才能承载住全量的需求内容呢?另外通过什么样的方式能让运营能接受和理解这部分的逻辑编排?

  首先我们解决的问题一定是有边界的是处在一个业务领域的,并在这个业务域下做多元化的分析。因此我们分析了一下我们最常见的业务形态-模块。而据统计“相同业务能力,不同技术实现”的模块在整个天马体系中的占比非常的高,单单拿通用商品坑来看就有上千个,而这些模块大部分都是相同的逻辑实现,也有很多是处于不同时期的技术产品。

  一个模块在前端的开发设计里,有可能可以分为4部分,通用组件,通用Action,视觉代码,驱动逻辑。

  我们能够正常的看到视觉和通用组件以及Action都是已经有了的,变动周期比较低。而驱动逻辑部分是是业务中的主要实现逻辑,如何让这部分逻辑能让运营进行产出呢?

  首先我们将这部分能力进行一个拆解,我们得出一个初步的结构,就是由 运算符 + 表达式 + 基础action + pipeline 组成的表达结构,这个表达也可以组成一个新的action,再加上trigger,整体就完成一个workflow的能力了。

  业务模块的四个部分中,驱动逻辑就是我们主要核心产出的内容,依照我们的经验这部分ProCode 大部分都是表达式 Expression 内容。因此我们只要能让运营能够自主的完成 ProCode 部分的编排即可高级定制需求的产出物。

  让运营完成所有的ProCode 也显然是不现实的,但是对于IFTTT 这种简单的逻辑表达,只要将这部分内容的表达能够正常的使用更接近自然语言的表达方式,自然会降低整个的理解难度。

  为了验证我们的拆解过程,我们把pmod 分组下的9千多个仓库进行一个拆解分析,发现平均每个模块都有逻辑表达 52.6 个,函数表达 37.55 个, if 语句 35.5 个,这三大部分实现是符合我们的拆解预期的。这部分的逻辑大部分都是可以用IFTTT 的模型套用。

  而一个复杂的模块,光有IFTTT 是不够的,逻辑的表达是具有很强的依赖上下文结构的,但是为降低整体的复杂度,我们应该对逻辑进行拍平表述,对拍平后的逻辑我设计了一套 StateLink的工作流管理库,这里就不详细介绍了。

  最后我们通过一个 When + Then + Trigger 三元素的DSL就能描述我们所有的业务逻辑部分了。这个DSL也为我们2.0 版的出码提前做好了准备,同时也能应对因技术升级而导致模块要重新开发的尴尬。

  为了让运营能够用得懂用的轻松,我们采取了中文编排的方式,即首先是根据选取的视觉对象进行一些具象的操作表达。

  我们将pd需求的一句可以拆分为上图这样的表达,对于使用者只需要顺着决策树表达自己的意图即可,类似于输入法,当我们输入一句话的时候,输入法通过预测词能表达所有的表达意图,比如输入“我”,那么一定能枚举“我们”、“我的”、“我..”等词并可以一直预测下去,而每个词的预测都是一个有限的枚举,同样pd在描述一个需求时我们也能够准确的通过语法和目的预测出所有的可能项。

  我们将常用的逻辑表达拆解为中文关键词,通过关键词关系可以让运营通过编排一句话的形式来表达事物的逻辑关系。

  我们目前已初步完成了第一个版本的运营逻辑编排平台,通过该平台可以先让运营能够进来满足一些简单的需求。

  虽然人工智能目前还有很多的不足和局限性,但随着深度学习的不断进化,我相信从需求理解到需求实现全过程的自动化会离我们越来越近。

  我相信未来不但可以实现从需求到代码的智能生产,也将会从智能生产覆盖到智能视觉、智能测试、智能运营的全链路智能场景。

  就像我们的大厨,一开始是需要人工切菜人工炒菜,后来是人工按菜谱备料再由机器辅助炒菜,再然后是直接输入菜谱机器就能自动根据菜谱备料和炒菜,而未来只要描述想吃什么口味就能自动做出符合用户的菜。

  P2C的未来就是将过程描述简化为目标描述,一个需求只需要表达诉求和目标而不再需要描述详细的生产的全部过程及规则,只需简单的几句话我们就能够知道用户想要什么该产生什么样的交付物了,这就是我们未来的“智能大厨”。

  我们是阿里巴巴-淘系技术部-频道与D2C智能 F(x) 团队,致力于前端智能化领域的探索和实践,赋能淘宝、天猫、聚划算等日常与大促(如双 11 )业务,是淘系前端智能化实践的领路人,也是阿里经济体前端委员会智能化方向的核心团队。目前团队有较多高校和海外背景的技术小二,专业领域涉及前端、算法、全栈等。我们在 D2C(Design to Code) 领域开放了Imgcook平台,在逐步释放阿里生态的前端生产力;我们也与 Google 的 tensorflow 团队保持长线合作,基于 tfjs-node 之上,开源了我们的前端算法工程框架Pipcook,在引领前端行业向智能化时代迈进。

  ——————————————————————————————————————

  本账号主体为阿里巴巴淘系技术,淘系技术部隶属于阿里巴巴新零售技术事业群,旗下包含淘宝技术、天猫技术、农村淘宝技术、闲鱼、躺平等团队和业务,是一支是具有商业和技术双重基因的螺旋体。

  我们入驻知乎,将给大家带来超多干货分享,立体化输出我们对于技术和商业的思考与见解。

  龙书开头就说得很清楚了:编译器就是一个读入一种语言的程序并输出为等价的另一种语言的程序的程序

  所以你这样的一个问题的核心就是你怎么定义你的源语言,让它可以严谨地描述需求,你说“输入”,是输入什么?这个有无数潜台词,跟当时的语境有关系

  让老板和产品人员能用更严谨的语言描述需求?还是说让计算机能更“智能”地理解你的“自然语言描述的需求”(换个说法就是有个AI能大概率“猜对”你的真实意图,但万一猜错了怎么办,你是否接受?)?至少目前看来,这两者都不靠谱,让程序员严谨地写源代码暂时是成本最低的办法,所能努力的方向是在具体场景下尽量让大家去更方便更安全地写

  穿磁芯的看不起打纸带的看不起搞汇编的看不起写C的看不起编C艹的看不起堆Java的看不起玩Python的看不起买MatLab的大致上就是这一个道理 :)

  关于自动生成代码的问题总是周期性的出现,说明人们还是对程序和语言的本质缺乏认识。

  对这个问题的最简单的回答是:能!而且已经被普遍的使用了。而且问题最后一句中所谓的程序员失业的事情已发生过很多次了。当然这样的回答肯定会让人非常疑惑。

  我们需要回到计算机历史的曙光时代,看看那时候的编程是怎样的。首先,颠覆一下大家的固有印象,在很多人的直觉中程序员就等于足不出户,交际能力很差的宅男,可是在最开始,所谓的程序员几乎都是女的,而她们的工作性质和电话公司的接线员基本上没有区别,所谓的编程是通过插拔电线来实现的,也就是说手工实现0和1的交换。很明显,这种编程方式效率是非常低下的,现在的人几乎没办法相像。于是科学家们大胆创新,发明了机器语言,此后的编程工作不再是接插电线,而使用扳开关,以及更高级的穿孔纸带等方式向机器发送指令。此时就需要能熟练做这些操作的人员来担任程序员的工作,之前的那些程序员们如果不更新技能就将面临失业。随后又出现了汇编语言,它淘汰了机器语言,又出现了FORTRAN等高级语言,让汇编语言让位。

  从这些历史能够准确的看出,几乎每当计算机技术出现革命性的进步,上一代被称为程序员的人群都几乎被淘汰掉,而那些具有新技能的人重新被冠以程序员这个称呼。我们也能够正常的看到,上面每一次的革命性技术出现时,新技术都可以被称为能自动“编程”的技术:机器语言让机器自动接线,汇编语言让机器自动识别指令,高级语言让机器能“听懂”人话。这基本上就是自动化编程的本质。把编程等同于写代码是非常狭隘的。

  虽然高级语言出现后并没有再出现太多本质上革命性的变化,但是仍然有很多变化在潜移默化的进行中。从IDE、库和框架、UML等新技术到语言本身的特性上都一直在进化。有时候甚至仅仅借助于成熟的框架就可以快速的把需求转化为代码,而无需手工编写很多代码。而因为这一些功能的实现太过理所当然,我们也已经不把它们当作编程了。

  任何编程活动都是在处理问题,只不过有些问题别人解决了并且把代码或可执行程序员发布了出来,就不再是问题了。然而总是会有新的问题是需要解决,也就总会有新的技术和掌握新技能的程序员出现来解决这样一些问题,而不管这些程序员是不是通过写代码的方式来进行编程。

  总结一下,自动实现代码的技术一直有,程序员不会消失!至于当前的自动代码生成技术也有一大堆,面向意图编程、通过UML生成代码等成熟不成熟的技术有很多,也有JetBrains的MPS这样面向语言编程的工具,将需求直接转化为代码的方式有描述性语言、逻辑式语言等,就不再赘述了。

  自动生成代码的事儿不少见。这个事情无非就是你想用更高级、更抽象的语言去描述一个算法,然后把剩下的工作交给机器。

  这件事的难点在于,这个生成出来的代码给不给力,性能好不好,可不可靠等等。毕竟大家都不满足于能跑,而是要求效率。从算法的角度上讲,这件事儿有两种办法。一种方法认为一些先进的硬件特性,比如out-of-order excution,可以帮我们保证性能,不用我们在算法上操心。这种叫hardware oblivious。另一种认为我们应该根据硬件架构来手动优化代码。这种叫hardware conscious。我认为hardware oblivious的算法是更方便代码的自动生成,因为不用管太多硬件细节。hardware conscious的算法就不太好搞了,需要研究算法和硬件的特性,然后对症下药。

  通过代码生成代码,原来用Excel就可以轻轻松松实现。最近接触了一些嵌入式编程的知识,以STM32 MCU为例,入门的应用就是IO口初始化了。Excel表哥公众号也有不少工程师朋友,想必对这样的一个过程都比较清楚。下面表哥就来和大家一起用Excel实现STM32 MCU的IO口初始化代码生成。

  只需要在下面的工具中按每个IO口的属性修改相应的二进制值,这个工具会自动生成十六进制码。

  自动计算十六进制的原理也格外的简单,主要是利用Excel自带的进制转换函数DEC2HEX,以及TEXT 和REPT函数。

  F26,E26单元格中设置的公式分别是实现将二进制数转化为十六进制,同时设置整齐的8位格式。

  将某个Port配置完成后点击工具中的代码生成就会自动生成这个Port口的初始化代码:

  所有的Port口配置完成之后点击复制代码,然后在IDE窗口中粘贴就ok了。

  可以看出这样生成的代码不仅非常整齐美观,而且连二进制注释也自动帮大家写好了,非常方便。

  STM32配置IO口的过程由原来的拿程序员计算器反复在二进制和十六进制之间来回转换变成了通过鼠标点一点,能够说是减少了很多不必要的工作量了。

  通过上面的案例分享你们可以发现其实代码生成也没有想象中的那么难。ST公司官方有一个功能更完善的工具STM32Cube,实现的功能可能也无非如此,但是思路我猜测是一致的。这个例子也进一步说明Excel这个软件的强大,用好Excel能够大大减少很多不必要的重复工作!

  需要此工具的读者朋友能关注公众号并在下方的留言区获取后台下载关键词哦~

  欢迎关注这个分享Excel知识的公众号,关注【Excel表哥】领取为你准备的各类excel模板福利!

  我觉得这和解压缩的原理是一样的,你想输入少量的信息去表达大量的信息,要么信息失真,要么需要一个密码本。若不想失真,那么输入的信息越少,需要的密码本的内容就越大。而且这个密码本必然是有明确的目的性的,也就是说一个高度复杂的密码本能生成的程序是有限的。

  比如说,你设计了一款究极语言,你只要说一个字母,他就能层层翻译最后得到一个程序。但是你最多只能制造26个不同的程序,因为字母只有26个。

  其实你说的“scanf(“%s”,temp)”,就已经是一级翻译了。从高级语言翻译到汇编,又要从汇编翻译到机器码,真正最原始的代码其实是机器码。

  你所言的这个系统,其实就是进行了更高一级的翻译,那这样的翻译究竟有毫无意义,才是设计这个程序的人所需要仔细考虑的问题。类似的程序其实也有,但是针对性都比较强,比如有些程序能比较自动化地制作安卓APP,还有些程序能较为简便地生成一些简单得Win32程序。

  用一个大盒子把100个微软工程师和100个程序员装起来,留个接口输入输出,差不多能满足你的需求。