ANTIGRAVITY LABEN
記事一覧/Antigravity 基本
Antigravity 基本/2026-08-18中級

/codesearch が ripgrep を使えない環境では、検索が何倍遅くなるのか比べました

Antigravity CLI 1.1.13 で埋め込み ripgrep の置き場所が変わりました。実行できない環境では検索が静かにフォールバックします。その差を運用中のリポジトリで実測し、どちらの経路に落ちているかを確かめる手順をまとめました。

Antigravity CLI26codesearch2ripgrepパフォーマンス7環境構築

Antigravity CLI 1.1.13 のリリースノートに、埋め込みの ripgrep が実行できない環境では /codesearch がローカル検索へフォールバックする、という一行があります。

そこで手が止まりました。

フォールバックは黙って起きます。エラーは出ませんし、結果も返ってきます。つまり、落ちた先がどれくらい遅いのかを知らないまま使い続けられてしまう、ということです。

知らないままにしておきたくなかったので、運用中のリポジトリで検索経路そのものを並べて計測しました。あわせて、自分の環境がどちらの経路にいるかを確かめる手順もまとめています。

なお本記事で測ったのは Antigravity CLI の内部ではなく、フォールバックが行き来する検索エンジンそのものです。CLI の内部処理まで踏み込めていない点は、先にお伝えしておきます。

個人開発でアプリとサイトのリポジトリを行き来していると、検索が返るまでの数百ミリ秒は一日のうちに何十回も積み上がります。気づける形にしておきたい種類の差でした。

1.1.13 で ripgrep の置き場所が変わりました

一次情報として公開されている 1.1.13(2026年8月14日)の変更のうち、検索まわりは次の4点です。

変更内容
展開先の移動埋め込み ripgrep の展開先が /tmp からユーザーキャッシュディレクトリへ移動
整合性検証展開したバイナリを SHA-256 で検証
競合の回避同時実行時の衝突を避けるアトミックなリネーム
/codesearch の耐障害性ripgrep が実行できない環境ではローカル検索へフォールバック

展開先が /tmp から移った理由は、実際に運用していると想像がつきます。/tmpnoexec でマウントしている環境では、バイナリを置けても実行できません。共有マシンや検証用のコンテナでは珍しくない設定です。

実行できなくなる事情は、おおむね次の3つに分かれます。

  1. /tmp やキャッシュ領域が noexec でマウントされている
  2. エンドポイントセキュリティ製品が、署名のないバイナリの実行を遮断している
  3. キャッシュディレクトリに書き込み権限がない

1 番目は 1.1.13 の変更で緩和されました。2 番目と 3 番目は、環境側を触らないかぎり残ります。

自分がどちらの経路にいるかは、終了コードに出ます

「実行できない」は、シェルの終了コード 126 として現れます。手元で再現できます。

cp "$(command -v rg)" "$HOME/rgtest"
chmod -x "$HOME/rgtest"
"$HOME/rgtest" --version
echo "exit=$?"

手元の Linux では次のようになりました。

bash: /home/user/rgtest: Permission denied
exit=126

126 は「ファイルは見つかったが実行できなかった」を意味します。noexec マウントも、セキュリティ製品による遮断も、多くはここに現れます。ファイルが存在しない 127 とは区別できます。

ひとつ注意があります。判定に使うコマンドを headtail にパイプしないでください。$? がパイプ後段の終了コードに置き換わり、126 が 0 に化けます。私はこの計測中に一度取り違えて、実行できているものと思い込みました。

環境を確かめるときに見る場所は3つです。

見るところコマンド期待する状態
/tmp のマウントオプションfindmnt -no OPTIONS /tmpnoexec が含まれていない
キャッシュ領域のマウントオプションfindmnt -no OPTIONS "${XDG_CACHE_HOME:-$HOME/.cache}"同上(1.1.13 以降はこちらが本命)
バイナリの実行可否上の chmod テスト終了コードが 126 でない

展開先の実体は環境によって異なります。キャッシュ領域から探すなら次のようにします。

find "${XDG_CACHE_HOME:-$HOME/.cache}" -type f -name 'rg*' 2>/dev/null

同じリポジトリで、3つの検索経路を比べました

計測対象は、運用中の Next.js サイトのリポジトリです。.git を除いて 2,225 ファイル・49 MB、大半が MDX とテキストです。

比べたのは次の3つです。

  • ripgrep 13.0.0(rg -n
  • GNU grep(grep -rn --exclude-dir=.git
  • 素朴なローカル検索の代表として、Python で書いた逐次読み込み実装

3 番目はフォールバック先の実装そのものではありませんが、「特別な最適化を持たない実装」の目安として置いています。コードは次の通りです。

import os, re, sys, time
 
root, pat = sys.argv[1], sys.argv[2]
rx = re.compile(pat)
hits = 0
t0 = time.perf_counter()
 
for dirpath, dirnames, filenames in os.walk(root):
    dirnames[:] = [d for d in dirnames if d != ".git"]
    for fn in filenames:
        path = os.path.join(dirpath, fn)
        try:
            with open(path, "r", encoding="utf-8", errors="ignore") as f:
                for line in f:
                    if rx.search(line):
                        hits += 1
        except (OSError, UnicodeError):
            continue
 
print(f"{hits} hits {(time.perf_counter() - t0) * 1000:.0f} ms")

os.walk で辿り、1 行ずつ正規表現に掛けるだけの実装です。除外は .git のみにしています。フォールバック側が持っていそうな最低限の条件に揃えるためです。

計測は同じクエリを5回ずつ流し、中央値を取りました。ページキャッシュが温まった状態での値です。

経路リテラル検索正規表現検索
ripgrep18 ms19 ms
grep -rn32 ms39 ms
Python 逐次読み込み277 ms281 ms

この規模なら、いちばん遅い経路でも 0.3 秒です。体感としては「少し待つ」程度で、原因を疑うところまではいきません。

問題は規模が増えたときです。同じ内容を6部複製した 200 MB・12,654 ファイルの合成コーパスで測り直しました。複製である以上、内容の多様性は本物のモノレポと違います。あくまで規模の効き方を見るための数字として読んでください。

経路49 MB / 2,225 ファイル200 MB / 12,654 ファイル倍率
ripgrep18 ms56 ms3.1 倍
grep -rn32 ms141 ms4.4 倍
Python 逐次読み込み277 ms1,510 ms5.5 倍

対象が 4 倍になったとき、ripgrep は 3.1 倍で済んでいます。素朴な実装は 5.5 倍でした。ripgrep との比も 15 倍から 27 倍へ開いています。

つまり、小さなリポジトリで気づかなかった差は、node_modules を含む実プロジェクトの規模では気づく側に回ります。エージェントが1ターンに何度も検索を投げる使い方なら、なおさらです。

速さより先に効くのは、拾う範囲が変わることです

計測中に、速度より気になる差が出ました。走査対象のファイル数です。

rg --files . | wc -l    # 2213
find . -path ./.git -prune -o -type f -print | wc -l    # 2225

12 ファイルの差があります。中身を出すと .gitignore.npmrc・各カテゴリの .gitkeep でした。ripgrep は既定で隠しファイルを走査しません。

今回のリポジトリでは、この 12 ファイルに検索語が含まれていなかったため、ヒット行数は3経路とも 9,714 行で一致しました。差は出ていません。

ただし条件が揃っていただけです。ripgrep は既定で .gitignore を尊重します。node_modules やビルド生成物を持つプロジェクトでは、フォールバック側がそれらを拾うかどうかで結果の量が変わります。フォールバック実装が同じ除外規則を持っている保証はありません。

速度の差は待てば済みます。拾う範囲の差は、エージェントに渡す文脈そのものを変えます。ビルド生成物の中の古いコードが検索に混ざれば、エージェントはそれを現在のコードとして読みます。私自身、重く見ているのはこちらのほうです。

実行できないと分かったときに、先に試すこと

順番をつけるなら、次のようになります。

  1. 終了コードが 126 かどうかを確定させる。ここを曖昧にしたまま設定を触り始めると、原因の切り分けが後戻りします
  2. /tmp とキャッシュ領域のマウントオプションを両方見る。1.1.13 以降は展開先がキャッシュ側なので、/tmp だけ直しても変わりません
  3. セキュリティ製品の例外申請を出すときは、展開されたバイナリが SHA-256 で検証されている点を添える。実行を許す根拠として、担当者が判断しやすくなります
  4. どうしても通らない環境では、フォールバックしたまま使う判断も現実的です。今回の実測なら grep 相当の経路で 2〜2.5 倍、素朴な実装で 15〜27 倍。前者なら許容できる場面は多いはずです
  5. 検索の当たり方そのものを見直す。経路の速さより、クエリが何を拾っているかのほうが結果に効きます

5 番目については、/codesearch に渡す正規表現の既定を測り直した記事を別に書いています。検索経路を直せない環境ほど、1 回の検索で無駄なく取りにいく設計が効きます。関心があればエージェントに任せるコード検索を契約として書くもあわせてご覧ください。

サインインできない環境で 1.1.13 を動かす話はAntigravity CLI 1.1.13 の GEMINI_API_KEY 直接認証をサインイン不可の環境で使うにまとめています。制約の多い端末では、この2つは同時に効いてきます。

まずは手元の端末で chmod -x の再現を1回だけ流して、終了コードが 126 になる環境かどうかを見てください。それが分かれば、次に触る場所は自然に決まります。

計測に付き合っていただき、ありがとうございました。

シェア

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

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

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

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

関連記事

Antigravity 基本2026-08-17
Antigravity CLI の会話データベースは、重複を消しても 1 バイトも縮みません
会話データベースの肥大化を、スキーマを知らないまま棚卸しする手順です。削除しただけでは縮まない理由と、freelist_count を回収可能量と読み違えたときに起きることを実測で切り分けます。
Antigravity 基本2026-08-16
Antigravity CLI 1.1.13 の GEMINI_API_KEY 直接認証をサインイン不可の環境で使う
ブラウザのない環境に agy を入れたらサインインで止まりました。8月14日の CLI 1.1.13 で入った GEMINI_API_KEY 直接認証の設定手順と、確認方法、そしてアプリで使っているキーを流用してはいけない理由をまとめました。
Antigravity 基本2026-08-10
何にも一致しないつもりの1行が、全コマンドを承認していました — allowlist の空集合を棚卸しする
コマンド語がゼロ個に分解される allowlist entry が、すべてのコマンドに一致して自動承認していた問題。手元の設定を分解して測り、修正で閉じた穴と閉じなかった穴を切り分け、先頭トークン列一致へ書き換えるまでの手順をまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →