IDEにAIを統合する

Integrating AI into IDE

AIは、質問に答えたり、コードスニペットを生成したり、コードの説明や問題の検出など、コーディングタスクの支援でその潜在能力を示しています。ただし、ChatGPTのようなWeb UIを使用し、コピー/貼り付けの方法に大いに依存する現在のアプローチは、手間がかかり効率が低下する可能性があります。コーディングにおけるAIの利益を最大化するには、現代の統合開発環境(IDE)内でAIの機能をより緊密に統合することが不可欠です。このシームレスな統合を実現するためには、いくつかのアイデアが検討される可能性があり、そのうちのいくつかはIntelliJ IDEAなどのIDEに既に実装されており、他のいくつかは未開拓の機会となっています。

このような統合の2つの主要な概念が存在します: AIアクションとAIアシスタント(チャットUI)です。

AIアクション

AIアクションは、望ましい結果を達成するためにAIを活用するタスクです。各AIアクションは、次のいずれかを行う必要があります:

  1. プロンプトとコンテキストを準備し、AIを利用してデータを処理し、結果を収集し、ユーザーに最も便利な形式で提示するか、コードに変更を加えます。
  2. プロンプトとコンテキストを準備し、AIアシスタントを呼び出し、ユーザーに作業を完了させます。
  3. 1と2のシナリオを複雑に組み合わせたものを行います。

AIアクションは、次のようなさまざまな方法で実行できます:

  • ユーザーの要求によってトリガーされます(例: リファクタリングとして)
  • システムサービスによってスケジュールされ、バックグラウンドで実行されるか、適切なタイミングで実行されます(例: コード解析アクション)

AIコードインテンション

現代のIDEの世界では、ますます一般的になっている強力な機能の1つが「インテンション」という概念です。これらのインテンションは、特定のコンテキストに基づいてコード上で事前に定義されたアクションを実行する能力をユーザーに提供します。例えば、「for」ステートメントで作業している場合、そのコンテキスト内で「whileに変換する」、「順序を逆にする」、「ストリームを使用する」といったさまざまなインテンションが利用可能です。インテンションの利用は、コードの迅速なリファクタリングや操作を可能にするため、開発プロセスを効率化するのに非常に有利です。

ただし、インテンションの開発は容易な作業ではありません。そのため、IDEベンダーはインテンションをハードコードし、それらを各IDEにバンドルしています。一部のIDEでは、開発者が独自のインテンションを作成できるようになっていますが、この取り組みは非常に困難であり、IDEプラットフォームの深い知識、包括的なコーディング、および新たに開発されたインテンションを展開するためのプラグインの作成を要求します。

幸いにも、ChatGPTのようなLLMの出現により、コード関連のアクションをリクエストすることが非常に簡単になりました。コードスニペットとプロンプトを提供するだけで、LLMは容易に指定されたアクションを実行することができます。たとえば、ループを「ループの方向を逆転する」というプロンプトでLLMに提供すると、指定された変換を与えられたコードスニペット上で容易に実行されます。

そして、ハードコードされたインテンションと同じ結果が得られます:

そのため、AIインテンションを導入することが自然です。これは、基本的には特定のコンテキストにバインドされた名前付きのAIプロンプトです。コンテキストは、ファイル、クラス、ステートメント、特定のメソッドなどである可能性があります。したがって、AIインテンションは、プロンプトを提供し、IDEにコンテキストを要求し、AIを活用してデータを処理し、結果を収集し、ユーザーに最も便利な形式で提示するか、コードに変更を加える必要があります。

AIインテンションの利点:

  1. ほとんどのリファクタリングは自然言語を使って行うことができます。プロンプトは、よく知られたAPI(JavaのPrintStream.println(String)など)に対して「formatを使用して置き換える」といったシンプルなものであるか、より複雑なAPIに対してより多くの指示を含むものであるかなど、さまざまな形式で提供できます。
  2. このようなインテンションをハードコードする必要はありません。
  3. このようなインテンションを配布するためにプラグインを作成する必要はありません。
  4. このようなインテンションは、ユーザーが簡単に設定できます。
  5. 繰り返しのアクションには、特にチャットインターフェースを使用する必要はありません。
  6. コストを節約するために、LLMトークンのトラフィックが少なくて済みます。

アノテーションを使用してAIコードインテンションを定義する

検討すべき興味深い革新的な機能は、アノテーションを使用してAIインテンションを直接APIに統合することです。宣言的なAIインテンションを導入することで、開発者は各クラス、フィールド、またはメソッドごとに利用可能なインテンションについてIDEに指示を出すことができ、LLMのような言語モデルの支援を通じて特定のインテンションを実行するための適切なプロンプトを指定できます。これらの宣言的なAIインテンションは、フレームワーク/ライブラリの作者によって提供され、それらをサポートするIDEを使用するすべての開発者がシームレスにアクセスできます。

具体的な例として、「フォーマットを使用した置換」AIインテンションを見てみましょう。このインテンションにより、開発者はprintln(String)呼び出しを効率の良いprintls()呼び出しに置き換えることができます。この場合、フォーマットと引数リストを入力として受け取ります:

したがって、次のようなインテンションを呼び出すと:

System.out.println("i = " + i);

結果は:

System.out.printf("i = %d%n", i);

もしIDEがエディタ内の一部のテキスト要素にレンダリングされたビューを提供できる場合、アノテーション付きのAIインテンションはタイトルのみを表示し、長いプロンプトを隠すことができます。また、そのレンダリングには、ワンクリックでアクションを実行できるPlayボタンが含まれている場合もあります。

非推奨の修正アクション

宣言型のAIインテンションを使用するもう1つの非常に良い用途は、非推奨のAPIの処理です。したがって、各非推奨メソッドには、そのメソッドをモダンなバージョンにリファクタリングするための特別なAIインテンションを定義するアノテーションが含まれる場合があります。このようなAIインテンションは、コードの編集/閲覧時に明示的に呼び出すことができます。または、非推奨のメソッドをすべて収集し、開発者にそれらのいくつかまたはすべてを修正するように促す別の上位レベルのアクションもあります。

非推奨APIを処理するために宣言型のAIインテンションを利用する利点は数多くあります。これにより、レガシーコードのメンテナンスと更新に必要な時間と労力が大幅に削減され、最新の技術とベストプラクティスへのスムーズな移行が促進されます。さらに、コードベース全体で非推奨メソッドの管理を統一的に行うことで、開発者間のコラボレーションが向上します。

TODOアクション

多くの場合、TODOコメント(// TODO:のような)には、LLMが必要なコードを生成するために十分な手順が記載されています。たとえば、次のコード:

は、LLMによって正しくリファクタリングされ、次のようになります:

したがって、TODOコメントを収集し、実行するAIアクションのリストに表示するのは非常に自然です。クラスレベルのTODOはクラスのどこでも提供されるべきであり、メソッドレベルのTODOはメソッドのスコープで提供されるべきです。もちろん、いくつか/多くのTODOはLLMだけで一般的なプロンプトを使用して完了することができないかもしれませんが、それを呼び出すかどうかは特定の開発者に委ねられます。

もしIDEがエディタ内の一部のテキスト要素にレンダリングされたビューを提供できる場合、TODOは、ワンクリックでそのTODOを完了させるPlayなどのボタンが含まれているコード内にレンダリングされることができます。

メソッド作成アクション

AIを利用して、型付きメソッド名を使用し、戻り値の型とパラメータを推測してメソッドのシグネチャを生成させることは良いことです。たとえば、「メソッドのシグネチャを提案する(空の本体で):splitStringUsingRegex」というプロンプトは、ほぼ正確に次のメソッドを生成します:

オプションとして、メソッドの本体の生成も含まれるでしょう。

「メソッドの作成」アクションは、メソッド名を入力し、Tabキー(または他の適切なショートカットキー)を押すか、明示的に「メソッドの作成」アクションを選択することで、コードエディタ内で直接呼び出されるべきです。

依存関係の提案アクション

LLMは、ユーザーの要件に基づいてコードを生成するのに長けています。しかし、生成されたコードはしばしばサードパーティのライブラリやフレームワークに依存しています。これにより、必要な依存関係がプロジェクトに既に追加されていない場合、コンパイルエラーが発生する可能性があります。そのため、必要な依存関係を手動で見つけて追加する作業は、コード自体を取得するよりも時間がかかる場合があります。

この問題に対処するために、便利な追加機能として「依存関係の提案」アクションが考えられます。このアクションにより、ユーザーはLLM(または特定のトレーニングモデル)に特定のタイプの依存関係(ライブラリ、Maven、Gradleなど)に関する情報をリクエストすることができます。依存関係が見つかれば、それらをプロジェクトに自動的に適用することができ、プロセスを効率化し時間を節約することができます。

たとえば、LLMに「org.json.JSONObject」のMaven依存関係を見つけるように依頼すると、次のような提案が得られるでしょう:

これを使用してプロジェクトの依存関係を変更することができます。

名前の提案アクション

「メソッドの抽出」、「パラメータの導入」など、新しいクラスメソッド、パラメータ、または変数を導入する既存のコードリファクタリングがたくさんあります。このようなリファクタリング中に作成されるすべての新しい要素は適切に名前を付ける必要があります。したがって、LLMを利用してリファクタリングされるコードに基づいて提案される可能性のある名前を検索し、それらの名前をポップアップで表示するのは非常に自然です。名前の取得には時間がかかるため、侵入的ではなく、バックグラウンドで実行されるべきです。

実装アクションの提案

このアクションは、空の本体を持つメソッドの実装を生成することを可能にします。メソッド名と引数が明確に(そうすべきであるべき)メソッドの目的を定義している場合、LLMは非常に優れています。例えば、次の空のメソッドの場合:

LLMは、正しく以下の内容を提案します:

このアクションはバックグラウンドで実行され、追加のUIを表示せずにコードエディタに直接適用され、開発者がIDEでの作業を中断することなく続けることができるようにする必要があります。

必要に応じて、「Suggest Implementation」アクションをChat UIで起動するためのオプションがあるべきです。

正規表現アクションの提案

「正規表現の提案」アクションは、すべての文字列リテラルに対して利用可能であり、文字列リテラルを取り、それをAIにクエリし正規表現を生成します。

たとえば、次のコードの文字列リテラルに対して「Suggest regex」アクションを呼び出した後、コードは生成された正規表現を含むように変更されます:

コードの説明アクション

「コードの説明」アクションは、適切な「コードの説明」プロンプトを使用してLLMを活用し、コードの動作の説明を取得するべきです。デフォルトでは、そのような説明はポップアップで表示され、短い説明と完全な説明の間を切り替えることができるようになっています。また、必要に応じて「コードの説明」アクションをChat UIで起動するオプションも用意されています。

コードのコメントアクション

「コードのコメント」アクションは、LLMを活用し、「コードの説明」プロンプトの一種を使用して、コードの右側に非常に短いコード説明としてコメントを挿入するべきです。このアクションはバックグラウンドで実行され、追加のUIを表示せずにコードエディタに直接適用され、開発者がコード作業を中断することなく続けることができるようにする必要があります。

文字列の説明アクション

このアクションは、文字列リテラルに対して利用可能であり、ポップアップで説明を表示するべきです。追加の説明やテストが必要な場合、この説明をChat UIで開くオプションが用意されているべきです。

LLMは、文字列に組み込まれているものを非常に良く認識するため、このアクションはかなり基本的なプロンプトで動作します。例えば、LLMは以下を簡単に認識します:

  • より複雑な正規表現
  • SQL文
  • Printfフォーマット文字列
  • MessageFormat文字列
  • その他

LLMが文字列の形式を検出できない場合、形式を説明するプロンプトが表示されるべきです。

潜在的な問題の検出アクション

ほとんどの現代のIDEには、コンパイラによって検出されたコードのすべてのエラーや警告をハイライトするツールが含まれています。

ただし、LLMは非常に厄介な状況で特に潜在的な問題を検出することができます。適切なプロンプトを使用すると、LLMはテキスト形式またはJSON形式で構造化された問題レポートを作成できます。そのレポートを解析して利用することは非常に簡単です。

そのため、「潜在的な問題の検出」アクションは、適切な「コード内の問題の検出」プロンプトとコンテキストを活用し、結果を解析し、通常のメッセージリストビューで表示し、コードナビゲーションなどの一般的なUXを提供することができます。

リファクタリングの提案アクション

「リファクタリングの提案」アクションは、コードの最適化、修正、または改善されたバージョンを取得するためにLLMを活用するべきです。

デフォルトでは、このアクションはバックグラウンドで実行され、追加の侵入的なUIを表示せずにコードエディタに直接適用されるべきです。必要に応じて、Chat UIでこのリファクタリングを開くオプションがあるべきです(追加の手順、説明、またはテストが必要な場合)。

もしIDEがエディタ内の一部のテキスト要素にレンダリングされたビューを提供できる場合、リファクタリングされたメソッドは、右側にPrev/Nextボタンが埋め込まれた一時的なレンダリングで表示され、リファクタリングされたコードの変更バリアントを素早く切り替えることができるようになります(あれば)。

コミットメッセージの提案アクション

「提案されたコミットメッセージ」アクションは、プロジェクトで行われた変更のキュレーションされたリストに基づいて、VCS(バージョン管理システム)のコミットメッセージを作成するためにLLMを利用する必要があります。モノリシックな形式やアイテム化されたリストなど、異なるスタイルのメッセージに切り替えるオプションが必要です。

ドキュメント生成アクション

「ドキュメント生成」アクションは、LLMを利用して、メソッドやクラスの開発者向けドキュメントを言語固有の形式(例:JavaDoc)で作成する必要があります。

AIアシスタント

AIアシスタントは、ChatGPTが提供するものと似たユニバーサルなチャットUIを提供し、開発者はLLMと対話し、回答やコードを取得し、必要に応じて結果をコミットできるようにします。

AIアシスタントはチャットのコンテキストを追跡し、編集ポイントがどこにあるかを認識する必要があります。これにより、以下のことが可能になります:

  • 既存のコードベースに基づいてコードを生成する(コンテキストウィンドウサイズがこれを許可する場合)。
  • 挿入するコードをチェックおよび変更して、有効なコンパイル可能な結果を生成します。例えば:
    • AIアシスタントがメソッドを生成した場合、キャレットの位置を無視するか、最も近い有効な場所に配置するように正しく挿入されるべきです。
    • AIアシスタントがコードスニペットを生成し、挿入ポイントがメソッド内にない場合、AIが提案するメソッド名でメソッドにラップすることができます。
    • その他。
  • 明示的に要求されるまで、クラスとmain()メソッドの生成を避けます。
  • 重複する名前のものを生成しないように、名前のチェックを行います。
  • 既に存在するメソッドを生成せずに再利用します(プロンプトによるプロンプトが必要かもしれません)。

AIアシスタントには、プレイグラウンドが直接組み込まれている必要があります。生成されたコードを貼り付けたり、main()メソッドを追加したり、プロジェクトをビルドする必要なく、場所でテストおよびデバッグができるようにします。これは、AIアシスタント自体または関連するウィンドウ/ビューで行うことができます。必要な依存関係が自動的に解決されるべきです(詳細については、「依存関係の提案」アクションを参照)。

注意:適切に設計されたプロンプトを使用して単一のLLMトランザクションで十分な結果を得ることができる場合、AIアシスタントの使用を避けることが良いでしょう。AIアシスタントは、ユーザーによって明示的に呼び出される場合または複数のトランザクションが必要であるために直接ユーザーの関与が必要な望ましい結果を得るために使用されるべきです。専用のUIを設計することはほとんど不可能です。

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more