Vibe Coding的正确打开方式

目前vibe coding风头正盛,特别是叠加了SDD、Skill等一系列方法,更是横空出世,就像秋风扫落叶一样,转瞬间就遍及软件研发的各个角落,软件开发人员要说没用vibe coding都不好意思跟人打招呼。用的人好评如潮,纷纷觉得人月神话里的银弹终于被我们找到了,以后软件开发那不就一目十行,如虎添翼,仿佛一夜间软件开发就从以人为主变成了以大模型为代表的机器为主,就差宣布:硅替代了碳了。但是也有很多谨慎的人,告诫大家要谨慎vibe coding的隐患,比如: 又比如:上述观点本质上是表达了对于使用vibe coding后,对于软件可维护性上的担忧。众所周知,软件除了实现功能外,还要持续重构以实现软件的简单设计使软件代码变得容易懂容易改;一个软件之所以有用,就是它能够承载合理、完整、一致性的业务流程,对于复杂的、高可靠性场景下的业务流程,软件一版就能实现对并且覆盖到所有的极端场景组合获得极高可靠性的假设,基本不可能成立。软件只要上线,几乎100%会碰到bug和需求不满足、需求变更的情况,所以软件一定会持续演进,这个软件才有生命力。持续演进必然会碰到软件维护性(bugfix、新增功能、现场故障定界定位等)的要求,要想易于维护,本质上就要解决代码的容易懂容易改的问题。这就解释了为啥不同的人对vibe coding的感观如此不一致呢?在于看待问题的视角不同,就像小马过河里说的一样,老牛说水太浅,松鼠说水很深,其实都是从不同的角度来谈问题,所谓横看成岭侧成峰,远近高低各不同。我们尝试从vibe coding作用对象:软件的性质和软件的维护性来谈这个问题。首先看软件的性质,聪上个世纪50年代,软件工程兴起依赖,软件遍布我们周围的每个角落,虽然都叫软件,其实内涵和外延确可能大不相同,参见下图:软件总体上可以从不同类型、不同架构层次、不同阶段、不同目标客户四个维度来划分性质。毋庸置疑,vibe coding在这4个维度的不同阶段作用和体感是不同的。大家对vibe coding爽感的推崇和隐患的担心其实都是在软件不同维度的映射,这个非常好理解:vibe coding能够端到端生成代码并且不需要投入后续太大精力维护这种观感主要集中在小型个人工具、软件0-1阶段、非技术群体使用等。这种情况下,尽可能使用vibe coding,怎么快怎么来,爽就行了。反之,在vibe coding帮助下,完成功能,还需要投入额外的工作,比如读懂代码,特别是复杂代码,有时候比自己全新写还要费精力。读大模型生成的代码,跟读懂别人代码一样,就是一件非常残忍的事,读代码的过程会碰到三高两难(记忆成本高、搜索成本高、意图还原成本高;分离主业务流程难+分离异常流程难)的障碍;然后在读懂代码的基础上继续借助大模型进行简单设计的重构。这部分代码包括不限于操作系统/数据库;电信/军工/能源等运行在嵌入式操作系统中的行业软件;底层框架;维护期遗留代码等等,也就是Martin Fowler对大模型编程提出警告中提到的“严肃软件”,这部分怎么强调可维护性都是不过分的。这种场景下使用vibe coding可不能怎么快怎么来。纯人工实现复杂功能过程中基本都会经历说清问题、建立模型、设计验收、实现算法,显式或隐式的经历这4步,可能是显式使用也可能是隐式思考,总之一步都不能少。对于严肃软件,vibe coding我们认为也不能跳过上述4步,只不过可以通过大模型+人高效人机协同的方式实现。接下来讨论在“严肃软件”中如何通过vibe coding来提升软件的可维护性。对于软件设计来说,reasonable永远是第一性原理,只有软件满足reasonable,才能证明软件实现的是正确的,而不是通过软件实现后测试来证明其正确。这个很容易理解,很多场景下测试正确,其实不一定正确,因为开发阶段测试一般会聚焦基本功能和主要异常,而不会进行过多设计场景组合验证,比如转弯、条件竞争、失败的假设、级联故障等,因为不理解,所以想不到,很正常嘛。比如我们用大模型实现一个无锁队列,测试后觉得这个队列实现是正确的,其实这个无锁队列不一定正确。无锁队列在异步多线程极端场景组合下很容易出现死锁,光靠测试是很难保证其正确的。如果不读懂代码,并且理解其中业务逻辑的reasonable,人工看不太懂的无锁队列合入版本就非常危险。对于大模型生成的代码必须读懂,否则会非常危险。大模型编码的危险程度,从大模型做的对(大模型自测+人工抽测)和开发人员轻松看得懂的维度看,可以分为4个象限,见下图:可以看到,使用大模型编程风险最大的地方在于左上角第四象限,即测试的对但是人很难看懂或者根本就不想花力气看懂的代码,这部分代码被采纳并合入代码库后,由于代码很难看懂,其中隐藏的bug又会被新增功能代码包裹起来,形成一个大泥球,后续这部分代码一旦出了问题,整个开发团队就只能束手无策。我们既想发挥大模型vibe coding的创造力,又想获得较高的可维护性该怎么做呢?这个问题可以做一个等价转换,即我们寻找一种形式化的设计构造和大模型协同交互,大模型实现功能后,通过设计构造就可以轻量级收获以下收益:首先我们可以通过观察这种核心设计构造的变化来验证大模型生成代码实现的是否正确;其次通过这种设计构造本身和变化显式的表达清楚代码意图和实现逻辑,从而轻易理解代码并看懂逻辑,实现reasonable;再次,实现reasonable后才可能利用大模型进行软件简单设计的重构,驱使大模型一步步从代码work-》clean code-》simple design。最后,可以通过这种设计构造跟大模型进行精准互动,对大模型输出的代码结果进行纠偏。我们把这种vibe coding的打开方式称作契约编程,上述的设计构造就是契约。契约编程的原理参见下图:软件的本质是承载业务流程,业务流程中拆分出业务场景,业务场景再次细化为业务行为,业务行为通过业务模型中状态组合的变化来承载,业务行为通过状态组合变化体现,关键词:状态、组合、变化。我们先看什么是业务状态组合,以用户管理模块举例:一般系统中都有用户管理的场景,场景中有用户注册的业务行为,和业务行为对应的业务状态是用户实体;所有实体存放在某种数据结构中,比如列表、字典、数据表等等,其实都可以抽象成set的数据结构(用户ID不重复、同时不关心用户次序),这种这个set就是状态组合;系统初始化是set是空,当某个用户x完成用户注册这个业务行为后,set就不为空了,且其中有且只有一个值x,这种变化就表示且仅表示注册完成了,这是就是状态组合变化表征了业务行为。开发人员通过观察业务状态和组合变化的正确性,很容易理解软件的设计和大模型对代码的实现逻辑,并能够精准给出系统实现是否正确的判断,这样就高效实现了大模型和开发人员协同,同时也实现了代码快速理解,为后续持续演进和维护打牢基础。底层的软件架构和算法支撑业务模型,就这样通过业务模型为核心和抓手,把业务行为(外延到业务场景)+业务模型(状态、组合、变化)+软件架构/算法全部整合起来形成高质量精确整合和重塑的simple design。在此,我们非常严肃的表明我们的观点,我们强烈支持大模型对软件开发的提效;并且再次大力倡导,我们应该敞开怀抱,大力拥抱vibe coding。对于非“严肃软件”,尽可能使用vibe coding,怎么快怎么来,大幅提升生产效率。但是对于“严肃软件”,要充分认识到软件reasonable的重要性,充分考虑软件的可维护性,在这个前提下,一定要用正确的方式打开vibe coding。步骤如下:首先人工建模或让大模型设计业务模型(状态、组合、变化),人工确认并修订,做到机谋人断,这里以人为主,以机为辅;然后让大模型通过业务模型中状态组合的变化映射到业务行为,生成状态组合变化的观察接口,并尽可能生成自动化测试用例。最后让大模型实现底层框架+算法,这块大模型非常擅长,这里以机为主,以人为辅。

小结
通过自动化测试用例,并补充观察状态组合变化的正确性,并通过状态组合和大模型进行有效交互,从而实现精准高效对大模型生成代码错误进行纠偏。
并通过状态和组合变化进一步完全理解代码实现的核心意图和思路,达到对大模型实现代码的reasonable。
把握住业务模型(状态、组合、变化)后,就可以轻松愉悦的使用状态和组合变变化为载体精准指导大模型对代码进行代码重构,逐步迭代演进到simple design,这样既解决了大模型提效,又彻底解决长期维护(新增功能、bugfix、现场问题定位定界等)的问题。

声明:来自丁辉的软件架构说,仅代表创作者观点。链接:https://eyangzhen.com/4916.html

丁辉的软件架构说的头像丁辉的软件架构说

相关推荐

关注我们
关注我们
购买服务
购买服务
返回顶部