anchors
Static analysis that hands an LLM your call graph so it stops guessing its way around a codebase. Abandoned.
- status
- Abandoned
- parsing
- tree-sitter
- storage
- YAML files, then a SQLite call graph
- tested on
- Java and TypeScript
AI tools get lost in big codebases. Ask them where a field gets populated and they start reading files, lots of files, and then they guess. LLMs are bad at exhaustive traversal (finding every caller of a function, say) and static analysis has been good at exactly that for decades. So the idea behind anchors was to split the work: static analysis builds the complete call graph, the LLM adds the meaning, and the next prompt starts from that map instead of from raw files.
It started while I was building rkv's event loop, which got me thinking about code as graphs of function calls.
# What it did
The first version worked off a comment. You put // @anchor:name on an entry point method, the analyzer parsed the code with tree-sitter, built the call graph from that entry point and wrote it to an .anchor.yaml file. Then an "enhance" pass had the LLM add a business_context for each method, parameter descriptions and debug_keywords, so the file explained what each method is for on top of how it's wired.
The YAML files were big, slow to generate and didn't scale, so I dropped them. The second version put the whole call graph (methods, call relationships, file locations) in a SQLite database, and the LLM stopped reading files and queried the graph instead.
# The numbers
The first proof of concept was a sorting bug I had already fixed by hand, old items showing up above recent ones in a feed. Claude CLI crawled through the codebase for 8 minutes before it found the right spot. A basic chat model with only the anchor file pointed at the exact line in 15 seconds. 32x faster, on what I called at the time an overly optimized duct-taped test.
The SQLite version got one real test, on a TypeScript codebase of around 600 files and 180k lines, with a known batching bug as ground truth and an intentionally vague prompt.
| Without anchors | With anchors | |
|---|---|---|
| Found the bug | No, it found a different one (a missing ORDER BY) | Yes, the batching bug |
| Cost | $0.09 | $0.36 |
| Wall time | 1m 19s | 3m 10s |
| Files read | 7 | 5 |
So it was slower and 4x more expensive, which is the opposite of what I expected, but it traced the call chain from the entry point down and found the bug instead of a bug. One test proves nothing tho.
# Why it stopped
Two reasons. It answered the question I had, and then open source projects showed up that do it properly. codegraph builds a pre-indexed code knowledge graph in SQLite that agents query instead of reading files, which is pretty much the anchors v2 idea, and Trail-Code goes after the same problem of giving coding agents an understanding of your codebase.