はじめに
最近、PythonやRust、Webアプリなどを個人で実装する際に、生成AIを使うことが増えました。
ただし、AIにコードをすべて書かせるだけでは、実装は完成しても、自分の理解があまり残らないことがあります。
そこで現在は、生成AIを「答えを出す道具」ではなく、学習の工程を分解するための道具として使っています。
特に効果があったのが、次の流れです。
自分で作りたいものを考える
↓
LLMに要件を整理させる
↓
別のLLMに実装させる
↓
テスト結果や差分を自分で確認する
↓
分からなかった部分を再びLLMに質問する
この記事では、私が実践している生成AIを使った実装学習法を簡単に紹介します。
1. 最初からコードを書かせない
以前は、生成AIにいきなり次のような依頼をしていました。
この機能を実装してください。
これでもコードは生成されます。
しかし、完成したコードを見ても、
- なぜこの設計になったのか
- ほかにどんな方法があるのか
- どこが重要な判断だったのか
が分からないままになることがありました。
そこで、最初にコードを書かせるのではなく、作りたいものを整理させるようにしました。
次の機能を実装したいです。
実装を始める前に、
目的、必要な処理、考えられる失敗、
必要なテストを整理してください。
この段階では、コードよりも設計や論点を確認します。
2. 実装用のプロンプトを別のLLMに作らせる
作りたい機能が少し複雑な場合は、実装担当のLLMへ直接指示を出さず、別のLLMにプロンプトを作らせています。
例えば、次のように依頼します。
以下の要望を、コーディングエージェント向けの
実装プロンプトに変換してください。
次の項目を含めてください。
- 実装の目的
- 現在の問題
- 変更する範囲
- 変更してはいけない範囲
- 必要なテスト
- 完了条件
すると、曖昧だった要望が次のように整理されます。
## 目的
ダウンロードが途中で失敗した場合に、
不完全なファイルを正式な成果物として残さない。
## 実装要件
- ダウンロード中は `.part` ファイルを使用する
- 成功時のみ正式なファイル名へ変更する
- 失敗理由を記録する
- 既存の正常系の動作は変更しない
## 完了条件
- 新しく追加したテストが通る
- 既存のテストがすべて通る
- 不完全なファイルが正式名で残らない
このプロンプトを自分で確認し、修正したうえで、実装担当のLLMに渡します。
ここで重要なのは、プロンプトを書く作業を省略することではありません。
LLMが整理した要件を自分でレビューすること自体が、学習になると感じています。
3. 実装方法よりも完了条件を決める
生成AIに細かい実装手順をすべて指示すると、その手順が正しいかどうかを判断しにくくなります。
そのため、私は作業手順よりも、完成後に満たすべき条件を重視しています。
例えば、入力値を検証する機能なら、期待する動作をテストとして表します。
def test_rejects_negative_value():
assert validate_value(-1) is False
def test_accepts_zero():
assert validate_value(0) is True
実装担当のLLMには、次のように依頼します。
既存の設計を壊さず、このテストが通るように実装してください。
実装後は全テストを実行し、
失敗した場合は原因を調査してください。
実装方法はLLMに考えさせますが、正しい状態は自分で定義します。
この違いによって、AIのコードを受け取るだけではなく、
- どのような入力を考慮するべきか
- 何を異常とするか
- どこまでを一つの機能とするか
を考えるようになりました。
4. AIの説明ではなく、差分とテストを見る
生成AIは、実装後に自然な文章で成功を報告します。
機能を実装しました。
エラーハンドリングも追加しています。
ただし、この説明だけでは本当に正しいか分かりません。
そこで、主に次のものを確認します。
変更されたファイル
コードの差分
追加されたテスト
テストの実行結果
実際に生成されたファイル
エラー発生時の挙動
特に大切なのは、成功した場合だけでなく、失敗した場合の動作を見ることです。
AIが生成したコードに問題があった場合も、すぐに修正を依頼するのではなく、まず原因を自分なりに考えます。
テストの想定が間違っているのか
実装が間違っているのか
既存仕様と衝突しているのか
境界条件が抜けているのか
この原因分類が、実装学習として特に役立ちました。
5. 分からないコードは、その場で教材にする
AIが生成したコードの中に分からない記述があった場合は、そのまま先に進まないようにしています。
例えば、次のように質問します。
この変更で使われている一時ファイル方式について、
初心者向けに説明してください。
また、直接正式なファイル名へ保存する場合と比べて、
どのような障害に強くなるのか説明してください。
さらに、比較させることもあります。
この実装以外に考えられる方法を2つ示してください。
それぞれの利点、欠点、
今回の実装が選ばれた理由を説明してください。
実際に作っているコードを教材として使えるため、一般的な入門書だけを読むよりも、目的を持って学びやすくなります。
6. 一つのLLMだけを正解にしない
プロンプト作成と実装を別のLLMに分けると、同じ問題を異なる視点から確認できます。
例えば、
- 一つ目のLLMが要件を整理する
- 二つ目のLLMが実装する
- 必要であれば三つ目のLLMにレビューさせる
という使い方ができます。
ただし、複数のLLMが同じ回答をしたとしても、それが正しいとは限りません。
最終的には、自分でコード、テスト、公式ドキュメントなどを確認する必要があります。
LLMを増やす目的は、多数決で正解を決めることではなく、自分では気づかなかった論点を出してもらうことです。
まとめ
現在、私は次の手順で実装を学んでいます。
1. 自分で作りたいものを決める
2. LLMに要件や論点を整理させる
3. 必要なら別のLLMに実装プロンプトを書かせる
4. 実装担当のLLMにコードを変更させる
5. 自分で差分とテスト結果を確認する
6. 分からない部分をLLMに説明させる
7. 別の方法と比較する
生成AIを使うと、コードを書く作業そのものは減ります。
一方で、
- 要件を定義する
- 完了条件を考える
- テストを設計する
- 実装の妥当性を確認する
- 複数の方法を比較する
といった学習に時間を使えるようになります。
AIに答えを出してもらうだけではなく、設計、実装、検証、復習を分けるためにAIを使う。
これが、現在の私にとって最も学びやすい生成AIの活用方法です。