🤖

Github Copilotの精度を上げる使い方

2023/10/19に公開

はじめに

Github Copilot使ってますか?
僕はそれがないとダメな体にされてしまいました。

冗談はさておき、大手各社によるCopilotの導入と検証結果が公表されるようになってきました。いずれも、Github社の主張を裏付けるようなものとなり、これはもう乗るしかない!このビッグウェーブに!て感じですね。

さて、本記事はそんな私がGithub Copilotの精度を上げる使い方をまとめた記事です。

Copilotの構成

クライアント、バックエンド、LLMの3レイヤーでGitHub Copilotは作成されています。
Copilot Client → Copilot Platform(API) → OpenAI Model
の流れですね。

LLM(Large Language Models)は、いわゆる次の言葉を読むモデル。

https://toukei-lab.com/llm

与えられた入力に基づいて特定のタスクを遂行することを目的としていた過去のモデルに対して、補完モデルのLLMは、与えられた文脈に基づいて入力を補完することを目的としています。つまり、与えられた情報を補完し、文脈に基づいた意味を生成することを目指しています。したがって、求める回答の精度を高めるためにはコンテキストが重要になるということです。(コンテキストを調整していくことをGithub社では「Prompt Crafting」って呼んでるらしいです)

また記述の通り、リクエストボディに情報を突っ込んで、バックエンドに渡して、コードが提供されて返ってくるという形をとっています。コンテキストが重要とはいえ、トークン数も含めて限りがありますね。最低限のトークン数で最適な提案をもらうためには、さらにリクエスト内の優先順位も大事になってくるわけです。

Prompt Crafting

Copilotに渡っているコンテキスト情報は以下です。

  • Language Marker:プログラミング言語情報
  • Path Marker:現在のファイルへのパス
  • Neighboring Tabs:非アクティブなオープンしているタブ
  • Code Retrieval: コードベースの中の他の場所のコード

今のところ、GitHub Copilotは同じプログラミング言語のファイルを読んでいるそうです。それとファイルパス。ファイルパスで何をしようとしてるかを判断するようです。また、オープンにしている非アクティブなタブも最大20ファイルまで読む可能性があるそうです。
したがって、隣で開いているファイルをどうやってハンドリングするのかによって、精度が変わってきます。

また、関数名も自然言語だと思うようにしましょう。
結局Copilotは自然言語を読むトレーニングしたエンジンを使ってるわけなので、一貫して命名規則と綺麗なコードが大事であることに変わりはありません。それと今何やってるかにフォーカスして作業することです。記述の通り、同時に開いているファイルのコードは精度に影響してきます。今取り掛かっているタスクに集中してファイルを開き、コーディングしましょう。

ちなみに、実際どれぐらいのトークン送ってるのかというと、512トークンから始まって、2048トークンまで含めることができるようになっているようです。これは日に日に変わっているようですが、当然トークンに限りがある中で、より多くの情報を渡せた方が良いですよね?
このような点で言うと、英語の方が渡せる情報量は多いです。また簡潔で明快な命名はここでも優位になります。
とはいえ情報量が増えればそれで確実に精度が上がるわけではないので、そこは悪しからず。

Tips

上記の仕組みを理解した上で、実際に使用する際のTipsを紹介していきます。

ファイルのピン留め

TypeScriptでいう「.d.ts」のような型定義ファイルは、いわゆるインターフェイスや、引数で何を与えたらいいのかというところも含めて関数にまつわる情報をだいぶ持っています。そういったファイルをピン留めしておくと、Copilotの精度が上がります。

https://igawa.co/memos/vscodeのタブ「ピン留め」機能が手軽で快適。/

CSVやMarkdownのファイルはコピペ、コメントアウト

Copilotは同じ言語のファイルを読みます。したがってCSVやMarkdownの情報をコンテキストとして読み込ませたい場合は、コメントアウトのところに持ってきてコピペする方法がベストのようです。

ハイレベルなアーキテクチャを先に設計、提案する

いきなり細部のコードに飛び込んで、プログラムの全体的なアーキテクチャを見失うことはありがちですが、Copilotを用いた開発も同様に全体的なアーキテクチャを見失う可能性があります。プログラムのハイレベルなアーキテクチャを先に設計し、コードの各部分の機能と目的についてコメントしていくことで、Copilotも文脈をよりよく理解し、的確な提案をすることができます。

例えば、APIのエンドポイントファイルのような設計を初期に自然言語で提案してあげておくと、読み込んでくれます。

# GET /items
# - アイテムのリストを取得します。
# - 応答でアイテムのコレクションを返します。
# 
# POST /items
# - 新しいアイテムを作成し、コレクションに追加します。
# - リクエストでアイテムのパラメーターが必要です。
# - 成功時に成功メッセージとともにカートページにリダイレクトします。
# - 失敗した場合、新しいアイテムのフォームを表示します。

AIフレンドリーなドキュメンテーション

Infrastructure as Code、データベーステーブル仕様、テスト要件などのファイルは、即座に実際のコードに変換できる可能性を持っています。テキストベースのドキュメントを提供することでAIがコーディングを支援することができます。

例えば

# | カラム名      | データ型   | 説明                       |
# |---------------|-----------|----------------------------|
# | id            | integer   | アイテムの一意の識別子     |
# | name          | string    | アイテムの名前             |
# | description   | string    | アイテムの説明             |
# | price         | decimal   | アイテムの価格             |
# | created_at    | datetime  | アイテムの作成日時         |
# | updated_at    | datetime  | アイテムの最終更新日時     |

# item publicのマイグレーションファイル作成(指示文)

class CreateItem < ActiveRecord::Migration[7.0]
  def change
    # <Copilotの提案がここに入る>

Chat、もしくはコード内でオープンクエスチョン

Copilotでオープン・クエスチョンを利用することで、コードの改善に取り組むことができます。

例えば、以下のようにA:と記載することで回答を得る使い方もできます。

// Q: このコードの堅牢性を高めるにはどのような方法が考えられますか? 
// A: <Copilotの提案がここに入る>
function changeItem(data) {
  // 実装はこちら
}

また、VSCodeの拡張機能を使うことでChat形式でCopilotを使用することもできます。
https://docs.github.com/ja/copilot/github-copilot-chat/using-github-copilot-chat

まとめ

Copilotの仕組みやTipsを紹介してきました。日々進化しているので、極端な話明日には無意味なTipsになってるかも!?

参考

https://logmi.jp/tech/articles/329426
https://patterns.hattori.dev/ja/

Discussion