「GitHub Copilot」の裏側

服部佑樹氏:ここから、「Behind the curtain」というところで、ちょっと裏側にいきたいと思います。仕組みと、あとは、どうやって読み取るのか、Tips and Tricks、というところでいきたいと思います。

先ほど、3レイヤーありますというお話をしました。やはりこのGitHub Copilot、「Copilot Client」と呼ばれるところですね。「Visual Studio」やVisual Studio Codeがある中で、いろいろな実装があるんですが、サポートしているエディタの中ではVisual Studio Code向けの実装が一番最新のもの、かつ、精度が高いものになっているかなと思います。

「Nightly(GitHub Copilot Nightly)」というエクステンションでGitHub Copilotを入れると、ダウンロードできるのが、見えるのですが、我々もここらへんを進化させるためにA/B Testingをしています。

どこのファイルを見て言ったほうが、コードの採用率が良いかというところも含めて、いろいろ実装を進めているので、もしそういうところにご興味がある方は、1回見ていただければいいんじゃないかなと思います。

このLarge Language Models、今のトレンドで、GitHub Copilotもそれを使っていますが、けっこう勘違いされているところがあります。

例えば「GitHub Copilot」、ないし、「Copilot Chat」など、新しくできた、いわゆるチャットベースのインターフェイスを使っていると、なんでもかんでも予測してくれるという以外にも、例えばJavaのコードをRubyにしたり、RubyのコードをPythonにしたりなど、コンバージョンをしてくれるという印象を持つ方も多いと思うんですね。

実際、それは半分正しくて、半分間違いなんです。Large Language Modelsは、いわゆる次の言葉を読むモデルですね。

結局のところは、ほかのエンジンの究極版みたいなものなので、どうやって次の言葉を提案させるための情報を提供するのかが重要になってきますし、あくまでもコンバージョンモデルではなく補完モデル、というところで、コンテキストが本当に重要になってきます。

「Prompt Crafting」と社内では呼んでいますが、実際にこのGitHub Copilotにどんな情報を渡すのかが、けっこう実装で大事になってきています。

GitHub Copilotが読むファイルの一番重要なものは、上から順番になっているんですけれども、GitHub Copilotも、ChatGPTなどと一緒です。プロンプトとしてイメージしてもらうとわかると思いますが、リクエストボディに情報を突っ込んで、バックエンドに渡して、コードが提供されて返ってくるというかたちです。

ただ、やはりトークンに限りがあるので、全部のソースコードを渡す側のトークンに入れて、GitHub Copilotに提案をもらうことってなかなかできません。

あとは、それは速度を落とすという問題になるので、なるべく最低限のトークン数で、リクエストも早くポンポンポンポン送れるところを目指していると、じゃあ、どういうプライオリティでどんどん入れていくのかがけっこう重要になってくると思います。

そうした時、Pythonで書いている場合、隣で開いている別のコードはたぶんあまり価値がない。もしかすると、バックエンドのインターフェイスと合わせたいという、ユースケースはあるかもしれませんが、それは常ではないと思います。

あとは、キャメルケースなのかスネークケースなのかというところも含めて、やはり違うところもあります。なので、今のところ、GitHub Copilotは同じプログラミング言語のファイルを読んでいます。

「Language Marker」のところで、よく「これはPythonです」と一番上の先頭行に表記されていると思います。

あとはファイルパスです。例えばMVCのモノリシックなアプリケーションとかを考えると、ディレクトリの下にたぶんControllerがありますよね。そういうところできちんとファイルパスも読んでいって、今、このユーザーが何をしているのかも渡るようになっています。

(スライドを示して)あとは、オープンにしている非アクティブなタブというところで、これも全部読むわけではありませんが最大一応20ファイルまで読む可能性があります。

ですが、「First In, First Out」で、どんどんどんどん溜まっていくので、最新のファイルから、「たぶんこの人は、前の動作でこのファイルにアクセスしたからここを読むんだろうな」とか、「ここはたぶん関連しているんだろうな」とGitHub Copilotは類推して、スニペットを入れます。Prompt Craftingの中に入れるということをやっています。こういったところが重要です。

なので、Language Markerのところとか、隣で開いているファイルをどうやってハンドリングするのかによって、けっこう精度が変わってくると思います。

どうやって類似性を測っているのか?

実際にGitHub Copilotはどうやって類似性を測るかというと、GitHub Copilotは、文字の類似性を計算するアルゴリズムを活用します。

そうした時に、やはり似た文字が出現したほかのファイルのコードは、GitHub Copilotが参考情報として送るトークンの中に含まれる可能性が高くなります。

実際にGitHub Copilotをやる時には、きちんと命名規則をしておくと、さらに後ろのファイルまで影響してきちんと読んでくれる可能性が高くなるので、命名規則がかなり重要になってきます。

これは、GitHub Copilotの実装の話なんですが、実は日本に1人、GitHub Copilotの中の人というか、リサーチャーの人がいて、彼はずっとそういうエバリュエーションやGitHub Copilotをどうやって評価するのかというところをやっています。

自然言語としてどういうコードを書いていくのかというところも、調査から言えて、実際にこれは、かなり重要なところで、やはり我々も自然言語を読むトレーニングしたエンジンをGitHub Copilotのエンジンとして使っているので、いわゆる関数名も、言っちゃえば自然言語なんですよね。開発段階ではx、y、適当なfoobarなどを使いがちですが、やはりそういうところをきちんと調整してあげるといいです。

プロンプトの制限トークン数ですが、今のところ、512トークンから始まって、2048トークンまで含めることができるようになっていて、これは日に日に変わっています。

(スライドを示して)これが今の情報ですが、最新はたぶんどんどん上がりますし、今のところは、Large Language Modelsなども、どんどんどんどん与えられるトークン数を増やしていこうという方向に進んでいるので、ここはだいぶ変わっていくところかなとは思います。

一方で、多ければ多いほどいいという話ではないので、いかに最低限のコンテキストで最適な解をCopilotから引き出すかというところがかなり重要になってきます。

そうした時に、これは、こうしたほうがいいという話なのですが、トークン数を節約するには英語のほうがベターです。こういうちょっと言語的なところももしかすると関わってくるところかもしれないと思っています。

ファイルのピン留め・一貫性のあるコーディングスタイル・命名規則…Tipsを紹介

ちょっと、「Tips and Tricks」というところで、背景も含めてGitHub Copilotではどういったプラクティスがあるのかを、まとめたブログのようなものを個人的に作っているので、ぜひアクセスしていただくと、「あぁ、なるほどね」と(なると思います)。

もしかしたら、それぞれのセクションのヘッダーを見れば、「あぁ、なるほど」と、よくある目次だけ読めば納得できる本みたいな感じになっているかもしれない(笑)。アクセスして見ていただくと、「あぁ、なるほどね」と、ちょっとわかると思うので、ぜひ参考にしていただければなと思います。

Tipsとして挙げられるものをいくつか持ってきました。まず、便利なファイルのピン留め。例えばTypeScriptとかを書いていると、「.d.ts」、型定義ファイルがあると思います。デクラレーションファイルですね。

そういったファイルって、いわゆるインターフェイスや、引数で何を与えたらいいのかというところも含めて関数にまつわる情報をだいぶ持っているんですよね。

そういったものをピン留めしておくと、非常にGitHub Copilotの精度が上がります。もちろんピン留めするだけじゃなくて、「最近開いた項目」というところの履歴を残す必要があるので、そこはちょっと注意が必要です。

あとは、CSVやMarkdownのファイルに関しては、先ほど、同じ言語のファイルを読みますというお話をしましたが、今のところコメントアウトのところに持ってきてコピペしてもらうという方法がベストかなと思います。

それ以外にも、ライブラリ、共有ライブラリ、ないし、オープンソースのライブラリを使っている中で、どうやってそこの情報を含めるのかというところでいうと、Visual Studio Codeには、「定義へ移動」というボタンがあります。それでどんどんどんどん実装をさかのぼっていくと、GitHub Copilotは、実装のところまで見てくれるので、最終的に、「なるほど、こういう条件だったからこうなんだ」ということがわかってくれます。

あとは、先ほど言いましたが、一貫性のあるコーディングスタイルおよび命名規則がだいぶ重要になってきます。

というところで、あとは、見ていただければと思います。ぜひ、「GitHub Copilotでこんな方法がありました」みたいなことをTwitter(現X)などで共有していただければなと思います。

ものすごいざくっといきましたが、最終的にはみなさんが質問できるように我々は作っているので、元も子もないことをまとめで言っていますが、あまり気にし過ぎず、ハッピーコーディングというところで。

ぜひ、わかりやすいコードを書くというところを意識していただけたらなと思います。

というところで、次の方にバトンを渡したいと思います。ありがとうございました。

(会場拍手)