こんにちは! KEPPLE CREATORS LABでエンジニアをやっている丸山です。
近年、ChatGPT を始めとする AI ツールが着々と浸透しつつあると思います。私自身の身近なところで使用頻度が高いのは GitHub Copilot です。
GitHub Copilot は学習したコードのパターンをもとに、自動でコードを生成してくれるため、日頃の開発を手助けしてくれています。また、GitHub Copilot は OpenAI と GitHub が共同開発したツールであり、事前に GitHub 上のコードを学習しているため、高い精度でコードを補完してくれます。
VSCode の拡張機能としても提供されており、普段から VSCode を使っている人は普段のツールをそのまま使えるので良いですね。
今回は数ヶ月Github Copilot を使ってみて便利だと思った使い方を紹介しようと思います。
テストコードを生成する
GitHub Copilot は、テストを書く際に非常に役立ちます。テストのパターンを 1 つ書くと、他のパターンを補完してくれるため大変便利です。
試しに簡単なテストコードを生成してみようと思います。一から十の漢数字を引数に取り英数字に変換して返す関数のテストを書きます。まずは、はじめに以下のテストを自分で書きます。
describe("kan2num", () => {
it("引数に「一」が渡された場合に1を返す", () => {
expect(kan2num("一")).toBe(1);
});
})
そして、このテストの下で改行をすると右下の Copilot のアイコンがローディングされます。
すると、以下のように基本的なパターンを自分で書いたコードを見ていい感じに補完してくれます。
![](https://assets.st-note.com/production/uploads/images/115532211/picture_pc_48426ebb443fdafd89fcafeaf9b06ab0.gif)
テストはどうしても単純なパターンを複数書くことになるので、この補完はとても便利です。正直、私が GitHub Copilot を利用する上で便利に感じている部分の 7 割ぐらいはこの機能と言っても過言ではありません。
もちろん必ず完璧なテストコードが生成される訳ではないので補完されたパターンを確認し、必要に応じて修正してください。
実装前にコメントもしくはテストを書くとコードを実装してくれる
ここまでは GitHub Copilot によってテストを生成してきましたが、今度はコードの実装をしてもらおうと思います。
何らかの関数を生成する際のコツはコメントとテストを書くことです。私は実装前に設計を整理するのにテストを先に書くことが多くあり、Copilot に実装させることと合わせてメリットが多いです。
先程のテストを一から十まで検証するように書きました。
it("引数に「一」が渡された場合に1を返す", () => {
expect(kan2num("一")).toBe(1);
});
it("引数に「二」が渡された場合に2を返す", () => {
expect(kan2num("二")).toBe(2);
});
it("引数に「三」が渡された場合に3を返す", () => {
expect(kan2num("三")).toBe(3);
});
it("引数に「四」が渡された場合に4を返す", () => {
expect(kan2num("四")).toBe(4);
});
it("引数に「五」が渡された場合に5を返す", () => {
expect(kan2num("五")).toBe(5);
});
it("引数に「六」が渡された場合に6を返す", () => {
expect(kan2num("六")).toBe(6);
});
it("引数に「七」が渡された場合に7を返す", () => {
expect(kan2num("七")).toBe(7);
});
it("引数に「八」が渡された場合に8を返す", () => {
expect(kan2num("八")).toBe(8);
});
it("引数に「九」が渡された場合に9を返す", () => {
expect(kan2num("九")).toBe(9);
});
次に、別のファイルに関数の雛形を書き、処理を生成します。
![](https://assets.st-note.com/production/uploads/images/115532301/picture_pc_e21a698359a2edbdece28b24390e2d2c.gif)
簡単な関数であれば、このような具合に生成することができます。
この関数では漢数字一文字しか渡すことができません。十の漢数字を使って二桁の漢数字を受け取れるようにするため、先程のテストに以下のようにテストパターンを足してみました。
it("引数に「十一」がのように組み合わせて渡された場合に11を返す", () => {
expect(kan2num("十一")).toBe(11);
});
it("引数に「二十」がのように組み合わせて渡された場合に20を返す", () => {
expect(kan2num("二十")).toBe(20);
});
it("引数に「二十一」がのように組み合わせて渡された場合に21を返す", () => {
expect(kan2num("二十一")).toBe(21);
});
上記コードを追記した上でもう一度補完してみます。
export const kan2num = (str): number => {
const kan2numMap = {
一: 1,
二: 2,
三: 3,
四: 4,
五: 5,
六: 6,
七: 7,
八: 8,
九: 9,
十: 10,
};
if (str.length === 1) {
return kan2numMap[str];
}
const [first, second] = str.split("");
return kan2numMap[first] * kan2numMap[second];
};
しかし、テストが複雑すぎるためか、このテストをうまく通るコードは生成できませんでした。
このような場合は、コメントを少しずつ追加で書いていくとうまく生成できるパターンがあります。
以下はコメントを追記し、その下に実装を生成していった結果です。
export const kan2num = (str) => {
const kan2numMap = {
一: 1,
二: 2,
三: 3,
四: 4,
五: 5,
六: 6,
七: 7,
八: 8,
九: 9,
十: 10,
};
// 十が含まれている場合
if (str.includes("十")) {
// 十の前後どちらにも数字がない場合
if (str.length === 1) {
return 10;
}
// 十の前後どちらかに数字がある場合
if (str.length === 2) {
// 十の前に数字がある場合
if (str[0] !== "十") {
return kan2numMap[str[0]] * 10;
}
// 十の後に数字がある場合
if (str[1] !== "十") {
return 10 + kan2numMap[str[1]];
}
}
// 十の前後に数字がある場合
if (str.length === 3) {
return kan2numMap[str[0]] * 10 + kan2numMap[str[2]];
}
}
return kan2numMap[str];
};
複雑な関数を書く前に、整理を目的にテストやコメント書いておくと、GitHub Copiilot がいい感じにコードを生成してくれることがあります。
仮に期待通りに生成できなくても、実装のベースになるコードを生成できることが多いです。
GitHub Copilot Chat
2023年7月20日にGitHub Copilot Chat という機能が追加されました。拡張機能を追加する必要がありますが ChatGPT のようなチャット形式で何でも質問することができます。発表時の記事を見る限りでは GPT-4 を利用しているようですね。
VSCode 上でチャットできるので、開発しながらシームレスに活用することができ、想像以上に便利です。
ちなみに、ファイルに書かれているコードを選択して右クリックの Copilot → コードチャットを開始する をクリックすることでそのコードをコンテキストにチャットすることができます。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/k/kepple-creators-lab/20240409/20240409185356.png)
コード記述時にとりあえず explainをする
何らかのロジックを書いたときに、とりあえず explain すると、そのロジックを説明してくれたり、そのコードの改善案を提示してくれることがあります。
コードの説明をもとにコメントを書いたりすることもできます。ただし、コードの説明は英語なので日本語に翻訳するとよいと思います。
以下のようなコードを書いてみました。三項演算子を繋げていて少し読みづらく扱いづらいと思います。
/*
* 数字を漢数字に変換する
* @param {number} num
* @returns {string}
/
export const num2kan = (num: number): string => {
return num === 1
? "一"
: num === 2
? "二"
: num === 3
? "三"
: num === 4
? "四"
: num === 5
? "五"
: num === 6
? "六"
: num === 7
? "七"
: num === 8
? "八"
: num === 9
? "九"
: num === 10
? "十"
: "";
};
上記のコードを選択し Copilot → これを説明する を選択します。するとチャットが表示され以下のようになります。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/k/kepple-creators-lab/20240409/20240409185401.png)
ここでは、コードの説明とそのコードをより読みやすく変更しやすい書き方にする提案が行われています。
パフォーマンスの観点の改善案や、より具体的なコードで「こう書いたほうがシンプルになる」というアドバイスを提示してくれるため、複雑なロジックを書いたりした場合は使ってみてもいいかもしれません。
また改善案が出てきた場合には、 Copilot → これを修正する で修正してみましょう。今度は入力欄が出てくるので修正したい内容を自由に書いてください。今回は可読性を上げてくださいと書きました。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/k/kepple-creators-lab/20240409/20240409185406.png)
すると選択範囲と提案されたコードの差分が表示され、同意のボタンを押すことでファイルに反映することができます。
内容もよりシンプルになったかと思います。普段からガンガン使うことは無いですが、たまに気づきをもらえるかもしれません。
まとめ
正直に言うと、当初思っていた以上に便利だと思いました。もし明日から使えなくなったらだいぶ開発効率が下がりそうで怖いです。
一方で、ここまで説明してきたようにコメントを書いても補完が出なかったり、うまく生成できないケースもあり歯がゆさを感じることはあります。
また、補完してもらったものを鵜呑みにしてそのまま使うのは危険なので、補完されたものを自身で確認することが大事です。
他にも便利な使い方がありそうなので、これからも活用方法を考えながら使って行きたいと思います。
弊社のように、企業で GitHub Copilot を導入する場合は、セキュリティの観点から GitHub Copilot for Business を利用するようにしましょう。