How ZigZag made our workflow worse before we fixed it

anzedev1 pts0 comments

We found a brutal issue with Zigzag and fixed it - how we did it — ZagforgeSkip to content<br>Back to blogWe asked a simple question: does feeding an AI coding agent a condensed AST report actually save it work and lower token consumption? The honest first answer was.. well no. We did a measurement that proved it, and the rebuild that turned it around.

What is ZigZag?<br>ZigZag is a small, fast CLI codebase walker that was designed for working with LLM styled programming practices. Generating an AST-chunked Markdown report with a configurable JSON file. By design it was trying to solve a niche problem when talking to chat-based LLMs (e.g ChatGPT, Claude, Grok) where going through 10 different folders, copying/pasting code would not only be time consuming, but inefficient. Chat-based LLMs work better with context and this is where ZigZag was born.

The brutal failure<br>We were using ZigZag on our internal projects testing it with Claude Code and other LLM driven development tools and everything worked fine, until we checked measurements and benchmarks.. We ran it against its own source tree. 209 files , 1,772 declarations and measured the real token cost of three things an agent actually does: locate declaration , map a module , and map the whole repo . Each was compared against what the native tools (alike of ripgrep) would spend on the same task.

The measurement: grep and slice really does win

First, what "grep-and-slice" means, since it's easy to confuse with plain search. The native way to find something is to run ripgrep over your source and then open the files it points at and reading those files is where the tokens go. Grep-and-slice replaces that second half: you grep ZigZag's condensed report instead of the source, get back an exact file:line–range, and read only that slice. The grep step itself is no faster than ripgrep, but the savings come from never opening the surrounding code.

For smaller jobs, the index paid off. Finding a declaration and reading only its condensed slice, rather than opening the file around it, was consistently cheaper. Mapping a directory or the whole repository is where the native approach means reading many files, and this is where the gap widened dramatically.

Concretely: locating a declaration ran 3.9x cheaper, mapping a module 6.8x, and mapping the whole repository 24-60x

Across 60 real declarations the pattern was hard to ignore. Finding a declaration through the report took just 174 tokens on average; a windowed read of the source cost 681 for the same answer. And that's the generous comparison against reading the whole file, grep-and-slice was 9.2× more efficient .<br>Repository scale is where it stops being a rounding error. The complete File Index; a structural map of all 209 files and 1,772 declarations costs only 2,801 tokens to take in the shape of the codebase. A partial Explore sweep of the same repo would spend roughly 67,000 tokens just building that context.<br>The conclusion was simple: the bottleneck was never the amount of code, it was the cost of discovering where the important code lived. Turning the repository into a navigable map instead of a pile of files changes exploration from a search problem into a lookup problem.

The trap: we tried to load the whole thing<br>Here is where the story turns. The natural instinct with a "condensed" report is to load the whole thing into context once and query it in place, correct? Or so we thought, we measured that too, and the full report against simply reading every source file it summarizes:<br>The condensed report revealed an unexpected limitation; it was larger than the source it was meant to compress. The problem was that the report added its own overhead. A structural index, per-declaration headers, and metadata while only marginally reducing the underlying code. Instead of shrinking the information footprint, it layered additional context bloat on top of the content that was already difficult to compress. So the tool built to make a codebase cheaper to hold in context made it increasingly more expensive . The savings came from a different source, grepping the report and pulling a slice, never from ingesting it. The approach became a net loss. For a system positioned as an LLM index, this was a fundamental flaw that needed patching. This is the exact kind of issue that benchmarks reveal while polished demos tend to hide.

A condensed report that costs more than the source is NOT an index, it is simply a second copy with worse ergonomics. An index should reduce cost of understanding and navigating a codebase. If the generated artifact requires more context, more tokens, and more effort to consume than the original source, it failed at its primary purpose.

The fix: keep the shape, but drop the body<br>The diagnosis pointed us directly to the fix. The report's real value was never the copied source; it was the structure around it. Declarations , signatures , and precise line ranges . The weight came from embedding condensed...

report source zigzag condensed slice file

Related Articles