はじめに
前回のブログ「プロジェクト完成度の法則」(https://qiita.com/EasyCording/items/a2b41b6fc331858c908f)
で、AIコーディングの落とし穴と、0%から始めるプロジェクトが「雪の家」になる理由を話しました。今回はその続編として、AIを賢く使いこなすための「参考→リプレース戦略」を紹介します。書き換え(rewrite)で泥沼にはまるのではなく、既存コードを参考にしつつ、クリーンなコードで置き換える方法を、実体験ベースで解説します。
最近、AIコーディングを試してまたしても時間を溶かした(笑)んですが、この戦略でだいぶ効率が上がったので、皆さんにもシェアしたいと思います!
なぜ「書き換え」じゃダメなのか
前回、AIが生成するコードは「パクりコードの寄せ集め」で、整合性が低いと書きました。例えば、AIにお任せでコードを修正させると、こんなことが起こりがち:
- 部分修正の罠: コードの一部だけ直そうとすると、依存関係が崩れて新しいバグが誕生。
- 複雑化の連鎖: AIは「これで動くよ!」と自信満々に出力するけど、実際は古いライブラリや非推奨の書き方が混ざってたり。
- 理解不能のコード: 修正されたコードが、元の意図とズレて「何これ?」状態に。
そこで気づいたのが、書き換えよりリプレースが強いってこと。既存コードを「参考」にしつつ、ゼロから書き直したコードで置き換える。これなら、AIの「寄せ集め癖」を活かしつつ、整合性を保てるんです。
参考→リプレース戦略とは?
この戦略の基本は、既存コードをガイドラインとしてAIに渡し、新規コードを生成させて、それを既存部分に置き換えること。ポイントは、AIに「修正」を頼まないこと。修正はパッチワークになりがちだけど、リプレースならクリーンな設計を保ちやすい。
イメージで言うと、ボロボロの木造家屋を直すんじゃなく、設計図(既存コード)を参考にしながら、鉄筋コンクリートの新築を建てる感じ。では、具体的にどうやるか?
実践:参考→リプレースの3ステップ
STEP1:既存コードを「参考資料」として整理
まず、置き換えたいコードを明確にします。どのモジュール?どの関数?目的は何か?これをハッキリさせると、AIへの指示がブレません。
例: 古いFlaskのログイン機能を、セキュリティを強化したバージョンにリプレースしたい。
- 既存コードをコピー(例:
login.py
)。 - 問題点(例: パスワードが平文、セッション管理が弱い)をメモ。
- 新しい要件(例: bcryptでハッシュ化、JWTトークン導入)を定義。
STEP2:AIに「参考ベースの新規コード」を生成させる
AIに「修正」ではなく「新しいコード」を作らせます。プロンプトのコツは、役割を明確にし、参考コードを渡しつつ、出力形式を指定すること。
サンプルプロンプト:
あなたはソフトウェアアーキテクトです。以下の参考コードを分析し、[要件: セキュリティ強化、bcryptでパスワードハッシュ化、JWTトークン使用] を満たす新しいログイン機能を生成。参考コードを直接修正せず、置き換え可能な独立したコードを作成し、統合手順を提案してください。
参考コード:
[既存のlogin.pyコード]
出力フォーマット:
- 新しいコード: [コードブロック]
- 置き換え手順: [ステップごとの説明]
- 改善点: [なぜこのコードが優れているか]
生成例:
from flask import Flask, request, jsonify
from flask_jwt_extended import JWTManager, create_access_token
import bcrypt
app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = 'your-secret-key' # 環境変数推奨
jwt = JWTManager(app)
users = {} # 仮のデータベース
@app.route('/register', methods=['POST'])
def register():
data = request.get_json()
username = data.get('username')
password = data.get('password').encode('utf-8')
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
users[username] = hashed
return jsonify({'message': 'User registered'}), 201
@app.route('/login', methods=['POST'])
def login():
data = request.get_json()
username = data.get('username')
password = data.get('password').encode('utf-8')
if username in users and bcrypt.checkpw(password, users[username]):
access_token = create_access_token(identity=username)
return jsonify({'access_token': access_token}), 200
return jsonify({'message': 'Invalid credentials'}), 401
置き換え手順:
- 既存の
login.py
をバックアップ。 - 新しい
login.py
に上記コードをコピー。 - 依存ライブラリをインストール:
pip install flask-jwt-extended bcrypt
. -
JWT_SECRET_KEY
を環境変数で設定。 - テスト:
/register
と/login
エンドポイントをPostmanで確認。
改善点:
- パスワードをbcryptでハッシュ化し、平文保存を排除。
- JWTトークンでセッション管理を強化。
- コードがシンプルで、依存関係が明確。
STEP3:リプレースとテスト
生成されたコードを既存プロジェクトに統合し、テストします。ポイントは:
- 小さく始める: 最初は小さな関数やモジュールで試す。
- テスト必須: ユニットテストや手動テストで動作確認。
- コミットログを整理: 「AI生成コード」「リプレース完了」など、変更履歴を明確に。
成功のコツ:プロンプト設計の極意
参考→リプレースを成功させるには、プロンプトが命。以下のポイントを押さえてください:
- 役割指定: 「あなたは経験豊富なPython開発者です」など、AIの役割を明確に。
- 参考コードの明示: 既存コードをプロンプトに含め、「参考として使用」と指定。
- 出力形式の指定: コード、置き換え手順、改善点を分けて出させる。
- 制約を追加: 「Python 3.10使用」「不要な機能は追加しない」など、条件を明確に。
- 自己レビューを要求: 「このコードがリプレースに適している理由を説明」と入れると、AIが整合性を意識する。
例プロンプト(簡略版):
以下のコードを参考に、[要件]を満たす新しいコードを生成。修正ではなく、置き換え用のコードを。Python 3.10で、不要な機能は追加しない。
参考コード: [コード]
出力:
- 新コード: [コードブロック]
- 置き換え手順: [説明]
実体験:リプレースで変わったこと
この戦略を試した例として、ブログシステムのコメント機能をリプレースした話を。元のコードはSQLインジェクションのリスクがある雑な実装でした。AIに参考コードを渡し、「SQLAlchemyで安全なコメント機能」を作らせたところ:
- 結果: クリーンなコードが生成され、1時間で統合完了。
- 感想: 書き換えだとエラー祭りだったのが、リプレースだとテストもスムーズ!
でも、最初はプロンプトが甘くて、AIがまた「高機能化」しちゃう失敗も(笑)。要件を細かく指定する癖がつきました。
プロジェクト完成度の法則とのつながり
前回の「プロジェクト完成度の法則」では、0%スタートは失敗率100%、100%完成プロジェクトは活用しやすいと書きました。参考→リプレース戦略は、**30%-80%(成長期)**で特に効果的。屋台骨(コア機能)ができたら、AIに部分的な「リプレース」を任せることで、鉄筋コンクリートの家を効率よく強化できます。
これからのAIコーディング
結局、AIは「魔法の杖」じゃないけど、賢い助手にはなれる。参考→リプレースなら、AIの「寄せ集め」癖を逆手にとって、クリーンなコードを生み出せます。ただし、基本的なプログラミング知識は必須。AIのコードを読んで「ここおかしいな」と気づけるスキルがないと、結局ゴミリポジトリが増えるだけ(経験談)。
まとめ:雪の家を卒業しよう
- 書き換えは危険: パッチワークでコードが崩壊。
- 参考→リプレースが正解: 既存コードをガイドに、クリーンな新コードで置き換え。
- プロンプトが鍵: 役割、参考コード、出力形式を明確に。
この戦略で、AIコーディングの効率がグッと上がるはず。次は、もっと具体的なプロンプト集でも作ってみようかな?また面白いネタがあったら書きます!