【前編】良いコード / 悪いコード × AI – AI時代のソフトウェア設計
本記事は 2024/10/11 に開催されたイベント「良いコード / 悪いコード × AI – AI時代のソフトウェア設計」の内容をもとに執筆されました。
「コード×AI ー ソフトウェア開発者のための生成AI実践入門」(以降「コードAI本」)の著者である服部佑樹と、「良いコード/悪いコードで学ぶ設計入門」(以降「ミノ駆動本)でお馴染みのミノ駆動さんが、AI時代においてソフトウェアの品質特性を考える上での視点を共有しました。(以降敬称略)
本記事は二部構成のうちの前編となります。
「良いコード」というクソデカ主語 - 品質特性を踏まえて考えよう
服部:
まずはじめに、そもそも「良いコード」とは何でしょうか。AI時代になって、その定義や基準は変わるのでしょうか?
ミノ駆動:
「良いコード」という言葉自体が「クソデカ」な言葉なんですよね。実際、ソフトウェアには機能性、可用性、移植性、完全性など、さまざまな品質特性があります。結局のところ、「良いコード」とは、これらの特性のうちどの特性に優れているかを明確にする必要があるのです。
したがって、「良いコード」と一口に言っても、パフォーマンスに優れたコードであれば「パフォーマンスに優れた良いコード」ですし、保守性や変更容易性に優れたコードであれば「変更容易性に優れた良いコード」と言えます。
つまり、品質特性に基づいて「どの特性を指して“良いコード”と呼んでいるのか」を定義することから始めるべきだと考えています。
服部:
なるほど、ありがとうございます。実際、「リファクタリングしてください」といった非常に抽象的なコメントをAI支援ツールに投げかける事例をよく見かけますが、それが「スタイルを改善してほしい」のか、「パフォーマンスを向上させてほしい」のか、あるいは「依存関係を整理したい」のか、「アーキテクチャレベルで再構築したい」のかが曖昧では、ツール側も対応が難しいですよね。結局、人間側が考えなければならない点が残るわけです。
最近、リファクタリングやAIの活用方法で、何か面白い事例や有用な活用例はありますか?
ミノ駆動:
私は現在、自分の「分身」を増やす試みをしています。私一人では設計観点でのコードレビューをすべて賄えないため、自動生成型AIにレビューを任せられないか実験中です。
とはいえ、「リファクタリングしてください」といった曖昧な指示では、AIは適切なアイデアを出しづらいものです。また、「このコードが良いか悪いか判断して」と頼んだとしても、パフォーマンスや可用性といった異なる品質特性に関する回答が返ってきてしまい、狙いどころを定めづらい状況があります。
カプセル化と関心の分離
ミノ駆動:
そこで重要になるのが、たとえば変更容易性を高める設計原則です。カプセル化が適切か、関心が明確に分離されているか、といった観点を明示的にプロンプトとして与えると、AIの判断精度が向上します。
やはり、曖昧な指示ではなく、明確な基準に基づく指示をAIに与えることが、的確な提案を得るポイントだと思います。
服部:
おっしゃる通りです。私も著書で述べましたが、AIツールを介してコードを記述したりリファクタリングしたりする際は、「どの基準で“良い”と判断するのか」を明確にすることが肝要です。
GitHub CopilotをはじめとするAIツールは裏でコードを収集して自動的にプロンプトを生成しますが、断片的なコードを無造作に提示するだけでは、的確な提案を得にくくなります。そこで、コードを小さなチャンクに分解したり、説明的なコメントを書き加えたり、関心の分離を意識することで、AIからの提案の質が向上すると考えています。
命名やスタイルガイドの明示も同様で、記述的な情報を与えるとAIが理解しやすくなり、非ネイティブな開発者でもAIの提案でより自然な命名が可能になります。
カプセル化と関心の分離に対する想い
服部:「良いコード」というテーマは非常に大きな話題です。その中で、「カプセル化と関心の分離」や「命名とAI」、「リファクタリングとAI」、「コードレビューとAI」といった具体的なトピックがあります。
特に「カプセル化と関心の分離」について、ミノ駆動さんはどのようにお考えですか?
ミノ駆動:
非常に強い思いがあります(笑)。変更容易性という観点で言えば、それは「コードを素早く正確に変更でき、バグを埋め込みにくい度合い」を指します。技術的負債があると、当然変更容易性は下がります。
この変更容易性を高めるには、古くから言われている基本原則を守ることが近道です。その中でも「カプセル化」と「関心の分離」は特に重要な2つの原則です。
カプセル化とは、データとそれを操作するロジックをひとまとめにすること。関心の分離とは、ソフトウェアを機能や目的別に明確なモジュールへ分けることです。要するに、密接に関連する要素はまとめ、異なる関心領域は明確に分離することで、ある機能の変更が他の無関係な機能に影響しづらくなります。
SOLID原則など多くの設計原則は、ほとんどこのカプセル化と関心の分離で説明できるほど、重要な基本概念だと思います。
生成AIによるコードレビュー
ミノ駆動:
このカプセル化と関心の分離を生成AIに理解させ、コードレビューで活用するのは非常に奥が深い取り組みです。何度も試行錯誤する中で、自分自身がこれらの原理を本当に理解しているかを再確認する機会にもなります。
AIとの対話で、こちらが明確な基準を提示すればAIもそれに応じた回答を返すようになりますし、その過程で「ここはまだ曖昧だったな」と自分自身が気づかされることもあります。まるでAIとの対話を通じて双方が成長していく、不思議な感覚がありますね。
服部:
なるほど。プロンプトの書き方や落とし込み方が極めて重要になるわけですね。
リファクタリング手法を体系的に適用したり、オープンクエスチョンをクローズドクエスチョンに変えることで、AIに「どの手法を使うべきか」「なぜそれが適切なのか」と問うと、より的確な回答が得られる場合があります。
マーチンファイラーのリファクタリングカタログなど、AIが知っている領域を活用することで、理由づけが容易になり、レビューや改善の軸が明確になります。こうした手法は、AIと協調しながら「良いコード」を模索・前進する有効な方法の一つだと感じます。
ミノ駆動:
まさにその通りです。品質特性を明確にし、その基本原則(カプセル化と関心の分離)を理解した上で、プロンプトを工夫してAIと対話しながら改善していく流れは、今後いっそう重要性を増していくでしょう。
AIとの協働について書いたコードAI本、そしてより成長させやすいコードの書き方と設計を学ぶ入門書のミノ駆動本、ぜひご一読ください!