GitHub Copilotを使って簡単なスクリプトとAdvent Caledarの記事が作れるか検証してみた

# はじめに

最近チームで[Gahter](https://app.gather.town/app)やLLMの話題が増えてきました。既に一周どころか二周回っていそうですが、今更ながらにGitHub Copilotがどこまで律儀に相談に乗ってくれるか試してみたくなり、READMEに要件を書き、それを読ませて実装を任せてみました。

## 基本の流れ

1. README.mdを用意
1. GitHub CopilotにREADMEを読んでもらい実装を進める

今回は1-2をひたすら繰り返し最終的にどんなものができるだろう？というお気持ちで試してみました。

### README.md v0.1

    # Advent Calendar 2024 12/12の記事
    
    ### 書きたい内容と試したいこと
    
    LLMが昨今話題のため、AdventCalendarの記事として書こうとしていたGatherスペースの複製処理を、LLMを使って実装してみたい。
    
    
    ### 進行
    まずはどんな情報を渡すと実装がしやすいか相談し、情報を整理
    

### Copilotさんに1回目のお願い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19911/88af0057-a9b2-37a3-f25d-4b144f59ef1f.png)


### README.md v0.2

    # Advent Calendar 2024 12/12の記事
    
    ### 書きたい内容と試したいこと
    
    LLMが昨今話題のため、AdventCalendarの記事として書こうとしていたGatherスペースの複製処理を、LLMを使って実装してみたい。
    
    
    ### 進め方
    まずはどんな情報を渡すと実装がしやすいか相談する。
    
    ### サポートして欲しい部分
    
    #### 情報収集
    - Gatherスペースの複製処理の実装はプログラムで可能か？
    - Gatherスペースの複製処理を実装するために必要な情報は何か？
    
### Copilotさんに2回目のお願い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19911/96ced326-ccff-90cc-69be-5f557982bfb0.png)

### README.md v0.3

    # Advent Calendar 2024 12/12の記事
    
    ### 書きたい内容と試したいこと

    LLMが昨今話題のため、AdventCalendarの記事として書こうとしていたGatherスペースの複製処理を、LLMを使って実装してみたい。
    
    
    ### 進め方
    まずはどんな情報を渡すと実装がしやすいか相談する。
    
    ### サポートして欲しい部分
    
    #### 情報収集
    - Gatherスペースの複製処理の実装はプログラムで可能か？
    - Gatherスペースの複製処理を実装するために必要な情報は何か？
    
    #### 必要な情報
    APIのアクセスキー： XXXXXXXXXXX
    元のスペースID：XXXXXXXXX/YYYYYY
    新しいスペースの設定情報：new_space_name

### Copilotさんに3回目のお願い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19911/328fef82-51e3-02b5-0d6c-a05b962991cb.png)


## 一息
ここまで3回のやり取りで、サンプルのコードまで提供してくれました。参考までに提供されたコードは以下となります。

### 提供されたサンプルコード(Python)

```python
import requests

# Gather APIのアクセスキー
api_key = 'XXXXXXXXXXX'
headers = {
    'Authorization': f'Bearer {api_key}',
    'Content-Type': 'application/json'
}

# 元のスペースID
original_space_id = 'XXXXXXXXX/YYYYYY'

# 1. 元のスペースの情報を取得する
response = requests.get(f'https://api.gather.town/api/spaces/{original_space_id}', headers=headers)
original_space_data = response.json()

# 2. 新しいスペースを作成するためのデータを準備する
new_space_data = {
    'name': 'new_space_name',
    'settings': original_space_data['settings']
}

# 3. 新しいスペースを作成する
response = requests.post('https://api.gather.town/api/spaces', headers=headers, json=new_space_data)
new_space = response.json()

print(f'New space created with ID: {new_space["id"]}')
```

このまま動かしても良かったのですが、実行する前にapiのドキュメントを自分でも確認することにしました。
流石にAPIの仕様もわからずに叩くのは気が引けたので。

[Gatherの公式提供されているドキュメント](https://gathertown.notion.site/Gather-HTTP-API-3bbf6c59325f40aca7ef5ce14c677444#4821956d4559419da1fca24910960e44
)を見たところまず最初に気づいたのが**APIのエンドポイントが一致しない**、という点でした。

### 公式ドキュメントで提供されている資料
```js
axios.post(
  "https://api.gather.town/api/v2/spaces",
  {
    sourceSpace: SPACE_ID,
    name: "my new space",
  },
  {
    headers: {
      apiKey: API_KEY,
    },
  }
)
```

この時点でAPIの情報を渡していなかったことで、古いバージョン、もしくはREST APIのお作法通りのエンドポイントを生成してくれたのとだと考えました。このため、APIのリファレンス情報を渡すことにしました。
もしかすると古いバージョンなだけで動くのかもしれませんが、あえて古いAPIを利用して変なつまづきをしたくなかったので、素直に新しいAPIを使う方向に切り替えました。

### README.md v0.4

    # Advent Calendar 2024 12/12の記事
    
    ### 書きたい内容と試したいこと

    LLMが昨今話題のため、AdventCalendarの記事として書こうとしていたGatherスペースの複製処理を、LLMを使って実装してみたい。
    
    
    ### 進め方
    まずはどんな情報を渡すと実装がしやすいか相談する。
    
    ### サポートして欲しい部分
    
    #### 情報収集
    - Gatherスペースの複製処理の実装はプログラムで可能か？
    - Gatherスペースの複製処理を実装するために必要な情報は何か？
    
    #### 必要な情報
    APIのアクセスキー： XXXXXXXXXXX
    元のスペースID：XXXXXXXXX/YYYYYY
    新しいスペースの設定情報：new_space_name
    APIのリファレンス情報 https://gathertown.notion.site/Gather-HTTP-API-3bbf6c59325f40aca7ef5ce14c677444#4ec9ab98775544459a2d4f28fdf1aa47

### Copilotさんに4回目のお願い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19911/66812ab1-a062-826c-2dd2-bb04257891f9.png)

## 検証
4回目のお願いで生成されたサンプルコードは以下となりました。かなり綺麗になっているのと公式のサンプルとほぼ一致しているので、これは動くでのは...!と考えましたが、結果的にはエラーとなりました。

### 提供されたサンプルコード
```js
const axios = require('axios');

const { SPACE_ID, API_KEY } = require("./config");

axios
    .post(
        "https://api.gather.town/api/v2/spaces",
        {
            sourceSpace: SPACE_ID,
            name: "my new space test",
        },
        {
            headers: {
                apiKey: API_KEY,
            },
        }
    )
    .then((response) => console.log(response.data))
    .catch((error) => {
        console.error('Error creating new space:', error.response.data);
    });
```

### 公式提供のサンプルコード
```js
const axios = require("axios");

const { SPACE_ID, API_KEY } = require("./config");

axios
  .post(
    "https://api.gather.town/api/v2/spaces",
    {
      sourceSpace: SPACE_ID,
      name: "my new space",
    },
    {
      headers: {
        apiKey: API_KEY,
      },
    }
  )
  .then((response) => console.log(response.data))
  .catch(console.error);
```

### 実行結果
API Keyの認証はできているようですが、送ったリクエスト情報が不正そうです。
もしかするとコピー元に何か癖のあるオブジェクトなどがあったのかなと思いましたが、概ね試したかったことは検証できました。

```bash
➜  2024 git:(main) ✗ node sample.js  
Error creating new space: {
  error: 'INVALID_REQUEST',
  errors: [
    {
      code: 'invalid_type',
      expected: 'object',
      received: 'undefined',
      path: [Array],
      message: 'Required'
    }
  ]
}
```

# まとめ
今回試してわかったことは適切な情報さえ記載すれば、GitHub Copilotを使う事で簡単なスクリプトはかなり手軽に作れます。
具体的には20行程度のREADMEでchatopsのスクリプトなどは生成してくれそうな所感でした。

ただし、生成されたコードが実際に動作するかどうかは検証が必要で特にAPIなどを利用する場合はCopilotにリファレンスの情報などを正しく伝える必要があるとわかりました。

適切な情報をCopilotに渡しやすくするためのテンプレートを用意すれば、ほとんど知見のない人でも実務をどんどん自動化できるのではないかと思います。

# おまけネタ
CopilotにChatのやり取りを元にAdventCalendarの記事を作成して欲しいと相談しましたが、特にひねりのない箇条書きとなってしまったので、採用を見送ることにしました :cry: 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19911/8ac4f23d-f86e-65e7-1aa3-52b3bc244751.png)