GraphWalk: Enabling Reasoning in Large Language Models through Tool-Based Graph Navigation
Organizations: Faculty of Science, McMaster University · BASF Digital Solutions
Abstract
The use of knowledge graphs for grounding agents in real-world Q&A applications has become increasingly common. Answering complex queries often requires multi-hop reasoning and the ability to navigate vast relational structures. Standard approaches rely on prompting techniques that steer large language models to reason over raw graph context, or retrieval-augmented generation pipelines where relevant subgraphs are injected into the context. These, however, face severe limitations with enterprise-scale KGs that cannot fit in even the largest context windows available today. We present GraphWalk, a problem-agnostic, training-free, tool-based framework that allows off-the-shelf LLMs to reason through sequential graph navigation, dramatically increasing performance across different tasks. Unlike task-specific agent frameworks that encode domain knowledge into specialized tools, GraphWalk equips the LLM with a minimal set of orthogonal graph operations sufficient to traverse any graph structure. We evaluate whether models equipped with GraphWalk can compose these operations into correct multi-step reasoning chains, where each tool call represents a verifiable step creating a transparent execution trace. We first demonstrate our approach on maze traversal, a problem non-reasoning models are completely unable to solve, then present results on graphs resembling real-world enterprise knowledge graphs. To isolate structural reasoning from world knowledge, we evaluate on entirely synthetic graphs with random, non-semantic labels. Our benchmark spans 12 query templates from basic retrieval to compound first-order logic queries. Results show that tool-based traversal yields substantial and consistent gains over in-context baselines across all model families tested, with gains becoming more pronounced as scale increases, precisely where in-context approaches fail catastrophically.
Figures & tables
| Model | Tools | Correct | Accuracy | Avg IT | Avg TC |
|---|---|---|---|---|---|
| gpt-4o-mini | True | 8/10 | 80.00 | 144.971 | 22.125 |
| False | 0/10 | 0.00 | 27.541 | - | |
| gpt-4o | True | 6/10 | 60.00 | 135.196 | 15.1 |
| False | 1/10 | 10.00 | 14.159 | - | |
| gpt-4.1 | True | 10/10 | 100.00 | 127.299 | 21.4 |
| False | 1/10 | 10.00 | 13.060 | - |
| Model | T | C | A | P | R | F1 | FP | TC |
|---|---|---|---|---|---|---|---|---|
| gpt-4o-mini | True | 18 | 15.00 | 0.23 | 0.25 | 0.23 | 170 | 7362 |
| False | 6 | 5.00 | 0.35 | 0.24 | 0.26 | 350 | - | |
| gpt-4o | True | 34 | 28.33 | 0.42 | 0.39 | 0.39 | 235 | 2548 |
| False | 18 | 15.00 | 0.50 | 0.44 | 0.44 | 300 | - | |
| gpt-4.1 | True | 35 | 29.17 | 0.47 | 0.41 | 0.43 | 232 | 2483 |
| False | 21 | 17.50 | 0.52 | 0.49 | 0.48 | 1006 | - |
| Category | Total | gpt-4o-mini | gpt-4o | gpt-4.1-nano | gpt-4.1-mini | gpt-4.1 | o3-mini | o4-mini | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| T | NT | T | NT | T | NT | T | NT | T | NT | NT | NT | ||
| Node Count | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| Relationship Count | 2 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
| Node with Most Relationships | 26 | 3 | 0 | 3 | 0 | 0 | 1 | 3 | 2 | 3 | 2 | 1 | 8 |
| Node by Property | 85 | 10 | 0 | 10 | 6 | 7 | 0 | 10 | 5 | 10 | 7 | 10 | 10 |
| Relationship by Property | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 8 |
| Model | Metric | 100 | 150 | 200 | 500 |
|---|---|---|---|---|---|
| gpt-4.1 (w.t) | Acc. | 29.17 | 28.33 | 28.33 | 26.67 |
| P. | 0.47 | 0.39 | 0.40 | 0.39 | |
| R. | 0.41 | 0.37 | 0.38 | 0.35 | |
| F1 | 0.43 | 0.37 | 0.38 | 0.35 | |
| F.P. | 232 | 149 | 170 | 151 | |
| gpt-4.1 (w.o.t) | Acc. | 17.5 | 29.17 | 23.33 | 10.83 |
Appendix figures & tables2 assets
Supplementary material from the paper’s appendix.
Appendix
| # | Entity Type | Entity Name | Cypher Pattern | Property |
| 0 | Node | Cevaz | (:Cevaz) | bexame |
| 1 | Node | Cevaz | (:Cevaz) | key |
| 2 | Node | Cevaz | (:Cevaz) | tanu |
| … | … | … | … | … |
| 18 | Relation-ship | EPUQOSS | (:Cevaz)-[:EPUQOSS]-> (:Egodpw) | ukog |
| 19 | Relation-ship | EPUQOSS | (:Cevaz)-[:EPUQOSS]-> (:Egodpw) | uqpc |
| Category | Question Class | Instruction Template | Output Schema | Ground Truth (Cypher) |
|---|---|---|---|---|
| Retrieval & Aggre-gation | Node Count | Count the number of "{source_label}" nodes that are connected to any "{target_label}" node. Return ONLY the output with the count in JSON format: {{output_schema}}. | [{"count": "number"}] | MATCH (a:{source_label}) --> (b:{target_label}) RETURN count(DISTINCT a) AS count |
| Relation-ship Count | How many relationships of type "{rel_type_name}" exist? Return ONLY the output with the count in JSON format: {{output_schema}}. | [{"count": "number"}] | MATCH ()-[r:{rel_type_name}]->() RETURN count(DISTINCT r) AS count | |
| Node with Most Relationships | Which "{source_node_label}" node has the most outgoing "{rel_type_name}" relationships? Return ONLY ONE answer in JSON format as per the schema: {{output_schema}}. | [{"node_key": "string", "rel_count": "number"}] | MATCH (n:{source_node_label}) -[r:{rel_type_name}] ->() WITH n, count(r) AS rel_count RETURN n.key AS node_key, rel_count ORDER BY rel_count DESC LIMIT 1 | |
| Node by Property | Find all "{node_label}" nodes where "{prop_name}" is "{prop_value}". Return results in JSON format according to the schema: {{output_schema}}. | [{"node_key": "string"}] | MATCH (n:{node_label} { {prop_name}: {query_prop_value} }) RETURN DISTINCT n.key AS node_key | |
| Relation-ship by Property | Find all "{rel_type_name}" relationships where "{prop_name}" is "{prop_value}". Return results in JSON format based on the schema: {{output_schema}}. | [{"source_key": "string", "target_key": "string", ...}] | MATCH (s)-[r:{rel_type_name} { {prop_name}: {query_prop_value} }]->(t) RETURN s.key as source_key, t.key as target_key, {return_clause} | |
| Path & Relational Traversal | Path Finding | Find all paths from "{source_label}" to "{target_label}" through "{middle_label}". Return results in JSON format as per schema: {{output_schema}}. | [{"source_node _key": "string", "target_node_key": "string"}] | MATCH (a:{source_label})--> (b:{middle_label})--> (c:{target_label}) RETURN a.key AS source_node_key, c.key AS target_node_key |