GitHub Copilot:貴方とペアを組んでプログラミングする人工知能(2/2)

AI

1.GitHub Copilot:貴方とペアを組んでプログラミングする人工知能(2/2)まとめ

・Copilotの生成するコードはベストなものではないが2つの認知バイアスを誘発
・様々な負の側面も持ち、は初心者が気づきにくい足枷となる可能性がある
・人とコンピューターの相互作用などを取り込んで改良する必要がある

2.GitHub Copilotの問題点

以下、www.fast.aiより「Is GitHub Copilot a blessing, or a curse?」の意訳です。元記事は2021年7月19日、Jeremy Howardさんによる投稿です。

アイキャッチ画像のクレジットはPhoto by Mael BALLAND on Unsplash

自動生成されたコードの問題点

コード自動生成ツールは、コードが存在するのとほぼ同じくらい以前から存在します。そして、彼らは彼らの歴史を通して物議を醸してきました。

ほとんどの場合、コーディング作業はコードの記述だけではなく、コードの設計、デバッグ、および保守に費やされます。コードが自動的に生成されると、コードがさらに多くなる可能性があります。

コードテンプレートツールを使用している場合などでは、これは必ずしも問題にはなりません。コードの自動生成元のソースを変更するだけ良いため、メンテナンスやデバッグを行う必要はありません。しかし、それでも、デバッガーとスタックトレースは通常、テンプレート化された綺麗なソースではなく、ゴチャゴチャになったコードを生成するため、デバッグ時に混乱する可能性があります。

Copilotを使うと、コードテンプレートツールのような利点はありません。ほとんどの場合、作成されたコードを更に変更する必要があります。コードの動作を変更したい場合に、Copilotに再出力させることはできません。生成されたコードを直接デバッグする必要があります。

経験則として、コードが少ないということは、維持および理解する必要が少ないことを意味します。Copilotのコードは冗長であり、大量のコードを生成するのは非常に簡単なので、多くのコードが作成される可能性があります。

Pythonには、コード生成の必要性を大幅に減らす豊富な動的およびメタプログラミング機能があります。

多くのプログラマーが、Copilotが多様な定型文(boilerplate)を書いてくれるのが好きだと言っているのを聞いたことがあります。ただし、私は定型文で使う事はほとんどありません。過去に定型文が必要になったときはいつでも、動的なPythonの仕組みを使用して定型文をリファクタリングしたので、定型文を生成する必要はありませんでした。

たとえば、ghapiでは、動的Pythonを使用して、サイズがわずか40kBのパッケージでGitHubのAPI全体への完全なインターフェイスを作成しました。(比較すると、Go言語で同等のパッケージを実現するコードには100,000行を超えるコードが含まれており、そのほとんどは自動生成されます)。

非常に有益な例は、Copilotに次のように入力した際に何が起こったかです。

def finetune(folder, model):
    """fine tune pytorch model using images from folder and report results on validation set"""

非常に少量の追加入力で、89行のコード(https://gist.github.com/jph00/bc1c623943d1cc93165f8c8825bb9b6c)がほぼ完全に自動的に生成されました。ある意味、これは本当に印象的です。それは確かに基本的に要求されたことを実行します。PyTorchモデルを微調整するのです。

ただし、モデルの微調整はうまくいきません。このモデルはトレーニングに時間がかかり、精度が低くなります。モデルを正しく微調整するには、バッチノルムレイヤー統計の処理、ボディの前にモデルのヘッドを微調整、学習率の正しい選択、適切なアニーリングスケジュールの使用などを考慮する必要があります。

また、最近のCUDA GPUで採用された混合精度トレーニング(mixed precision training)を使用したいと考えており、MixUpなどのより優れた拡張方法を追加したいと考えています。これらを追加するためにコードを修正するには、数百行以上のコードと、ディープラーニングに関する多くの専門知識が必要になります。(または、4行のコードでPyTorchモデルを微調整できるfastaiなどの高レベルAPIを使用すると、より高い精度、より高速な、より拡張性の高いものが得られます)

私はこういった作業が求められた場合にCopilotが何を出力するのが最善なのかは判断がつきかねます。印象的なデモンストレーションですが、現在行われていることは実際には役に立たないと思います。

正規表現を使用してPythonスクリプトを解析

私はfast.aiのコミュニティに、Copilotがコードの作成に役立った事例があるかを尋ねました。ある人は、Pythonコードを含む文字列からコメントを抽出する正規表現を書いているときに非常に重宝したと言っていました。

これを自分で試してみることにしました。Copilotに与えた入力は次のとおりです。

code_str = """def connect(
    host:str, # host to connect to
    port:int=80, # port to connect to
    ssl:bool=True, # whether to use SSL
) -> socket.socket: # the connected socket
"""
# regex to extract comments from strings looking like code_str

生成された正規表現は以下になります。

comment_re = re.compile(r'^\s*#.*$', re.MULTILINE)

誤った「^」が行の先頭を表現しているため、このコードは機能しません。また、正規表現でマッチした場所を抽出するための()が欠落しているため、実際にはコメントを捕捉できていません。(Copilotの2番目の提案では、^文字を正しく削除していましたが、マッチした場所の抽出はやはり出来ていませんでした)

ただし、これらはマイナーな問題ですが、このコードの大きな問題は、正規表現では実際にはPythonのコメントを正しく解析できないことです。 たとえば、以下のような表現があった際、文字列中の#がコメントの開始として誤って解析されるため、これは失敗します。

code_str = """def find_tags(
    input_str:str,     # the string to search for tags
    tag_prefix:str="#" # prefix marking the start of a tag
) -> List[str]:        # list of all tags found
"""

さて、正規表現を使用してPythonコードを正しく解析することは、実際には不可能であることが判明しました。

しかし、Copilotは私たちが求めたことを実行しています。私達はプロンプト入力で、明示的に正規表現を要求し、それがCopilotから提供されました。

この例を提供したコミュニティメンバーは、正規表現がこの問題を解決する正しい方法であると考えていたため、まさにこのコードを実行しました。(Copilotへ与える入力から正規表現を意味する「regex to」の文字列を削除しても、Copilotはまだ正規表現を使った解法を提案しました)

この場合の問題は、Copilotが何か間違ったことをしているということではありません。問題は、Copilotが行うように設計されていることは、プログラマーの最善の利益とはならないかもしれないということです。

GitHubは、Copilotを「ペアプログラマー」として喧伝しています。しかし、これが実際に何をしているのかを把握しているのかどうかはわかりません。優れたペアプログラマーとは、仮定に疑問を投げかけ、隠れた問題を特定し、全体像を把握するのに役立つ人です。

Copilotはこれらのことを何もしません。まったく逆に、あなたの仮定が適切であると盲目的に仮定し、テキストカーソルが現在どこにあるかという直接の指示に基づいてコードを大量生産する事に完全に焦点を合わせます。

認知バイアスとAIペアプログラミング

AIペアプログラマーは人間とうまく連携する必要があります。そしてその逆も同様です。

しかし、人間には特にこれを困難にする2つの認知バイアスがあります。自動化バイアス(automation bias)とアンカーバイアス(anchoring bias)です。この一対の人間のささいな弱点のおかげで、たとえ明示的にそうしないように試みたとしても、私たちは皆、Copilotの提案に過度に依存する傾向があります。

Wikipediaでは、自動化バイアスを次のように説明しています。

「人間が自動化された意思決定システムからの提案を盲目的に支持し、その提案に矛盾する自動化されていない正しい情報があっても無視する傾向」

自動化バイアスは、コンピューターの意思決定支援システムが広く使用されている医療において、すでに重大な問題として認識されています。司法および警察のコミュニティにも多くの実例があります。

カリフォルニアの市当局者が、予測的警備(Predictive policing)に使用されるIBM Watsonツールについて誤って説明したケースなどです。

「機械学習と自動化で99%の成功を収めています。そのため、ロボットは次に何が起こるかを99%正確に伝えることができるのです。」

これを聞いた市長は「ほぅ、ではソイツに重機関銃を取り付けるのはどうだい?」と言ったとの事です。(彼は後日、自分がふざけていただけだと主張しています。)

AIの能力に関するこの種の膨らんだ信念は、Copilotのユーザー、特に自分の能力に自信がないプログラマーにも影響を与える可能性があります。

The Decision Labはアンカーバイアスを次のように説明しています。

「あるテーマについて与えられた最初の情報に過度に依存してしまう原因となる認知バイアス」

アンカーバイアスは非常に広く文書化されており、交渉や価格設定などを行う際の便利なツールとして多くのビジネススクールで教えられています。

vscodeを使ってプログラムを書いてるときに、Copilotを使うと、補完されたコードが完全に自動的に提案されます。前述の正規表現の例のように、これは、私たちがどこに向かっているのかを実際に考える前に、Copilotがすでに私たちの道を計画してくれることを意味します。

これは、私たちが取得する「最初の情報」であるだけでなく、「自動化された意思決定システムからの提案」の例でもあります。これは、克服すべき認知バイアスで二重に強化されている事を意味します。

そして、それは一度だけではなく、テキストエディタでさらにいくつかの単語を書くたびに起こります。

残念ながら、認知バイアスについて私たちが知っていることの1つは、「認知バイアスに気付くだけでは、それらにだまされるのを避けるのに十分ではない」ということです。

従って、これは、Copilotが行う提案とユーザーに対する教育を注意深く行うだけでGitHubが対応できるものではありません。

Stack Overflow、Google検索、APIの使用例

一般に、プログラマーが何かを使う方法を知らず、Copilotも使用していない場合、プログラマーはそれをGoogle検索します。たとえば、Pythonコードを含む文字列内のパラメーターとコメントを検索したかった前述のコーダーは、「pythonは正規表現を使ってパラメーターリストをコードから抽出します(python extract parameter list from code regex)」のような検索語で検索する可能性があります。

この検索をして出て来る2番目の結果は、Pythonの正規表現ではそれが実現できないと正しく述べた回答を含むStack Overflow(QAサイト)の投稿です。代わりに、pyparsingなどのパーサーを使用することを提案している答えです。

次に、「Pythonコメントのpyparsing」を検索してみたところ、このモジュールを使うと問題が正確に解決されることがわかりました。

また、私は「Pythonファイルからコメントを抽出する(extract comments from python file)」を検索してみました。これにより、Python標準ライブラリのtokenizeモジュールを使用して問題を解決する方法を示す回答が最初に得られました。この場合、質問者は「ユーザーが入力したコードからコメントを抽出するプログラムを作成しようとしています。 正規表現を使おうとしましたが、書きづらいと感じました」と書いてました。

先ほどと同じですね!

これは、答えを直接与えるCopilotのプロンプトを見つけるよりも数分長くかかりましたが、問題と可能な解決策の範囲についてはるかに多くを学ぶことになりました。Stack Overflowの掲示板は、Pythonで引用符で囲まれた文字列を処理する際の課題を理解するのに役立ち、Pythonの正規表現エンジンの制限についても説明していました。

このケースでは、Copilotを使うアプローチは、経験豊富なプログラマーと初心者のプログラマーの両方にとってより悪いと感じました。経験豊富なプログラマーは、Copilotが提案したさまざまな選択肢の調査に時間を費やし、問題を正しく解決していないことを認識し、いずれにしても解決策をオンラインで検索する必要があります。

初心者のプログラマーは、問題を解決したように感じ、正規表現の制限と機能について理解する必要があることを実際に学習せず、気付かないうちにコードを壊してしまう可能性があります。

CoPilotに加えて、GitHubの所有者であるMicrosoftは、「APIの使用例(API Usage Examples)」と呼ばれる別の関連製品を発表しました。以下は彼らのウェブサイトから直接取得したサンプル動画です。

このツールは、ユーザが使用しているAPIまたはライブラリを使用している事例をインターネットから探し、その使用方法を示す実際のコードの例と、そのソースへのリンクを提供します。

これは、Stack Overflow(ただし、貴重な議論を見逃している)とCopilot(ただし、特定のコードに合わせてカスタマイズされた提案を提供していません)の間のどこかに位置する興味深いアプローチです。

ここで追加された重要な部分は、ソースコードにリンクしていることです。つまり、コーダーは、他の人がその機能をどのように使用しているかの完全な実装を実際に見ることができます。コーディングを上手に行うための最良の方法は、コードを読んで書くことです。コーダーが読むのに関連するコードを見つけるのを助けることは、人々の問題を解決すると同時に、スキルを向上させるための優れたアプローチのように見えます。

Microsoftの「APIの使用例」機能が優れているかどうかは、コードを品質順でランキング付けし、使用例の最良の例を示す能力があるか否かに本当に依存します。プロダクトマネージャーのTwitterによると、これは彼らが現在取り組んでいることです。

結論

この投稿の元タイトルである「GitHub Copilotは祝福ですか、それとも呪いですか?(Is GitHub Copilot a blessing, or a curse?)」という質問に対する答えはまだわかりません。

それはある人にとっては祝福であり、他の人にとっては呪いかもしれません。そしてそれが呪いである人々にとって、彼らは何年もの間その呪いを見つけられないかもしれません。なぜなら、彼らは学習量が少なくなり、学習速度が遅くなり、技術的負債が増え、微妙なバグを発生させ入れ込むからです。これらは全て新人開発者にとっては、気付きにくい事です。

Copilotは、定型文が多く、メタプログラミング機能が制限されているGoなどのプログラミング言語に役立つ場合があります。(今日、多くの人がこの理由でGoでテンプレート化されたコード生成を使用しています)

これが特に適している可能性のある別の領域は、ライブラリ関数や良くある書き方を知るのに役立つため「基本的な構文を正しく理解しているがなじみのない言語で作業する経験豊富なプログラマ」にとって適する可能性があります。

覚えておくべきことは、Copilotは、次第に改善されていく非常に新しいテクノロジーの初期のプレビュー版であるということです。今後数か月から数年の間に多くの競合製品が登場し、GitHubは間違いなく独自のツールの新しいより良いバージョンをリリースするでしょう。

プログラム合成の実際の改善を確認するには、言語モデルだけでなく、人間とコンピューターの相互作用、ソフトウェアエンジニアリング、テスト、およびその他の多くの分野に関するベストプラクティスを組み込んだより包括的なソリューションに移行する必要があります。

現在、Copilotは、必要なすべての領域の専門知識を組み込んだ完全なソリューションではなく、機械学習の研究者によって設計および実装された製品のように感じています。

これはきっと変わっていくでしょう。

3.GitHub Copilot:貴方とペアを組んでプログラミングする人工知能(2/2)関連リンク

1)www.fast.ai
Is GitHub Copilot a blessing, or a curse?

2)copilot.github.com
GitHub Copilot · Your AI pair programmer

3)marketplace.visualstudio.com
Visual Studio IntelliCode Insiders – Visual Studio Marketplace(API Usage Examples)

タイトルとURLをコピーしました