【ChatGPT】プログラミングでAIを活用する5つのパターン

ChatGPTをソフトウェア開発(プログラミング)に応用する

2023年3月14日にChatGPT (GTP-4) がリリースされてから、その威力に全世界が注目するようになりました。

まだ多くの人が手さぐりで使い方を模索しているChatGPTですが、アカデミックの世界ではChatGPTの活用方法について既に研究が進んでいます。

このブログでは、論文などのエビデンスに基づいた知識をもとに、ChatGPTの応用方法を解説したいと思います。

 

今回は以下の論文から、ChatGPTをソフトウェア開発における製造フェーズ(プログラミング)に応用する方法についてまとめます。

WHITE, Jules, et al. ChatGPT Prompt Patterns for Improving Code Quality, Refactoring, Requirements Elicitation, and Software Design. arXiv preprint arXiv:2303.07839, 2023.

 

この論文では、ChatGPTを製造フェーズ(プログラミング)に応用するにあたって、以下4つのプロンプトパターンが使用できると述べられています。

 

  1. コードクラスタリングパターン
  2. 中間抽象パターン
  3. 原則に基づくコードパターン
  4. 隠れた仮定パターン

 

 

コードクラスタリングパターン

どんな場合に使用できるパターンか?

このパターンは、コードを特定の属性に基づいて関数やクラスなどに分離・クラスタリングすることを目的としています。例えば、純粋なコードと非純粋なコードの分離や、ビジネスロジックとデータベースアクセスの分離、HTTPリクエスト処理とビジネスロジックの分離などです。

プロンプトパターン

  1. スコープX内で
  2. Yの属性を持つコードとZの属性を持つコードを分離するようにコードを書くかリファクタリングしてください。
  3. Yの属性を持つコードの例です。
  4. Zの属性を持つコードの例です。

実装例

「コードを書く際は、ファイルシステム、データベース、ネットワークアクセスなどの副作用を持つ関数と、副作用のない関数を分離するようにしてください。」

メリットとデメリット

メリット デメリット
  • このパターンは、LLMが生成するコードの品質を大幅に向上させる基本的なパターンの1つです。LLMに指示しない限り、コードは手元の問題を解決するだけで、純粋な関数と非純粋な関数の分離など、求められていない構造化の問題は解決しません。このパターンは、LLMの出力は与えられたプロンプトによって左右されるという、ソフトウェア工学における重要な問題を浮き彫りにします。
  • LLMには暗黙の知識がなく、特定のクラスタリング属性を示すコードが必要であるという情報がプロンプトで提供されない限り、LLMはその情報を知ることはできません。

中間抽象パターン

どんな場合に使用できるパターンか?

抽象化とモジュール性は、高品質で保守性と再利用性のあるコードの基本的な要素です。このパターンは、コードを個々の関数やクラスに分割し、編集範囲を限定する方法でコードを書くことを目的としています。

プロンプトパターン

  1. Xの属性を持つコードを書くかリファクタリングする場合
  2. Yの属性を持つ他のコードを使用する場合
  3. (オプション)Xの属性を定義する
  4. (オプション)Yの属性を定義する
  5. XとYの間に中間抽象Zを挿入する
  6. (オプション)抽象Zはこれらの属性を持つべきです

実装例

「コードを書く際は、ビジネスロジックをできるだけ3rdパーティのライブラリから分離してください。ビジネスロジックが3rdパーティのライブラリを使用する場合は、代わりにビジネスロジックが使用する中間抽象を書いてください。これにより、必要に応じて別のライブラリに交換できるようになります。」

メリットとデメリット

メリット デメリット
  • このパターンの利点は、3rdパーティのライブラリ依存関係が開発者の直接の制御下にないため、プロジェクトにリスクを生じることがある点に対処できることです。この例では、LLMを使用して明示的に中間抽象を挿入し、このタイプのリスクに対処します。
  • このパターンの検討事項の1つは、単一の3rdパーティのライブラリの分析だけから良い抽象を設計することができない場合があることです。例えば、異なる依存関係は異なる基本的なアーキテクチャやインターフェイスを持つ可能性があります。これを回避する1つの方法は、他の比較可能な3rdパーティのライブラリとその使用例を作成し、LLMにどの代替案でも実装可能なインターフェースにリファクタリングするよう依頼するために、Few-shot Example Generatorパターンを利用することです。

原則に基づくコードパターン

どんな場合に使用できるパターンか?

このパターンの目的は、個々の設計ルールを明示的に説明することなく、コーディング原則のよく知られた名前を使って、求められるコード構造を説明することです。生成されたコード、リファクタリングされたコード、レビューされたコードが、期待される設計原則やその他の原則に従うようにすることが目的です。

プロンプトパターン

  1. この範囲内で
  2. 原則Xに従ってコードを生成、リファクタリング、または作成する

実装例

「これからは、コードを書く、リファクタリングする、またはレビューする際は、SOLID設計原則に従っていることを確認してください。」
この例では、SOLID設計原則を望ましい設計指針として使用しています。SOLIDコードは、以下の5つの明確な設計原則に従うコードを指します: 1) 単一責任、2) 開放/閉鎖原則、3) リスコフの置換原則、4) インターフェース分離、5) 依存性逆転。指定された設計手法は、コードが従うべき5つの基本原則をすぐに導入します。

メリットとデメリット

メリット デメリット
  • このパターンは、LLMが訓練された際に、指定された原則を異なるコードベースに適用する方法を説明する多くの文献が存在する場合に最も効果的です。設計原則がよく知られているほど、LLMが訓練された例が多くなります。訓練例の利用可能性は、Prologのようなあまり一般的でない言語や独自の設計を持つ言語に特に重要です。
  • このパターンは、LLMが訓練された時点で、コード品質の名前が付けられた記述がよく知られている場合にのみ機能します。訓練日以降に登場した新しいコーディングスタイルや設計スタイルは、このパターンではアクセスできません。ただし、他のアプローチを使用して、インコンテキスト学習と少数のショット例を利用して、アクセスできない名前付きコーディングスタイルや設計スタイルを示すことができます。これにより、LLMが生成するコードを改善し、期待される設計原則に従ったコードを生成することができるようになります。このパターンは、開発者がデザイン方法論の基本的な名前を知っていても、自然言語でこれらのルールを定義する能力を超える場合に特に有用です。このパターンは、以前の作業で概説されたPersonaパターンに似ており、ユーザーがよく知られた名前を使用して望ましい出力を説明します。

隠れた仮定パターン

どんな場合に使用できるパターンか?

コード内の隠れた仮定を特定し、それらをユーザーに説明することが目的です。

プロンプトパターン

  1. この範囲内で
  2. このコードが行っている仮定をリストアップしてください
  3. (オプション)これらの仮定を変更する難しさや、変更される可能性を推定してください

実装例

「このコードが行っている仮定をリストアップし、現在のコード構造を考慮してそれぞれを変更する難しさを評価してください。」
この例では、将来変更が難しい可能性のある仮定をリストアップすることに焦点を当てています。このパターンは、開発者がコードの将来の変更に関して責任を持つことを助けます。仮定が容易に変更できない場合で、開発者がその要素を変更する必要があると予想している場合、LLMに問題のある仮定を削除するためのリファクタリングを依頼できます。

メリットとデメリット

メリット デメリット
  • コード内の隠れた仮定を特定し、ユーザーがそれらを考慮して適切な判断を行うことができるようにします。
  • すべての仮定を特定できない可能性があります。例えば、LLMに提供されたコンテキスト内にないコードが、仮定を特定するために必要な場合があります。
  • 開発者が、このパターンをコード内のすべての仮定に対する真実の源として受け取るリスクがあります。これは、開発者が検討すべきいくつかの可能性のある仮定を特定するものであるということを忘れないようにする必要があります。

 

最新情報をチェックしよう!