今更ですが、『プロフェッショナルAI駆動開発』を約70ページ読んで、AIが生成したコードをどう受け取り、どう確認するかを考えるようになりました。
この記事では、現時点での理解を、簡単なコード例とともに整理します。以下の実装例は本書からの引用ではなく、説明のために作成したものです。
Y = F(X) を自分なりに捉える
本書では、AIを使った開発を Y = F(X) という形で捉えています。今の私は、次のように理解しています。
- X:AIに渡す仕様や既存コードなどの情報
- F:AIによる処理
- Y:作られたコードと、それが満たすべき結果
たとえば「削除ダイアログをキャンセルしたらエラーを消す」とだけ伝えた場合、AIはエラーを消すコードを追加できるかもしれません。ただ、それだけでは「再度開いたときはどうするか」「削除を確定したときの処理は維持するか」が分かりません。
AIに渡す情報が足りないと、動くコードができても、期待した動作とずれる可能性があります。
コードが動いても、確認したい動作は残る
次は、削除ダイアログのエラー表示を扱う簡単な例です。
function DeleteDialog() {
const [open, setOpen] = useState(false);
const [error, setError] = useState<string | null>(null);
function handleCancel() {
setError(null);
setOpen(false);
}
// ダイアログの表示部分は省略
}
handleCancel を見ると、キャンセル時にエラーを消す処理はあります。しかし、コードを読むだけで修正を完了とは判断できません。
- エラーが表示された状態でキャンセルすると、エラーが消えるか
- ダイアログを開き直したとき、古いエラーが表示されないか
- 削除を確定する操作は、修正前と同じように動くか
こうした動作をテストや画面操作で確認して、初めて今回の修正が目的を満たしたか判断できます。
リファクタリングも必要になる
AIへの依頼を重ねると、その都度の修正は動いていても、似た処理が複数の場所に増えることがあります。
function handleCancel() {
setError(null);
setOpen(false);
}
function handleCloseButton() {
setError(null);
setOpen(false);
}
この場合、二つの操作が常に同じ振る舞いをする仕様なら、処理を一つにまとめられます。
function closeDialog() {
setError(null);
setOpen(false);
}
function handleCancel() {
closeDialog();
}
function handleCloseButton() {
closeDialog();
}
小さな例ですが、修正を積み重ねるだけでなく、後からコードの構造を見直すことも必要だと感じました。リファクタリング後には、キャンセルと閉じるボタンの両方が期待どおり動くことを確認します。
サブエージェントには確認する観点を渡す
実装を担当するAIとは別に、サブエージェントへレビューを依頼する場合も、単に「レビューして」と伝えるだけでは確認範囲が曖昧です。
今回の例なら、次のように役割を絞れます。
削除ダイアログの変更をレビューしてください。
確認する観点は次の3点です。
- キャンセル時と閉じるボタンで、エラー表示が正しく消えるか
- ダイアログを開き直したとき、古いエラーが残らないか
- 削除を確定する処理に意図しない変更がないか
問題を指摘する場合は、該当するコードと再現手順を示してください。
観点を分けると、レビュー結果を自分でも確かめやすくなります。ただし、サブエージェントの「問題なし」という回答だけで完了とせず、実際の動作と変更内容を確認する必要があります。
おわりに
約70ページを読んだ現時点では、AIの出力を毎回同じにすることよりも、AIに渡す情報と、結果を確かめる方法を整えることに関心を持っています。
今後も本書を読みながらその使い方を見直していきたいと思います。
