【ITニュース解説】Refactor with a local model, and review it as a diff
2026年11月03日に「Dev.to」が公開したITニュース「Refactor with a local model, and review it as a diff」について初心者にもわかりやすく解説しています。
ITニュース概要
AIでコードをリファクタリングする際、意図せぬ動作変更を防ぐには、事前に簡単なアサーションでコードの振る舞いを固定する。AIの提案は差分(diff)としてレビューし、特に比較演算子や論理演算子の変更に注意が必要だ。ローカルAIを使い、安全にコードを改善できる。
ITニュース解説
近年、AIを活用したプログラミングの支援ツールが急速に普及し、開発の現場でコードの自動修正、つまりリファクタリングをAIに依頼する機会が増えている。リファクタリングとは、プログラムの外部から見た動作は変えずに、内部の構造を改善し、読みやすく、保守しやすいコードにすることである。AIはこのような作業を非常に高速に実行できる一方で、時に小さな、しかし決定的な間違いを自信満々に犯す場合がある。このようなAIの特性を理解し、その利用を止めるのではなく、効果的に活用するためのレビュー方法を学ぶことが、システムエンジニアを目指す上で非常に重要になる。
AIによるリファクタリングが引き起こす問題を回避し、その恩恵を最大限に受けるためには、まずコードの「振る舞い」を明確に固定することから始める。例えば、ある古いJavaScriptの関数summarizeが、注文データの中から支払い済みの注文の合計金額を地域ごとに集計する機能を持っていると仮定しよう。リファクタリングに着手する前に、この関数がどのような入力に対してどのような結果を返すのかを具体的に示す必要がある。単に厳密なテストコードを書くのではなく、いくつかの具体的な入力データと、それに対する期待される出力値をconsole.assertのようなシンプルな形で記述する。
ここで特に重要なのは、「奇妙な入力」も考慮に入れることである。実際のデータは常に整理されているわけではなく、例えばpaidという支払い状態を示すプロパティがtrueではなく数値の1であるようなケースも存在し得る。古いコードがo.paid == trueという緩やかな比較で1をtrueとして扱っているならば、それが現在のコードの「振る舞い」となる。このような細部まで含めて、コードがどのように動作するかを明確に固定しておくことで、後のAIによる変更が元の振る舞いを維持しているかを検証するための確固たる基準が確立される。
次に、このコードを「現代的なJavaScriptの書き方にリファクタリングしてほしい。ただし、コードの振る舞いは一切変更しないこと」という明確な指示をAIに与える。AIが生成するコードは、例えばループ処理をfor...of構文に置き換えたり、オブジェクトのプロパティへのアクセスを簡潔にしたりと、見た目には非常にクリーンでモダンな形になるだろう。しかし、ここで問題が発生する可能性がある。AIが生成したコードの中で、if (paid !== true) continue;のような記述があったとする。これは、元のコードのif (o.paid == true)とは異なる厳密な比較を行っているため、先ほど固定した「paid: 1も支払い済みとして扱う」という振る舞いが変わってしまうのだ。具体的には、paidが1である注文が支払い済みとして扱われなくなり、結果として集計結果が元の期待値と異なってしまう。
このような微妙なバグは、AIが生成した新しいコード全体を最初から最後まで読むだけでは見過ごされやすい。なぜなら、多くの部分は正しく、見た目も綺麗だからである。そこで、AIによる変更を「差分」(diff)としてレビューすることが極めて重要になる。差分とは、元のコードと変更後のコードの「違い」だけを視覚的に表示する機能で、削除された行と追加された行が明確に示される。
この差分画面では、if (o.paid == true)という行が削除され、if (paid !== true) continue;という行が追加された箇所に、開発者の注意が集中する。==(等価演算子)から===(厳密等価演算子)への変更、あるいは!=から!==への変更は、一見すると単なるスタイルの変更のように見えるかもしれない。しかし、外部から入力されるデータを扱う場合、これらの比較演算子の選択はコードの振る舞いに大きな影響を与える可能性がある。特に==は値の型が異なっていても変換を試みて比較するため、1 == trueがtrueになるような挙動を示す。これに対し===は型まで厳密に一致することを求めるため、1 === trueはfalseとなる。この違いを理解し、このような変更点を見つけたら必ず立ち止まり、その変更がコードの振る舞いを意図せず変えていないかを慎重に検討する必要がある。この例では、緩やかなチェックを維持するか、あるいはデータを事前に正規化するなどの対応が必要であると判断できる。
このようなAIとの協調開発のワークフローは、JSLabのような特定の開発環境と、Ollamaのようなローカルで動作するAIモデルを組み合わせることで効率的に実現できる。ローカルモデルを使用すれば、機密性の高いコードを外部に送信することなくAIの恩恵を受けられる利点もある。JSLabでは、AIが提案する変更を「Preview Changes」機能で差分として確認し、問題がなければその変更を適用し、問題があれば破棄できる。変更を適用すると、最初に定義したアサーションが自動的に再実行され、振る舞いの変化によるエラーがすぐに表示されるため、開発者は迅速にフィードバックを得て、問題があれば即座に修正に取り掛かれる。
最終的に、AIを効果的にプログラミングに活用するためには、以下の重要な点を忘れてはならない。まず、リファクタリングを始める前に、奇妙な入力も含め、数個のアサーションを用いてコードの「振る舞い」を明確に固定すること。次に、AIが生成したコードは、完成したファイルとしてすべてを受け入れるのではなく、「差分」としてレビューすること。そして、特に==と===、||(論理OR演算子)と??(Nullish coalescing演算子)、および真偽値の扱いに影響する変更には細心の注意を払い、それが元のコードの振る舞いを意図せず変えていないかを慎重に確認することが肝要である。これらの原則を守ることで、AIを強力な味方につけ、開発効率とコード品質を同時に向上させることが可能となる。