软件复杂性的协同:AI 工具应如何与人类协作解决软件开发任务?
在设计 Unit Mesh 架构时,其思想是以 Unit(如代码单元)作为 AI 辅助生成的元素,以辅助人类解决复杂的软件开发问题。
围绕于 Unit Mesh 的理念,在 AutoDev 1.6.0 版本中,我们开发了更多的生成 “单元” 的功能:
生成 React 前端单个组件、页面的:AutoPage
生成后端代码 SQL 中的:AutoSQL
如上的视频所示,即在这里的页面、SQL、函数是一系列的 AI 生成的 “单元”, 以更好地探索我们对于生成式 AI 辅助思考。
如何解决复杂软件问题?
由于人类本身的能力限制,所以对于复杂任务来说,首先要做的事情是拆解。随后,要么我们委托给其他人来完成,要么我们自己 “努力” 完成。而在有了 AI 之后,如何让 AI 协助完成复杂任务,这是我们考虑的合理。
分而治之的软件架构
正因为问题本身过于复杂,边界模糊不清,所以前人(Eric Evans)总结了《领域驱动设计:软件核心复杂性应对之道》。在有了明界的边界之后,实现起来就简单了,模板化的服务化、模块化代码。
在不同的时代里,它应用对于不同的解决方案:
上一个时代,在复杂系统里代表性的架构是类似于 OSGi 的可插拔性、插件化的架构。
这一个时代,微服务是在结合软件复杂性、知识负载的一种架构模式。
在下一个时代,Gartner 等公司在预测可组合架构可是下一个趋势。
但是,其核心的思路是不变的,将复杂的问题拆解到人类可以解决的范畴。
软件架构的设计:协作以收集信息
在设计软件架构时,要做的很重要的一个沟通活动是:与利益相关者达到对系统的一致理解。简单来说,我们需要收集不同与这个系统相关的人员对系统的理解、要求等一系列信息,他可能是系统的使用者、各级领导等。
在理解软件架构时,需要从不同层次的实现去理解宏观和微观的实现。如我们在设计 ArchGuard 架构治理平台时,我们结合 C4 模式与一系列依赖分析模式,以期望从现有的代码中理解软件的设计。它需要从软件库依赖、API 依赖、模块依赖等构建出完整的信息。但是,我们可能对于业务信息还是缺乏理解的,毕竟软件的功能可能实现是错的。
软件架构的实现:围绕任务的拆解
在有了充足的信息(大部分时候都是不充足的)之后,我们就需要考虑如何去实现这个功能,所以就有了一系列的架构文档、决策记录等。简单来说,它就是我们针对于这个任务的初步计划。我们需要考虑设计每一部分如何实现,以及需要哪些人员支持等。
拆解完后,在进入开发后,一个功能进而被分解为一系列的需求/用户故事、详细的验收标准。而当开发人员接到一个需求时,就需要考虑(后端为例):
是否需要新的 API,如果不需要要改哪个 API?
API 的输入和输出是什么?
需要调用哪个 Service?
需要实现对应的数据库调用吗?
也就是我们在 AutoDev 中实现的 AutoCRUD 的功能。
AI 辅助的开发范式与思维框架
在有了生成式 AI 的辅助之后,人类的产品经理们,一直在纠结人与 AI 的边界:到底哪些事项应该交由人来实现,哪些应该交由 AI 来实现?
不过,至少大部分人能达成一致:AI 不能为你坐牢。所以呢,人类还得为 AI 生成的内容负责,还得检验 AI 生成的代码是否可靠。
在现有范式增强的 AI 辅助
从个人对于架构设计的理解来说,我会把它划为四个步骤:
分析。即基于上述的协作设计的架构概念达到一致。
设计。生成系统的逻辑架构与物理架构(即部署架构等)。
次序。生成一系列的架构决策以及软件所需要的优先级。
实现。结合技术决策,实现对应的软件架构。
在这几个阶段里,AI 在分析阶段可以帮助我们理解现有系统的设计,帮助我们设计通用的实现步骤。但是,由于我们需要对结果负责,所以并没有那么大的可信度。简单来说,对于精准的内容,还需要由人来把握。
GitHub 的 AI 辅助复杂任务框架
相似的,GitHub 也基于《Social Integration of Artificial Intelligence: Functions, Automation Allocation Logic and Human-Autonomy Trust》构建了自己的 AI 辅助解决复杂问题的思维框架:
构建感知。收集和综合形成任务背景的所有相关信息。
制定决策。提出应该针对这个任务采取的措施 。
制定行动。定义执行任务的具体步骤和步骤的顺序。
实现任务。执行按照定义的顺序进行的步骤。
从 GitHub 对于开发者的调研结果来看:
开发者对于在构建感知和制定行动计划方面,接受 AI 的协助。而对 AI 在制定决策、实现任务方面的自主性持谨慎态度。
那么,我们应该如何去设计 AI 工具的能力。
AutoDev 对于 AI 辅助复杂任务的思考
在探索性的构建 AutoDev 的 AutoCRUD 一个基于特定步骤的 AI Agent 时,我们发现了生成式 AI 并不能很好地处理这种高可靠的场景。所以,转为构建了针对于每个更细小任务的功能辅助。在具备了大量的子任务能力之后,便可以实现转由 AI Agent 来接入和改进。
上下文感知的任务辅助:AutoXXX
在现在 AutoDev 中,我们设计了一系列围绕于实现某一个需要所需要的一系列子任务。即诸如,当你需要写一个 API 时,你需要写文档、 SQL 、单元测试等,由这一系列更小的子任务去完成你的需求。对应的包含功能有:
Code Complete 。自动代码补全
Document。自动编写文档
AutoTest 。自动生成单元测试并运行
AutoPage 。自动生成前端页面
AutoSQL 。自动生成后端 SQL
AutoCRUD 。早期的探索性编码 agent
尽管我们采用的是静态代码分析方式,具备比 GitHub Copilot 更好的上下文能力和架构,但是生成式 AI 并没有能力来确保结果的准确性。
也因此,我们可以达成上述的那个结论:AI 的实现并没有那么靠谱。但是,它依然可以快速帮你完成你的一部分任务。
有限知识的任务分析与行动生成:Tasking
显然与编写代码相比,人们还需要的一类功能是:理解现有的代码。即从一个现有的知识中,萃取出完成任务所需要的信息。而由于,我们是从准确性的代码中生成内容,并且我们对于结果准确性的要求并没有那么高。所以,但是它节省了信息收集的时间,并可以为我们提供了初步的行动建议。
在有了运行建议之后,我们便可以将先前的一系列子任务辅助结合在一起。这就是我们正在设计的AutoDev Tasking 相关的功能。但是,它也不非那么可靠的,如果过去的知识并非语义化的,语义化搜索(RAG)相关的体系会在此失效。
从确实性的结果中,得到一份参考,其接受率往往会更高。s
其它
在 2023 年,从各类的报告中,我们可以看到:AI 工具缺乏设计,导致开发人员准备内容(上下文)的时间过长,进而带来的负的效率提升。而随着工具的进一步成熟,对应的成本会进一步下降。而随着 AI 能力和工具的演进,模式将进一步演进。
微信扫码关注该文公众号作者