バイブコーディングで起きた、再発しそうな爆弾いろいろ

AIによるプログラミングは間違いなく総合的な生産性の段階を飛躍的に上げたのはそう思う一方で、自分でコードを書いている時には起こり得なかったことが次々と起きています。

若干とりとめのない感じになってしまっているのは、根本原因でこれと言えるものがなんとも言いづらいからです。現状、個別の事例を積み重ねて、自分なりに消化しぼんやりと概念化していく段階かと思います。

まぁなんか増えたら付け足していきます。

目次

全般

それらしい計算でデータを捏造する

かなりタチの悪い挙動として、データの捏造がある。しかも完全なランダムではなく、独自のアルゴリズムを勝手に作って、なんだかパッと見でそれらしい感じのするデータを作ることがある。したがって、チャートで雑に「だいたい合ってんな」をやると騙される。

コードを見るならアルゴリズムがどうなっているか確認するのが確実だし、ブラックボックスで見るならば、数字が1もずれていないことを確認する必要がある。要注意なのは、データの欠損や異常値のときだけ勝手に捏造をする、というパターンもあること。

誤差問題

データについていえば、古典的な誤差問題は顕在。AIにやらせるとまずデフォルトで丸め込み誤差などは考慮されていない。データの精度が求められる分野においてはここは見る必要がある。

これについては指摘すればなおすのだが、その直し方が場当たり的な誤魔化しでないか、意味不明な切り捨てなどしてないかなど、補正の根拠についてきちんと見る必要がある。

タイムゾーンが滅茶苦茶

JST/UTCの解釈が滅茶苦茶。時系列データがあった場合、これは明示的にかなり指定して、本当に出来ているかどうかをよくよく確認する必要がある。特にUTC/JSTが混在するデータを処理する場合、何も言わないとマジで混同してグチャグチャになる。人間がさんざっぱらやってきた二重JSTもある。

こんなのされたらすぐわかると思うだろうか?瞬時値ならばそうであろう。しかし連続した24時間データの場合、時間がずれるだけで合計は一致しているし、大まかな傾向はあっていたりするので、やはりわかりづらかったりする。

安易なタイマーで誤魔化す

sleepだのsetTimeoutだのコードに見えたら注意事項になる。wait自体が悪いわけではないのだけれど、そうではなく、レースコンディションやらなんやらをタイマーで安直に場当たり的に誤魔化していることが稀によくある。

個人的にはタイマーを使うところは明示的な指示以外全部禁止にしている(なおそれでも使ってくる模様)。

仕様改修系

主に仕様改修で生じがちな部分。

圧倒的密結合

最初にプリミティブなものを作って、ユースケースを考えながら機能を拡張していく場合、まず間違いなく起きるのが圧倒的密結合アーキテクチャ。一つのロジックに複数のドメインが混在、同じ目的のボタンAとボタンBで異なるビジネスロジックを発火(やりたいことは同じ)などなど。

これについては改修の都度、内部的な設計を想像しながらやっていくのが自分の実情。テンプレを強制するという解に向かう人もけっこういるだろうが、個人的にはAIに大して強烈な外形の制約は、AIの能力を殺しかねないので慎重。

あとは矛盾が顕在化したとき、これはおかしいと指摘すること、先のボタンAとボタンBで結果が異なったとき、AIは確実に場当たり的な対応をする。「ボタンBのロジックをボタンAと同じにしました(関数は別々)」みたいな感じ。ここで、そもそもそのような事象が起きうること自体が設計の不備なのであって、設計の見直しを要求しないといけない。

古い仕様のコードを残す

古い仕様のコードがゴミとして残っている。デッドコードと化しているならマシで、しばしばフォールバックとして処理が残り、それが後々の時限爆弾として炸裂する。特にデータベース関係だと酷いことになる。

外部仕様が変わった時点で、レガシーコードの存在を確認しておく。特にconfigやmodel、schema系が変更されていたら要注意。というか、modelが変わってるけどデータベースは手を加えないよパターンもある。

フロントエンドしか変えてない、バックエンドを誤魔化す

個人的に一番クソ最低だと思うが稀によくあるのが、画面だけ変えてバックエンドを変えてない。変えてないならまだ気づけるが、バックエンドのコードが中途半端で、フロントエンドとの辻褄合わせで誤魔化していた、ということがある。これは本当によくある。だいたい後述のデフォルト上書きやフォールバックによるエラー握りつぶしなども合わせ技になっている。正常系はとおるものだから気づきづらい。

これは、既存のコードを無理やり流用しようとしたが、できなかったので誤魔化して使ってやれ、みたいな感じで起きがちに思う。なので、たとえば具体的な機能を汎用化させた時なんかには、かなり見てやる必要がある。

フロントエンドを見た時に違和感があったら(なんか余計な入力欄があるな…?とか、逆になぜこの値の入力がないな…?とか)、誤魔化しのサインの気がする。減ってるのはもちろん、増えていても誤魔化しのサイン(仕様を適当に理解している?)。フロントエンドの入力値を無視することもしばしばあるので、変えてやると誤魔化しが露呈する、などがある。

こういうことがあると、フロントエンドとバックエンドでリポジトリごと変えてやろうかという気もしてくるが、今のところ効率優先でそうしてはいない。

ハードコーディングやデフォルト上書きで設定を無視する

設定ファイルやWebUI上での設定値が完全に無視されるパターンあり。これは開発環境だと気付けないことも多いうえに、本番環境で起きると死にうるので非常に厄介。環境変数、コマンドライン引数、設定ファイルなど複数の経路での入力がある時や、入力パターンを柔軟にした時なんかに注意。

内部的には、ハードコーディングしていたりデフォルト値で上書きしていたり、謎のエラーを起こしているが謎のフォールバックで値を変えていたりなどがある。これもやはり仕様改修で起きることが多いので、入出力インタフェース部分が変わったときは注意。

永遠に残るマイグレーションコード

AIはスクリプトでやるべきマイグレーション処理を起動時スクリプトでやりたがりがち。気づかずやっていると、永遠にマイグレーションコードが残り、肥大化するだけならまだしも、時限爆弾になりかねない。

後方互換性のために必要なことはあるが、そうでないならなるべく都度処理したい。

全部取得してフィルタ

パフォーマンスが異常に遅いと感じられたときのパターンの一つ。たとえば最新の10件の情報だけでいいのに、マウント時に全件取得して10件フィルタなどやっていることがある。

仕様改修時とは限らないかもしれないが、基本的には改修で起きやすいという認識。初期のプリミティブな段階では全件取得で良かったのが、そのまま残ってしまっているパターンだと思う。検索バーとかあるページで起こりがち。

クエリの問題だけならだいたいすぐに修正できるのだけれど、DBが正規化されていないクソ設計になっていることが露呈することもあるので、発生を確認したら注意されたい。

データベースが正規化されていない

本来一つのテーブルでやるべきだったりリレーション貼ってやるべきところを、独立した2つのテーブルを作成し、アプリケーションのコードで辻褄を合わせていることがある。これは特にデータベースの拡張で起きる。

気づくのが遅れるほど悲惨なので、データベース設計はやはり最低限確認したい。

機能が消える、デグレする

しれっと機能が消えていることがある。単なるデグレならまだよいのだが、これはもっと大きな問題のサインの可能性があるため、デグレがあった時には徹底的に詰める。

最悪なパターンとして、今まで動いてそうで実は動いていなかったことが、リファクタリングによってその矛盾が顕在化された、というものがある。そもそも動いてなかったので、リファクタで整理されたときに、しれっと機能自体をなかった、ということ。これはかなり大規模な改修に繋がることもある。

インストール・アップデート周り

コンテナ使わないアプリで特に問題になりがち。

アプリの権限は誰か

これは根本的なシステム設計の問題になるが、アプリケーションの権限が誰なのか(システム、独自ユーザ、ログインユーザなど)を明確にする。ここが想定と合っていないと後で根本的な改修になってしまう。

アップデータで自爆する

アップデート系の仕組みを入れたとき、自分自身を更新するdpkgが、更新対象サービスと同じcgroupで動いて、何もかも巻き添えでkillしていたりする。中途半端に処理が残って次回のdpkgでsudo dpkg --configure -aしろとか言われる。まぁなんかsystemdの仕様が複雑過ぎるせいの気もする。

まぁだいたいアップデータの仕組みや権限が根本的におかしいので、自爆したら絆創膏で誤魔化さず、抜本的な仕組みの問題について徹底的に追求する。killとかpkillの痕跡が見えたらまず間違いなく強烈なことをしている。プロセス殺す系は全面禁止でいいと思う。

違和感がすべて

チャットしていて、なんか場当たり的な感じがする…そう思ったときはだいたいそう。そういうときのAIの説明は、何かをごまかそうとしているときの人間の説明と一致。以下のような傾向が見られる。

  • UIのウィジェットがおかしい
    • 必要なものがない
    • 不必要なものがある
  • パフォーマンスが「想定より」遅い。あるいは遅くなった
  • 質問の回答がおかしい
    • 端的に理解不能
    • 意図が不明
    • 無駄に長い
    • 異常に複雑
    • 質問の回答になっていない
  • 強烈なコマンドを使い始める
    • killとか

エラーを指摘して、その回答がなんだか妙に回りくどくて、何をしているのかよくわからない回答が返ってきたなど。絆創膏を張っているか、ひどい時はエラーの握りつぶし、エラー箇所をスキップして迂回、などしている。

上位モデルにして「本当にそれが抜本的な対策ですか?」と念押ししてきくと、たいてい「全然抜本的じゃないです」と白状する。でも上位モデルも平然と嘘つくので、モデルの賢さの問題とは思わないほうがよい。

とにかく、何か誤魔化されているような違和感はだいたいあたっている。何が起きているのか、何をしようとしているのかを自分が理解できる程度にまで落とし込むしかない…。

この記事をいいなと思っていただけた方、よければ高評価・チャンネル登録……はないので、コメント・SNSでシェア・ブックマーク、RSSフィード登録を、よろしくお願い致します。

コメント

コメントする

目次