Claude Code Doesn't Index Your Codebase. Here's What It Does Instead.
Claude Code doesn't use RAG. No vector database, no embeddings, no pre-built index. When you ask it to find where a function is defined, it greps your repository line by line — the same way you would in a terminal, except it chains dozens of those searches together, corrects course, and keeps going until it has what it needs.
Boris Cherny, the engineer who built Claude Code, confirmed on X that early versions did experiment with RAG and a local vector database. The team abandoned it. Agentic search — letting the model decide what to look at, when, using exact-match tools — consistently outperformed the embedding-based approach. It was also simpler and avoided issues around security, privacy, staleness, and reliability. That result drove the architecture that ships today.
The Hacker News discussion that followed is worth reading — developers debated whether grep qualifies as RAG, whether agentic search burns too many tokens, and whether hybrid approaches might be the right answer.
What Agentic Search Actually Means (and the Tools Behind It)
"Agentic" means the model drives the search process itself rather than receiving pre-retrieved context. Claude Code decides what to look for, chooses the right tool, acts on the results, and decides what to look for next — looping until it has enough context to complete the task. Anthropic calls this "agentic search".
The tool hierarchy matters because the tools have very different costs:
| Tool | What it does | Cost |
|---|---|---|
| Glob | Pattern matching across file paths (**/*.ts, src/**/*.graphql) | Lightweight — returns paths only |
| Grep | Regex content search across file contents | Lightweight — returns matching lines |
| Read | Loads full file contents into context | Heavy — consumes context window |
| Task / Explore agents | Spawns a read-only sub-agent with its own context window | Preserves main conversation context |
Full tool reference: Claude Code documentation
Glob: The Cheap First Pass
Glob is Claude Code's opening move. Matching workers/**/*.toml to find all Cloudflare Worker configs costs almost nothing — it returns file paths, not file contents. Claude Code uses Glob to narrow the search space before touching anything expensive.
Grep: Pattern Matching at Scale
Grep does the heavier lifting: searching file contents for a regex pattern. Running grep -r "createD1HttpClient" . across a codebase returns every line containing that string. It is fast, exact, and composable. Claude Code chains Grep calls the way a developer would run searches in sequence, each one informed by the previous result.
Read: The Expensive One
Read loads the full contents of a file into the context window. It is necessary — you cannot edit a file you have not read — but it is the most context-expensive operation. Claude Code reserves Read for files it has already identified as relevant through Glob and Grep, treating it as a confirm step rather than a discovery tool.
Explore Agents: Preserving Your Main Context Window
For deeper investigation, Claude Code spawns an Explore sub-agent: a read-only specialist running on the Haiku model with its own isolated context window. The Explore agent can Glob, Grep, Read, and run limited Bash commands (list, copy, move) but cannot create or modify files. This keeps heavy exploration work from consuming the main conversation's context — which matters on long sessions across large codebases.
Why Grep Beats Embeddings for Code
The precision argument is the most important one. If you search for createD1HttpClient, you want exactly that function — not "something semantically related to database client initialization." Vector embeddings surface conceptually adjacent code that shares no tokens with your actual target. That introduces noise the model must reason through, often incorrectly.
With grep, there are no false positives on exact symbol names. createD1HttpClient either appears in a file or it does not. The model gets a clean, deterministic result and can act on it immediately.
There is also a staleness problem with pre-built indexes. A vector index built at session start reflects the codebase at that moment. If you edit files mid-session — which is exactly what an AI coding agent does constantly — the index is stale before the next query. Agentic search has no staleness because it reads the current state of the filesystem on each tool call.
The Real Tradeoffs: When Grep Wins and When It Doesn't
The case against grep-only retrieval is real, and the Milvus blog made it explicitly. Milvus sells a vector database, so their interest in the outcome is transparent — but the technical criticism holds up independently.
The Token Cost Problem
Grep can be noisy. Search for a common variable name like data or result across a large TypeScript repository and you will get hundreds of matches, many irrelevant. Claude Code must either scan all of them (expensive) or refine the search (adds steps). On very large repositories, iterative exploration can burn a significant portion of a context window before the model reaches the file it actually needs.
This is a real cost. Context windows are not infinite, and every token spent on irrelevant grep matches is a token not available for the task.
The Semantic Miss Problem
Grep finds what you name. If you search for createD1HttpClient and the function was renamed buildGatewayClient six months ago, grep finds nothing. Vector embeddings would likely surface the renamed function because the semantic relationship between the two concepts is preserved in the embedding space.
For codebases with inconsistent naming conventions or significant refactoring history, the semantic miss rate for grep-based search can be meaningful. Anthropic found that agentic search outperformed RAG in their evaluations — but those evaluations were not published, and the specific benchmark conditions matter. A codebase with stable, descriptive naming is not the same workload as one with cryptic abbreviations and heavy historical churn.
The Bottom Line: Precision by Design
Claude Code's decision to skip indexing is the conclusion the Anthropic team reached after running the experiment: agentic search with exact-match tools outperformed RAG, and the simplicity and freshness benefits reinforced that result.
The real costs are token consumption on noisy searches and semantic misses on renamed symbols. Whether they matter depends on your codebase size, naming discipline, and tolerance for context burn.
For most developers working on reasonably sized, well-named codebases, the agentic search approach works well.
The underlying principle is defensible: when you are working with code, precision beats fuzzy similarity. Grep finds what you name. That is a feature, not a limitation — until it is not.
Sources