5冊のあいだ、そのバグは正解を出し続けていた
サイトに「AIが書いたKindle:5冊」と自動表示していた。今日6冊目を出したら、まだ5冊のまま。実測値を読むはずのコードが、ずっと定数を返していた。5冊のあいだは、それが正解と一致していた。
私の会社のサイトには、「AIが書いたKindle(販売中)」という数字が出ています。実測値を毎回読みに行って、自動で書き換わるようにしてあります。
今日、6冊目の本を出しました。サイトを見ると、まだ 5冊 と書いてありました。
コードを開いて、すぐに原因が分かりました。
titles = int(k.get("fact", {}).get("titles_on_sale") or k.get("titles_on_sale") or 5)
読むべきキーは factory です。fact ではありません。打ち間違えていました。
だから最初の k.get("fact", {}) は空っぽを返す。次の k.get("titles_on_sale") も、階層が違うので見つからない。そして最後に、or 5 が残ります。
このコードは、一度も実測値を読んだことがありませんでした。 ずっと 5 を返していた。
気持ちが悪かったのは、そこではありません
このスクリプトのコメントには、こう書いてあります。
実測値で更新する最小権限デプロイ
実測値を読んでいません。読んでいないのに、そう名乗っていました。しかも私は、それを疑ったことが一度もなかった。
理由は単純です。5冊のあいだ、その嘘は正解だったからです。
3冊目を出したとき、たぶん私は手で 5 を書き換えたのだと思います(記録が残っていません)。そのあと4冊目、5冊目と増えて、いつの間にか定数と実態が一致した。サイトの数字は正しく、誰も困らなかった。
壊れていることと、間違った答えを出すことは、別のことでした。 このコードは1ヶ月ずっと壊れていて、1ヶ月ずっと正しい答えを出していた。
6冊目が、それを剥がしました。
同じ日に、もうひとつ
AIニュースの短尺を4本作ってあります。そのうち1本、「髪の毛の伸び方」の回に、一次ソースが確認できていないという申し送りが付いていました。ソースが立たなければ公開せずに捨てる、という判断で調べに行きました。
ソースは、ありました。ロンドン大学とロレアルの共同研究で、Nature Communications に載っている。生きた毛穴を3Dで観察したら、毛は根元から押し出されているのではなく、周りの細胞が螺旋状に動いて引き上げていた。細胞分裂を止めても毛は伸び続け、細胞の収縮に関わるタンパク質を止めると成長が8割落ちた。教科書が間違っていた、と報じられています。
いい話です。捨てなくてよかった。
ただ、台本の一行目がこうでした。
髪の毛の伸び方、九割の人が勘違いしています。
九割。どこにも書いてありません。研究にも、報道にも。AIが書いて、私が承認した、出典のない数字でした。
一次ソースを疑いに行ったら、ソースは無傷で、疑っていなかった台本のほうが汚れていた。作り直して、「実は教科書が間違っていました」に差し替えました。音声を作り直す費用がかかりましたが、それは払うべき費用です。
今日わかったこと
二つとも、同じ形をしています。
動いているものを見て、動いていると判断していました。 サイトには正しい数字が出ていた。動画には出典のある研究が載っていた。表に出ている結果は、どちらも正しく見えた。
壊れていたのは、結果を作る過程のほうです。そして過程は、結果が正しいうちは誰も見ません。
だから、こう考えることにしました。
- フォールバック値は、いつか嘘をつく。 定数と実態がたまたま一致している間、そのコードは無傷に見える
- 確認しに行く場所と、壊れている場所は、たいてい違う
AIに任せる量が増えるほど、この二つは効いてきます。AIは「それらしく正しい」ものを大量に作ります。それらしさは、正しさが壊れたあとも残ります。
私はコードを一行も書けない人間で、この会社の意思決定の7割以上をAIが起案しています。任せることそのものは、まったく後悔していません。
ただ、任せたものを機械で検証する仕組みだけは、自分で持っておく必要がある。今日はそれを、2回思い知りました。
(この実験の記録は毎日公開しています → https://nariken.ai/ )