写点什么

谁说 AI 编程工具缺乏记忆和联想能力,简单琐碎的需求完全可以交给它

  • 2023-08-23
    北京
  • 本文字数:5298 字

    阅读完需:约 17 分钟

谁说 AI 编程工具缺乏记忆和联想能力,简单琐碎的需求完全可以交给它

活动推荐: #生成式 AI 先锋开发者集结令 #

免费体验编程神器,丰厚大奖等你来拿!👉🏻👉🏻https://jinshuju.net/f/rVuKYa


今年算是 AI 正式破圈的一年,无数的工具,产品横空出世。无论在面向企业的大语言模型,还是帮助个人的 AI 工具,数不胜数。其中关于 AI 编程助手领域,近年来也涌现了很多不错的产品,例如 Copilot, Cursor, 还是我们今天要体验的 CodeWhisperer。已经在潜移默化中改变了程序员们的生产和解决问题的方式,传统解决问题往往依靠的是谷歌等搜索引擎,找到对应的官网和知名的论坛查找问题。而如今,我们仅仅依靠 AI 编程助手就能解决很多问题。


回到 CodeWhisperer 上来,它的出生还是带着许多光环的。首先来自著名的大厂 Amazon, 他们在 AI 领域有足够多的积累,在面向开发者方面有足够多的经验和产品用户体验来反馈用户感受,不断迭代相关产品,而且还有一个相当强大的优势,借助亚马逊云的力量,能够将 AI 和云打通,这在当前云原生时代是必不可少的能力。


目标及前期准备


先给大家讲讲今天我们希望实现的目标,基于 Spring Boot 框架,简单实现用户登陆,。我们使用的是 IntelliJ 开发工具,选用 Maven 进行管理依赖管理,用到的依赖如下。


  • Web

  • JPA

  • H2


我们首先尝试安装 CodeWhisperer 插件,在 Plugins 中搜索 AWS Toolkit 下载即可。



下载完成后绑定自己的亚马逊账号即可开始使用,默认开启自动建议。


项目结构如图所示


pom.xml 文件如下

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">	<modelVersion>4.0.0</modelVersion>	<parent>		<groupId>org.springframework.boot</groupId>		<artifactId>spring-boot-starter-parent</artifactId>		<version>3.1.0</version>		<relativePath/> <!-- lookup parent from repository -->	</parent>	<groupId>com.example</groupId>	<artifactId>demo</artifactId>	<version>0.0.1-SNAPSHOT</version>	<name>demo</name>	<description>demo</description>	<properties>		<java.version>17</java.version>	</properties>	<dependencies>		<dependency>			<groupId>org.springframework.boot</groupId>			<artifactId>spring-boot-starter-data-jpa</artifactId>		</dependency>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
</project>
复制代码


开始


  • 健康检查

我们先实现一个最简单的 Controller,请求 /ping 返回 pong 即可。


package com.example.demo.controller;
import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;
@Controllerpublic class PingController {
@RequestMapping("/ping") public @ResponseBody String greeting() { return "pong"; }
}
复制代码


测试用例是检验代码正确性必不可少的一环,我们来写个简单的测试用例。这时 CodeWhisperer 已经开始展示它的实力了,只是写了一行 @Test 注解,它将我们想要做的测试代码完整提示出来。



下面是完整的测试代码。

package com.example.demo;
import com.example.demo.controller.PingController;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@AutoConfigureMockMvc@WebMvcTest(PingController.class)public class TestWebApplication { @Autowired private MockMvc mockMvc;
@Test public void shouldReturnDefaultMessage() throws Exception { this.mockMvc.perform(get("/ping")).andDo(print()).andExpect(status().isOk()) .andExpect(content().string("pong")); }}
复制代码


运行一下测试用例,很顺利的通过🎉。



  • 用户类设计


我们来定一个 User 模型,发现它在 Table To Class 的实现中具备一定的表设计能力,以及字段关联联想,约束设计能力。




能推测我想要的表字段,索引约束建议。这对于新手来说是莫大的帮助,想象有一位功力深厚的同伴在旁指点你设计表结构,那么表结构的设计就能相对合理一些。

package com.example.demo.model;

import jakarta.persistence.*;import lombok.AllArgsConstructor;import lombok.Getter;import lombok.NoArgsConstructor;import lombok.Setter;import org.springframework.stereotype.Indexed;
@Entity@Getter@Setter@AllArgsConstructor@NoArgsConstructor@Table(name = "game_users")public class User { @Id private Long id; @Column(unique = true, nullable = false) private String username; @Column(nullable = false, length = 64) private String password; @Column(unique = true, nullable = false) private String email;}
复制代码


  • DAO 层实现


这时我灵光一现,根据官网的 GIF 图展示,可以通过注释进行代码推断,那好,DAO 层的实现就交给它啦。


哎哟,不错哦,根据我上面想要根据邮箱查询用户的注视,它已经给出了相应的提示,让我们再考考它,注释中进行多个方法的描述。



挺聪明呀,也很顺利的实现了。


package com.example.demo.dao;
import com.example.demo.model.User;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repositorypublic interface UserDao extends JpaRepository<User, Long> { // function to implement find user by email Optional<User> findByEmail(String email);
Optional<User> findByUsername(String username);
// two function to implement find user by id or email Optional<User> findById(Long id); Optional<User> findByEmailIgnoreCase(String email);
// function to implement check user is existed Boolean existsByEmail(String email);
}
复制代码


看来以后 CRUDDAO 层实现可以交给它来完成啦。我们希望能够预先插入一些数据便于测试,琐碎的日志测试对它来说轻轻松松。



package com.example.demo;
import com.example.demo.dao.UserDao;import com.example.demo.model.User;import org.slf4j.Logger;import org.springframework.boot.CommandLineRunner;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;
@Configurationclass LoadDatabase { public static final Logger log = org.slf4j.LoggerFactory.getLogger(LoadDatabase.class);
// this is Bean is loaded once in the application context // it is used to load the data into the database @Bean public CommandLineRunner initDatabase(UserDao dao) { return args -> { log.info("Preloading " + dao.save(new User(1L, "test1", "111111", "abc@gmail.com"))); log.info("Preloading " + dao.save(new User(2L, "test2", "222222", "123@gmail.com"))); }; }}
复制代码


  • Service 层实现


轮到 Service 层了,让我们看看它的表现,在这里我们简单的根据用户名查询用户,返回对应的数据即可。当我方法签名写一半时,它给我的建议让我停下继续敲击的手指,因为基本符合我的预期,而且具备一定的记忆联想能力,在 DAO 层定义的 Optional<User>,这里也能找到对应的方法进行处理。



package com.example.demo.service;
import com.example.demo.dao.UserDao;import com.example.demo.model.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;
import java.util.Optional;
@Servicepublic class UserDetailServiceImpl { private final UserDao userdao;
@Autowired public UserDetailServiceImpl(UserDao userdao) { this.userdao = userdao; }
public User getUserByUsername(String username) throws Exception { Optional<User> user = userdao.findByUsername(username); if (user.isPresent()) { return user.get(); } else { throw new Exception("User not found"); } }}
复制代码


  • Controller 层实现


最后我们来实现最外层入口,简单的进行相关业务校验,用户名是否为空,密码是否正确,在这里用于演示。



用户不存在相关处理,密码正确性验证,基本符合我们的要求。


package com.example.demo.controller;
import com.example.demo.model.User;import com.example.demo.service.UserDetailServiceImpl;import org.apache.coyote.Response;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.*;
@RestController@RequestMapping("/api/auth")public class UserController { private final UserDetailServiceImpl userDetailService;
@Autowired public UserController(UserDetailServiceImpl userDetailService) { this.userDetailService = userDetailService; }
@PostMapping("/login") public ResponseEntity<?> login(@RequestBody User user) { try { if (user.getUsername().isEmpty()) { return ResponseEntity.badRequest().body("user name is empty"); }
User res; res = userDetailService.getUserByUsername(user.getUsername()); if (res == null) { return ResponseEntity.badRequest().body("user not found"); }
if (res.getPassword().equals(user.getPassword())) { return ResponseEntity.ok(res); } return new ResponseEntity<>("user password invalid", HttpStatus.BAD_REQUEST); } catch (Exception e) { return ResponseEntity.notFound().build(); } }}
复制代码


最后我们来测试一下,格式错误和用户密码错误的情况。



与预期一致,撒花。

总结


CodeWhisperer 就我今天的使用而言,还是有些出乎我的意料,之前的一些 AI 编程工具并不具备记忆和联想能力,今天 CodeWhisperer 展示的记忆联想效果不错,并且具备一定的表结构设计能力,一些简单的测试用例完成度也不错,我想未来一些简单琐碎的需求,测试用例也可以交给它了。但是今天在体验的过程中还是发现了一些不足,插件 UI 会出现挡住建议的情况,这样我需要再次触发建议才行,目前阶段可以使用它来投入生产,在一些复杂的场景还是需要谨慎,会出现胡言乱语的情况,跟上下文关联性不强的建议。


当然,这些问题相信随着模型的数据量级和质量不断优化能够慢慢解决🎉。


版权声明: 本文为 InfoQ 作者【天黑黑】的原创文章。

原文链接:【https://xie.infoq.cn/article/179127e04fff483aac667444d】。文章转载请联系作者。

2023-08-23 10:564277

评论

发布
暂无评论
发现更多内容

2025杭州国际智能建筑展览会

AIOTE智博会

智能楼宇展 智能楼宇展会 智能楼宇展览会 智能楼宇博览会

京东平台内容合规的技术与挑战

京东科技开发者

流程挖掘价值实现的加速器!望繁信科技全链路解决方案惊艳刷屏

望繁信科技

数字化转型 流程挖掘 流程资产 流程智能 望繁信科技

一种PyInstaller中优雅的控制包大小的方法

不在线第一只蜗牛

Java JavaScript 数据库

影子测试:软件测试的创新策略

FunTester

高效整理,创造灵活工作空间——iCollections for Mac 🚀🌟

柠檬与橘子

如何通过关键词搜索API接口,淘宝商品关键词搜索电商API接口揭秘

联讯数据

智谱开源 CogVideoX-5B 视频生成模型,RTX 3060 显卡可运行;曝 OpenAI 模型「草莓」今秋推出

声网

Java元注解介绍

不在线第一只蜗牛

Java

再获殊荣 | 澳鹏Appen获评2024全球数据标注领域Top领军者

澳鹏Appen

数据标注

Proxyless的多活流量和微服务治理

京东科技开发者

视频审核架构实践

京东科技开发者

OgPhone海外云手机是什么

Ogcloud

云手机 海外云手机 tiktok云手机 云手机海外版 海外社媒运营

淘宝商品详情API返回值中的商品材质与成分

技术冰糖葫芦

API Explorer API 测试 API 策略 pinduoduo API

今日分享丨微服务架构下查询数据缓存策略

inBuilder低代码平台

微服务 数据缓存

清华大学ChatGLM大模型

霍格沃兹测试开发学社

SD-WAN组网部署需要多久?

Ogcloud

SD-WAN 企业组网 SD-WAN组网 SD-WAN服务商 SDWAN

openGauss- 智能基数估计

Gauss松鼠会

opengauss

聚焦 AI 加持下泛娱乐场景的技术革新|RTE Plus 声网城市沙龙杭州站

声网

从零开始带你玩转 AI 变现公开课

霍格沃兹测试开发学社

独享代理IP有哪些优势?

IPIDEA全球HTTP

BSC发力DEX交易量超过Solana,MEME赛道王者易主?

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

关于告警,要想做好,从这些方面着手

巴辉特

告警降噪 oncall 告警聚合 告警排班 PagerDuty

感谢 Fluent Editor 开源富文本首位贡献者!

OpenTiny社区

富文本 OpenTiny 开源前端

AI引领,驱动未来:零售企业的新质生产力革命

第七在线

谁说 AI 编程工具缺乏记忆和联想能力,简单琐碎的需求完全可以交给它_亚马逊云科技_天黑黑_InfoQ精选文章