场景驱动的 AI 体验设计:如何让智能 IDE 赋能遗留系统重写

作为 AutoDev 的核心开发,我们不仅在不断丰富 AutoDev 的功能以满足不同公司的定制需求,还在与各种团队进行持续交流。在处理遗留系统时,我们发现程序员们日常工作中需要面对大量使用过时技术、基础设施混乱的系统。

在这个背景下,探索如何利用人工智能增强这些系统的演进成为一项极富挑战性的任务。毕竟,大佬们都说:所有的应用都要重写一遍

PS:当然了,大佬也在说:未来不会有应用~~。

为什么场景驱动

fa1fade23bf3292dff6d0e18ca3ef563.png

Thoughtworks 与其他大多数模型厂商不同,一直在探索最佳的编程实践。因此,在 AutoDev 中,我们考虑融入各种实践,而不仅仅是代码生成。我们在设计功能时一直关注不同的场景,以满足不同场景的需求。

在有了大模型加持之后,AI + IDE 有了更多的可能性:

  • 代码增强。即让 AI 来加快开发人员的日常编码速度,诸如代码补全、生成文档、生成测试等等。

  • 普通活动增强。即让 AI 来修复错误、生成提交信息、进行代码检视等等。

  • 融入其他活动。即以 IDE 为媒介,持续将其他的开发活动集成到 IDE 中,诸如文档查询、API 接入等等。

而这些都是基于能力所设计的,位于其背后其实包含了一系列的场景:编码、调试、测试、联调等等,每个场景背后都需要不同的功能来连动,以完成连贯的场景体验。

这就意味着,我们需要能够更好地:理解和适应开发者在不同场景时面临的复杂情境,并提供更智能、个性化的开发体验。诸如于,在遗留系统场景下,它通常具有复杂的代码结构和多语言混合使用,往往需要由人来分析和指令,让 AI 做一些繁琐和重复的工作。

场景:遗留系统改造

对于编码和其它场景,在我先前的《上下文工程:基于 Github Copilot 的实时能力分析与思考》 等文档,以及 NJSD 大会的《从个人到组织, AIGC技术的工程化落地》上的分享里,已经做了详细的介绍。而作为一个开发团队,我们每天不可能有大量的新增代码,大部分人还是工作在遗留系统上 —— 一个你可能不知道某个功能、某块业务是如何实现的?

生成式 AI 增强 :“遗留系统改造”

c0777c9a5a8066b82d5cd9752b5ca226.png

在我开源的那本《系统重构与迁移指南》(https://github.com/phodal/migration,stars:3.3k)电子里,详细介绍了如何分析、评估现有系统、制定重构策略、探索可行重构方案等一系列的遗留系统重写与重构模式。

基于经典的遗留系统重构范式,在代码层面我们要做这么一些事情:

  • 建立评估与度量

  • 搭建测试防护网

  • 重新设计系统架构。诸如于 DDD 用于改善模块化架构

  • 业务提取与服务重构。

  • 进行细粒度的重构。诸如于代码等等

而在有了生成式 AI 之后,在我们做完了顶层设计之后,它可以大大加速我们的落地实践。

创意阶段:增强环节分析

基于这个场景之下,我们就需要思考哪些功能可以借助生成式 AI 来辅助。如下我们是会在头脑风暴时产生的一些想法:

  • 改造方案设计。即通过聊天的方式,获得一些创意式的输入,以帮助我们更好地编写解决方案。

  • 测试防护网搭建。根据系统的复杂度,需要创建不同维度的测试数据、测试用例等。

  • 系统架构设计。即通过聊天的方式,获得一些创意式的输入,以知道什么是更好的架构。

  • 业务信息提取。即通过文档生成、调用链分析等方式,分析某一个 API 的业务与实现逻辑。

  • 基础设施重写。诸如 Maven 迁移到 Gradle,上云基础设施改造(Dockerfile 生成 等)。

  • 代码重写。适用于语言翻译(如 js 转换 ts)、逻辑优化等场景。

  • 文档重新生成。即针对于现有的旧文档,重新生成一份新的文档。

  • ……

除了,这些通用的功能之后,事实上还存在大量的复杂场景,诸如于:

  • 存储过程代码的分析与迁移。

  • 复杂构建脚本的迁移。

  • 领域特定语言的重写。

根据不同的场景,我们都需要有选择地进行设计和强化。但是,显然我们可以看到生成式 AI 可以大大加速这一过程。

端到端定制方案

18d139c6e2ff7f439feccefad7d571d6.png

而对于更复杂的场景而言,我们则需要构建专有的工具来实现这个过程。诸如于 IBM 在设计针对于 COBOL 语言迁移时,将重构过程分为了三大阶段:

  • 理解。即理解 COBOL 代码中的代码、数据、依赖部分,采用诸如可视化等方式设计。

  • 重构。将已有的 COBOL 代码解耦,并重构为模块化的方式。

  • 转换。将模块化的代码翻译为 Java 代码。

而过程中,还需要针对于已有的业务编写对应的 Java 测试代码,以方便进行手动和自动化的验证。

AI 如何增强遗留系统改造?

在对遗留系统进行改造时,智能 IDE 的升级将是一个关键因素。然而,如何将新功能转化为易于操作和高效的组件,以及如何在不同场景中提供最佳的用户体验,是一项具有挑战性的任务。

在功能与场景的设计中,我们需要回答一些关键问题:

  1. 何时开发新功能? 确定新功能的开发时机,使其与遗留系统的改造需求相匹配。

  2. 何时开放定制化能力? 确定定制化的灵活性在哪些场景下是必要的,以满足用户的个性化需求。

  3. 何时交由开发人员决定? 确定哪些场景下,完全交由开发人员决定,以保持系统的灵活性。

并且,我们还应该确保这些功能应该是方便使用的。当然了,最简单的方式就是完全开放这种定制能力。基于这些思考,以我们开源 AutoDev 插件为例来介绍。

如何验证生成的代码?

a12a7a99ec485e3f78ea3af87ffbef48.png

在引入 AIGC 来生成代码时,都需要考虑的一个点是:如何验证生成代码的准确性?。这是一个复杂的问题,通常来说,应该是再由人去验证一遍的,但是有各种取巧的方式。诸如:

  1. 结合人工智能进行检查: 利用人工智能辅助验证生成的代码,提高验证效率。

  2. 生成测试以验证业务代码: 通过生成测试用例,确保生成的代码在业务场景中的正确性。

  3. 基于测试用例文档生成单元测试: 利用测试用例文档生成单元测试,使验证过程更加规范化。

当然了,这些都是规范化的团队所做的事情,实在不行就如我们在 Unit Mesh 架构所说的,由人来验证 AI 生成的代码。而在进行遗留系统改造时,有时这个问题就显得比较简单了 —— 只需要验证输入和输出,诸如于 Http API 的输入和输出。

所以,对应到功能上,只需要一键生成测试或者生成测试的方式,也就可以分为专有和自定义能力。

完成自定义:自定义语言转换    

e75b0795d9f3f06fde1a0fb0e8d37a5a.png

自定义是三种模式里最懒的方案,然而也是在实现上最复杂的,采用何种的交互方式,如何提供这一类灵活的接口。

作为工具的设计者,其实我们是无法枚举语言间的转换,常用的语言都有十几个,他们之间可以随意转换。这也就是最开始的是一个自定义 Action(https://ide.unitmesh.cc/custom/action),让开发人员可以通过 JSON 来配置这种转换:

{
"title": " Translate to Kotlin",
"autoInvoke": false,
"matchRegex": ".*",
"priority": 0,
"template": "将如下的代码翻译为 Kotlin.\n${SIMILAR_CHUNK}\nCompare these snippets:\n${METHOD_INPUT_OUTPUT}\n原始代码如下:\n${SELECTION}"
}

并将相似的代码块 ${SIMILAR_CHUNK} 和函数的输入和输出 {METHOD_INPUT_OUTPUT} 作为上下文的一部分。

部分定制:活文档生成

b27627ae6a01e708c23b7a363d1ff837.png

开放定制是三种模式最复杂的,如何去平衡应该由程序的某一部分来完成,这并不是一件容易的事情。并且也有可能,它会变成一种不三不四的方案。

对于复杂的遗留系统来说,我们还需要理解现有的业务,需要了解业务的各种信息。而我们所推荐的一种方式就是活文档。活文档的方式有多种多样的,在代码中一种比较简单的实现方式就是通过注解。

而由于注释本身就是文档,所以活文档的功能在实现时是与注释生成一起的,其自定义方式如下:

{
"title": "Living Documentation",
"prompt": "编写 Living Documentation。按如下的格式返回:",
"start": "",
"end": "",
"type": "annotated",
"example": {
"question": "public BookMeetingRoomResponse bookMeetingRoom(@RequestBody BookMeetingRoomRequest request) {\n        MeetingRoom meetingRoom = meetingRoomService.bookMeetingRoom(request.getMeetingRoomId());\n        BookMeetingRoomResponse response = new BookMeetingRoomResponse();\n        BeanUtils.copyProperties(meetingRoom, response);\n        return response;\n    }",
"answer": "    @ScenarioDescription(\n        given = \"there is a meeting room available with ID 123\",\n        when = \"a user books the meeting room with ID 123\",\n        then = \"the booking response should contain the details of the booked meeting room\"\n    )"
}
}

这里的 example 是为 LLM 提供一个示例,以更符合生成的结果。从实现上,远比先前的完成自定义复杂得多。

专有的新特性:API 测试数据生成

专有特性是三种模式中最简单的,也是最不对用户负责的。我们直接将功能放入到了系统中,用户的系统菜单和交互变得异常臃肿。

在实现上,也只需要根据这些场景做一些简单的接口和实现即可。

总结

开发一个 AI 原生应用并不是一件简单的事。我们应该思考:如何将生成式 AI 应用对更有价值的日常活动中?我们应该思考:如何将更多的自主性和决定权交由用户?

如果你也有兴趣来探索,欢迎来 AutoDev 探索:https://github.com/unit-mesh/auto-dev 。


AutoDev 功能全景

76415c939d6a6f5c8d41ee984c6529b6.png

Unit Mesh 开源项目全景(https://github.com/unit-mesh/)

a6b073db220c60448f646a41bdf2c883.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/156924.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode:20. 有效的括号

一、题目: 链接:20. 有效的括号 - 力扣(LeetCode) 函数原型:bool isValid(char* s) 二、思路: 利用栈来解这道题会方便许多: 遍历字符串s,当遇到左括号就将其压入栈中;遇…

局域网无法上网主机通过TinyProxy代理主机访问公网Internet

1.代理主机搭建: 系统:ubuntu 网卡:2个 运行于 VMWare上 第一个网卡用于NAT 第二个网卡用于私有网络 两个IP如下: 192.168.31.243为NAT可访问Internet 192.168.144.141属于私有网络,用于访问局域网 安装tinyproxy sudo apt install tinyproxy 查看服务状态

webAPI serial——串口连称

重点 关闭正在读的串口 借鉴文章:webapi串口 async closeport() {this.$emit("changeSerialStatus", false);//这里要注意,一定要关闭读取this.status false;//取消后,done会变成true,会执行reader.releaseLock();this.reader.c…

git常常用命令

这篇文章中,一些简单的,大家都知道的git 命令我就不再赘述,我只写出来最近在项目中常用到的一些命令。这些命令可以帮助我更好的开发。 git stash 请大家设想下面的场景,你的本地有两个分支,develop,fix分支&#xf…

禁止linux shell 终端显示完整工作路径,如何让linux bash终端不显示当前工作路径

在操作linux时,默认安装的linux终端会显示当前完整的工作目录,如果目录比较短还是可以接收,如果目录比较长,就显得比较别扭,操作起来不方便,因此需要关闭这种功能。 要关闭这个功能,请按如下步骤…

智能座舱架构与芯片- (11) 软件篇 上

一、智能汽车基础软件平台分类 汽车软件主要分为应用软件和基础软件。应用软件和业务形态高度关联,不同控制器的应用软件之间差异较大。基础软件介于应用软件和硬件之间,用于屏蔽硬件特性、支撑应用软件。可有效地实现应用软件与硬件之间解耦&#xff0…

ky10 server x86 安装、更新openssl3.1.4(在线编译安装、离线安装)

查看openssl版本 openssl version 离线编译安装升级 #!/bin/shOPENSSLVER3.1.4OPENSSL_Vopenssl versionecho "当前OpenSSL 版本 ${OPENSSL_V}" #------------------------------------------------ #wget https://www.openssl.org/source/openssl-3.1.4.tar.gzech…

【Python】学习Python面向对象编程的疑问

(Java菜鸟来学Python了) 🤔 1. 静态方法与类方法什么区别? 实例方法只能被实例对象调用(Python3 中,如果类调用实例方法,需要显示的传self, 也就是实例对象自己),静态方法(由staticmethod装饰…

LangChain 6根据图片生成推广文案HuggingFace中的image-caption模型

根据图片生成推广文案, 用的HuggingFace中的image-caption模型 LangChain 实现给动物取名字,LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字LangChain 3使用Agent访问Wikipedia和llm-math计算狗的平均年龄LangChain 4用向量数…

STM32 寄存器配置笔记——系统时钟配置 HSE as PLL

一、概述 本文主要介绍使用HSE高速外部时钟通过PLL倍频输出72MHZ的时钟作为系统时钟。下图为时钟树。 使用正点原子的开发板调试OSC_IN、OSC_OUT接的是8MHZ的晶振即为HSE时钟。 二、配置流程 1)复位RCC相关的所有寄存器 复位内容是参考正点原子例程,按照…

云计算:开辟数字时代的无限可能

云计算是一项革命性的技术,为企业和个人提供了灵活、可扩展和高效的计算资源。本文将介绍云计算的概念、架构和优势,并探讨其在数字化时代的重要性和未来发展趋势。 引言 随着信息技术的日新月异和数字化转型的浪潮席卷全球,云计算作为一种颠…

多元函数奇偶性

多元函数奇偶性 多元函数的定义域 定义域根据函数的变量数不同,有不同的形式 一元函数 y f ( x ) yf(x) yf(x),定义域可以是数集二元函数 z f ( x , y ) zf(x,y) zf(x,y),定义域可以是一平面区域,是平面点集三元函数 v f ( x , y , z ) vf(x,y,z) vf(x,y,z),定义域是一块空…

ZYNQ_project:lcd_pic_400x400

在lcd液晶屏上显示400x400像素的图片, 像素信息通过电脑的串口调试助手,发送给fpga,存储在例化的双端口ram中, 在要显示图像区域,读取ram中的像素信息。 模块框图: 时序图: 代码:…

O-Star|再相识

暑去秋来,岁月如梭,几名"O-Star"们已经入职一段时间,在这期间他们褪去青涩,逐渐适应了公司的工作环境和文化,迈向沉稳~ 为了进一步加深校招生之间的交流与了解,提高校招生的凝聚力和…

gitlab

Gitlab 安装git yum安装 [rootgit ~]# yum -y install git编译安装 Git官网 #安装依赖关系 [rootgit ~]# yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel autoconf gcc perl-ExtUtils-MakeMaker # 编译安装 [rootgit ~]# tar -zxf git-2.0…

基于 Eureka 的 Ribbon 负载均衡实现原理【SpringCloud 源码分析】

目录 一、前言 二、源码分析 三、负载均衡策略 一、前言 如下图,我们在 orderserver 中通过 restTemplate 向 usersever 发起 http 请求,在服务拉取的时候,主机名 localhost 是用服务名 userserver 代替的,那么该 url 是一个可…

Java动态代理JKD版本

1、ISale.java package com.atguigu; public interface ISale {void saleShaoBing();void saleJianBing();void saleYueBing();void saleManTou(); }2、WuDa.java package com.atguigu;//Target:目标类、目标对象 public class WuDa implements ISale{//target method:目标方法…

DAY60 84.柱状图中最大的矩形

84.柱状图中最大的矩形 题目要求:给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 思路 单调栈 本地单调栈的解法和接雨水的题目是遥相呼…

git -1

1.创建第一个仓库并配置local用户信息 git config git config --global 对当前用户所有仓库有效 git config --system 对系统所有登录的用户有效 git config --local 只对某个仓库有效 git config --list 显示配置 git config --list --global 所有仓库 git config --list…

微信小程序 prettier 格式化

一、安装prettier插件 二、打开设置 然后再打开setting.json 新增代码 {"editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","prettier.documentSelectors": ["**/*.wxml", "**/*.wx…