ASADASHI
研究・論文
研究・論文2026.09.08·読了 2·難易度: ふつう

AIがコードを「正しく読めてる」は本当か?

朝の出汁版(通勤2分)

  • ポイント1: LLMが復元したコードはビルドも動作テストも通るのに、特定の入力で元の挙動と食い違うケースが全体の約5〜13%存在することが研究で明らかになった。
  • ポイント2: 「テストを通過した=正しい」という判断軸だけでは、脆弱性が消えたり動作が変わったりする見えないズレを見逃すリスクがある。
  • ポイント3: AIでコードを自動生成・変換するワークフローを組んでいるなら、単体テストの通過だけでなく、境界値や想定外の入力でも動作を確認する習慣を取り入れると精度が上がる。

出汁の素(深読みモード)

「テストを通過したコード」が実は別物になっている

LLMを使ってコードを逆コンパイル(機械語から元のソースコードへ復元)する技術が急速に進化している。Ghidraなど従来ツールが「読めない部分はそのまま空欄にする」だったのに対し、LLMベースのツールは見た目にも自然なCコードを生成できる。問題は、この「きれいさ」が盲点を生んでいる点だ。

今回の研究が示したのは、LLMが復元したコードがビルドに成功し、付属テストもすべて通過しながら、それでも元のコードとは異なる動作をするケースが存在するという事実。研究者が独自に用意した入力パターンで検証したところ、テスト通過済みのコードでも全体の約4.9〜13%が元の挙動から逸脱していた。さらに深刻なのは、実際のセキュリティ脆弱性がLLMの「補完」によって静かに消えてしまうケースも確認されている点だ。バグが修正されたのではなく、単に見えなくなっただけ、という状況だ。

これはLLMのコード生成全般にも通じる話で、AIエージェントがテスト合格だけでは不十分な理由でも触れたように、「動いているように見える」と「正しく動いている」は別物だという問題が、今度はコード解析の領域でも浮上してきた。

なぜLLMは「それらしい嘘」をつくのか

LLMがコードを復元するとき、実質的にやっていることは「このバイナリはこういう意図で書かれたはずだ」という推測の補完だ。その補完は人間が読んでも自然に見えるし、代表的な入力パターンでは正しく動作する。だがオリジナルコードが持っていた細かい境界値の扱いや、特定条件下でのエラー処理まで忠実に再現できているとは限らない。

たとえば、整数のオーバーフローが起きたときだけ特定の挙動をするコードがあったとする。LLMはその部分を「不自然に見えるから」として整理・省略してしまうことがある。テスト側がそのオーバーフロー条件を試していなければ、テストはすべてグリーン、しかし挙動は別物、というシナリオが成立する。

研究チームはこの問題に対して「Decompile-Diverge」というアプローチを提案している。あらかじめ用意した固定テストではなく、元のコードと復元コードに同じ入力を大量に流し込んで出力を比較するというファジング(意図的に境界値や異常値を試す手法)ベースの検証手法だ。「テストが通るかどうか」ではなく「元の動きと一致するかどうか」を直接確かめるアプローチで、再現性の精度を測る軸が変わっている。

AIで自動生成・変換したコードを信頼しすぎる前に確認したいこと

逆コンパイルという特殊な用途に限らず、LLMにコードを生成・変換・リファクタリングさせるワークフローを組んでいる人にとって、この研究は実用的な問い直しになる。「動いた」「テストが通った」だけで本番に載せていないか、という点だ。

すぐに取れるアクションとして以下が使える。

境界値・エッジケースを意図的に試す習慣を入れる:正常系のテストに加えて、空文字列・ゼロ・マイナス値・巨大な数・nullなど、本番でありうる例外的な入力を手動でも流してみる。LLMが生成したコードほど、この手の入力で元の仕様と挙動がずれやすい。

元のコードと並べて比較できる状況を作る:元のコードが手元にある場合、同じ入力に対して元版とLLM生成版の両方を実行して出力差分を確認する。Pythonならdifflib、CLIならdiffコマンドで出力を突き合わせるだけでもかなり違う。

脆弱性やエラーハンドリングを含む箇所は手でレビューする:研究では「脆弱性が消えた」ケースも確認されている。セキュリティ上のチェック処理やバリデーションロジックはLLMが「冗長」と判断して省くことがあるため、その周辺は自動テストだけに頼らず目視確認を残しておく。

ファジングツールを導入するなら、PythonであればHypothesisが比較的すぐ使い始めやすい。「任意のランダム入力でこの関数を叩いて例外が出ないか」を自動で探してくれる。

この問題が開発以外にも影響する理由

逆コンパイル技術はセキュリティ研究者やマルウェア解析者が使う専門領域だが、この研究が示す「LLMがテストを満たしながら意味を変える」という構造的な問題は、もっと広い文脈でも起きている。

たとえばAIで文章を翻訳・要約・変換するワークフローでも同じことが言える。元のドキュメントと「意味的に一致しているように見えるが、特定の解釈では別の結論を導く」出力は、ありふれた問題だ。翻訳の品質チェックも「読んで自然かどうか」だけを見ていると、細かいニュアンスのズレを見逃す。

つまりこの研究が問題提起しているのは、「LLMの出力をどう検証するか」という評価軸そのものだ。「見た目が自然」「代表的なケースで動く」は出発点であって、終着点ではない。LLMを使い倒す側として知っておくべきは、どのレイヤーで何を信頼し、何を自分で確かめるかの線引きだろう。

研究の原典はarXivで公開されており(arxiv.org/abs/2609.05370)、英語だが抄録だけでも読むと問題の輪郭がつかみやすい。

参照ソース