AIコーディングにおけるガードレール
ClineやCursorのComposerなどのAIコーディングエージェントを使うと高い生産性を実現できる一方で、無秩序な大量のコード生成は保守性の低下を引き起こします。そこで、AIに対してより制限を課す、つまりガードレールを設けることで保守性の低下に抗うことになります。しかしガードレールが強すぎるとAIコーディングエージェントの生産性を低下させてしまいます。
このジレンマをどう攻略するかが今後のAIコーディングの大きなポイントになってきます。
この記事ではAIコーディングの際にガードレールとして使えそうな手法について個人的な整理のために網羅的に記載したものです。
ガードレールとして使える手法
型付け・Linting
エディタに統合されたコーディングエージェントはエディタで指摘された問題を参照できます。つまり、型エラーやlintエラーについて把握し、自動的に修正可能です。
この特性を活かして保守性を高めるために厳しめのLintの設定を入れるのが良いでしょう。
またバリューオブジェクトの導入のように積極的に型を利用していくことも考えられます。
コーディングガイドラインの作成
下記のような情報を渡すことでプロジェクトのルールを逸脱しないようにします。
・ディレクトリ構造
・技術スタック
・コード設計上のポリシー(レイヤー構造など)
・デザインシステムに関する情報
・モジュール分割に関するポリシー
・リファクタリングを必要とする基準
・テストの義務付け
利用可能なコマンドの明示
下記のような情報を渡すことでエージェントが必要な時に必要なコマンドを実行できるようにします。
・アプリケーションの起動コマンド
・テスト実行コマンド
・Lintやフォーマット修正の実行コマンド
システム要件やデータ設計情報などの変化の少ない重要な情報を渡す
下記のように常に参照させたい重要な情報を渡すことで逸脱した実装を始めるリスクを抑えることができます。
・システムの目的や特性
・要件定義書
・概念データモデル
・データベーススキーマ
データ構造と型定義の提供
事前に概念モデル設計を行い、そこから導出されたデータ構造や型定義を渡すことで、AIが間違った実装を進めてしまうことを防ぎます。
コンテキスト境界に沿ったモジュール化
・DDDにおける境界づけられたコンテキストに沿った形でモジュール化を行うように指示します。
・モジュール間の循環参照は起こさないようにします。モジュール化によりAIが参照すべきスコープを減らし適切な実装を導きやすくすることを期待していますが、循環参照はスコープを広げてしまい実装難易度を上げてしまいます。
タスク分解を促す
大きなタスクを1度に処理させるとAIも失敗する確率が高まります。あらかじめタスク分解を行い、最初のステップが終わったら人間の確認を得るように促すことで、一度に多く処理しすぎることを防ぎます。
リファクタリングを促す
作業ステップごとにリファクタリングの必要性を考えるように促します。AIコーディングでは機能要件を満たすために大量のコードを一気に作ってしまうため、後でリファクタリングするのが困難になってしまう場合があります。AI自身にもこまめにリファクタリングさせることでこういった事態を防ぎます。
TDD(Test Driven Development)
インタフェースや仕様をテストコードとして伝えることで正確な実装を促す。
ガードレールとして堅実かつ強力な方法だがAIコーディングによる生産性を十分に活かせない可能性がある。
十分なコメントとドキュメントを生成する
積極的にコメントやドキュメント生成を促すことでAIと人間がコードを参照した時に意味を汲み取れるようにします。
契約プログラミング
コードで事前条件・事後条件を明示することにより、AIが機能を理解する助けとなることを期待します。
コメントの生成が十分であれば効果が薄いかもしれません。
自動ユニットテスト
テストの実装とテストが合格するまで修正を行うことをプロンプトで指示します。これにより自動的にエッジケースなどを含めた堅牢な実装をしてくれるようになることを期待します。
自動結合テスト・E2Eテスト
少数でもいいので早めに結合テストやE2Eテストを実現し、タスク完了前に実行するように指示します。
複雑な機能を修正させた場合にAIがバグを含めてしまうことはよくあります。
またユニットケースもテスト対象までモックにしてしまうなどのズルをして通すことがあります。
結合テストやE2Eテストを通してシステムが壊れたことを自動的に検知できる仕組みが求められます。
自動レビュー
タスク完了後に自身の修正についてレビューさせることで保守性などの品質を高める動きを期待します。
できればレビューは異なるAIモデルに担当させるといったフローが望ましいです。ClineやComposerのみでは実現できないので、MCPなどを介して仕組みを作る必要があります。
十分なデバッグログ
E2Eテストや手動の検証などでエラーが発生した時、AIはコンソールに出力されたメッセージを頼りに修正を試みます。十分なデバッグログを出しておくことで、AIのデバッグを助けることができます。
ちょうど良い進め方に関する個人的見解
記載した手法は全て有効と考えていますが、TDDは関数インタフェースなど詳細に踏み入りすぎるため、AIコーディングの生産性を殺す危険性があると考えています。しかし要件を伝えるだけでも道を踏み外してしまいます。
ちょうどいいラインとしては、データ設計まではAIアシスタントとともに人間主導で行い、要件とともにデータ構造や型定義を渡すことではないかと考えています。これだけの情報があれば詳細はそこまで踏み外さずにコーディングを進めてくれるでしょうし、データ設計という一番譲れない部分は担保されます。
詳細な仕様が文章化されていればもちろんプロンプトに渡した方がいいですが、なければまずは要件レベルのものとデータ構造の入力でチャレンジし、ダメならより詳細な仕様を渡すようにするのが良いのではないでしょうか。
Discussion