コードの自動生成をあなたのPCでも実現！GitHub CopilotをVisual Studio Codeで使ってみた

こんにちは、もっちゃんと申します。

こちらの記事は Visual Studio Code Advent Calendar 2021 の14日目の記事でもあります。

https://qiita.com/advent-calendar/2021/vscode

そして2021年最後のVS　Code MeetupイベントのLTネタだったりもします。

https://vscode.connpass.com/event/231495/

昨今、機械学習は我々にとって身近なものになりつつあります。そしてその進歩は目覚ましく、特に自然言語にまつわる分野はブレイクスルーが起きている状態です。
開発の場においても機械学習と自然言語で世間を賑わせている存在があることをご存知でしょうか？
そう、`GitHub Copilot`のことです。
この記事では`GitHub Copilot`がどのようなものなのか、皆さんと一緒に見ていきたいと思います。

## GitHub Copilotとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/65019ded-767a-46d3-0591-b602227becf9.png)

>Today, we are launching a technical preview of GitHub Copilot, a new AI pair programmer that helps you write better code. GitHub Copilot draws context from the code you’re working on, suggesting whole lines or entire functions. It helps you quickly discover alternative ways to solve problems, write tests, and explore new APIs without having to tediously tailor a search for answers on the internet. As you type, it adapts to the way you write code—to help you complete your work faster.
Developed in collaboration with OpenAI, GitHub Copilot is powered by OpenAI Codex, a new AI system created by OpenAI. OpenAI Codex has broad knowledge of how people use code and is significantly more capable than GPT-3 in code generation, in part, because it was trained on a data set that includes a much larger concentration of public source code. GitHub Copilot works with a broad set of frameworks and languages, but this technical preview works especially well for Python, JavaScript, TypeScript, Ruby and Go.
本日、GitHub Copilotのテクニカルプレビューを開始します。GitHub Copilotは、より良いコードを書くための新しいAIペアプログラマーです。GitHub Copilot は、あなたが作業しているコードからコンテキストを引き出し、行全体や関数全体を提案します。問題を解決するための別の方法をすばやく見つけ出し、テストを書いたり、新しいAPIを探索したりする際に、インターネットで答えを探すような面倒な作業をしなくても済むようになります。入力すると、コードの書き方に合わせて、より速く作業を終えることができるようになります。
OpenAIと共同で開発されたGitHub Copilotは、OpenAIが開発した新しいAIシステムであるOpenAI Codexを搭載しています。OpenAI Codexは、人々がどのようにコードを使用しているかについて幅広い知識を持っており、公開されているソースコードをより多く含むデータセットで学習されたこともあり、コード生成能力はGPT-3よりも格段に高くなっています。GitHub Copilotはさまざまなフレームワークや言語に対応していますが、今回のテクニカルプレビューでは特にPython、JavaScript、TypeScript、Ruby、Goに対応しています。

* https://copilot.github.com/
* https://github.blog/2021-06-29-introducing-github-copilot-ai-pair-programmer/

昨今、文章自動生成などにおいて目覚ましい成果をあげているGPT-3よりもさらにコード生成に特化したOpenAI Codexが使用されている。
開発者がエディタ(VS Codeなど)に入力した文字情報(コード、文章など)をコンテキストに、OpenAI Codexがコンテキストにもどづいて次に続く文字列(コード、文章など)を予測して返すというもの。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/1fe3a463-e776-ea54-2c60-a1135caf0afe.png)

※ Microsoft Ignite 2021 『[An introduction to the Azure OpenAI Service](https://myignite.microsoft.com/sessions/e3f5c4bc-5cc8-4e09-89a7-033da3a16433?source=sessions)』 セッションより情報を引用

## ちなみにGPT-3とは

超巨大な汎用言語モデルのことである。
詳細は割愛するが、Generative Pre-trained Transformer(GPT)の名前にもある通り、事前学習を大規模に行う機械学習モデルで、Transformerと呼ばれる仕組みを導入にしているのが特徴。
非常に精度が高く、また１つのモデルで複数のタスク（分類、翻訳、要約などなど）をこなすことができる。

OpenAI Codexはコードに特化したモデルとのことで、コーパスはおそらくGitHubなどのインターネットに公開されているコード情報が学習データに活用されていると思われる。
（私自身、至らないコードをそれなりにGitHubに上げてしまっているので、それも学習データに含まれているのではということで、モデルの精度の足を引っ張ってたらちょっと申し訳ない気持ち^^;）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/8fdb1449-c7ad-f399-2f53-7b3ebae5949f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/25b8f87f-3bb5-cd5a-1b9d-13fae0cd3ea8.png)

※ 論文: 『[Attention Is All You Need](https://arxiv.org/abs/1706.03762)』から画像を引用

## どうやって使うの？

まずはGitHub Copilotの[waitlistに登録します](https://github.com/features/copilot/signup)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/bbe99a00-e0fd-0a02-65df-76651d9fb549.png)

すると、プレビューが通った連絡のメールが来るので

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/96aa6944-aaff-0633-348c-10722ec38e35.png)

案内に従い、[GitHub Copilotのドキュメントサイト](https://github.com/github/copilot-docs)にアクセスします。
あとはドキュメントの[Getting Started](https://github.com/github/copilot-docs/blob/main/docs/visualstudiocode/gettingstarted.md#getting-started-with-github-copilot-in-visual-studio-code)を参考に

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/932e3181-423d-39e0-55cc-0e9d16bbcc89.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/e833810d-b8a2-3d90-6987-43c75fea4564.png)


GitHub Copilot の拡張機能をVS Codeにインストールするという感じです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/d02c0e30-f6f1-14de-5f92-4542050189e2.png)

## さっそく使ってみよう

自然言語を用いて、意図したコードを生成してくれるかみてみましょう。
ここではアドレスの値をチェックして、正しいアドレスのものをリストで返してくださいと、コメントしています。
すると...見事にそれっぽいコードを生成してくれていますね！

![githubcopilot3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/da9bdbde-7f9a-4e72-94e8-9b5de7b6c43a.gif)

ちなみに下記のように予測候補を複数持っている場合があり、「次へ」、「前へ」で選ぶ事ができます。今表示されている候補でよければ　Tabを押して確定する感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/35c410df-b733-37c5-c462-d091f425f440.png)

ちなみに「Open GitHub Copilot」を選ぶと、右側に候補全てが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/c8e2eb82-299a-b66c-21c0-2e046192ce0e.png)



## さらに試してみる

上の方の説明で`Transformer`というものに触れていますが、こちらはもともと機械翻訳を目的としたものでした。
ということで、コードの翻訳！...別言語へのコンバートは相性が良いのではないかと思い、試してみましょう！...

とりあえずここでは、[The State of the Octoverse(GitHub)](https://octoverse.github.com/)のランキング上位に位置している言語を対象にしてみます。
（上位の言語であれば学習で使ったデータの量がある程度多く、精度が高くなると思ったというのもあります。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/16899323-6b5a-0b47-b49a-3f2c2dd0ee09.png)

まずはコンバート元となるプログラムを用意します。こちらは`Javascript`を使用しました。

* Javascript

```javascript
// BubbleSort method
function BubbleSort(arr) {
    var result = arr;
    for (var i = 0; i < result.length; i++) {
        for (var j = 0; j < result.length - i - 1; j++) {
            if (result[j] > result[j + 1]) {
                var temp = result[j];
                result[j] = result[j + 1];
                result[j + 1] = temp;
            }
        }
    }
    return result;
}

// main
function main() {
    var arr = [2,10,3,5,4,9,6,8,7,1];
    console.log("Array after sorting: " + BubbleSort(arr));
}

```


そしてここから下がコンバート先の言語を記載しています。
ちょっと手を加えたところもありますが、それなりにコンバートできていそうですかね。
（ちなみにPHPとかはあまり上手くいきませんでした汗）

<details>
  <summary>Python</summary>
  <div>   

  ````Python
## convert to Python, BubbleSort method
def BubbleSort(arr):
    for i in range(len(arr)):
        for j in range(len(arr) - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr

## convert to Python, main
def main():
    arr = [2,10,3,5,4,9,6,8,7,1]
    print("Array after sorting: ", BubbleSort(arr))
   ```

  </div>
</details>

<details>
  <summary>TypeScript</summary>
  <div>   

  ````TypeScript
// convert to Typescript, BubbleSort method
function BubbleSort(arr: number[]): number[] {
    var result = arr;
    for (var i = 0; i < result.length; i++) {
        for (var j = 0; j < result.length - i - 1; j++) {
            if (result[j] > result[j + 1]) {
                var temp = result[j];
                result[j] = result[j + 1];
                result[j + 1] = temp;
            }
        }
    }
    return result;
}

// convert to Typescript, main
function main()
    var arr = [2,10,3,5,4,9,6,8,7,1];
    console.log("Array after sorting: " + BubbleSort(arr));
}

   ```

  </div>
</details>

<details>
  <summary>Java</summary>
  <div>   

  ```Java
// convert to Java, BubbleSort method
import java.util.*; // add

public class BubbleSort {
    public static void main(String[] args) {
        int[] arr = {2,10,3,5,4,9,6,8,7,1};
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        System.out.println("Array after sorting: " + Arrays.toString(arr));
    }
}

  ```

  </div>
</details>

<details>
  <summary>C#</summary>
  <div>   

  ````csharp
// convert to csharp, BubbleSort method
public class BubbleSort
{
    public static void Main(string[] args)
    {
        int[] arr = {2,10,3,5,4,9,6,8,7,1};
        for (int i = 0; i < arr.Length; i++)
        {
            for (int j = 0; j < arr.Length - i - 1; j++)
            {
                if (arr[j] > arr[j + 1])
                {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        System.Console.WriteLine("Array after sorting: " + string.Join(",", arr));
    }  
}

   ```

  </div>
</details>


## GitHub Copilot の新しい機能？コードの説明文も自動生成(12/13時点)

さらにさらに[こんな投稿](https://github.com/github/feedback/discussions/8308)を見つけたので、試してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/e807c88c-52d5-99ed-f426-8db4e0458924.png)

さっそく[GitHub Copilot Nightly 拡張機能](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-nightly)を入れて...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/0e5b6ada-294a-5b53-9638-5f0e81aea30b.png)

なんと、コードの処理内容を文章化してくれました！...GitHub Copilotの進化は止まりません！...

![githubcopilot2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/a999396e-1732-7eef-14dd-14af1ed6575d.gif)


## まとめ　

`GitHub Copilot`については今のところ賛否両論（めちゃくちゃ優秀、現時点で使い物にならない）や様々な意見があると思いますが、個人的には人が入力した文字列情報を見て、意図した内容の文字情報を返してきており人間に近いやり取りが成立しているところに感動しています。基本的なやり取りが成立しているということで、返ってくるコードの予測精度は日々改善されていくと考えると、いずれは誰もが認める完全なコードの自動生成が実現する日が来ると確信しています。今後がとても楽しみで機械学習って本当に良いものですねぇ。そして今回のこと含めあらゆる事にVS Codeは絡んでいてそれもまた素晴らしい。

## 参考

* https://qiita.com/uikou/items/5f026cd7b4aacf74eeaf