It is difficult to measure how well an AI follows a logical sequence of steps to reach a goal. Current tools often struggle to track both the complexity of the task and the accuracy of the path taken.
It tracks a sequence of steps and assigns a score based on how well the path follows the intended logic. It evaluates how deep a goal is buried while measuring the different ways to reach it.
It provides a clear way to measure the logical accuracy and depth of an AI's reasoning path.
It was run inside an isolated container with no network access. This is the exact command and the real output it produced — captured process output, not written by a model.
$ python3 graph_path_memory_trace.py
Path 1 (start/A/C/E/target): Score 12.40
Path 2 (start/B/D/target): Score 11.25
Memory storage: {'start': [12.4, 11.25], 'A': [12.4], 'C': [12.4], 'E': [12.4], 'target': [12.4, 11.25], 'B': [11.25], 'D': [11.25]}A screenshot of that run.
A clean run proves this does what is shown above, in a CPU-only sandbox. It is a small research demo — not a production tool, and nothing here was published anywhere.
All of it — 92 lines, one file, standard library only.
class GraphPathMemoryTrace:
def __init__(self):
self.graph = {}
self.memory = {}
self.path_history = []
def add_node(self, node, edges=None):
self.graph[node] = edges or []
def calculate_reachability_score(self, node):
visited = set()
stack = [(node, 0)]
while stack:
current, depth = stack.pop()
if current not in visited:
visited.add(current)
for neighbor in self.graph.get(current, []):
stack.append((neighbor, depth + 1))
return len(visited) * (depth + 1)
def evaluate_path(self, path):
if not path:
return 0
path_score = sum(
self.calculate_reachability_score(node) for node in path
) / len(path)
memory_match = 0
for i, node in enumerate(path):
if node in self.memory:
memory_match += len(self.memory[node]) / (i + 1)
return path_score + memory_match
def record_path(self, path, score):
for node in path:
if node not in self.memory:
self.memory[node] = []
self.memory[node].append(score)
self.path_history.append((path, score))
def _bfs_shortest_path(self, start_node, target_node='target'):
if start_node == target_node:
return 0
visited = set()
queue = [(start_node, 0)]
while queue:
current, depth = queue.pop(0)
for neighbor in self.graph.get(current, []):
if neighbor == target_node:
return depth + 1
if neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, depth + 1))
return float('inf')
def calculate_path_efficiency(self, path):
if not path or path[-1] != 'target':
return 0.0
unique_nodes = set(path)
redundant_visits = len(path) - len(unique_nodes)
start_node = path[0]
shortest_length = self._bfs_shortest_path(start_node)
if shortest_length == float('inf'):
return 0.0
current_length = len(path)
length_ratio = shortest_length / current_length
redundancy_penalty = 1 - (redundant_visits / current_length)
return length_ratio * redundancy_penalty
if __name__ == "__main__":
gpt = GraphPathMemoryTrace()
gpt.add_node('start', ['A', 'B'])
gpt.add_node('A', ['C', 'D'])
gpt.add_node('B', ['D', 'E'])
gpt.add_node('C', ['E'])
gpt.add_node('D', ['target'])
gpt.add_node('E', ['target'])
gpt.add_node('target')
path1 = ['start', 'A', 'C', 'E', 'target']
path2 = ['start', 'B', 'D', 'target']
score1 = gpt.evaluate_path(path1)
score2 = gpt.evaluate_path(path2)
eff1 = gpt.calculate_path_efficiency(path1)
eff2 = gpt.calculate_path_efficiency(path2)
gpt.record_path(path1, score1)
gpt.record_path(path2, score2)
print(f"Path 1 ({'/'.join(path1)}): Score {score1:.2f}, Efficiency {eff1:.2f}")
print(f"Path 2 ({'/'.join(path2)}): Score {score2:.2f}, Efficiency {eff2:.2f}")
print("\nMemory storage:", gpt.memory)