---
title: "Stop Grepping, Ask the Compiler"
slug: stop-grepping
date: "April 2026"
read_time: "3 min read"
word_count: 920
excerpt: "When you change a function, the compiler already knows everything about it, and yet agents ignore all of that and go grepping instead."
filed_under: ["Code intelligence","Agent systems","LSP"]
---

# Stop Grepping, Ask the Compiler

When you change a function, the compiler already knows everything about it. Where it lives, what calls it, what types flow through it, what breaks if you touch its signature. It built this map the last time it ran. It's sitting right there.

But agents almost never reach for it, and go grepping instead.

They grep for the function name, read some files, grep again with a different pattern, read more files, and repeat. Each round costs tokens and latency. *k* rounds of search to answer a question the compiler could answer in one.

With *n* files in a codebase, grepping is O(n) per query. You scan everything for string matches when what you want is a graph traversal. Like reading every page in a library to find a phone number when there's a phone book on the front desk.

> The compiler already did the hard work. Every symbol, every reference, every type — resolved. Why make agents *rediscover* it, one grep at a time?

Why do agents grep? Because that's the tool they were given, and most agent frameworks hand you nothing beyond a file system and a text search.

What agents actually need is structural, which is to say not which files contain the string `validateToken` but what calls it and what breaks if it changes. Those are graph questions rather than text questions.

Tree-sitter turns out to be a surprisingly good middle path. It parses many languages with the same interface, works on broken code, and gives you the structural skeleton: functions, classes, imports, call relationships. Enough to build a dependency graph.

A dependency graph can answer the questions agents actually ask. What depends on this function? What's the blast radius of this change? Which tests cover this code? Every one of those is a graph traversal, and none of them need grepping at all.

Grepping returns text matches where a dependency graph returns relationships. Grep for `validateToken` and you get every file that mentions it: tests, comments, string literals, unrelated functions with similar names. The graph gives you exactly the callers and nothing else.

Agents pay for noise with tokens. For a human, scanning grep results and skipping junk takes seconds. For an agent, every line of junk is real cost against a hard context limit.
