ANTIGRAVITY LABEN
記事一覧/Tips & 活用術
Tips & 活用術/2026-05-01中級

AntigravityのAIが存在しないパッケージをimportする原因と直し方

Antigravity の AI が npm にも package.json にも存在しないパッケージを import に書き込んでくるとき、原因はモデルの「もっともらしさ優先」と文脈の薄さに分かれます。発生条件を切り分け、再発を抑えるエージェント設定まで丁寧にまとめました。

antigravity436ai-agent17troubleshooting88npm5import

pnpm install したら ERR_PNPM_NO_MATCHING_VERSION で止まりました」— Antigravity の AI が書いてくれたコードをそのまま走らせて、こうしたエラーで足止めされた経験はないでしょうか。私自身、Next.js のリファクタリングで react-hook-toast という、それらしい名前のパッケージを当たり前のように import 文に並べられて、最初は自分の知識の方を疑ってしまいました。

実在しないパッケージを AI がしれっと import に書き込む現象は、業界では「Phantom Import」「Slopsquatting の温床」と呼ばれていて、Antigravity に限らず Cursor や Claude Code でも報告されています。ただ Antigravity はマルチエージェントが並列で書き換えるぶん、誰がいつ phantom を入れたかが追いにくく、放置するとビルドだけでなくサプライチェーンの脆さにもつながります。今回はこの現象の発生メカニズムと、エディタ側でできる予防策まで掘り下げて整理します。

なぜ「ありそうなパッケージ名」が生成されるのか

phantom import の根っこには、LLM が「もっともらしさ」を最大化するように訓練されているという事実があります。たとえば「react-hook-toast」は実在しませんが、react-hot-toastreact-hook-formuse-toast といった近接パッケージのトークンが学習データで共起していて、モデルにとっては同じくらい自然に見えてしまうのです。

加えて、Antigravity のエージェントは Manager Surface 経由でファイルを書き換えるとき、package.json の現状を毎回フルに読み込むわけではありません。大規模リポジトリではトークン上限を節約するためメタ情報のみが渡るケースがあり、その状態で「Toast 通知を導入してください」と頼むと、似た名前を当てに行く確率が上がります。

私が観測したかぎりでは、以下の3つの場面で再現性が高いです。

  • 一度のプロンプトで複数機能(認証+通知+分析)を追加させたとき
  • 既存パッケージのバージョンを大きく上げる作業のついで
  • README しかコンテキストに渡していない新しいワークスペース

起きた phantom import を5分で見抜く手順

慌てて pnpm install を走らせる前に、AI が触ったファイルの import 文を一気に検証する癖を付けると安全です。次のスクリプトは、未インストールの依存と package.json 未登録の依存を分けて表示します。何を解決するためのコードかというと、「ファイル上に書かれた import 文」と「実際にインストールできる依存」のズレを可視化するためのものです。

# scripts/scan-phantom-imports.sh
# 使い方: bash scripts/scan-phantom-imports.sh src
set -euo pipefail
TARGET="${1:-src}"
 
# 1. ソース内の import から外部パッケージ名のみ抽出
mapfile -t IMPORTS < <(
  grep -rEho "from ['\"][^'\"./][^'\"]*['\"]" "$TARGET" \
    | sed -E "s/from ['\"]([^'\"]+)['\"]/\1/" \
    | awk -F/ '/^@/ {print $1"/"$2; next} {print $1}' \
    | sort -u
)
 
# 2. package.json と npm registry を突き合わせ
for pkg in "${IMPORTS[@]}"; do
  in_pkg=$(jq -r --arg p "$pkg" '
    (.dependencies // {}) + (.devDependencies // {}) | has($p)
  ' package.json)
 
  exists=$(npm view "$pkg" name 2>/dev/null || echo "")
  if [ "$in_pkg" = "false" ] && [ -z "$exists" ]; then
    echo "🚨 PHANTOM: $pkg (npm にも package.json にも無し)"
  elif [ "$in_pkg" = "false" ]; then
    echo "⚠️  MISSING DEP: $pkg (npm には在るが未インストール)"
  fi
done

期待する出力は次のようなものです。PHANTOM 行は AI のハルシネーション、MISSING DEP 行は通常の入れ忘れと切り分けられます。

🚨 PHANTOM: react-hook-toast (npm にも package.json にも無し)
⚠️  MISSING DEP: zod (npm には在るが未インストール)

このスクリプトをリポジトリの scripts/ に置いて、エージェントに「変更を提案する前に必ず bash scripts/scan-phantom-imports.sh src を走らせ、PHANTOM がゼロであることを確認してください」とルール化しておくと、未然に防げる確率がぐっと上がります。

Antigravity 側で再発を抑える設定

検出だけでなく、AI の出力そのものに歯止めをかけたいところです。私のプロジェクトでは、ワークスペース直下の AGENTS.md に次のブロックを置いています。Manager Surface のエージェントはこのファイルを優先的に読みに行く挙動があるため、phantom 抑制の効きが体感的に良くなりました。

## Dependency Discipline
- Never invent a package name. If you are not 100% sure a package exists on npm,
  call the `pnpm search` tool first and quote the registry response.
- Always update `package.json` and run `pnpm install` *in the same task*.
  Do not split "edit code" and "install deps" across separate tasks.
- If the user requests a feature that needs a new dep, list 2 candidate
  packages with weekly download counts before choosing one.

さらに、設定 → AI Behavior → Tool Permissions で pnpmnpm のサブコマンドのうち searchview をホワイトリスト化しておくと、エージェントが「想像」ではなく「確認」してから書き始めるようになります。

エージェントを複数走らせている場合は、Manager Surface のレビューエージェントに「依存関係追加 PR は phantom スキャンを通過していなければ却下」というプロンプトを与え、書き手と監査役を分業させるのが効果的です。これは AI エージェントの指示が守られない問題への対処 で触れた「ロール分業によるドリフト抑制」の応用でもあります。

「インストールできてしまった」ときの後始末

phantom と気づかず pnpm install を通してしまった場合、本物そっくりの悪意あるパッケージ(typosquat / slopsquat)を踏んでいる可能性があります。次の3点をその場で確認してください。

  • pnpm why <pkg> で依存ツリーのどこから入ったかを特定する
  • pnpm audit --prod を走らせて警告が増えていないかを比較する
  • node_modules/<pkg>/package.jsonrepository.url を開いて、GitHub のスター数や最終更新日を目視で確認する

怪しい挙動があれば、pnpm remove だけでなく pnpm store prunerm -rf node_modules .pnpm-store まで踏んで完全に消し去るのが安心です。SBOM を運用しているなら、CI で cyclonedx-pnpm の差分を見て、知らない名前が紛れ込んでいないかをチェックする運用も合わせておきたいところです。具体的な手順は モジュール・パッケージエラーの恒久対処 でまとめています。

よく出会う「もっともらしい」名前のパターン

scan を1年ほど回し続けて気づいたのですが、phantom にもいくつか定型のパターンがあります。覚えておくと、見た瞬間に「あ、これか」と判断できて時短になります。

  • ハイフン継ぎ接ぎ型: react-hook-toastnext-auth-helperstailwind-merge-cn のように、実在する2つのパッケージを共通トークンで溶接した名前
  • それっぽいスコープ付き: @vercel/edge-cache@nextjs/auth のように、公式が出していそうで出していない命名
  • 動詞+名詞の造語: validate-zodformat-date-fns のように、実在ライブラリ+意図を表す動詞を組み合わせた名前
  • バージョン埋め込み型: react-query-v5zod-v4 のように、メジャー更新を別パッケージとして幻視する名前

このパターンに当てはまる phantom なら、エージェントに「いちばん近い実在パッケージは何?」と聞き直すだけで安全に切り替えられます。逆にどのパターンにも当てはまらない名前は、本物の typosquat の可能性が一段高いので、ストアの過去版確認まで踏み込んでください。

全体を振り返って

phantom import に出会ったら、まず「AI が書いた import 文」を package.json と npm registry に突き合わせて、ハルシネーションなのか単純な入れ忘れなのかを切り分けてみてください。今日からできる一歩としては、上のシェルスクリプトを scripts/scan-phantom-imports.sh として保存し、AGENTS.md に「変更前に必ずこれを走らせる」と一文だけ追記することをおすすめします。検出と抑制の2段構えに切り替えるだけで、ビルドの時間も心の余裕も、目に見えて戻ってきます。

シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Tips & 活用術2026-05-19
AntigravityのAIがpackage.jsonの依存バージョンを上書きしてビルドが壊れた時の対処と予防
Antigravity の AI に小さな修正を頼んだだけのはずが、気づくと package.json の caret/tilde 指定が外れて全パッケージが latest に差し替えられ、ビルドが壊れる現象があります。発生条件と原状復帰、そして再発させない運用ルールを実装ベースで整理しました。
Tips & 活用術2026-05-29
Antigravity でオートセーブが原因でエージェントの差分が消える問題と対処
Antigravity でエージェントが提案した差分が、オートセーブ動作と競合して一部だけ適用される・気づかぬうちに巻き戻る問題の原因と、確実に再現を止めるための設定手順をまとめます。
Tips & 活用術2026-05-27
Antigravity 内蔵ターミナルで日本語が文字化けするときの原因と対処
Antigravity の内蔵ターミナルで `git log` や `npm` の出力、ファイル名に含まれる日本語が「譁?ュ怜喧縺」のような文字列になってしまう。Windows / macOS / WSL それぞれの典型パターンを、原因別の最短手順で直していきます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →