生成AIで実装した機能を検証していると、「動いているのに、なんだか怖い」と感じることがある。
今回の事例は、管理画面にある削除機能だった。記事やお知らせ、商品情報などの一覧画面によくある、各行に「削除」ボタンが付いているタイプの画面である。特別な機能ではない。むしろ、どのシステムにもありそうな、ごく普通の機能だった。
私はいつものように動作確認を始めた。削除ボタンを押すと確認ダイアログが表示され、「OK」を押すと一覧からデータが消える。ここまでは期待どおりの動きだったので、「問題なさそうだな」と思った。
でも、そのあと少しだけ気になってデータベースを確認した。すると、データそのものがなくなっていた。
「あれ?」
画面上は正しく削除されているように見える。でも、裏側ではレコードそのものが消えている。その瞬間、「これは削除できているのではなく、物理削除されているのか」と感じた。
「削除」とだけ書くと、物理削除になることがある
生成AIに「削除機能を作って」と頼めば、削除ボタンを作り、押したら対象データを消す処理を実装してくれる。実装としては自然だし、コードとしても間違っているようには見えない。
でも、業務システムでいう「削除」は、必ずしもデータベースから完全に消すことではない。
一覧から非表示にするだけの場合もある。削除フラグを立てるだけの場合もある。削除日時や削除者を残し、必要があれば管理者だけ復元できるようにする場合もある。つまり、「削除」と言っても、物理削除なのか論理削除なのかで意味がまったく変わる。
ここを明確に指示しないと、AIは素直に物理削除で実装してしまうことがあるのだと思った。
論理削除にしたいなら、そう書かないと伝わらない
人間同士で開発していると、「これ、本当に消していいんですか?」とか「論理削除ですよね?」という会話がどこかで出ることがある。
でもAI相手だと、その会話が発生しないまま実装が進むことがある。
仕様書に「削除」とだけ書いてある。プロンプトにも「削除できるようにしてください」とだけ書いてある。そうなると、AIから見れば、データを消す実装を選んでも不思議ではない。
論理削除にしたいなら、最初からそう書く必要がある。
「削除ボタンを押したら、対象データを物理削除しない」
「deleted_at に削除日時を入れる」
「deleted_by に削除したユーザーIDを入れる」
「一覧画面では deleted_at が入っているデータを表示しない」
「管理者は削除済みデータを復元できる」
このくらいまで書いて、ようやくAIに伝わるのだと思う。
画面だけ見ていると、合格に見えてしまう
この不具合が怖いのは、画面上では正しく動いているように見えるところだ。
削除ボタンを押す。確認ダイアログが出る。OKを押す。一覧からデータが消える。利用者の操作としては自然だし、テストケースに「削除したデータが一覧に表示されないこと」と書いてあれば、合格になってしまう。
でも、本当に見るべきだったのはその先だった。
データは物理削除されていないか。削除フラグや deleted_at で管理されているか。削除者は記録されているか。関連データまで一緒に消えていないか。復元が必要な業務なら、復元できる状態になっているか。
ここまで確認しないと、業務として安全な削除かどうかは判断できない。
QAは「できたか」を見るだけでは足りない。「やりすぎていないか」も見ないといけない。今回で言えば、削除できたかではなく、消しすぎていないかを見る必要があった。
AI開発では、言葉の意味を分解する必要がある
今回の事例で感じたのは、AI開発では「削除」という言葉をそのまま使うのが危ないということだった。
削除とは、画面から消すことなのか。データベースから消すことなのか。利用者から見えなくすることなのか。管理者だけが見られる状態にすることなのか。あとから戻せるようにすることなのか。
人間同士なら、会話の中で補えることもある。でもAI相手では、そこを仕様として書かないと抜け落ちる。
これはAIが悪いというより、こちらが言葉を雑に使っていたのだと思う。
「削除してください」では足りない。「物理削除ではなく、論理削除にしてください」「削除済みデータは通常一覧に表示しないでください」「復元できるようにしてください」。ここまで書いて、ようやく業務に合った削除機能になる。
AI開発で怖いのは、機能が動かないことではない。機能としてはちゃんと動いている。でも、業務上の意味が少しだけズレている。今回の削除機能も、まさにそれだった。
だからこれからは、「何をするか」だけではなく、「その言葉が業務上どういう意味なのか」まで仕様に書く必要があるのだと思った。