We spent a lot of effort building an accurate code graph: calls, type references, inheritance and interface implementations, each tied to an exact location in the source. On compiler-checked corpora it reaches about 0.98 precision (how it compares with open-source graph indexers).
Then we gave the graph to our research agent and measured what it changed. On a medium-sized repository it added almost nothing. On a larger and harder one it helped more. And getting the agent to use the graph at all turned out to be harder than building it, with results that depend heavily on the model.
The setup
We ran the experiment on RepoContextBench v2: 40 source-grounded questions over two pinned repositories.
Every configuration used the same CodeAlive research agent, the same index and the same judge (Muse Spark 1.3, two votes per task). The only thing we changed was how the relationship graph reached the model. Most runs used DeepSeek V4.1 Flash. Scores run from 0 to 100.
One caveat applies to the whole post. Hard differs from Lite in more than size: its questions are harder, and its language mix is different. So the honest reading is "the graph helps more on the larger and harder repository", not "size alone causes the gain". A repeated identical run moved the score by about ±2 points, so we treat anything smaller than that as noise.
We built a graph tool, and the agent never called it
The first version exposed the graph as a separate tool, get_artifact_relationships. It returns callers, callees, implementations and references for a symbol.
DeepSeek V4.1 Flash had the tool available in all 40 tasks and called it zero times. Removing the tool entirely did not lower the score either: 62.2 without it versus 59.4 with it, within noise.
We tried to push it toward the graph:
Reading the model's reasoning at those decision points explained why. It was looking for literal facts: signatures, property names, keywords. Search and file reads return exactly that, so the graph never came up as an option. Most practical questions are phrased as "how does X work?", not "who calls X?". We have seen next-step hints in tool results work well for other behaviour, but they did not change this one.
It depends on the model
The same tasks with other models:
The stronger model reached for the graph on its own, and it did so five times more often on the larger repository. For Luna, having the graph tool was worth about 4–5 points on both tracks. That is roughly twice our noise level, from a single run per configuration.
If the agent won't ask, put the graph where it already reads
Since the model reliably reads code with fetch_artifacts, we tried putting the call graph inside that response. Next to the code of a function, the agent now sees who calls it and what it calls.
The model now saw the graph in almost every task, so the question became whether it helped:
On Lite the change is within noise. On Hard the agent collected noticeably more of the right code (+4 to +5 points on each retrieval metric). The final answer improved less: +1.2 points, below our noise threshold.
More context is not free
We also tested adding the exact position of every call to the graph in the output. It looked useful: the agent could jump straight to the line.
It made things worse: −6.2 points on Hard, −3.5 across all 40 tasks. The agent was shown 2,276 call positions and did not cite a single one. They took space in the context and did not help.
What we took from it
Before comparing scores, count the graph calls in the traces. A tool the model never calls cannot help it, and a tool list tells you nothing about that.
If the model does not ask for the graph, put it into the response it already reads. For us that was fetch_artifacts: callers and callees next to the code improved retrieval on the large repository. Call-site positions in the same place made answers worse, so they do not belong in the default output.
On a medium-sized repository, search already finds most of what the graph would add. We expect the graph to matter on large, highly connected codebases, To measure that properly, a benchmark needs questions about callers and change impact, and our current set has few of them.
Finally, run repeats. Our run-to-run noise was ±2 points, and twice an early result on 6–11 tasks showed a leader that lost on the full set.
The agent harness itself had a much larger effect than the graph did. With the same model, the CodeAlive harness scored 18.7 points above a general-purpose coding agent: Same model, different harness: CodeAlive vs OpenCode.