以下の内容はhttps://syu-m-5151.hatenablog.com/entry/2025/03/19/201025より取得しました。


生成AIといっしょ: 動作するきれいなコードを生成AIとつくる

※こちらは社内で発表したものを外部で登壇できるように修正したものです。

はじめに

2021年にGitHub Copilotが発表され、2022年に一般利用可能になって以来、生成AIはソフトウェア開発の世界に急速に浸透してきました。「動作するきれいなコード」はソフトウェア開発の理想とされてきましたが、生成AIの登場によってこの理想に到達する道筋が大きく変化しています。本記事では、テスト駆動開発の原典である『テスト駆動開発』の基本理念を踏まえ、生成AIとの協業によって「動作するきれいなコード」を実現する方法について考察します。

「動作するきれいなコード」とは何か

t-wada氏がSeleniumConf Tokyo 2019での基調講演で引用したように、テスト駆動開発のゴールは「動作するきれいなコード(Clean code that works)」です。Kent Beckによるテスト駆動開発の書籍の冒頭には、次のような一節があります。

speakerdeck.com

「動作するきれいなコード」。Ron Jeffriesのこの簡潔な言葉が、テスト駆動開発(TDD)のゴールだ。動作するきれいなコードはあらゆる意味で価値がある

「動作する」と「きれい」の2つの要素に分解すると、ソフトウェア開発においては以下の4つの象限が考えられます:

  1. きれいで動作する(理想)
  2. きれいだが動作しない(机上の空論)
  3. きたないが動作する(現実の妥協)
  4. きたなくて動作しない(最悪の状態)

Kent Beckは、この目標に対して、天才的なプログラマならすぐに到達できるかもしれないが、一般のプログラマはすぐには書けないと述べています。そこで彼は分割統治法を提案し、まず「動作する」ことを優先し、その後「きれい」にすることを推奨しています。

生成AIとテスト駆動開発の融合

ソフトウェア開発における三種の神器

t-wada氏の講演では、ソフトウェア開発において欠かせない三つの技術的な柱(三種の神器)が紹介されています。これらは生成AIと協働する際にも極めて重要な基盤となります。

1. バージョン管理(Version Control)

バージョン管理は、人間の記憶力の限界を補うために生まれました。バージョン管理システムは:

  • いつ、誰が、どのような変更をしたかを記録
  • 異なるバージョン間の差分を可視化
  • 複数の開発者が同時に作業することを可能に
  • 過去の状態に簡単に戻れる安全網を提供

生成AIとの協働においても、AIが生成したコードを適切に管理し、問題が生じた場合に以前の状態に戻れるようにするためにバージョン管理は不可欠です。

2. テスティング(Testing)

テスティングは人間の把握力の限界を補います。システムが複雑化するにつれ、変更が他の部分に与える影響を人間が完全に把握することは困難になります。テスティングにより:

生成AIとの協業では、この安全網がさらに重要となります。AIが生成したコードが本当に要件を満たしているかを客観的に評価するためのテストは不可欠です。

3. 自動化(Automation)

自動化は人間の忍耐力の限界を補います。自動化により:

特に重要なのは、自動化がソフトウェア開発におけるガードレールとしての役割を果たすことです。AIが生成したコードの品質、セキュリティ、パフォーマンスを自動的に検証することで、AIの「創造性」と「安全性」のバランスを取ることができます。

三種の神器は、「あれば便利」という加点法ではなく、「なければ危険」という減点法の世界です。生成AI時代においても、これらの基盤があってこそ、安全かつ効率的な開発が可能になります。

AIとの協業進化段階

AIによる開発支援は、自動車の自動運転レベルに似た段階を経て進化しています:

  • レベル0:AI支援なし - 従来の手動開発
  • レベル1:AI支援(Chat) - LLMによる情報提供のみ
  • レベル2:AI支援(補完+Chat) - GitHub Copilotなどの部分的補完
  • レベル3:Agent(人間が支援) - AIが主に作業し、人間が確認・修正
  • レベル4:Agent(人間の支援なし) - AIが自律的に開発
  • レベル5:業務の完全自動化 - 要求からプロセス全体を自動生成

2025年の開発環境は、主にレベル3〜4の間で推移しており、「副操縦士(Copilot)」から「操縦士(Pilot)」へと主役が交代しつつあります。

生成AIの強みと限界

生成AIの特性は以下のようにまとめられます:

  • 強み:

    • 膨大なコードパターンとベストプラクティスの学習
    • 自然言語からコードを生成する能力
    • 環境情報を参照し、実行結果から学習して修正する能力
    • 圧倒的な速度でのコード生成・実行・修正
    • 多言語・多フレームワークへの対応
    • 多様な実装アプローチの提案能力
  • 限界:

    • ビジネスロジックドメイン知識の理解が浅い
    • コンテキストの保持と長期的な一貫性の維持が苦手
    • 複雑なコンパイラ制約がある言語での実装に課題
    • 「テストを無理に通そうとする」傾向
    • 参照の明示的な解決が苦手

特にCLINEなどの環境統合型エージェントは、実行と修正のサイクルを驚くべき速度で回すことができ、「どんなエキスパートでも勝てないレベル」に達しつつあります。AIツールを使いこなすためには、「コンテキストを記述する能力」「ドメインを記述する能力」「AIの性能に対する直感」といった新しいスキルセットが求められます。

zenn.dev

ドライバー席を譲った後の新しい役割

開発者が主導権(ドライバー席)をAIに譲った後、どのような新しい役割を担うべきでしょうか。

助手席のナビゲーター

最も有望なポジションは「助手席」です:

  • AIに対して適切な指示と方向性を提供する
  • 生成された成果物の品質と整合性を評価する
  • AIの能力を最大限に引き出すプロンプトエンジニアリングを行う

後部座席への後退リスク

一方で、単に「後部座席」に座り、AIの決定に従うだけの受動的な立場になるリスクも存在します:

  • AIが示した選択肢から選ぶだけの存在に
  • 専門的理解が浅くなり、本質的な問題解決能力が衰える
  • 「運試し」と「結果責任」だけが残される状態

speakerdeck.com

この比喩はとても好きなので、将来的には「お前は後部座席に座るなよ」とか言いそうです。

レッドボックスの内に対処する

生成AIの発展に伴い、小説「BEATLESS」で描かれた「人類未到産物(レッドボックス)」の概念が現実味を帯びてきています。

「超高度AIが生み出した、今の人類には理解できない超高度技術によってつくられた産物。「レッドボックス」という名称には、観測者から遠ざかる光が赤方偏移により赤から黒(赤外領域)へと変わるように、人類が必死に追いすがらなければいずれ遠ざかりブラックボックスになってしまうという意味が込められている。」

現在のAIコーディングでも、AIが生成した複雑なコードや設計に対して、人間が「理解できない」状態に陥るリスクが現実化しつつあります。それらには以下のような対策が考えられます。

  • 意図的な単純化 - AIに「人間が理解できるようなシンプルな実装」を明示的に要求する
  • 解説の要求 - 実装だけでなく、その設計思想や動作原理の解説を求める
  • 段階的な理解 - 複雑な実装を小さな部分に分解して理解する
  • テストによる挙動の可視化 - 振る舞いを詳細なテストで定義することで、ブラックボックス化を防ぐ
  • 継続的な学習 - AIが使用する最新の技術やパターンを人間側も学び続ける

speakerdeck.com

AIの能力が人間の理解を超えた「レッドボックス」となっても、その内部を理解するための努力を怠らないことが、「助手席」の位置を維持するために不可欠です。技術が人間から遠ざかっていくのを防ぐために、テスト駆動開発のような体系的なアプローチが重要な役割を果たします。

バイブス労働とAIコーディング

バイブスコーディングとは何か

Andrej Karpathy(OpenAI共同創業者)が提唱した"vibe coding"という概念が注目を集めています。

「新しい種類のコーディングがあって、私はこれを"vibe coding"と呼んでいます。そこでは完全に"vibe(雰囲気、直感)"に身を任せ、指数関数的成長を歓迎し、コードそのものが存在していることさえ忘れてしまいます。」 — Andrej Karpathy

このバイブスコーディングは、以下の特徴を持っています:

  1. 自力で成果物を作り込まない - AIに指示を出すことに集中
  2. ノールックマージ - AIの提案を直感的に受け入れる
  3. エラー解決のアウトソース - 問題発生時にAIに解決を依頼
  4. 理詰めな部分はAIに任せる - 人間は直感と判断に集中

Andrej Karpathyが提唱する「バイブスコーディング」の考え方を適度に取り入れることで、生成AIとの協業をより効果的にできます。

  • 直感を大切に - AIとの対話では、時に論理的思考よりも直感が良い結果を生むことがある
  • 反復の高速化 - AIがエラー修正や実装変更を高速で行える特性を活かし、試行錯誤のサイクルを加速
  • 余分な労力の削減 - 自明な実装や定型コードの作成はAIに任せ、本質的な部分に集中
  • 創造的提案の受け入れ - AIが提案する予想外のアプローチに対してオープンな姿勢を持つ

ただし、バイブスに任せすぎることなく、テストという客観的基準を常に維持することで、「ノリ」と「品質」の両立を図ります。特に、重要な意思決定やアーキテクチャに関わる部分では、専門知識に基づく判断を優先しましょう。

learning.oreilly.com

blog.lai.so

バイブス労働の広がり

バイブスコーディングの概念は、プログラミングの領域を超えて様々な知識労働にも応用できる「バイブス労働」という新たなパラダイムを生み出しています。バイブス労働では、AIを活用して直感的かつ効率的に成果を生み出す働き方が可能になります。

バイブス労働の特徴には以下のようなものがあります:

  • プロンプトクラフティング - AIに適切な指示を出すスキルが新たな専門性として価値を持つ
  • 創造的監督 - 細部の実装よりも、全体の方向性や品質の判断に人間の能力を集中させる
  • 反復と共進化 - 人間とAIが互いにフィードバックを与え合いながら成果物を進化させていく
  • メタ認知の重要性 - 自分の思考プロセスを客観視し、AIとの協業に最適な役割分担を模索する

バイブス労働の時代においては、「コードを書く」「文章を作成する」といった直接的な生産活動よりも、「何を作るべきか」「どのような価値を提供するか」という本質的な問いに答えることにより多くの時間とエネルギーを費やすことが可能になります。これにより、人間の創造性と直感が最大限に発揮される新しい働き方が実現するでしょう。

生成AIとのテスト駆動開発の実践

テスト駆動開発(TDD)の基本サイクル「Red-Green-Refactoring」を生成AIと組み合わせると、以下のようなアプローチが考えられます:

t-wada.hatenablog.jp

Red: AIを活用したテスト設計

生成AIはこのステップで:

  • ユーザーストーリーや仕様から、テストケースを提案
  • 自然言語からテストコードを生成
  • 人間が見落としがちなエッジケースを発見
  • 様々なテスト方法を提示

人間は機能要件を明確に定義し、AIが提案するテストケースが要件を正確に反映しているか評価します。

Green: AIによる実装の高速化

生成AIはここで:

  • 失敗するテストを満たす実装コードを生成
  • 複数の実装アプローチを提案
  • 素早いプロトタイピングを実現
  • テスト失敗時のデバッグを支援

テストという明確な基準があるため、AIの出力の正確性を客観的に評価できます。Kent Beckの原則通り、まずはテストを通過することを優先し、きれいさは次のステップで追求します。

Refactoring: AIと共にコードをきれいにする

このステップでは、生成AIは:

テストが引き続き成功することを確認しながら、コードの品質を向上させます。AIはコードの「きれいさ」に関する豊富な知識を持っていますが、プロジェクト固有の規約やアーキテクチャの理解には限界があるため、人間による最終確認が不可欠です。

人間の役割の根本的な変化:「望ましい状態」の設計者へ

生成AIとの協働を通じて、私たちの仕事の本質が根本的に変わりつつあることを実感しています。これまで人間は「どうやって実現するか」という実行プロセスに多くの時間を費やしてきましたが、今後は「どうあるべきか」という理想状態の定義に集中することになるでしょう。

現在と理想の継続的な調整

日々の開発で感じるのは、人間が担うべき役割が「現在の状態を正確に把握し、望ましい状態を明確に宣言する」ことに収斂していく感覚です。生成AIは、この両者の差分を自律的に検知し、継続的に調整を行ってくれます。まるで優秀なアシスタントが、私たちの意図を汲み取り、現実と理想のギャップを埋め続けてくれるかのようです。

意図の翻訳者としての新たな専門性

この変化の中で、人間の新たな専門性は「AIに適切な仕事を持ってくること」になります。現実世界の複雑な文脈、ビジネス要求、制約条件をAIが理解できる形で翻訳し、伝達する能力が求められます。AIは実装を担い、人間は意図と方向性を示す—この役割分担により、より高度な価値創造が可能になっています。

バイブスと直感の背後にある判断プロセス

興味深いことに、AIが生成したアウトプットを評価する際、私たちは「これは良い」「これは違う」という直感的な判断を瞬時に下しています。この一見感覚的な判断の背後では、実は脳内で理想状態と現状を高速で照合しているのです。

この体験は時に、ギャンブルのような興奮を伴います。AIが次々と提案を生成し、理想的な解決策が現れた時の喜びは、まるで大当たりを引いたような高揚感があります。しかし決定的に違うのは、適切な評価基準があれば必ず理想に到達できるという点です。

問題設定力と評価基準の設計

この新しいパラダイムで人間に求められるのは、「問題設定力」と「評価基準の設計力」です。何を解決すべきか、どのような状態が理想的なのか、そしてその達成度をどう測定するのか—これらの判断には、倫理観、美意識、長期的視野といった、数値化困難な人間固有の価値観が不可欠です。

例えば、新しいプロダクト開発において、エンジニアは細かな実装から解放され、「ユーザーにとって本当に価値のある体験とは何か」という本質的な問いに集中できるようになります。

新たな責任:賢明な意図の設計

しかし、この変化は同時に重大な責任も生みます。AIが強力になればなるほど、人間が設定する「望ましい状態」の定義が社会に与える影響は計り知れません。偏った価値観や短絡的な目標設定は、AIの力によって増幅され、意図しない結果を招く可能性があります。

だからこそ、多様な視点を取り入れ、長期的な影響を慎重に検討する「賢明な意図の設計」が、これからの時代の最も重要な人間の仕事となるでしょう。私たちは単なる実行者から、理想の設計者へと進化しているのです。

直感的判断の背後にある無意識の照合プロセス

バイブスコーディングで「なんかこのコード良さげ」と感じる瞬間、それは単なる感覚ではありません。実は私たちの脳が「理想的な状態に到達した」と無意識に判定している瞬間なのです。逆に「ここの実装はしっくりこないな」と感じるのは、頭の中で「期待している姿と実際の姿にズレがある」と検出している証拠でしょう。

この生成→確認→判断→再生成…というシンプルな繰り返しは、人間の脳の報酬系を強く刺激します。理想的な結果が出た時の満足感、期待外れだった時の「もう一度」という衝動—これらの感情的な起伏が、開発プロセスに独特の中毒性をもたらしているのかもしれません。

新たな役割への変貌の自覚

「理想の状態を定義し、現実との差を埋める方向性を示す」という新しい役割が、今や私自身の働き方の中核になってきました。かつては実装の詳細に没頭していた自分が、いつの間にか「どうあるべきかを示し、AIと共に理想に近づけていく調整役」になっている—この変化に気づいた時、まるで別の職業に転職したような感覚を覚えます。

品質を保証する仕組みの重要性

ソフトウェア開発において、「あるべき姿を定義し維持するための検証の仕組み」は欠かせません。テストはコードの正しさを、継続的インテグレーションは全体の一貫性を、本番環境の監視システムは実際の動作を検証します。これらは人間の意図と実際のシステムの振る舞いの間に一貫性を保つ自動化された仕組みといえるでしょう。

生成AIの時代においては、AIの創造性と自由度が高まるほど、これらの検証の仕組みはさらに重要になります。AIが生み出す無限の可能性の中から、本当に価値のあるものを選び取るための基準と検証プロセスこそが、人間が設計すべき最も重要な要素なのです。

生成AIとTDDの相性の良さ

生成AIとテスト駆動開発には、以下のような相性の良さがあります:

  1. 明確な評価基準 - テストがAIの出力の正確性を評価する客観的基準となる
  2. 繰り返しのフィードバック - 小さなサイクルによる継続的改善がAIとの協業に適している
  3. 段階的な複雑性の増加 - 単純から複雑へ進むアプローチがAIの能力を引き出す
  4. 品質保証の自動化 - テストによる安全網でAIコードの品質を保証
  5. 責任の分担 - 人間がテストで要件を明確にし、AIが実装を担当という自然な役割分担
  6. 人間の尺度のリファクタリング - AIが生成した複雑なコードを、TDDを通じて人間が理解・保守しやすい形に整理できる

効果的な生成AI活用のためのプラクティス

1. テスト優先の指示

AIに実装を依頼する前にテストを先に書くよう指示することで、テスト駆動の流れを維持します。テストを通じて機能要件を明確に定義し、AIがその要件を正確に理解することを促します。

2. 段階的な複雑性の増加

単純なテストケースから始め、徐々に複雑なケースを追加していくアプローチがAIとの協業に効果的です。AIが問題を段階的に理解し、複雑性を徐々に取り入れることができます。

3. リファクタリングの明示的な依頼

具体的なリファクタリングの観点(命名の改善、重複の排除、可読性向上など)を指定すると良い結果が得られます。焦点を絞ることでAIはより的確な改善提案ができます。

4. 小さなサイクルの維持

小さな機能単位でテスト→実装→リファクタリングのサイクルを回すことで、問題発生時の影響範囲を限定し、修正を容易にします。短いサイクルは、AIにとっても理解しやすく、効率的な協業を促進します。

5. 三種の神器を活用したAI協業ワークフロー

バージョン管理: - AIが生成したコードを適切にコミットし、変更履歴を明確に残す - AIの提案ごとにブランチを作成して比較検討 - 問題発生時に以前の状態に容易に戻れるよう準備

テスティング: - 先にテストコードを作成し、明確な目標を設定 - テストと実装の両方を継続的に改善 - テストカバレッジをモニタリングして品質保証

自動化: - CIパイプラインでAIコードの品質を自動検証 - 静的解析とセキュリティスキャンでAIの盲点をカバー - 自動化されたガードレールで意図しない問題を防止

三種の神器は、AIとの協業における品質と安全性を保証する基盤となります。

6. 私が生成AIの時代にRustを選択する理由

テスト駆動開発は効果的ですが、テストだけではすべての不具合を検出できないという限界があります。特に生成AI時代において、型システムによる形式検証を提供するRustのような言語を選択することで、AIとの協業をより確実なものにできます。

Rustの型システムは「軽量な形式検証」として機能し、テストでは捉えきれない問題を発見します。所有権と借用チェッカーによるメモリ安全性の数学的保証、代数的データ型による未定義状態の排除、トレイト境界によるコードの整合性の静的検証など、多くの利点があります。

現時点では、生成AIがRustコードを一発でコンパイル通過させることは難しく、私の経験上も何度か修正が必要になることが多いです。しかし、これは欠点というよりも、Rustのコンパイラが持つ厳格なチェック機能が「ガードレール」として働いている証拠と言えるでしょう。AIが生成したコードでもコンパイラが厳密な検証を行うことで、多くの潜在的な問題が実行前に排除されます。

Rustの型システムとテスト駆動開発相互補完的な関係にあります。型システムがコード全体の整合性と安全性を保証し、テストがビジネスロジックの正確さを検証します。このような組み合わせにより、AIが生成したコードの品質担保と不具合検出の両面をカバーできます。テストだけでは見つけられない並行処理やメモリの問題も、Rustのコンパイラが捕捉してくれるのです。

生成AI時代において、言語自体が提供する安全性保証は、人間のレビュー負担を軽減し、AIとの効率的な協業を実現します。コンパイラが通過するまでに何度か調整が必要でも、その過程自体がコードの品質向上に貢献していることを忘れてはなりません。

おわりに

生成AIとテスト駆動開発を組み合わせることで、「動作するきれいなコード」を効率的に実現できる可能性が広がっています。AIの創造性と生産性、人間の判断力と創造性を組み合わせるための鍵は、テスト駆動開発の原則と三種の神器という堅固な基盤です。

t-wada氏の言葉を借りれば、「テスト駆動開発は、設計のひらめきが正しい瞬間に訪れることを保証するものではない。しかし、自信を与えてくれるテストときちんと手入れされたコードは、ひらめきへの備えであり、いざひらめいたときに、それを具現化するための備えでもある」のです。

t-wada.hatenablog.jp

生成AIはこの「備え」をより強固にする強力なパートナーとなります。AIとの協業においても、テスト駆動開発の原則を守りながら、AIの能力を最大限に活用することで、より良いソフトウェア開発が実現できるでしょう。




以上の内容はhttps://syu-m-5151.hatenablog.com/entry/2025/03/19/201025より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14