大语言模型 AI 辅助编码使用过程体验报告(Github Copilot、Cursor)

编码感受和评估

在过去一周多的时间里,我在 ChatGPT 的协助下,生成了做一个简单编辑器的产品文档、技术方案文档,然后在这个基础上,进行程序的编码。

使用的工具纪要

为了更全面地感受 AI IDE 对研发过程的影响,我特意选择了一个我不太了解的项目,并且以整体形式做下来,从中深度感受 AI IDE 对我们开发过程的影响。

产品文档和技术文档生成的辅助工具:New Bing,The New Bing – Learn More

编程过程使用的编程工具:VScode + Cursor/Coplit,Cursor IDE

涉及的编程语言:JavaScript、CSS、HTML、Python、SQL

涉及的组成部分:前端、后台、数据库、Canvas 相关的图形处理接口

累计耗时:在过去一周多,断断续续地使用了 15 + 小时(包括生成产品和技术方案文档,有不少时间用于排查程序 Bug)。

代码规模:1500行+

个人使用感受记录

使用的第一感受

  1. 产生一种惊喜感,发现用它来做我所不了解的项目,也能对我形成比较大的帮助。

  2. 显著减少了我查询和搜索技术文档的时间,通过对话,能直接完成不少的工作。

  3. 是一种开发模式的变革,虽然现在还存在不足,但是,潜力无限!

关于研发效率

  1. 会有提升,但是比例不会很大,个人感觉 30%左右,因为生成的结果代码仍然需要进一步的详细 review 和测试。

  2. 在 prompt 描述非常详细的情况下,例如登录功能,它生成了详细的异常判断逻辑,这一块的生成非常快。当提供给它的 prompt 比较模糊时,则需要多次互动,而且未必能提供符合我们预期的代码。

关于 IDE 的选择(推荐 Cursor)

非常推荐使用Cursor,它不仅支持对话,而且能够选中指定代码,让它做逻辑修改,它会将修改记录反馈出来,问你是否 accept?并且,能够清晰看见它进行的代码改动。支持精细化控制,使用过程中,个人的强烈感受到,选中的范围越小、越细,它的结果越好,错误也越少。

如下图所示(我让它给button添加样式):

指定具体的函数,让它添加代码注释。

注释添加的结果:

关于它的不足之处(关键阅读项):

  1. 代码规模少的时候,例如只有 1 个文件,100 – 200 行代码时,它生成和修改都比较准确,当代码规模和文件逐渐变多,逻辑变多时,它的生成和修改变得有误,会遇到包括变量未定义、错删代码、没有考虑上下文逻辑等问题。缩小代码的选中范围、让prompt变得更详细能够一定程度上减少问题,但是,仍然会出现。

  2. 生成的代码中,偶尔会含有不存在的、但是命名很通用的样式、函数,它有时会默认认为你的上下文中存在这种“通用”函数,实际上并没有。

  3. 如果我修改的逻辑要同时改动多个文件,该功能并不支持,它目前只支持一个文件一个文件修改。不过,使用对话功能,它能以对话的方式告诉我们要在多个文件里修改代码,此时要我们手动复制和修改代码。

  4. 开发者对开发领域具体问题的认知仍然非常重要,如果开发者在prompt里没有提及,则它生成的代码也不考虑。例如,需要等待img.src的load完成后再重新刷新canvas画布,如果不提及,它的代码就是直接刷新画布,此时由于img并没有load完成,画布刷新的内容是空白的。

  5. 相比于生成文档、注释,程序代码对错误几乎是零容忍度的,一个未定义的变量就可以让整个程序完全终止运行,但是,生成文档有少量错误是不影响文档的阅读的,出版社对著作出版要求错误率达到万分之一。对于一个大规模程序而言,这个要求要高得多。

  6. 根据个人对 NLP 领域 AIGC 的理解,AIGC 本质是根据前文推理下文,模型精度越高,推理越准确,对于代码来说,则要求推理的准确度非常高,后面 2-3 代的 GPT 可能能解决该问题。

  7. 对话中,Cursor反馈结果以英文为主,偶尔才能看见中文。

简要总结:

  1. 短期看,GPT 还远不足以取代程序员,长期看,它的潜力无限,是一种趋势,随着它持续升级和迭代,预计它对研发效率的提升会越来越多。

  2. 我们应当拥抱 AI IDE,构造更详细、逻辑清晰的prompt,充分利用它的能力提升研发效率。

编码过程纪要(部分):

帮我生成一个基于VueJS的登录HTML页面,包含如下逻辑:

  • 前置条件:用户已经注册过账号

  • 后置条件:用户成功登录并进入图片编辑器页面

  • UI描述:见功能原型

  • 流程/子流程/分支流程:

    • 流程:用户在登录页面输入用户名和密码,点击登录按钮

    • 子流程:系统验证用户名和密码是否正确,如果正确,则跳转到图片编辑器页面;如果不正确,则提示“用户名或密码错误,请重新输入”

    • 分支流程:无

  • 与其他子模块的接口:无

  • 业务数据描述:

    • 用户名:由字母、数字、下划线组成,长度为4~16个字符

    • 密码:由字母、数字、特殊符号组成,长度为6~16个字符

  • 边界值处理:

    • 如果用户名或密码为空,则提示“请输入用户名和密码”

    • 如果用户名或密码长度不符合要求,则提示“用户名或密码长度不合法”

修改为引用项目文件夹内的vue.js

登陆界面比较简陋,能帮我美化一下吗?

我想把页面元素居中

页面中的两个input没有对齐,帮我修改CSS

链接数据库操作

写一段Python代码,它的主要逻辑是读取用户表的账号密码,然后判断url请求传入的账号密码是否匹配,并且该python文件能以web服务形式运行。

相关信息:链接MySQL数据库,IP是111.230.249.101,port是20086,库名是editor。

表结构:CREATE TABLE `users` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `username` varchar(16) NOT NULL,

  `password` varchar(32) NOT NULL,

  `register_time` datetime DEFAULT CURRENT_TIMESTAMP,

  PRIMARY KEY (`id`),

  UNIQUE KEY `username` (`username`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

它的表编码为latin1,不正确,修改为utf8

帮我写一个web图片编辑器页面,包含以下功能:

  • 前端使用HTML5的Canvas元素来实现图片编辑功能,Canvas可以支持图片的上传、裁剪、旋转、尺度变换等基本操作,并可以将编辑后的结果导出为一张图片

    • 使用<input type=”file”>元素来让用户选择本地的图片文件,然后使用FileReader对象来读取文件内容,并将其转换为DataURL格式。

    • 使用CanvasRenderingContext2D.drawImage()方法来将DataURL格式的图片绘制到Canvas上,然后使用CanvasRenderingContext2D.getImageData()方法来获取图片的像素数据。

    • 使用CanvasRenderingContext2D.putImageData()方法来修改图片的像素数据,实现裁剪、旋转、尺度变换等操作。

    • 使用HTMLCanvasElement.toDataURL()方法来将修改后的图片转换为DataURL格式,并使用<a download>元素来实现图片的下载功能。

上传或的效果,表现比较差:

修复x 报错

图片上传后,图片展示在canvas里变形了,请修复该问题。画布先定义为 1000*800

(AI 一直没有找到,是人工找出来的)

用div包起来,画布固定到页面的右侧

canvas画布支持上传多个图片,这些图片是共存的,并且,每个图片可以在画布中被移动.

这次它写得比较好,基本上只需要很少的修改就一步到位了。

这是上一条命令:canvas画布支持上传多个图片,这些图片是共存的,并且,每个图片可以在画布中被移动。在上一条命令的基础上,除了支持移动之外,还支持选中图片后的放大和缩小。

它提供的代码犯了一个小错,上下文理解不到位,变量名不对。(人工:手动修正)

在放大缩小问题上,它总是给我加这个事件,这个事件并不是我想要的,我想要的是稿定编辑器的那种效果。

但是,它添加的边框总是不生效,问了它多次,它也回答不出来。

人工发现,代码有 Bug,这句话让边框自动消失了。

比较正常的代码需要保存,AI 有时会把代码改乱,导致之前有的功能消失,例如,多张图片共存的能力。

在编辑器中,支持图片对象的选中和拖动

先问 new bing:基于canvas实现的web编辑器中,要实现选中一张图,出现一个边框,可以拖过拖拉边框实现放大和缩小,html和JS代码要怎么实现?

您好,这是必应。我尝试了一些网上搜索,发现了一些可能对您有用的资源。您可以参考以下链接12,它们提供了一些示例代码和解释,如何使用 HTML5 canvas 实现图片的拖拽和缩放功能。基本思路是:

当选中某个图片时:

  • 在 canvas 上绘制图片,并在图片的四个角绘制可拖拽的锚点。

  • 如果用户按下鼠标左键并拖动一个锚点,就根据锚点的位置调整图片的宽度和高度。

  • 如果用户按下鼠标左键并拖动图片内部,就根据鼠标的移动距离移动图片的位置。

  • 在每次鼠标移动后,重新绘制图片和锚点。

就当前阶段的 AI 而言,还是需要懂得代码,只是自己写的代码量变少了,程序员仍然有其价值。

添加缩放按钮,实现放大和缩小功能

AI 实现了这个功能,但是没有考虑保持图片原来的比例。

修正:

编辑器简单旋转功能开发

增加旋转后,坐标计算错误:

让它纠正,它一直都改不过来,一直错(后来我手动修正)。

创建后端服务代码(Python)

给当前代码增加跨域:放开cess-Control-Allow-Origin,允许跨域访问

from flask import Flask, request, jsonify

app = Flask(__name__)

# Connect to the MySQL database
mydb = mysql.connector.connect(
  host="111.230.249.101",
  port="20086",
  user="root",
  password="hello",
  database="editor"
)

# Define a route for the login page
@app.route('/login')
def login():
  # Get the username and password from the URL request
  username = request.args.get('username')
  password = request.args.get('password')

  # Query the user table for the given username and password
  mycursor = mydb.cursor()
  sql = "SELECT * FROM users WHERE username = %s AND password = %s"
  val = (username, password)
  mycursor.execute(sql, val)
  result = mycursor.fetchone()

  # If the query returns a result, the username and password are valid
  if result:
    response = jsonify({"message": "Login successful"})
    response.headers.add('Access-Control-Allow-Origin', '*')
    return response
  else:
    response = jsonify({"message": "Invalid username or password"})
    response.headers.add('Access-Control-Allow-Origin', '*')
    return response

if __name__ == '__main__':
  app.run()

能统一添加吗?这样每行都添加比较麻烦?

下文中的CORS(app)就实现了统一添加跨域头。

from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

# Connect to the MySQL database
mydb = mysql.connector.connect(
***
)

# Define a route for the login page
@app.route('/login', methods=['POST'])
def login():
  # Get the username and password from the request body
  data = request.json
  username = data['username']
  password = data['password']

  # Query the user table for the given username and password
  mycursor = mydb.cursor()
  sql = "SELECT * FROM users WHERE username = %s AND password = %s"
  val = (username, password)
  mycursor.execute(sql, val)
  result = mycursor.fetchone()

  # If the query returns a result, the username and password are valid
  if result:
    return jsonify({"message": "Login successful"})
  else:
    return jsonify({"message": "Invalid username or password"})

if __name__ == '__main__':
  app.run()

登陆成功后,给HTTP页面中进行set-cookie,设置username为对应的用户名。

当这个阶段,我将编辑器换成了 Cursor

把button的class变成light-button

它直接给我修改了代码:

在JS 代码中给input对象添加样式对象:

最终的效果:

按钮上下添加5 margin:

给按钮添加一个 width = 180 的约束:

给editor.html页面添加一个选中图片变换滤镜的功能

(事实上,没有支持选中图片)

产生了一行不对的代码,刷新的位置不对:

刷新的位置应该跟img当前的位置一致,不能是0,0开始:

存在一些问题:所有图片都变成了滤镜后的颜色

滤镜状态要保存在各个图片内部,而不是统一生效:

它又误删了一些代码,暂时不支持局部接受:

图片全部变灰的 Bug,它自身没能修复,但是,我 review 代码后,知道是因为 Filter 功能状态执行后没有保存对象到图片全局数据,我直接选中对应函数,让它把状态变更更新到数组中,问题终于被解决。

两个不同的prompt:

在 editor.html 中新增一个 Save 按钮,如果发现 cookie 中存在username用户名称,则将当前画布中 images 以username为key全部保存到IndexedDB中,并且支持通过给editor.html 传入username参数来获取存储在IndexedDB力的数据,并且还原到当前画布中。

在 editor.html 中新增一个 Save 按钮,如果发现 cookie 中存在username用户名称,则将当前画布中 images 以username为key全部保存到IndexedDB中,并且支持通过给editor.html 传入username参数来获取存储在IndexedDB力的数据,并且还原到当前画布中。并且,不能有语法错误,并且能够执行,不允许存在未定义的变量引用。

(后者可以规避 request 未定义的问题)

Cursor 生成了一大段代码给我:

它提供的代码执行有问题:

request未定义,报错了

让它修正:

通过username载入后的在画布上的图片对象,无法被选中和移动,请修正。并且,不能有语法错误,并且能够执行,不允许存在未定义的变量引用。

默认情况,无法修正。

载入的图片应该存入到全局的images数组中。

重新梳理描述:

你是一位资深的研发工程师,精通前端、数据库和Canvas相关特性,现在,你要基于当前代码的上下文,完成如下任务:保存画布上的图片元素到IndexedDB,并且方便后续以用户名取回来,还原到画布上。有如下要求:

1. 给editor.html的save按钮绑定一个事件,该事件需要保存全局变量中的images数据和画布内的图片数据。

2. 支持通过给editor.html 传入username参数来获取存储在IndexedDB的数据,并且还原到当前画布中,还原到画布的图片元素能够被移动、选中和执行其他编辑操作。

3. 程序不能有 Bug,要可运行,不能随意大幅度删改原来的存在的代码和影响原来的功能。

这段代码无法把图片在画布中渲染出来:

它建议我添加日志打印代码:

告诉它,仍然没有解决:

继续让我加日志代码:

最终找到问题原因了:image 的 src 尚未完成 load,提前执行了 Canvas 的 redrew

选中对应的函数,让它优化 redrew 的执行时间:

问题获得解决:

下载后的部分成果图:

(在这个过程中有很多交互,没有一一写出来)

版权声明:本文为博主作者:徐汉彬-技术原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/qq_22520587/article/details/131671118

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2024年1月3日
下一篇 2024年1月3日

相关推荐

此站出售,如需请站内私信或者邮箱!