← 一覧へ

grep が強くなる条件 第3回:Agent 時代の検索設計

この記事の読み方
前回は、BM25 とベクトル検索を比べました。

前回は、BM25 とベクトル検索を比べました。

BM25 は、珍しい文字列に強い。
ベクトル検索は、意味の近さに強い。
RRF は、その 2 つを順位として混ぜる。

ここまで読むと、自然な結論はこうなります。

では、RAG では BM25 とベクトル検索を両方入れればよい。
必要なら reranker も足せばよい。

たしかに、これは多くの場面で正しいです。

ただ、Agent が検索する場合は、もう一つ別の問いが出てきます。

そもそも、本当に索引が必要なのか。
もっと低いレベルの道具で十分ではないのか。

ここで出てくるのが grep です。

grep は新しい技術ではありません。
ファイルから文字列を探す、昔からある道具です。

でも、Agent が自分で検索語を考え、失敗したら別の検索語で探し直せるなら、grep はただの古い道具ではなくなります。
Agent の探索ループの中に入ると、かなり強い検索インターフェースになります。

第3回では、grep とベクトル検索を比べます。

結論は、grep が万能という話ではありません。
大事なのは、検索器だけではなく、Agent がどう探し、どう読み、どう止まるかまで含めて設計することです。

Agent は一回だけ検索するわけではない

普通の RAG を考えると、検索は一回の処理に見えます。

ユーザーが質問する。
システムが query を作る。
検索器が top-K を返す。
その結果を LLM に渡す。

この形では、最初の検索で外すと厳しいです。
必要な文書が top-K に入らなければ、モデルは見ていないものについて答えることになります。

だから、検索器の単発性能がとても重要になります。

しかし Agent の場合は少し違います。

Agent は、検索して、読んで、足りなければまた検索できます。
最初の query が外れても、別の語に変えられる。
結果が多すぎれば、絞り込める。
ファイル名や周辺の文脈を見て、次に探す場所を変えられる。

つまり、検索は一発勝負ではなくなります。

ここでコストの考え方が変わります。

一回の検索で完璧に当てる必要があるのか。
それとも、安い検索を何回か試して、だんだん近づけばよいのか。

Agent 時代の grep は、この後者で強くなります。

grep が強いタスク

grep が強いのは、答えがどこかにそのまま書いてあるタスクです。

ログの中のエラー。
会話履歴の中の予定。
設定ファイルのキー。
コード中の関数名。
仕様書に書かれた数値。
過去のチケットに残っている決定事項。

こういうものは、意味的に近い文書を探すより、文字列を直接探したほうがよいことがあります。

たとえば、ユーザーが以前こう言っていたとします。

通知メールは毎朝 8:30 に送ってください。

あとで「通知メールは何時に送る予定だった?」と聞かれた場合、必要なのは高度な意味検索ではありません。
通知メール毎朝8:30 のような手がかりを拾えばよい。

grep は、この種の証拠回収に強いです。

しかも挙動が見えます。

どの語で探したか。
どの行に当たったか。
なぜ見つからなかったか。
検索範囲が間違っていたのか。
表記ゆれを拾えていないのか。

失敗の理由を追いやすい。

ベクトル検索では、ここが少し見えにくくなります。
embedding 空間では近かった。
でも、人間から見ると違う。
chunk の切り方が悪いのか、query が悪いのか、embedding モデルが合っていないのか、reranker が落としたのか。

原因を切り分けるだけで時間がかかります。

だから、答えが原文にあるタイプの Agent 検索では、まず grep を baseline にする価値があります。

実験が示したこと

この話は、感覚だけではありません。

PwC の研究チームが 2026年5月に出した「Is Grep All You Need? How Agent Harnesses Reshape Agentic Search」という実験があります。
LongMemEval から取った 116 問を使い、grep とベクトル検索を、複数の Agent harness 上で比べたものです。

ここでいう LongMemEval は、長い会話履歴から必要な情報を探して答えるベンチマークです。
つまり、過去の会話のどこかにある発言や時刻、好み、決定事項を見つけるタスクです。

この実験では、5 つのモデル、4 つの harness、grep とベクトル検索、さらに検索結果を inline で返す場合と file-based で返す場合を比べています。

結果の読みどころは、単純です。

検索結果を inline で Agent に渡す条件では、grep が 10 組すべてでベクトル検索を上回りました。

たとえば、GPT-5.4 を Codex CLI で使った条件では、grep inline が 93.1%、vector inline が 75.9% でした。
Claude Opus 4.6 を Chronos harness で使った条件では、grep inline が 93.1%、vector inline が 83.6% でした。

これは強い結果です。

ただし、ここで「grep はベクトル検索より上」と言い切るのは危険です。
この実験のタスクは、長期会話記憶 QA です。答えが原文のどこかにあることが多い。つまり、grep に向いたタスクです。

論文自身も、この点を限定しています。
科学文献をまたいだ要約、言い換えの多い調査、画像や表を含む文書、コードの意味検索では、結果が変わる可能性があります。

ここから得るべき教訓は、grep 万能論ではありません。

答えが原文にあるなら、ベクトル検索を入れる前に grep baseline を測る。

これです。

harness が結果を変える

この実験でもう一つ面白いのは、harness の差です。

同じ Claude Opus 4.6 でも、Chronos harness の grep inline は 93.1%。
Claude Code 上の grep inline は 76.7%。

同じモデル、同じ検索方式でも、harness が変わると大きく変わります。

これは、Agent 検索ではかなり重要です。

harness は、ただの入れ物ではありません。

system prompt をどう書くか。
検索ツールをどう説明するか。
検索結果を何件返すか。
長すぎる結果をどう切るか。
Agent に何回まで探させるか。
いつ「もう十分」と判断させるか。

こうした設計が、検索結果の使われ方を変えます。

同じ grep でも、Agent が検索語をうまく作れなければ外します。
同じベクトル検索でも、結果の見せ方が悪ければ読めません。
同じモデルでも、終了条件が弱ければ、証拠が足りないまま答えます。

だから、Agent 検索では retriever だけを変えても足りません。

検索器を入れ替える前に、harness を見る必要があります。

特に見るべきなのは、次の 4 つです。

system prompt
tool description
result truncation
termination condition

system prompt は、探し方の癖を決めます。

会話履歴 QA なら、「日付、時刻、固有名詞、短いフレーズを優先して探す」と書いたほうがよい。
文献調査なら、「同じ語が出ていなくても、近い主張や反対意見を探す」と書いたほうがよい。

tool description も効きます。

search(query) とだけ書くのと、短い文字列や固有名詞に強い検索。表記ゆれは自分で別 query を試す必要がある と書くのでは、Agent の使い方が変わります。

result truncation は、返す量です。

少なすぎると根拠を落とす。
多すぎると Agent が読めなくなる。

termination condition は、止め方です。

1 回検索して答えるのか。
根拠が弱ければ 2 回まで別の語で探すのか。
数値や日付を答えるときは、原文を確認してから答えるのか。

このあたりは検索器の性能ではありません。
でも、最終精度には効きます。

inline と file-based は別の設計である

もう一つ見落としやすいのが、検索結果の渡し方です。

検索結果を inline で返す場合、Agent はその場で結果を読みます。
会話コンテキストの中に結果が入り、すぐに答えに使えます。

file-based の場合、検索結果はファイルに書かれます。
Agent はそのファイルを開き、必要なところを読み、場合によってはさらに検索します。

この違いは、ただの実装詳細ではありません。

inline は単純です。
ただし、結果が大きいとコンテキストを圧迫します。

file-based は大きな結果を扱えます。
ただし、Agent がファイルを読む、戻る、統合する、再検索する、というワークフローを正しくこなす必要があります。

この違いだけで、結果は変わります。

先ほどの実験では、GPT-5.4 + Codex CLI の grep は、inline では 93.1% でした。
しかし file-based では 55.2% まで落ちています。
同じ grep でも、結果の渡し方が変わると、ここまで変わることがあります。

もちろん、file-based が悪いわけではありません。

大きなコードベースや大量文書を扱うなら、検索結果を全部 inline に入れるのは無理です。
ファイルに逃がし、Agent が必要なところだけ読む設計は必要になります。

ただし、その瞬間に問題は変わります。

検索の問題ではなく、Agent の読解ワークフローの問題になります。

結果ファイルを見つけられるか。
必要な箇所を開けるか。
複数の結果を混ぜずに扱えるか。
根拠を失わずに要約できるか。
足りないときに別の query で戻れるか。

ここを評価しないまま file-based にすると、検索器がよくても答えは崩れます。

「大きくなったらベクトル検索」ではない

よくある判断に、こういうものがあります。

小さいコーパスなら grep。
大きくなったらベクトル検索。

分かりやすいですが、少し粗いです。

大きさだけでは決まりません。

答えが原文にあるのか。
表記ゆれがどれくらいあるのか。
Agent がよい検索語を作れるのか。
検索結果のノイズ率はどれくらいか。
返した結果を Agent が読み切れるのか。
file-based の読解ループが安定しているのか。

この条件で変わります。

たとえば、巨大なログでも、探したいのがエラーコードなら grep が強い。
小さな文書集合でも、探したいのが抽象的な概念ならベクトル検索が必要になります。

つまり、判断軸はサイズではありません。

答えに届くために、Agent がどんな探索をする必要があるか です。

実務ではどう進めるか

Agent 検索を作るなら、最初にタスクを 2 つに分けるとよいです。

原文回収型:
  答えが元データのどこかにそのまま書いてある

概念探索型:
  言い換え、類似、複数文書の統合が必要になる

原文回収型なら、まず grep only を作ります。

ここで凝ったことはしません。
検索対象を決める。
短い query を複数回投げられるようにする。
結果にファイル名、行番号、前後の文脈を付ける。
Agent に「見つからなければ別表記で探す」と教える。

これを baseline にします。

そのうえで、ベクトル検索と比べます。

大事なのは、同じ条件で比べることです。
prompt、tool description、返す件数、評価データをそろえる。
そうしないと、検索器の差なのか、harness の差なのか分かりません。

次に、harness を 1 つずつ変えます。

prompt だけ変える。
tool description だけ変える。
返す件数だけ変える。
inline と file-based だけ変える。
終了条件だけ変える。

一度に全部変えない。
これは地味ですが、かなり大事です。

Agent 検索は、部品を足すほど複雑になります。
複雑になったシステムで精度が上がっても、なぜ上がったのか分からなければ、次に壊れたとき直せません。

grep とベクトル検索は、競争相手ではない

ここまで grep の話をしましたが、ベクトル検索を否定しているわけではありません。

ベクトル検索が必要な場面は、はっきりあります。

表現が違う文書を拾う。
別の言語で同じ意味の記述を探す。
複数の文書から似た主張を集める。
まだ名前のついていない概念に近い事例を探す。

こういう仕事を grep だけでやるのは苦しいです。

ただ、Agent に検索を任せるとき、最初から「ベクトル検索を入れれば RAG になる」と考えるのは危ない。

Agent は検索語を変えられます。
複数回試せます。
ファイルを開いて周辺を読めます。
結果を見て、次に探す方向を変えられます。

この能力を前提にすると、grep は単なる検索器ではなく、Agent の探索用インターフェースになります。

逆に、ベクトル検索も単なる検索器ではありません。
Agent が抽象的な問いから候補を広げるための道具です。

だから、競争ではありません。

grep は、原文にある手がかりを直接拾う道具です。
ベクトル検索は、言葉が違っても近い意味の候補を広げる道具です。

どちらを使うかは、問いの形で決まります。

次に見るべきもの

第2回では、BM25、ベクトル検索、RRF を見ました。
第3回では、Agent が検索を繰り返せるなら、grep のような低いレベルの道具が強くなる場面を見ました。

ここまでで、検索器の話はかなり見えてきます。

でも、まだ足りません。

本当の問題は、Agent が「もう十分に調べた」とどう判断するかです。
最初の検索で足りないとき、何を変えてもう一度探すのか。
複数の情報源があるとき、どの順番で見るのか。
矛盾する文書が出たとき、どこで止まるのか。

これは、検索器の性能だけではなく、検索の制御フローの問題です。

次回は Agentic RAG を扱います。
RAG を一回の検索ではなく、調べる、読む、足りなさを判断する、もう一度探す、というループとして見ます。

―― AI未来編集室「AIウォッチ」

← 一覧へ