はじめに
こんにちは!2024年度新入社員の松澤武志です!
実はこの度 AWS AI Practitioner試験を受験することにしました!(実はブログ執筆時点では5日前…ブログ書いている暇ないかも)
そこで、AWS SageMakerやAmazon Bedrockなど、生成AIや機械学習にまつわるAWSサービスについて勉強していて、その中でもAmazon Qにとても興味を持ちました!そこで、今回はAmazon Qを用いてアプリケーションを構築してみることにしました。
Amazon Q とは
どのようなサービスかといいますと、対話型の生成AIサービスです。なんだn番煎じか~と思ったそこのあなた、いや全然違うんです。もちろんプロンプトに入力した質問を生成AIが返してくれるという点では同じですが、ビジネスという観点において、Amazon Qは物凄く力を発揮します。
Amazon QはBusinessとDeveloperに大別され、それぞれ業務を手助けしてくれるサービスです。この記事ではAmazon Q Developerを用いてアプリケーションを作成していきます。
↓Amazon Qの説明動画です!
Amazon Q Business
こちらは、その名前の通りビジネス向けのサービスとなっています。生成AIを活用したアシスタントで、企業のシステム内のデータや情報に基づいて、質問への回答・要約の提供・コンテンツの生成・タスクの安全な実行を行えます。 中でも特に注目するべきポイントは2点あります。
- エンタープライズ内のデータや情報に基づいて、質問することができます
ex) 「明日のミーティングは何時から」→「13時からです」みたいに答えてくれます。
AWSの情報を学習した結果はもちろん、JiraやConfluence等のサードパーティ製のアプリケーションから会社の情報を学習した結果も併せて答えてくれます。 - アプリケーションを作ってくれます
ex) プロンプトに「新規チケットを連携するアプリケーションを作って」と入力すると、Amazon Q Appsの中にアプリケーションが生成されます。
Amazon Q Appsという専用のアプリの中限定ですが、コード補完とかすっとばしてアプリケーションを作れます。
Amazon Q Develper
Developerはその文字の通り、開発におけるあらゆるタスクをサポートすることができます。
- アプリケーションのコーディング
- テスト
- レガシーなコード等のアップグレード
- エラー診断
- セキュリティスキャン
- AWSリソースの最適化
とてもいろんなことができて便利ですね~。
VSCodeやJetBrains社のIDE等にもプラグインとしてインストールすることができます。
エンジニアの「あったらいいな」を具現化したサービスなのではないでしょうか。
こちらのAmazon Q Developerですが、他のサービスと同様にお金のかからない無料利用枠と、有料で様々なサービスを受けることができるAmazon Q Developer Proが存在します。今回は無料利用枠の範囲で使ってみようと思います。
公式ページによると、
無料利用枠ではソフトウェア開発のための Amazon Q Developer Agentの場合、1ヶ月あたり5回呼び出すことができます。 (Proの場合は、1か月あたり30回呼び出すことができます) コード変換のための Amazon Q Developer Agent の場合、1,000 行のコード/月を無料で変換してくれます。
とのことですので、後述する/dev
コマンドは月に5回使用できることになります。
Amazon Q Developerの使い方
Amazon Q Developerは、プロンプトに入力するときに以下の4つのコマンドを指定します。
/dev
:コードやファイルを生成してくれます。今回メインで使用するコマンドです。/transform
:古いバージョンのコードをアップグレードさせたりなど、コードを変換してくれます。/help
:Amazon Qに関するヘルプコマンドです。/clear
:セッションを切断します。
また、別途Explain selected code
などの一般的な質問も用意されており、ワンタッチで質問に回答してくれます。
執筆時はまだAmazon Q Developerは日本語に対応していないため、別途翻訳ツールを使用して英語に変換してからプロンプトに入力するものとします。
事前準備
Amazon Qプラグインのインストール
任意のエディタやIDEのプラグインでAmazon Q を選択し、インストールします。公式ページからもインストール可能です。今回はJetBrains社のIntelliJにインストールします。
エディタやIDEのAmazon Qタブをクリックすると、「Amazon Q Chat」というチャット欄が出現します。こちらのsign-in optionを選択するとAWSの認証画面に遷移するので、そこでログインすればAmazon Qを使用できます。
Spring InitializerでSpring Bootアプリケーションの作成
まず初めにプロジェクトを作成します。
今回は無料利用枠のコード生成コマンド5回使用以内にとどめるために下記の方針で進めます。
- UI上で「Hello World」を表示させる簡単なアプリケーションを作成
- 余った質問でAPIを作成
Amazon Q DeveloperはIntelliJ上ではプロジェクトに入らないと使用できないので、とりあえずSpring Initializerで(amazonq)という名前のSpring Boot Applicationプロジェクトを作成します。Initializerの設定は以下のようにしましたが、今回の論旨から外れるため説明は省略します。
こちらの設定でSpring Boot Applicationプロジェクトを作成することができました!
別途SDKにAmazon Corretto17を指定したりしました。
しかし、このままではControllerがないので、Whitelabel Error Pageが表示されてしまいます。
※ ページ表示時の環境によりポート番号が8081となっています。
いざ使ってみよう!
1. HelloWorldを表示させて
まず初めにHello Worldを表示させるコントローラーを作成します。したがって、以下の文章を入力しました。
HelloWorldを表示させるコントローラーを作成してください
プロンプトに入力すると、体感1分ほど経過した後に、Amazon Qがコードを生成してくれます!
今回のAmazon Qからの返信は以下の通りです。
Generating code ... I'll share updates here as I work on this. **Summary of changes** 1. Need to check content of "AmazonqApplication.java" first and then create a new controller class. 2. I need to create a new controller class to handle the HTTP request and return "HelloWorld!" as the response. I'll create a new HelloWorldController.java file in the appropriate package structure. 3. I have successfully created a HelloWorldController with a GET endpoint at "/hello" that returns "HelloWorld!" as requested. The Spring Boot application will automatically detect and register this controller. **Files used** *These fields can change throughout code generation* - Reviewed: 1 - src\main\java\com\amazon\amazonq\AmazonqApplication.java - Created: 1 - src/main/java/com/amazon/amazonq/controller/HelloWorldController.java - Changed: 0 - Deleted: 0
HelloWorldController.java
を生成してくれました。
package com.amazon.amazonq.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloWorldController { @GetMapping("/hello") public String sayHello() { return "HelloWorld!"; } }
コントローラーを作成したので▶ボタンでAmazonQApplicationを実行して
いざ実行!
しかし起動しませんでした…
2. 起動方法を教えて
次に起動方法を教えてもらうためにプロンプトに下記を入力しました。
このアプリケーションを起動させてください
そうすると、起動はしてもらえませんでしたが代わりにAction.md
に起動方法を記載してくれました。
アプリケーションの実装構成にかかわらずとも、説明書を生成してくれるんですね~。
Action.md
# How to Activate the Application This is a Spring Boot application that can be activated using Gradle. Follow these steps to run the application: 1. Open a terminal in the project root directory 2. Run the application using the Gradle wrapper: - On Windows: `.\gradlew.bat bootRun` - On Linux/Mac: `./gradlew bootRun` The application will start and be accessible through: - The default Spring Boot port (8080) - You can test it by accessing `http://localhost:8080` in your web browser Note: Make sure you have Java installed on your system before running the application.
こちらによると、ターミナルで.\gradlew.bat bootRun
を実行すれば実行できるとのことです。▶の実行ボタンとは違う起動方法を教えてくれました。
いざ実行!
してみましたが、まだ起動しませんでした…
エラーを見るとorg.springframework.boot.docker.compose.core.DockerProcessStartException: Unable to start docker process. Is docker correctly installed?
とありました。
そういえばDockerを起動していませんでしたので、デフォルトのcompose.yaml
を参照すると、services:
しか記載されていませんでした。
3. compose.yamlを追記して
次に、compose.yaml
にコンテナのポート番号等を記載してもらうために、プロンプトに下記を入力しました。
このアプリケーションをlocalhost:8080で起動させるために必要なコンテナを起動させる情報をcompose.yamlに記載してください
すると、compose.yaml
が下記のように修正されました。
services: app: build: . ports: - "8080:8080" environment: - SERVER_PORT=8080
Dockerイメージをビルドするためにdocker-compose -f compose.yaml build
をターミナルに入力したのですが、またもやエラーとなってしまいました…
私の事前知識不足でもあるのですが、Dockerイメージを出力するためにはDockerfile
が必要でした。
4. Dockerファイルを作成して
次に、Dockerfile
を作成してもらうために、プロンプトに下記を入力しました。
Dockerファイルを作成し、compose.ymlでDockerファイルを指定してください
すると、新規のDockerfile
が作成されました!
FROM eclipse-temurin:17-jdk-alpine WORKDIR /app COPY build/libs/*.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "/app/app.jar"]
docker-compose -f compose.yaml build
をターミナルに入力したのですが、またもやエラーとなってしまいました。
ここからは、残りの限られた質問回数で起動させられるか不安だったこともあり、手作業で環境を変更しました。Dockerfile
のFROMで指定するDockerイメージを変更したり、COPY句のパスを変更したり、ポート番号を8081に変更したり、いろいろ変更した結果起動することができました!
ブラウザにhttp://localhost:8081/hello
を入力し、
いざ実行!
すると、無事にHelloWorld!
を表示させることに成功しました!
5. タスクをINSERTするAPIを作成して
次に、APIを作成してもらいます。taskテーブルが存在し、タスク期限及びタスク名を格納するという体でPOSTリクエストを受け付けるAPIを作成します。
したがって、プロンプトに下記を入力しました。
タスク、日付が情報として格納されるPOSTリクエストを受け付け、taskテーブルにデータを格納するAPIを作成してください
すると、エンティティ、リポジトリ、コントローラー、アプリケーションクラス、H2DBに接続するためのapplication.properties
まで作成してくれました!
Task.java
package com.example.task; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import java.time.LocalDate; @Entity public class Task { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String task; private LocalDate date; // Default constructor public Task() {} // Constructor with parameters public Task(String task, LocalDate date) { this.task = task; this.date = date; } // Getters and setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTask() { return task; } public void setTask(String task) { this.task = task; } public LocalDate getDate() { return date; } public void setDate(LocalDate date) { this.date = date; } }
TaskRepository.java
package com.example.task; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface TaskRepository extends JpaRepository<Task, Long> { }
TaskController.java
package com.example.task; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.time.LocalDate; @RestController @RequestMapping("/api/tasks") public class TaskController { @Autowired private TaskRepository taskRepository; @PostMapping public ResponseEntity<Task> createTask(@RequestBody TaskRequest request) { Task task = new Task(request.getTask(), request.getDate()); Task savedTask = taskRepository.save(task); return ResponseEntity.ok(savedTask); } } class TaskRequest { private String task; private LocalDate date; // Getters and setters public String getTask() { return task; } public void setTask(String task) { this.task = task; } public LocalDate getDate() { return date; } public void setDate(LocalDate date) { this.date = date; } }
Application.java
package com.example.task; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
application.properties
# H2 Database Configuration spring.datasource.url=jdbc:h2:mem:taskdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.database-platform=org.hibernate.dialect.H2Dialect # Enable H2 Console spring.h2.console.enabled=true spring.h2.console.path=/h2-console # JPA/Hibernate properties spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true
しかし、この内容には下記の課題がありました。
- アプリケーションクラスは既存とは別で実装されてしまったこと
import javax.persistence.Entity;
等のjavax
ライブラリは既存の環境では使えないこと- コントローラ、リポジトリなどを別のパッケージに格納してほしかったが、同一パッケージに格納されてしまったこと
- H2DBが.application.propertiesの設定では使用できなかったこと
Hello worldを表示させるコントローラーやAPIに関しては大枠を簡単に作れましたが、importするライブラリや環境設定のところでAmazon Qは少し間違えた出力をしてしまうということが解りました。
これにて無料利用枠を使い切りました!(完)
まとめ
ここまで見てくださりありがとうございました!
私がAmazon Q Developerを使ってみた主な感想はこの3点ですね。
- 「APIを作ってください」など大雑把な入力に対してより効果を発揮できる
- API作成時に、コントローラー層からリポジトリ層まで作ってくれたので、コードを書く量を減らしてくれたというメリットが大きい。
- 逆に細かな動作はAmazon Qに任せずに自分でコードを書いたほうが速い
- importするライブラリが間違っていたり、依存関係が解消できなかったりと、環境設定の分野に関しては間違った設定がされることが多いのがデメリット。
- プロンプトエンジニアリングの技量も試される
- ある程度プロンプトで指定しないと、間違ったパッケージにクラスが配置されたり、不要なクラスも作成されてしまう。
Chat GPTが登場した時にも言われていましたが、Amazon Qでも生成したコードの後処理やプロンプトエンジニアリング等の技術が必要になってくるので、エンジニアが必要なくなるなんてことはなさそうです!
Amazon Q Businessは今年、2024年の12月から日本語版がリリースされるようです。ますます勢いを増していくAmazon Q、皆さんもぜひ使ってみてください!
ソースコード
こちらに、今回作成したアプリケーションのソースコードを記載しています!(起動はしませんのでご注意を)
https://github.com/18takeshi/amazonq/tree/main