Copilot Edits vs Cursor Composer

## はじめに
こちらは [エーピーコミュニケーションズ Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ap-com) の 12 日目の記事となります。

エンジニアたるもの、適度に楽しみつつできる限り楽したいですよね。
そんなエンジニアライフを薔薇色にできる生成系AIがどれくらい有効に働いてくれるのかを試してみたいと思います。

今回はエディタから直接コードの生成ができる機能を持つ`Copilot Edits`と`Cursor Composer`を利用して対決してみようと思います。
`Copilot Edits`については現状プレビュー扱いであり、モデルについてもまだまだプレビュー機能が多いため不利に思えますが、実際はどのような結果となるでしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/d560c36a-a374-0a7f-b2b6-a6ed5f31284b.png)

## 結論
**Cousor Composerの圧勝**です。

あくまで今回の検証内容の範囲に限った話にはなりますが、`Copilot Edits`は比較にならない程でした。
体感で言うと `ChatGPT o1 preview`や`o1 mini`をブラウザ上から利用しつつ、修正をお願いする方が上手く動作しているイメージでした。

`Cursor Composer`が1つ1つ問題を解決して進んでいくのに対し、`Copilot Edits`は紆余曲折しながらゴールへ進むではなく、ずっと同じところでぐるぐる迷っているイメージ、迷いながらそのまま他方へ寄り道してしまって戻ってこれなくなっています。
`Copilot Edits`では今回のミッションをこなすことができずに打ち切りと非常に残念な結果となってしまいました。

## 前提・ルール
### 前提
完全に条件を揃えられておらずフェアじゃない部分があるため、ご承知おきいただいた上で読み物としてお楽しみください。

`Copilot Edits`では使えるモデルが実質`GPT 4o`のみで、他は`preview`扱いとなっています。
`o1`系は利用制限があったはずなので、今回はやむなく`Claude 3.5 Sonnet(Preview)`としています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/8bcad07e-0058-8e75-bafa-df66bc8fba56.png)

`Cursor Composer`に関しては実際にどれくらい使い物になるのかを計測したいために最新の`claude-3-5-sonnet-20241022`を利用することとしました。
ベースモデルは同様の`Claude 3.5 Sonnet`ですが、既に利用モデル選択で若干の差が出ています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/610a96cd-fe13-370c-e6f7-fb3203cb0e8e.png)

### ルール
- コードは要件を伝えて0からの作成として依頼します
- ターン制とし、`Copilot Edits`と`Cursor Cpmposer`で交互にプロンプトを実行していきます
- 提案されたコードは基本的には`Accept`していくものとします
- `順次実装してください。`として進めます
- エラーが出た場合にはエラー内容を伝え、修正してもらいます
- 細かな仕様や指示出しが必要になったと思ったタイミングで、方針の指示だしをしつつ修正を依頼します

## 要件
こちらはお馴染みChatGPT先生に整理してもらいます。

### 生成用のプロンプト
```
生成系AIの性能をテストしたいため、テスト用の要件を作成したいです。
簡単なアプリ開発を想定しており、フロントエンドのデータを保管するのにAWSを利用します。

フロントエンドの言語はお任せします。簡単なものが良いですがWeb上で利用するため、S3の静的ホスティングとします。
バックエンドはAWS CDKを利用して構築するものとし、API Gateway、Lambda、S3を利用する想定です。
```

### 出力結果
```
# To-Doリストアプリ要件

## アプリ概要
簡単な「To-Doリスト」アプリを開発します。  
ユーザーがタスクを追加、編集、削除でき、フロントエンドで入力されたデータはバックエンドを通じてS3に保存されます。  
ウェブブラウザ上で動作するアプリを目指します。

---

## 要件

### フロントエンド
- **言語・フレームワーク**: HTML, CSS, JavaScript (またはReact)
- **機能**
  - タスクの一覧表示
  - 新規タスクの追加
  - 既存タスクの編集
  - タスクの削除
  - データの保存・読み込みはAPI Gateway経由で実施
- **ホスティング**
  - AWS S3の静的ウェブホスティングを利用
  - サイトはブラウザからアクセス可能

### バックエンド
- **AWS構成**: API Gateway, AWS Lambda, S3
- **機能**
  - **API Gateway**
    - フロントエンドからのHTTPリクエストを受け付けるエンドポイントを提供
    - `POST /tasks`: タスクデータをS3に保存
    - `GET /tasks`: S3からタスクデータを取得
    - `DELETE /tasks/{taskId}`: 指定されたタスクを削除
  - **AWS Lambda**
    - タスクデータを処理し、S3と連携
    - 各エンドポイントのロジックを担当
  - **S3**
    - タスクデータをJSON形式で保存
    - データはユーザーごとに識別できるようにディレクトリまたはファイルを分ける

### インフラ構築
- **AWS CDK**
  - API Gateway、Lambda、S3のリソースを定義
  - CDKでスタックを構築し、デプロイを自動化

---

## 開発ステップ
1. **AWS CDKのセットアップ**
   - AWS CDKを使用してAPI Gateway、Lambda、S3を定義
   - Lambda関数のコードを記述（Node.jsやPython推奨）
2. **フロントエンドの作成**
   - HTML/CSS/JavaScriptを用いて簡単なTo-Doリストアプリを作成
   - API Gatewayのエンドポイントと連携するコードを追加
3. **デプロイ**
   - フロントエンドコードをS3にアップロードし、静的ウェブホスティングを設定
   - バックエンドのAWSリソースをデプロイ
4. **テスト**
   - タスクの追加、編集、削除が正しく機能するか確認

---

## テスト観点
### フロントエンド
- 操作性が直感的か
- 正常なデータ送信・受信が可能か

### バックエンド
- Lambdaの処理速度
- API Gatewayのレスポンス速度
- S3との連携が正確に行われるか

### 全体
- フロントエンドとバックエンドの連携がスムーズか

---
```

## 全体感
共通して起きる事象
- ディレクトリ構成の誤認が非常に多い
  - 同じ名称のファイルを別階層に作成して上手くファイルが扱えない
  - プロジェクトルート配下にディレクトリを作成した場合、プロジェクトルートでやることと、配下でやることをディレクトリを指定した場合でも誤認してしまう

- コマンド操作が煩雑になる
  - ディレクトリ構造の誤認があるため、コマンド操作が発生する際に人間を混乱させることがある
  - スクリプトを生成してもらうことで対処

## 〜10ターン目
### Cursor Composer
初期設定などのセットアップなどは済ませ、AWS側へと初期デプロイ自体はできていたため、かなり早い印象です。
現段階ではスタックにリソースが実装されていないので、実装を進めます。

原因としては全体的によく起きる事象なのですが、ディレクトリ構造の取り違えが多く編集するファイルを間違ってしまうことが間々あります。
ファイル自体を作成しているのは確認していたので、フォルダの整理をした際に消えたものと考えられました。

### Copilot Edits
まだまだ初期セットアップで苦戦しています。

## 〜30ターン目
### Cursor Composer
30回程度のやり取りを重ねてComposerに関してはデプロイ完了
作成されたリソースについても、Web公開用のバケット、タスク保管用のバケット、Lambda、API、S3へのデプロイリソースと想定通りのラインナップです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/07f822cf-b66d-9e25-6771-0571cd3e056c.png)

実際にS3のURLにアクセスするとしっかりWebアプリ画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/92bf5cd2-d3af-52b9-3f2c-bf1e24ff022d.png)

この時点ではバックエンドとの連携が上手くいっていないようで正しく動作しないため、ここからはアプリ側の改善フェーズに入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/5c13296b-deab-78bf-a6c8-5e214797520e.png)

### Copilot Edits
同様のペースでは初期デプロイのみ完了状態ですが、リソースなどはできていない状態です。
正式に計測したわけではないですが、打ち込める文字数もCopilotの方が少なく感じます。
また、純粋な応答速度も遅い気がしています。

また途中で運悪くCDKToolkitが更新され、動作しなくなってしまったためこちらは手動で復旧。
こちらに関してはBootStrapはデプロイ済みと伝えられていなかったことも悪いですが、デプロイ済みである旨を伝えた後もセットアップスクリプトにデプロイコマンドが入っていました。
また、セットアップスクリプトの中でCDKToolkitをdestroyしていたのですが、S3バケットだけ残っていたために再セットアップができずに詰まってました。
初期のChatGPT 3.5やClaude3.0の頃のを思い出す手戻りを感じます。

## 〜35ターン目
### Cursor Composer
CDK デプロイ後のAPI GatewayのEndpointを手動で設定する手間がありました。
気づかずに何ターンか無駄にしてしまいましたが、手動で設定してデプロイ
フロントからだけでは同様にエラーが出てしまうため、デバッグ用にLambdaでログ出力をするように依頼する。

### Copilot Edits
エラーメッセージなどを投げても反応がなくなってしまいました。
エラーの対応が非常に遅いですくタイムアウトなども起きないために、非常にストレスです。
内容のフェーズだけでも差をつけられていましたが、反応が悪くなるためにこの辺りからターン数としては足並みが揃わなくなってきます。

## 〜40ターン目
### Cursor Composer
API GatewayのURL修正で詰まりカスタムリソースでの解決をしようとします。
ただ、カスタムリソースを定義する場合、エラー待ちに時間がかかるため手動で設定することにしました。
また、頻出エラーとしてCROSのエラーが出力されました。

### Copilot Edits
Copilotの反応が非常に悪くなり修正がされない。
また、修正後も同様にセットアップスクリプトだけでエラーが続出
CDKToolkitを修正しない旨を伝えても毎回デプロイをかけてしまいます。(修正でコードが復活する。)
デプロイが通ったと思えばまたリソースがない状態です。

## 〜45ターン目
### Cursor Composer
カスタムリソースのロールバックの待機に時間がかかりましたが、ここまで来ればもうゴールは近いです。
ちなみにCustom Resourceのタイムアウト時間自体はプロパティで指定できるため、手動で作成する際は必ず入れておきたいところです。(失敗ごとの待ちが非常に長いので)

### Copilot Edits
リソースが作成されない旨を伝えると要件に存在しないDynamoDBを定義しました。
また、毎回CDKフォルダをコピーして作成してしまうのでスタックが分かれていてどうにも使えません。(途中でディスク使用率が100%になりました。)
埒が開かないので`o1 preview`に切り替えます。
何度か利用すると使えなくなるはずなので、そんなに長くは利用できません。

## 〜50ターン目
### Cursor Composer
以下の様にディレクトリ構成が重複しているために、修正ファイルとアップロードファイルに相違が生まれてうまく動作しないケースでした。
ディレクトリ構成の見直しを依頼した上で、Lambda関数のファイルが修正されたところ正しく動作しました。(backend/lambdaとtodo-app/backend/lambdaが重複)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/b3cf6794-ce70-0608-38d4-ef5e2c65b4b1.png)

正直フロントが動作した時点からはもう少し早く解決できるかなとは思っていたのですが、修正内容は正しいけれど修正対象が違うという愛嬌のある面も見せてくれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/9f347e22-99a3-9783-b762-b5006f8cfab7.png)

レイアウト修正を依頼して並びも概ね良いでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/f3bc546d-ce26-35b4-5ffb-f5babe15bc46.png)

削除ができることも確認したためここで `Cursor Composer`に関しては完走です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/5f74984f-caae-e5b5-a92e-3aab2989527e.png)


### Copilot Edits
何も変わらずひたすらエラーを繰り返しています。
おそらく初期時点で方向性を間違えてしまい、動作的な修正ができない状況です。
一度ハマってしまうとどうしようもないようで、手も足も出ません。
何度も不要と伝えていますが、依然としてCDKToolKitを再デプロイし続けています。

## 〜60ターン目

### Copilot Edits
もうずっと同様のエラーが発生しており、セットアップスクリプトすらままならない状況です。
リソースがないと何度指示をしてもデプロイされたリソースがCDKMetadataのみです。
また、変わらずCDKToolKitを再デプロイします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/bd5d5c1a-2493-2a59-4976-568ee1660e5e.png)

正確な回数はカウントできていませんが、以降で以下の様にレート制限がかかってしまいました。
奥の手を出し切ってしまった`Cplilot Edits`がゴールまで行ける見込みも薄く感じたためにここで終了としました。
`o1-preview`はコード関連優秀と言われているので、やはりもんだいてんモデルだけの差ではない様な気もしてきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939906/4f5897a8-8c87-5852-2e3e-60e7e9e0001b.png)

## おわりに
コードが生成できる機能と非常に魅力的なAIたちですが、Copilot Editsが想像したよりも奮わずでした。
お財布事情としては当然どちらも利用するわけにもいかないので統合したいところですが、まだまだしばらくはCursorの利用価値が高そうに思えます。
Github Copilotもプレビューを終わらせてもっと実用的に利用できることを期待しております。