cd /news/ai-agents/my-coding-agent-kept-searching-the-s… · home › topics › ai-agents › article
[ARTICLE · art-152282] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

My coding agent kept searching the same repo again and again, so I gave it a memory

A developer built Engram, a tool that indexes a code repository into a FalkorDB graph and feeds Claude Code a roughly 200-token map of likely locations before its first tool call, cutting a sample click bug fix from 4 tool calls and 112,298 tokens to 2 calls and 75,733 tokens. The developer's own measurements across 83 sessions and 32,713 tool calls found 31% were searches and 44% of file opens re-read a file already seen in the session. The writeup also reports that an early benchmark was invalidated because the agent read the injected bug via git diff, and that a 1,600-token context injection raised token use until it was cut to a six-line map.

by read6 min views1 publishedOct 18, 2026

I use Claude Code every day. And one thing kept bugging me.

I gave it a small bug in a CLI library. Before it touched anything, it made 32 tool calls. grep, sed, cat, grep again. That one run used 1,052,132 input tokens. For a tiny fix.

So I went and counted my own sessions. 83 sessions, 32,713 tool calls. 31% of them were the agent just searching. The median was 24 searches before the first edit. And 44% of the time it opened a file, it had already read that file in the same session.

The next day, similar question, same repo. It did the same search again.

That's what I built Engram for, in the Graph Hacks hackathon (WeMakeDevs × FalkorDB).

Engram turns a repo into a graph in FalkorDB. Three kinds of things go in:

(:File)-[:DEFINES]->(:Symbol)-[:CALLS]->(:Symbol)
(:File)-[:IMPORTS]->(:File)
(:Person)-[:AUTHORED]->(:Commit)-[:TOUCHED]->(:File)
(:File)-[:CO_CHANGES {count, weight}]->(:File)
(:Agent)-[:RAN]->(:Session)-[:READ|EDITED]->(:File)
(:Session)-[:LEARNED]->(:Lesson)-[:ABOUT]->(:File|:Symbol)
(:Session)-[:CLAIMS {since}]->(:File)

Then, before the agent makes its first tool call, it gets a short map. Around 200 tokens. Just where to look.

This is the real map it gave Claude Code for one click bug ("click.Choice(["Apple", "Banana"], case_sensitive=False) rejects apple"):

[engram] Likely locations for this task (code graph, confidence high):
- src/click/types.py:406-424 Choice.normalize_choice
- src/click/exceptions.py:51-52 ClickException.format_message
- src/click/types.py:381-386 Choice.to_info_dict
- src/click/types.py:495-515 Choice.shell_complete
Tests: tests/test_types/test_Choice.py

Without Engram, the agent did grep, grep, sed, then the edit. 4 tool calls, 112,298 tokens.

With Engram: read the file, edit, done. 2 tool calls, 75,733 tokens. Tests passed in both.

Honestly this part taught me more than the parts that worked.

My first benchmark was fake. The agent fixed every bug super fast. Too fast. Then I read one of its answers and it said it "reverted the uncommitted edit". It had just run git diff and seen the bug I injected. So every run now gets a fresh copy with a single commit, the agent only sees a bug report like a user would write it, and a fix only counts if the whole test suite passes.

More context made it worse. My first version gave the agent 1,600 tokens of code and history up front. Tokens went up, not down. Whatever you inject gets re-read on every turn after that, so in a 6-turn session that's around 10k tokens. I cut it down to a map of 6 lines. Claude Code has to Read a file before editing it anyway, so pasting code in never saved a single call.

Bugs hide where names don't match. At first I matched words from the bug report to function names. That found the buggy function in the top 3 only 5 times out of 12. Bugs sit in big functions and private helpers. In networkx, the report says dijkstra_path_length but the bug is in _dijkstra_multisource, three calls down. That's not something grep finds. It's a graph walk:

MATCH p = (s:Symbol {id: $api})-[:CALLS*1..4]->(n:Symbol)
WHERE all(x IN nodes(p)[1..size(nodes(p)) - 1] WHERE size(x.callNames) <= 6)
RETURN n.qualname, min(length(p)) AS hops

After that, on networkx the buggy function was in the top 10 for all 6 bugs. No LLM involved.

Memory made it worse too, at first. I stored "the test command that worked" after each task. But I stored the exact command ("pytest tests/test_types.py"), not the general one. So the next task ran the wrong tests, they passed, and the agent got confused. Now it stores the general command and the graph picks the right tests for each edit.

The graph doubled itself. On a bigger repo I saw the same function listed twice in a map. Two indexers had run at the same time and both inserted everything. I reproduced it: 19,508 symbols instead of 9,754. The fix ended up being one Cypher write, because FalkorDB runs writes on a graph one at a time, so only one process can win:

MERGE (l:IndexLock {k: 1})
WITH l, (l.owner IS NULL OR l.at < $stale) AS free
SET l.owner = CASE WHEN free THEN $me ELSE l.owner END,
    l.at    = CASE WHEN free THEN $now ELSE l.at END
RETURN l.owner = $me AS got

I ran Claude Code (claude-haiku-5-5) on 12 real bugs I injected into pallets/click, 3 times each, in 4 setups. 144 runs.

Setup Fixed Input tokens Tool calls Time
Claude Code 36/36 137.6k 5.1 16.4 s
+ codebase-memory-mcp (47k★) 36/36 126.9k 4.7 13.4 s
+ Engram 35/36 103.5k (−25%) 3.6 (−29%) 12.7 s (−23%)

On networkx (128k lines, 6 bugs): −24% tokens, −40% tool calls, −36% time.

What actually goes away is the searching. Search calls per bug went from 3.4 to 1.7.

And yes, it missed one fix out of 36. That was my fault. The map showed a 5-line wrapper function and only mentioned the real function as "the next call", so the agent fixed the wrapper. I changed it so the real function gets its own line. I didn't re-run the whole benchmark after that, so I'm keeping 35/36.

Injected bugs are one thing. I wanted to see it on code I never touched, with bugs real people reported.

yt-dlp: 1,128 Python files, 248k lines, years of community patches. I indexed it as of 30 April (took 4 seconds) and took every fix after that which closes a GitHub issue. Engram only gets the issue the user wrote, and I check it against what the maintainers actually changed.

One small thing I learned here: in a GitHub issue the title matters most. A long description full of words like "download" and "video" was drowning out the one useful word in the title. Now title words count double.

If two agents try to edit the same file, the second one gets stopped. This is the actual message Engram's hook sent back when a second agent session tried to edit a yt-dlp file the first one had claimed:

Engram: yt_dlp/extractor/bandcamp.py is being edited by claude-code-agentC right now.
Work on something else or wait; do not edit this file.

Same trick as the index lock, one Cypher write.

I needed the graph to answer before every single prompt, without the agent waiting. Multi-hop walks and PageRank come back in milliseconds (my queries take 1 to 40 ms). One query after each edit joins git history, what this session edited, and the call graph, in about 11 ms. Locks between agents are just writes. One graph per repo, many repos in one instance. And FalkorDBLite, their embedded build, means people don't need Docker at all. It uses 43 to 60 MB of RAM with two repos loaded.

curl -fsSL https://raw.githubusercontent.com/ManojRakshu/engram/main/install.sh | sh

No Docker, no API keys, and Engram itself never calls an LLM. It connects to Claude Code, Cursor, Codex, Gemini CLI, VS Code and any MCP client it finds.

Code, the benchmark harness and all the raw results are here: github.com/ManojRakshu/engram. There's also a 30-second version of the video.

I'm curious: what does your agent waste the most calls on? Searching, re-reading files, running the wrong tests? Tell me, that's what I want to measure next.

I used Claude Code as a coding assistant while building this.

── more in #ai-agents 4 stories · sorted by recency
── more on @engram 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/my-coding-agent-kept…] indexed:0 read:6min 2026-10-18 · —