Amazon CodeWhispererを使用する方法(VSCode)

本記事ではAmazonが発表したAIコーディング支援サービス[Amazon CodeWhisperer](https://aws.amazon.com/jp/codewhisperer/)の使用方法を紹介します。CodeWhispererで、VSCodeにPython、TypeScript、AWSサービスのサンプルコードを提案してみました。
## CodeWhispererとは
統合開発環境 (IDE) のコードエディタでAmazonのコードや公開されているコードでトレーニングされており、自然言語で記述されたコメントを理解し、複数のコードの提案と生成、セキュリティスキャンを行います。（多くの場合、最大 10～15 行のコードで構成されます。）2023年4月13日に正式版として公開されました。
## VSCodeにCodeWhispererの利用を開始する
VSCodeでCodeWhispererを有効し、使い始める方法を紹介します。公式サイトは[こちら](https://aws.amazon.com/jp/codewhisperer/resources/#Getting_started)です。
・VSCodeを拡張機能から、AWS Toolkitと検索しインストールします。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727189/1c35ca8b-f687-39aa-8326-52d34f3b7f13.png">
・AWS Toolkit拡張パネルを開き、[開発者ツール] > [CodeWhisperer] の下にある [スタート] ボタンを選択します。ビルダーID を使用してサインインします。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727189/dc5a8975-7629-c755-efe2-a3e302a1563c.png">
・VSCodeに使用するため、コードをコピーして、自動的にビルダーIDのサイトが開けます。
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727189/cc1c1f87-9f6b-ba4f-3416-dd6d388fd419.png"><img width="150" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727189/24e482a3-f755-518c-94a2-65ab37e058e0.png">
・ビルダーIDのログインと登録です。ログインしたら、PCのVSCodeと連携するため、「Allow」を押してください。
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727189/ef2fe99f-0810-80f7-b6d6-59dab2e2f465.png"><img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727189/0908a4ba-f765-942e-9d7f-35109cd63492.png">
・VSCodeへ戻って、[スタート] ボタンを押すと、下記の画像のようになります。
<img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727189/e7ff0864-ab0d-541d-c98e-ceefffb16d2c.png">
これで、CodeWhisperer利用までの準備が完了しました。


**補足：セキュリティー**
CodeWhispererの提案コードを生成するために使用したコメントと提案コードを収集しています。
気になる方は、VSCodeのSettingでCodeWhispererと検索し、「Sharing Code Whisperer Content With AWS」のチェックを外します。参考リンクは[こちら](https://docs.aws.amazon.com/codewhisperer/latest/userguide/sharing-data.html)です。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727189/6d44a2b2-de93-b7b9-98af-919a2f76cf0b.png">
## 使用方法
CodeWhispererはコメントや関数名を解析し、コードを提案しています。
* **操作方法**
・コードの提案：Windows「Alt+C」、MacOS「Option+C」
・次の候補を提案：→キー or ←キー
・提案されたコードの採用：Tabキー
* **コードの生成方法**
・コメントからコードを生成する
![ezgif.com-video-to-gif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727189/e5abd56b-8ced-cf8b-dd57-e1bc9c82473c.gif)
・関数名からコードを生成する
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727189/db6915d8-13e7-f258-330b-b9c8fd2b8092.gif)

## PythonとTypeScriptのサンプルコード

### Pythonの例
```python:簡単なコード
# print hello world
print("hello world")

def add1to10():
    sum = 0
    for i in range(1,11):
        sum += i
    return sum

def greet(name):
    return "Hello " + name

import pandas as pd
#csvファイルをロードする関数
def load_csv(filename):
    data = pd.read_csv(filename, encoding='utf-8')
    return data
```
AWSサービス関連のコードも生成できました。
```python:s3
# s3バケットを作成する関数
import boto3
def create_s3_bucket(bucket_name):
    s3_client = boto3.client("s3")
    response = s3_client.create_bucket(Bucket=bucket_name)
    print(response)
    return True


# s3バケットを作成する関数、tryを使用してください
import boto3
def create_s3_bucket(bucket_name):
    s3_client = boto3.client("s3")
    try:
        response = s3_client.create_bucket(Bucket=bucket_name)
        print(response)
        return True
    except ClientError as e:
        print(e)
        return False
```
### TypeScriptの例
<details><summary>aws_cdk初期化と、React TypeScript環境構築</summary>


```:ターミナルに実行するコマンド
npx cdk init --language typescript
npx create-react-app my-app --template typescript
cd my-app
yarn add aws-sdk
```
</details>

```typescript:DynameDB
/*aws-sdk操作*/
// aws-sdkをimportし、DynamoDBにアイテムに挿入する関数
const putItem = async () => {
  const dynamoDB = new AWS.DynamoDB.DocumentClient();
  const params = {
    TableName: 'test',
    Item: {
      id: '1',
      name: 'test',
    },
  };
  await dynamoDB.put(params).promise();
}

import { DynamoDB } from 'aws-sdk';
const putItemToDynamoDB = async () => {
  const AWS = require('aws-sdk');
  const docClient = new AWS.DynamoDB.DocumentClient();
  const params = {
    TableName: 'test-table',
    Item: {
      id: '1',
      name: 'test-name',
    },
  };
  await docClient.put(params).promise();
}
/*スタック操作*/
// create dynamodb table
const dynamoTable = new cdk.aws_dynamodb.Table(this, 'AwsCdkExampleTable', {
  tableName: 'aws-cdk-example-table',
  partitionKey: {
    name: 'id',
    type: cdk.aws_dynamodb.AttributeType.STRING
    }
})

// Lambdaレイヤルを作成する、名前をappLambdaにしてください
const appLambda = new cdk.aws_lambda.Function(this, 'appLambda', {
  runtime: cdk.aws_lambda.Runtime.NODEJS_14_X,
  code: cdk.aws_lambda.Code.fromAsset('lambda'),
  handler: 'app.handler',
  environment: {
    TABLE_NAME: dynamoTable.tableName
  }
})
```
## ChatGPTと比べる
例：DynamoDBのテーブルにアイテムを挿入する関数を作る

```typescript:ChatGPT
export const uploadToDynamoDB = async (item: { id: string; name: string }) => {
  const params: DynamoDB.DocumentClient.PutItemInput = {
    TableName: "<YOUR_DYNAMODB_TABLE_NAME>",
    Item: {
      /*
      年齢や性別を追加したい場合は、引数の修正がしやすい
      */
      id: item.id,
      name: item.name
    }
  };

  try {
    await dynamoDB.put(params).promise();
    console.log("Item uploaded to DynamoDB");
    return true;
  } catch (error) {
    console.error("Error uploading item to DynamoDB:", error);
    return false;
  }
};
```
```typescript:CodeWhisperer
const uploadToDynamo = async (item: any) => {
  const dynamoDB = new DynamoDB.DocumentClient()
  const params = {
    /*
    テーブル名前を指定しないと仮なものを使用している
    */
    TableName: 'users',
    /*
    Itemという引数はどのようなものがわからないです…
    anyって指定して、typescriptには問題ないですが、厳しい場合には修正も必要と感じる
    */
    Item: item,
  }
  /*
  「tryを使用してください」と指示しないと、errorの処理を考えてくれない
  パラメーターの型もDynamoDB.DocumentClient.PutItemInputという型を指定した方がよい
  */
  await dynamoDB.put(params).promise()
}
```
CodeWhispererは複数の提案を行いますが、コードの生成には時間がかかるため、自分で書くよりも早く近い提案を選択することができます。ただし、バグ修正よりも最初から自分で書いた方が速い場合もあります。また、CodeWhispererの提案は一度に（多くの場合）最大10〜15行のコードを生成するため、複雑な要求にはあまり対応できないかもしれません。

ChatGPTに同じような質問を投げる場合、コードだけでなくコメントや説明、使用例なども一緒に表示されるため、より使いやすい印象です。

## まとめ
<table>
  <thead>
    <tr>
      <th>良い点</th> <th>悪い点</th>
    </tr>
  </thead>
  <tr>
    <td>簡単なコードが生成するのは速い</td> <td>型の変換が硬い　<br>例えば、関数を作る時、ドキュメントの関数の引数の定義から型を指名する感じです。</td>
  </tr>
  <tr>
    <td>ライブラリへの関連もできる</td> <td>上下関連のコードがない場合に提案する能力が弱い</td>
  </tr>
  <tr>
    <td>個人で無料で使える</td> <td>ChatGPTより説明がないため、生成してくれたコードを理解しにくい</td>
  </tr>
<thead>
    <tr>
      <th colspan="2">その他</th>
    </tr>
  </thead>

  <tr>
    <td colspan="2">import文をずれた場合があり、import文を先に記述すれば、よりよい結果が出れる</td>
  </tr>
  <tr>
    <td colspan="2">時々重複した括弧やコードが出ること、インデントがずれることがあり、修正するのは少し面倒な感じですね。</td>
  </tr>
</table>

**結論**
CodeWhispererは無料で利用できます。それは簡単なコードを生成する能力があり、特にAWSサービスに関連するコードの提案が得意です。ただし、複雑なコードの生成においては関連性が薄い提案が出る可能性があり、修正や改善には時間がかかるかもしれません。初心者や学習者にはおすすめですが、高度なプログラマにとっては補助的に使えるレベルで、簡単なコードや一部のコードを生成するのに役立つと思います。