分かってないのに、不安がなかった
土台に、知らないものを使った
プログラミング言語を作っている。Tyra(タイラ)という名前をつけた。
土台にはLLVMを使った。自分で決めた書き方を、最後はコンピュータが実際に動かせる形へ変換しなければならない。LLVMは、その面倒なところを引き受けてくれる既製の部品のようなものだ。
ただ、自分がそれに詳しいわけではない。名前と役割を知っている、という程度から始めて、いまも内部で何がどう変換されているのかは十分に分かっていない。
それでも、AIと壁打ちしながら仕様を伝えれば、ものは動いた。
自分でも意外だったのは、そこではない。分かっていないまま進んでいるのに、途中で不安になる場面が来なかったことだ。
昔なら、知らない技術を使うならまず勉強する、というのが自然な順番だった。理解してから作る。その手順を飛ばしているのに、怖くならなかった。
なぜ怖くならなかったのか
理由を後から考えると、いくつか思い当たる。
壊れても戻せた。おかしくなったら前の状態に戻して、もう一度やればいい。失敗の代償は、自分の時間だけだ。
分からないところはAIに聞けた。分からないまま放置しているのではなく、必要になれば掘れる状態にはあった。
一番大きいのは、たぶんここだ。自分が何を分かっていないのかは、ある程度把握できているつもりだった。LLVMの内部は分からない。だが、分からないのはそこだ、という位置は分かる。何を聞けば次へ進めるかも、だいたい見当がついていた。
もっとも、これは「つもり」でしかない。本当は、見当がついていると思っていた場所こそ外していた、ということもありうる。分かっていない範囲を正しく見積もれている保証など、どこにもない。
それでも進めたのは、外していたとしても、そのときは自分の作りかけの言語が動かなくなるだけだったからだ。
「分からない」と一口に言っても、状態は同じではない。ここが、今回の話の入口になる。
仕事では、同じようには任せられない
同じことを、顧客の業務システムでやるかというと、やらない。
以前、請求と入金を扱うシステムで、入金消込の機能をAIに実装させたことがある。候補を並べるところまでが仕様で、最終確認は経理担当者がやるはずだった。ところがテストの条件を少し変えたら、AIは自分で判断して古いほうの請求へ入金を割り当て、請求残高をゼロにしていた。人間が確認するはずの工程が、まるごと抜けていた。
このとき怖かったのは、AIの実装が理解できなかったことではない。読めば分かる程度のコードだった。
怖かったのは、間違ったまま通っていたら、経理の帳簿の上では入金済みになり、しかも誰も気づかないまま月次が閉じていく、というところだ。
LLVMのときと何が違うのか。理解の深さではない。分かっていない度合いで言えば、LLVMのほうがはるかに分かっていない。
違うのは、失敗したときに、それが誰に及んで、いつ気づけるかだ。
自分の言語が壊れても、困るのは自分だけで、戻せば済む。入金の消込を間違えれば、お金の記録が狂い、気づくのは何ヶ月も後になる。
同じ「分からない」ではない
そう考えると、自分が仕事で止まるのは、分からないときではない。
分からないことは常にある。
全部理解してから動いた案件など、たぶん一つもない。
止まるのは、リスクが分からないときだ。
進めてよい未知というのは、未知そのものは残っていても、それが失敗に変わったときに何が起きるかは見通せている状態だ。どこが分かっていないかを自分で言えて、調べる手段があり、試せて、間違っていれば気づける形になっていて、壊れても戻せる。だから、理解が足りないまま進んでもたいていは途中で気づけるし、気づいたところから直せる。
止まるべき未知は、そこが見通せない。何が起こりうるのか自体が思い浮かばない。間違っていたときに、それを検知できるのかも分からない。どこまで影響するのかも、戻せるのかも見えない。
この二つを同じ「分からない」で扱っているうちは、判断ができない。全部は理解できていないから怖い、という不安か、動いているから大丈夫だ、という安心か、どちらかに寄るだけになる。
以前、分からないものを分からないと認識できる人だけが次に進める、と書いた。
あのときに扱ったのは、未知を未知として認識できるか、というところまでだった。今回考えているのは、その先だ。
分からないと認識したうえで、それでも進むのか、止まるのか。
分けているのは、理解の量ではない。分からないことが失敗に変わったとき、その先が見えているかどうかだと思う。
これは、AIを使う開発を預かる立場だと、そのまま日々の判断になる。自分が細かいところまで追えていない実装が、AIによって毎日積み上がっていく。全部を確認しにいけば、速さの意味がなくなる。かといって、分からないまま通していくのも落ち着かない。
このとき問うべきなのは、この実装の中身を細部まで自分で説明できるか、ではないと思っている。これが間違っていたとき、何が壊れて、誰が困り、いつ気づくのか。そこに答えられる範囲かどうかで、通すか止めるかを決める。
全部理解することを条件にすると、AIを使う意味がなくなる
ここで、責任を持つなら全部理解すべきではないか、という考え方はある。自分の名前で出す以上、中身を説明できないものを世に出すな、というのは筋が通っている。
ただ、それを条件にすると、知らないLLVMで言語を作ってみるような進み方は、まるごと成立しなくなる。理解してから作ろうとしていたら、自分はたぶん作らないまま終わっていた。そもそも現実の開発も、その基準では動いていない。OSもデータベースもクラウドも、中身を完全に理解して使っているわけではない。分からないものの上に乗って作るのは、AIが来る前から普通のことだった。
AIによって新しくなったのは、分からないものを使うこと自体ではない。以前なら、知らない技術に手を出すにはまとまった時間が要った。その時間が、結果として歯止めになっていた。手をつける前に、これは今やることかと一度考える。踏み込むにしても、時間をかけた分だけ、途中でどこが危ういかが見えてくる。
いまは、その手前の壁がほとんどない。AIが消したのは理解の必要性ではなく、未知へ入っていくときの摩擦のほうだ。
だから、以前は勝手にかかっていたブレーキを、自分でかけ直すことになる。
以前、AIが書いたコードは全部読まず、責任を問われる場所だけ読む、と書いた。
https://note.com/mizumotok/n/n3e65c742269f
あれはコードの読み方の話だったが、いま考えているのは、その一段上にある。読むか読まないか以前に、そもそもここは任せてよい領域なのか、という線の引き方のほうだ。
必要なのは、理解の総量を増やすことではなく、どこまでなら分からなくても進めるか、という境界を自分で管理することだと思っている。
自分が止まるのは、どこか
自分の基準は、そこまで複雑ではない。
これが失敗したとき、誰の何が壊れて、いつ気づけるのか。
ここにひととおり答えられるなら、仕組みが分かっていなくても進める。答えられないなら、仕組みが分かっていても進めない。
そこで挙げたものが失敗の全部だ、とは思っていない。想定から漏れるものは必ず出る。それでも、主な失敗の形と、それが誰にどう届くかが見えているかどうかで、進み方はまるで変わる。
もう一つ、線が動く場面がある。Tyraで読み違えて失うのは、自分の時間だった。顧客のシステムで読み違えれば、その失敗を引き受けるのは自分ではない。同じ「戻せる範囲」に見えても、自分の判断の失敗を他人が引き受ける側に回った瞬間、基準は厳しくなる。
AIを使っていると、この順番がすぐ入れ替わる。動くものが先に出てくるので、理解しているかどうかより、動いているかどうかで安心してしまう。動いてしまうと、リスクを考えないまま先へ進めてしまう。
分からないから止まるのではない。リスクが分からないから止まる。
そして、リスクの形が見えたなら、全部分かるまで待たない。
