メインコンテンツへスキップ
ログイン

AIが存在しないパッケージを延々とimportする。私たちもうんざりでした。

AIは存在しないimportを幻覚し、攻撃者はその名前をマルウェア付きで登録します。マージ前に止める方法を解説します。

あるスレッドが話題になっています。「AIアシスタントが、存在しないimportを私のコードに勝手に追加し続ける」と誰かがこぼしているのです。面白いのは返信のほうです。ある人のコーディングエージェントはモジュールを一つでっち上げ、指摘されると「それは実在する」と言い返してきました。別の人は、TrjnHrs.Pkg のような名前の謎のパッケージが、プロジェクトにこっそり追加されているのを見つけました。さらに別の人は、存在しないモジュールこそが、AIに書き直してもらった同僚のサービスが丸一日、誰にも気づかれずに壊れていた原因だと気づきました。

私たちは笑いました。そして笑うのをやめました。これは私たちも悩まされてきた問題だったからです。

なぜモデルはimportを作り出すのか

大規模言語モデルはパターン照合器であって、コンパイラではありません。モデルが import のあとにそれらしい名前を書くとき、そのパッケージが存在するかどうかを確認しているわけではありません。自信のあるプログラマーなら次に何を打ちそうか、を予測しているだけです。たいていの場合、その予測は当たります。ですが時々、requests_asyncreact-use-debounce-hook、あるいは誰も公開したことのない、いかにもそれらしい名前のユーティリティに、堂々と手を伸ばします。

モデルにはグラウンドトゥルース(事実の裏付け)がありません。あるのは「雰囲気」です。そして雰囲気は、本物のパッケージそっくりの名前を生み出すのがとても得意です。

本当に怖いのはここから

幻覚されたimportは、単なるビルドの失敗ではありません。攻撃の入口です。

研究者たちはこれにすでに名前を付けています。スロップスクワッティング(slopsquatting)です。攻撃者は、AIツールがどんな偽のパッケージ名を幻覚しがちかを観察し、その名前をマルウェア入りで公開レジストリに登録します。あなたのアシスタントが trjnhrs-pkg を思いつく。誰かがすでに trjnhrs-pkg を公開している。あなたのインストールコマンドは何事もなく解決する。そして気づけば、他人のコードを実行しているのです。昨日「存在しなかった」importは、今日は意図的に存在し、しかも敵対的です。

これこそ、本当に危険な失敗モードです。タイプミスなら5秒で気づきます。ですが、誰かのペイロードへ静かに解決してしまうそれらしいパッケージ名は、本番に入るまで気づけない類いのものです。

「やめろと言えばいい」が効かない理由

スレッドには、いつものアドバイスが並んでいます。もっと良いプロンプトを書け。間違えるなと指示しろ。警告をエラー扱いにしろ。チェッカーを入れろ。

最初の二つは希望的観測です。確率的なシステムを、持っていない事実について決定論的にすることは、プロンプトではできません。後の二つは惜しいところまで来ていますが、汎用のリンターは症状(解決しないimport)を指摘するだけで、原因を理解しません。依存関係をマニフェストに追加し忘れただけなのか。リンターからは見えない内部モジュールなのか。それとも、このパッケージは地球上のどこにも本当に存在しないのか。この三つのケースは、頭の悪いチェッカーには同じに見えますが、必要な対応はまったく異なります。(自分のコードを自分で見直しても、AIのもっともらしい間違いを拾えないのと同じ理由です。コードを書いたものが、それを検証する唯一の存在であってはいけません。)

そのギャップを埋めるために作ったのが Surmado Code Review です。

どうやって実際に捕まえるのか:決定論的チェックと判断

答えは、より賢いモデルではありません。そもそも、事実に関する問いをモデルに投げないことです。

知る作業は、決定論的チェックが担います。プルリクエストのたびに、Surmado Code Review は差分の中の各importを、事実の裏付けに照らして解決します。あなたのロックファイル、マニフェスト、インストール済みモジュール、標準ライブラリ、社内パッケージです。この工程は推測しません。パッケージは解決するか、しないかのどちらかです。super-fast-parser が差分に現れて、依存グラフにもレジストリにも何も解決しないなら、それは意見ではなく事実です。ここでは生成が一切行われないので、幻覚は起こりようがありません。ただの照合です。

判断する作業は、Scout が担います。事実がそろえば、モデルは本当に得意なこと、つまり仕分けと説明を行います。「package.json への追加を忘れただけ」なのか、「このモジュールは存在せず、いちばん近い実在のものは名前が違う」のかを見分けます。重複を取り除きます。あなたがほぼ間違いなく意図していたimportを指し示します。そして、怖いケースを引き上げます。たとえば、この名前は3日前に公開されたばかりのパッケージに解決し、エコシステム内の他の何もそれを参照していない、というように。それがスロップスクワッティングの匂いであり、単純なリンターにはできない判断です。

どちらの半分も、単独では機能しません。判断のない決定論的チェックはノイズが多く、自分を説明できません。決定論的な裏付けのないモデルは、importを幻覚するもう一つの存在にすぎず、今度はあなたの幻覚importをレビューすることになります。両方を組み合わせると、あのスレッドの全員が本当に欲しかったものが手に入ります。何が本物かという確実性と、どうすべきかという判断です。

どこで動くのか

Surmado Code Review は、あなたのプルリクエストにコメントします。差分をチームの STANDARDS.MD に照らして確認し、でっち上げのimportがマージされる前に印を付けます。同僚のブランチを静かに壊したり、誰も精査していないパッケージを引き込んだりした後ではありません。PRごとに1つのコメント、あなたのルールに紐づき、修正をプッシュすれば同じ場所が書き換わります。「AIが書いた」と「mainに入った」のあいだの層です。

無料で試す

私たちがこれを作ったのは、存在しないimportの問題が自分たちの時間を奪っていたからであり、そのサプライチェーン版が本気で怖かったからです。私たちは自分たちのリポジトリで使っています。どう作ったかはこちら。だから、壁の向こうに隠したりはしません。

Surmado Code Review は月10PRまで無料です。GitHubリポジトリに接続し、STANDARDS.MD を書けば(新しいチームメイトにコードベースを説明するように、会話からScoutが下書きを手伝います)、次のPRから幻覚importを捕まえ始めます。それ以降は月額15ドルで100PRまで。席数による課金はありません。データ保持はゼロです。

あなたのAIは、これからもimportを作り続けます。あなたが、それをマージし続ける必要はありません。

Surmado Code Review を無料で試す


関連記事

次の一歩へ

Scoutが約15分でブランドを調査します。