🤖

Duet AI Assisted developmentがGAになったので検証しました

2023/11/22に公開

こんにちは、SREディビジョンの小林です。
この記事では Duet AI Assisted development の機能紹介と、検証結果を以下の項目でまとめています。

  • Duet AI Assisted development とは
  • 概要
  • 本機能のメリット
  • 実施した内容
  • どんなユーザにフィットするか
  • まとめ

Duet AI Assisted development とは

現在一部GA 版(一般提供)のDuet AI の中でも 開発支援 にフォーカスしている機能となります。
主な機能として以下の3点が取り上げられています。
この記事では、その中でも Duet AI in Visual Studio Code のみの検証となります。

  • Duet AI in Visual Studio Code
  • Duet AI in JetBrains IDEs
  • Duet AI in Cloud Workstations

https://cloud.google.com/duet-ai

Duet AI in Visual Studio Code

概要

Visual Studio Code (以下、VScode) で Duet AI を利用する機能となっていますが、使用用途は多岐に渡ります。ドキュメントベースとなりますが、現在想定される用途について、幾つか記載します。

  • コード生成
  • コード説明
  • テスト計画の生成
  • コード可読性の向上
  • トラブルシューティング支援

https://cloud.google.com/code/docs/vscode/write-code-duet-ai

本機能のメリット

これまでは、VScode 上の拡張機能としては、Cloud Code が主な製品となっていました。
こちらの製品では、k8s のサンプルアプリケーションの作成や Cloud Run へ簡単にデプロイが実施出来る等の機能を備えていました。
ですが、コード生成および修正トラブルシューティング等は、開発者のスキルセットや VScode を超えてブラウザを利用しての調査等が必要となっていました。Duet AI in Visual Studio Codeは、このような開発(主にコーディング)を実施する上で障害となるものが、VScode 上で解決出来るようになっています。

これまでの開発環境(Cloud Code を利用した)

  • サンプルアプリケーションの生成や Google Cloud へのアプリケーションデプロイを簡単に実施
  • 独自にコード生成や修正を実施する場合は、スキルもしくは、追加の調査が必要
  • トラブルシューティングにスキルもしくは、追加の調査が必要

Duet AI in Visual Studio Code を導入後の開発環境

  • 多言語のコード生成が可能(Python, Java, C++, JavaScript, Terraform...etc...)
    • コード生成は、プロンプトベース、チャットベースで可能
  • コード修正をチャットベースで可能
  • トラブルシューティングがVScode上で実施可能

実施した内容

合計 4 つの検証を実施しました。コード生成を実施する際には、精度を高めるために Google 翻訳を使った英語でのやりとりとしています。

利用における条件

上記機能を利用するためには、Duet AI 利用申請後に VScode で拡張機能のインストール等々の処理が必要となります。

  1. Google Cloud プロジェクトの作成
  2. プロジェクトの課金が有効になっていることを確認
  3. Duet AI がユーザアカウントとプロジェクトに紐づいているか確認
  4. VScode へ Cloud Code 拡張機能を導入済み
  5. Google Cloud へ接続
  6. Duet AI を有効化

1.🤖ドラえもんの誕生日までの日数を出力

まずは、簡単な Python コードの生成を実施しました。今回は、プロンプト付きのコード生成となります。
コード生成には、プロンプト付きのもの以外にもチャットを利用したものもあります。

回答を得るまでの流れを操作画面をベースに記載します。
はじめに # に続いて生成したいコードに関するプロンプトを記述します。
次に、プロンプトを記述した後に改行をします。改行後にゴーストテキスト形式(薄い文字)でコード提案を受けます。
コード内容に問題がない場合は、tab を入力してコードを生成します。
生成されたコードは、特に修正することなく動作させることが出来ました。

image1
image2

# 質問文
Please generate a code that calculates and outputs the number of days until Doraemon's birthday.
(ドラえもんの誕生日までの日数を出力するコードを生成してください)
# Please generate a code that calculates and outputs the number of days until Doraemon's birthday.

# Doraemon's birthday is September 3, 2112.
# Use the datetime module to get today's date.
# Use the timedelta module to find the difference between two dates.
# The difference between two dates is the number of days.

from datetime import datetime, timedelta

current_date = datetime.now()
print("Today's date is", current_date.strftime("%Y-%m-%d"))

birthday = datetime(2112, 9, 3)
print("Doraemon's birthday is", birthday.strftime("%Y-%m-%d"))

difference = birthday - current_date
print("There are", difference.days, "days until Doraemon's birthday")
# 実行結果
Today's date is 2023-11-21
Doraemon's birthday is 2112-09-03
There are 32427 days until Doraemon's birthday

2.🤖コード修正

現状のコードは、関数化や Docstring も追加されていないため、Duet AI チャットを利用してコードを修正を実施しました。

はじめに VScode から Duet AI アイコンを選択してチャット画面を表示させます。
表示されたチャット画面に対して実行したい内容を入力して、出力を得るのみです。
※Duet AI に修正してほしいコードが記述されているファイルを選択した状態としてください。

実行した結果、無事に関数化および Docstring とコメントの追加が出来て、それらしいコードとなりました。

image3
image4

# 質問文
Please modify the code with the following content.
- Convert existing code into a function
- Add Docstring
- Fixed so that it can be executed

以下の内容でコードを修正してください。
- 既存コードの関数化
- Docstring の追加
- 実行できるように修正
def calculate_days_until_doraemon_s_birthday():

  """Calculates and outputs the number of days until Doraemon's birthday.

  Doraemon's birthday is September 3, 2112.
  Uses the datetime module to get today's date.
  Uses the timedelta module to find the difference between two dates.
  The difference between two dates is the number of days.
  """

  # Get today's date.
  current_date = datetime.now()
  print("Today's date is", current_date.strftime("%Y-%m-%d"))

  # Get Doraemon's birthday.
  birthday = datetime(2112, 9, 3)
  print("Doraemon's birthday is", birthday.strftime("%Y-%m-%d"))

  # Find the difference between today's date and Doraemon's birthday.
  difference = birthday - current_date

  # Print the number of days until Doraemon's birthday.
  print("There are", difference.days, "days until Doraemon's birthday")

if __name__ == "__main__":
  calculate_days_until_doraemon_s_birthday()
# 実行結果
Today's date is 2023-11-21
Doraemon's birthday is 2112-09-03
There are 32427 days until Doraemon's birthday

3.🤖異なる言語内でのコード変換

ここまでは、全てPythonでのコード生成を実施してきましたが、
作成したコードをJavaGoに変換してみます。

先ほど同様に Duet AI チャットでのやり取りでコード生成を実施しました。

◾️Java

# 質問文
Convert Python language to Java language
(Python言語をJava言語に変換してください)
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class Birthday {

  public static void main(String[] args) {

    // Get today's date.
    LocalDate currentDate = LocalDate.now();
    System.out.println("Today's date is " + currentDate.toString());

    // Get Doraemon's birthday.
    LocalDate birthday = LocalDate.of(2112, 9, 3);
    System.out.println("Doraemon's birthday is " + birthday.toString());

    // Find the difference between today's date and Doraemon's birthday.
    long difference = ChronoUnit.DAYS.between(currentDate, birthday);

    // Print the number of days until Doraemon's birthday.
    System.out.println("There are " + difference + " days until Doraemon's birthday");
  }
}
# 実行結果
Today's date is 2023-11-21
Doraemon's birthday is 2112-09-03
There are 32428 days until Doraemon's birthday

◾️Go

# 質問文
Convert Python language to go language
(Python言語をGo言語に変換してください)
package main

import (
    "fmt"
    "time"
)

func calculateDaysUntilDoraemonSBirthday() {

    """Calculates and outputs the number of days until Doraemon's birthday.

    Doraemon's birthday is September 3, 2112.
    Uses the time module to get today's date.
    Uses the time.Duration type to find the difference between two dates.
    The difference between two dates is the number of days.
    """

    // Get today's date.
    currentDate := time.Now()
    fmt.Println("Today's date is", currentDate.Format("2006-01-02"))

    // Get Doraemon's birthday.
    birthday := time.Date(2112, 9, 3, 0, 0, 0, 0, time.UTC)
    fmt.Println("Doraemon's birthday is", birthday.Format("2006-01-02"))

    // Find the difference between today's date and Doraemon's birthday.
    difference := birthday.Sub(currentDate)

    // Print the number of days until Doraemon's birthday.
    fmt.Println("There are", difference.Days(), "days until Doraemon's birthday")

}

func main() {
    calculateDaysUntilDoraemonSBirthday()
}

# 実行結果
# command-line-arguments
./birthday.go:10:7: syntax error: unexpected literal "Calculates and outputs the number of days until Doraemon's birthday. at end of statement
./birthday.go:10:76: newline in string
./birthday.go:12:13: syntax error: unexpected literal 's birthday is September 3, 2112. at end of statement
./birthday.go:12:46: newline in rune literal
./birthday.go:13:10: syntax error: unexpected the at end of statement
./birthday.go:13:46: newline in rune literal
./birthday.go:14:10: syntax error: unexpected the at end of statement
./birthday.go:16:8: newline in string

Java は変換後のコードで正常に動作することが出来ましたが、Go が正常に動作していないようです。
出力されたエラー内容をもとに Duet AI チャットとやり取りをしましたが、有効な回答を得ることは出来ませんでした。
上記のエラーは、Pythonコードで記述していたDocstringの影響です。Java変換時には、上手に変換していたのですが、この点を正常に変換できなかったようです。

Docstring の箇所を削除後に改めて実施したところ、以下のエラーを確認しました。
今回も Duet AI チャットで解消を試みましたが、こちらは修正後のコードを無事に提供していただけました。

# 実行結果(エラー)
# command-line-arguments
./birthday.go:22:41: difference.Days undefined (type time.Duration has no field or method Days)
package main

import (
    "fmt"
    "time"
)

func calculateDaysUntilDoraemonSBirthday() {

    // Get today's date.
    currentDate := time.Now()
    fmt.Println("Today's date is", currentDate.Format("2006-01-02"))

    // Get Doraemon's birthday.
    birthday := time.Date(2112, 9, 3, 0, 0, 0, 0, time.UTC)
    fmt.Println("Doraemon's birthday is", birthday.Format("2006-01-02"))

    // Find the difference between today's date and Doraemon's birthday.
    difference := birthday.Sub(currentDate)

    // Print the number of days until Doraemon's birthday.
    fmt.Println("There are", difference.Hours()/24, "days until Doraemon's birthday")

}

func main() {
    calculateDaysUntilDoraemonSBirthday()
}
# 実行結果
Today's date is 2023-11-21
Doraemon's birthday is 2112-09-03
There are 32427.601215894814 days until Doraemon's birthday

エラーの原因は、dirrerence の中に Days メソッドが定義されていないことにありました。
Go の time.Duration 型は、時間の長さをナノ秒単位で表現しています。ですが、この型には直接日数を取得するためのメソッドは提供されていません。代わりに、時間の長さを他の単位(例えば、時間や分)に変換するメソッドが提供されています。日数を取得するには、time.Duration 型の値を時間(Hours)に変換し、それを24で割ることで計算します。

4.🤖GCEインスタンスの作成

最後に Terraform を利用した Google Cloud リソースの中でも代表的な GCE インスタンスを作成してみます。以下、プロンプト付きのコード生成で検証した結果です。

問題ないように見受けられますが、動作させるまでにいくつか問題があります。

  • project_id がない
  • debian-9 イメージは現在取り扱えない
    2点を修正したら動作するようになります。
# 質問文
create a GCE instance
(GCEを作成するTerraformコードを生成してください)
# Create a G
resource "google_compute_instance" "default" {
  name         = "terraform-instance"
  machine_type = "f1-micro"
  zone         = "us-central1-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network = "default"
    access_config {
      // Ephemeral IP
    }
  }
  metadata_startup_script = "sudo apt-get update; sudo apt-get install apache2 -y; sudo service apache2start; echo '<!doctype html><html><body><h1>Hello from Terraform!</h1></body></html>' | sudo tee /var/www/html/index.html"

image5

合わせて GitHub Copilot との比較も検証しました。
Duet AI は、先ほどと出力が変わって GCE インスタンス以外のリソースも作成する出力となっています。
こちらのコードも先ほど同様に各リソースの作成まで実施することが出来ました。
GitHub Copilot は、リポジトリ内やフォルダ内に参考とするコードの有無によって出力が異なるため、今回は、うまく出力が出来なかったように見受けられます。

左:GitHub Copilot 右:Duet AI
image6

どんなユーザにフィットするか

メリット、検証結果を踏まえた上で以下のユーザには、フィットするものと考えます。

  • コーディング初心者からすべての方(未経験者は除く)
    • イメージとしては、ペアプログラミングに近いかと思います。
    • ベースとなるコードを Duet AI で生成し、気になる点を自身で改善することで、コーディングスピードが向上するケースが増えそうです。
    • 仮に気になる点が不明な場合やデバッグが難しい場合は、チャットでのやり取りでトラブルシュートできる可能性もあります。

まとめ

全体を通してかなり好印象となっています。ですが、今回の検証内容は、基礎的な内容となっているため、もう少し複雑なことを実施しようとした際にどこまで通用するかが気になる点です。
類似製品に GitHub Copilot が挙がるかと思いますが、今後は、どちらのキャッチアップも重要になってくると考えています。

Discussion