概要
「GitHub Copilot」を使用して、日本語からソースコードを半自動生成させてみました。
また、しばらく試行してみて、Copilotの活用シーンを整理しました。
Copilotとは
2020年5月にイーロン・マスク氏らが関わっているAIの非営利団体OpenAIによって、自然言語モデルGPT-3が発表されました。このモデルは、生成された文章が、人間が書いたのかAIが書いたのか区別できないほど高精度なモデルということで当時、話題になりました。
OpenAIではGPT-3をカスタマイズし、自然言語からソースコードを生成するCodexモデルを開発していましたが、OpenAIとGithubが提携したことによって、Githubで公開されている数十億行のコードを学習させることができるようになり、より高精度なソースコードを生成させることが出来るようになりました。
そして、2021年6月29日にGithubによって、Codexモデルを利用した開発支援機能「GitHub Copilot」が発表されました。
OpenAI Codexは、APIでの利用のため使用方法が限定されていましたが、GitHub Copilotは、下記のような開発環境のアドオンとして機能追加できるため、よりユーザが使いやすいようになっています。
■Copilot対応 開発環境
- Neovim
- JetBrains IDE
- Visual Studio
- Visual Studio Code
なお、Github Copilotの費用は、最初の60日間は無料で、その後は有料で以下2プランから選択することになります。
■契約プラン
- 10ドル/月
- 100ドル/年
試行環境
今回、ソースコードを自動生成させた環境は下図の通りです。
実行環境はWindows11上に構築したWSL2/Ubuntu20.04です。
Windows11上にVisual Studio Codeをインストールし、拡張機能である「GitHub Copilot」と「WSL」を追加します。(下図「1.」と「2.」)
「GitHub Copilot」を追加することで、GitHub認証後にGiHub Copilotと連携できるようになります。(下図「3.」)
文章を与えると自動的にソースコードが提示(サジェスト)されます。この提示されたソースコードは、OpenAIのCodexモデルが利用されています。(下図「3.」~「6.」)
なお、Copilotとは関係ないですが「WSL」をVisual Studio Codeに追加することで、WSL内のファイルを制御できるようになります。
- 実行環境イメージ
自動生成イメージ
Visual Studio Codeでソースコードを自動生成させるのは、とても簡単です。
基本は待つだけです。 1~2文字でも入力すれば、Copilotが何かしらソースコードを提示してくれます。時には、何も入力しなくても提示してくれることもあります。
例えば、下図のように「import」と入力して1秒ほど待つと、「requests」というコードが提示されます。
この内容を受け入れる場合はTabキーを押下します。
Tabで受け入れて改行すると、今度は次の行のコードが自動的に提示されます。
提示されたコード「from requests_oauthlib import OAuth1Session」を受け入れる場合は、Tabを押下します。
改行すると、また次のコードが提示されます。
さらに改行すると、また次のコードが提示されます。
繰り返し提示されます。
このように、Tabと改行を繰り返すだけで、Copilotが勝手にソースコードを生成してくれるのです。
また、提示された際に「Ctrl+Enter」を押下すると、ある程度まとまった範囲で提示してくれます。
例えば、「requests」が提示された際に「Ctrl+Enter」を押下すると、下図のように纏まったソースコードが10パターン提示されます。
選択したいパターンの「Accept Solution」をクリックすると、そのコードを全て書き込んでくれます。
試行
では、より実践的に開発してみます。
今回は、以下の3行のコメントをVisual Studio Codeに入力して、コードを自動生成してみます。
あらかじめ、ファイル名には.pyとPythonと分かるようにしておきます。(Copilotは、Python以外も対応していますが、サジェストの採用率はPythonが40%と高いようです。)
# ニュースサイトをクローリングして、時系列順にAIのキーワードを抽出する。
# 抽出したキーワードからWordCloudを作成する。
# 作成したWordCloudをTwitterに投稿する。
結果は、ほぼ、Tabと改行だけでソースコードの土台ができました。
下記に、提示されたソースコードの一部を紹介します。
Twitterに投稿するための各種キーの設定です。OSの環境変数から取得するようになっています。
なお、コメント行も自動で生成されます。
# Twitter APIのキーを設定
CK = os.environ['CK']
CS = os.environ['CS']
AT = os.environ['AT']
AS = os.environ['AS']
クローリングするサイトのURLを指定しています。
# ニュースサイトのURLを設定
URL = 'https://www3.nhk.or.jp/news/easy/k10011852901000/k10011852901000.html'
まるで「クローリングなんて簡単、簡単!」と言わんばかりに、あっという間にBeautifulSoupを用いた処理を生成します。
# ニュースサイトをクローリングして、本文を取得する
def get_news_text(url):
r = requests.get(url)
soup = BeautifulSoup(r.text, 'html.parser')
news_text = soup.find('div', class_='text').text
return news_text
次は、Mecabを使用してキーワードのみを抽出します。
「私は自然言語にも強いのよ。」と言っているようです。
# 本文からAIのキーワードを抽出する
def get_ai_keywords(text):
# 形態素解析
tagger = MeCab.Tagger('-Ochasen')
tagger.parse('')
node = tagger.parseToNode(text)
keywords = []
while node:
# 品詞が名詞、動詞、形容詞の場合にキーワードとして抽出
if node.feature.split(',')[0] in ['名詞', '動詞', '形容詞']:
keywords.append(node.surface)
node = node.next
# キーワードをカウント
keywords_count = {}
for keyword in keywords:
if keyword in keywords_count:
keywords_count[keyword] += 1
else:
keywords_count[keyword] = 1
# キーワードを降順に並び替え
keywords_count = sorted(keywords_count.items(), key=lambda x:x[1], reverse=True)
return keywords_count
さらに、「WordCloudなんて、もう古い技術だけど仕方ないわね」と言われたりして、、、
# 抽出したキーワードからWordCloudを作成する
def create_wordcloud(keywords_count):
# フォントを設定
font_path = '/usr/share/fonts/truetype/fonts-japanese-gothic.ttf'
# マスク画像を設定
mask = np.array(Image.open('mask.png'))
# WordCloudを作成
wordcloud = WordCloud(background_color='white', font_path=font_path, mask=mask)
wordcloud.generate_from_frequencies(dict(keywords_count))
# WordCloudを保存
wordcloud.to_file('wordcloud.png')
最後は、Twitterに投稿して、「はい。いっちょうあがり!」という感じです。
# WordCloudをTwitterに投稿する
def post_wordcloud():
# 画像を読み込む
files = {'media[]': open('wordcloud.png', 'rb')}
# ツイート本文を設定
text = 'AIのキーワードを抽出したWordCloudです。'
# Twitterに投稿
twitter = OAuth1Session(CK, CS, AT, AS)
url = 'https://upload.twitter.com/1.1/media/upload.json'
req_media = twitter.post(url, files=files)
if req_media.status_code != 200:
print('画像のアップロードに失敗しました。')
sys.exit()
media_id = json.loads(req_media.text)['media_id']
url = 'https://api.twitter.com/1.1/statuses/update.json'
params = {'status': text, 'media_ids': media_id}
req_media = twitter.post(url, params=params)
if req_media.status_code != 200:
print('ツイートに失敗しました。')
sys.exit()
print('ツイートしました。')
ここまで作った関数を呼び出すmain処理も全て自動で作成されます。
def main():
# ニュースサイトをクローリングして、本文を取得する
text = get_news_text(URL)
# 本文からAIのキーワードを抽出する
keywords_count = get_ai_keywords(text)
# 抽出したキーワードからWordCloudを作成する
create_wordcloud(keywords_count)
# WordCloudをTwitterに投稿する
post_wordcloud()
if __name__ == '__main__':
main()
ただ、永遠と提示されるので辞め時は人間が判断しなければなりません。
最終的には、私が多少デバッグを行い、下図のようなWordCloudを作成させることが出来ました。
Copilotの活用シーン
しばらく試行した結果、私なりにCopilotの活用シーンを整理しました。
Copilotを使う良いタイミング
区分 | 項目 | 評価 |
---|---|---|
1 | 設計 | - |
2 | コーディング | ◎ |
3 | テスト | - |
4 | デバッグ | ◎ |
開発工程においてCopilotを活用できるのは、コーディング時とデバッグ時だと思います。
コーディング時はほとんど何もしなくて良かったため、考えるまでもなく評価「◎」としています。
人間の出番はデバッグ時からですが、デバッグ時のCopilotの威力が尋常ではないと感じました。
例を3つ挙げます。
デバッグ例1
下図のようにプログラム中の変数の中身を表示しようと「#デバッグ用」と打ち込むだけで、デバッグ用の構文を自動生成してくれました。(赤枠の箇所)
Copilotが前段のキーワードに関する処理を考慮してデバッグ文を提示してくれるのです。何を表示したいのか当てられてしまい、正直、自分の心が見透かされていると感じました。
デバッグ例2
また、BeautifulSoupでfind関数だと欲しいデータが取得できなかったため、私がfind_all関数に書き換えたのですが、戻り値news_textの型を知らず、print文でどう指定すれば良いか分かりませんでした。そのような時、「print」と打ち込むだけで、残りの変数名「new_text[0].text」など配列の要素を含んだ変数を自動補完してくれました。いちいち、Webで調べたりドキュメントを参照したりする手間が省けて、非常に楽でした。
デバッグ例3
さらに、変数が配列型では使いにくかったので、テキストに変換したいなと思い、コメントで「# 配列から」と打ち込むと「抽出したテキストを結合」と補完され、対応する処理を自動提示してくれました。
プログラミング言語によって微妙に仕様が異なる紛らわしい配列操作をいとも簡単に提示してくれるのです。
Copilotを活用できる人、活用できない人
区分 | 項目 | 評価 |
---|---|---|
1 | プログラミング言語未経験者 | ○ |
2 | 初心者~上級者 | ◎ |
3 | こだわり派 | △ |
多くの人がCopilotの恩恵を受けられると考えています。
仮にプログラミング言語の理解が2割程度であっても、大半はCopilotが自動生成してくれますので、最後のデバッグのみを人間が対応すれば、一応、完成までたどり着けるのではないかと思います。まさに、AIとのペアプログラミングです。(初心者◎)
仮に、言語を全く知らずデバッグが出来なかったとしても、言語に詳しい方にデバッグだけお願いすれば良い訳ですから、一からお願いするよりもはるかに短期間、低予算で委託することが出来るはずです。(未経験者○)
もちろん、言語を10割理解している上級者であっても、生産性は圧倒的にCopilotが高いはずですから、ベースはCopilotに任せて、気になる箇所だけ人間が修正すれば良いとも思います。(上級者◎)
逆に、自分のソースコードにこだわりを持っている方は、AIが提示したソースコードには気に入らないコードと感じる場合もあるかもしれません。AIが提示したと言っても結局は、GitHub上にあるソースコード群をもとに提示されているため、思想の異なるコーディングが次々に提示される可能性もあります。
例えば、「a + b」を計算するサジェストにおいて、ある時は変数「x」に代入し、また、ある時は 「+=」を使って「a」を上書きするというような、細かなサジェストの違いが発生する可能性があります。
x = a + b
a += b
どちらのサジェストが良いということはないですが、ソースコード全体としての統一感が失われることがあります。
このような動作を嫌い、自分でコーディングしたいと思われる方は、あまり向いていないかもしれません。(こだわり派△)
Copilotが向いている開発、向いていない開発
区分 | 項目 | 評価 |
---|---|---|
1 | 研究関連 | ◎ |
2 | アジャイル開発 | ◎ |
3 | ミッションクリティカル | × |
4 | 最先端技術開発 | △ |
Copilotでは、GitHub上のソースコードからサジェストされていると考えると、研究要素が強いソースコードが多いのではないかと推測します。このため、ソースコードに一部誤りがある可能性は否定できません。
そのようなソースコードでも許容できる開発を考えると、同じように研究関連の開発やアジャイル的に試行錯誤しながら開発できるような案件が向いていると思います。(研究開発◎、アジャイル開発◎)
一方、ミッションクリティカルなシステム開発には向いていないと思います。
止まってはいけない社会的にも重要なシステム(交通機関や金融機関など)は、高品質なプログラムを要求されますので、フールプルーフやフェイルセーフを意識してエラー処理を作りこむことがあると思いますが、Copilotが提示するソースコードに細部を考慮したエラー処理がない可能性が高いと考えています。あるいは、高速処理を要求されるようなシステムでは、性能を意識したコーディングが必要ですが、こちらもCopilotの提示が最良と判断するのは尚早だと思います。このような高品質なプログラムを要求される場合はCopilotを使用するのはリスクと考えておいても良いでしょう。(ミッションクリティカル×)
他には、最新技術を使用したい場合には、なかなか所望のソースコードを提示してくれない可能性が高いです。
もちろん、コメントで最新技術を提示するよう指定することは可能ですが、GitHubに登録されているソースコードが少ないと限界があります。(最先端技術開発△)
その他特徴
Copilotの仕様上の特徴ですが、何も提示するものがなさそうな時は、過去に提示した履歴から提示することがあるようです。
おそらく、人間が与える文章が少なすぎて何を提示して良いのか分からない時に、このような動作になる仕様だと思われます。
感想
Copilotを60日間の試行期間中に使ってみようと思っていましたが、全く時間が取れず、結局、月額利用で試してみました。
実際、私の場合、大体、コーディング時間は十分の一くらいにはなっていると思います。
すぐに辞めるつもりではありましたが、かなりの時間短縮になり、一度、この感動を味わってしまうと、辞めるのは惜しいと考えています。
何かを作りたいときだけ一時的に利用するのであれば、費用対効果の面で十分ありだと思いました。
補足
Copilotが作成したファイルと私がデバッグしたファイルを下記に登録しました。
https://github.com/artisanbaggio/Copilot_test.git
「test_only_copilot.py」←Copilotのみが生成したソースコード。このままでは動作しません。
「test_only_copilot_human.py」←Copilotのソースコードに私が手を加えたものです。動作しますが、Twitter投稿まではしません。
参考サイト
以上、最後までお読みいただき、ありがとうございました。