Navigating a Neo4j Knowledge Graph with Jev Neo4j Head of Product Innovation & Developer Strategy Michael Hunger built neo4jev, an open-source experiment that uses TypeSafe.AI's Jev classification model to navigate a Neo4j knowledge graph one relationship hop at a time. Jev, which TypeSafe.AI announced last week, is a non-LLM classification model priced at $42 per billion input tokens with free output that returns probabilities for Choice, Boolean Truth Decisions (Noul), and Scores in parallel rather than generating tokens. Hunger tested neo4jev on Neo4j's public Companies graph (15 labels, 28 relationship types) in the companies2 database, arguing LLMs are too slow and expensive for in-the-loop graph traversal decisions. Navigating a Neo4j Knowledge Graph with Jev Head of Product Innovation & Developer Strategy, Neo4j 12 min read Testing Jev TypeSafe System One with Navigation Decisons I built neo4jev https://github.com/jexp/neo4jev as an experiment to navigate a graph, here I explain a bit the why and how. What is Jev? And why should you care? Last week’s Typsafe.AI announcement of their Jev decision and classification model https://typesafe.ai/blog/introducing-system-one-models-and-jev has taken the AI engineering community by storm. Jev is the fastest-adopted model in AI Gateway history https://vercel.com/blog/ai-gateway-jev-model-launch It is not an LLM it’s a fast, small and cheap $42 per billion input tokens, output free classification model that only outputs probabilities for Choice, Boolean Truth Decisions Noul , and Scores with text and structured inputs but no text output. It doesn’t do single token at a time prediciton, but runs all predictions in parallel, so you can pass as many tasks as you want into a single API call. The model is not trained on RLHF for human alignment, but RLCD RL for Calibrated Decisions — so it is more like traditional ML tasks, just with a more modern model base. The docs are good https://docs.typesafe.ai/introduction , there is a Playground, and official SDKs for JavaScript https://docs.typesafe.ai/sdk/javascript and Python https://docs.typesafe.ai/sdk/python and inofficial ones for any other language. It has already been integrated into OpenRouter https://openrouter.ai/typesafe , Pydantic.ai https://pydantic.dev/docs/ai/models/typesafe/ great docs , LangChain https://docs.langchain.com/oss/python/integrations/providers/typesafe , BrainTrust https://braintrust-722z5inab.preview.braintrust.dev/docs/integrations/ai-providers/typesafe for judging These kind of models are meant to be used inside the hot loop of software, where you usually do if/switch decisions on data that are not deterministic but probabilistic. Current LLMs are too slow and expensive for that. Neo4Jev — Graph Navigation with Jev When a new model API or paradigm comes out, the toy examples usually work fine, look nice but don’t give you hands-on experience. While waiting for my waiting list submission to go through I wanted to try something close to my heart and easy to implement and demonstrate. Navigating an existing Neo4j knowledge graph, with real data, real schema, a task where you can see whether the thing actually works or just sounds convincing. I got the idea from their “WikiRacing/WikiGame” demo, just to have something doing meaningful work. Wikiracing The objective of the game is to start on one Wikipedia page and reach a specific other Wikipedia page using only links you come across while traversing. Each step can mean choosing between hundreds to thousands of links It’s a great playground for demonstrating not just intelligence-per-second, but also the compounding benefits of not hallucinating with high-cardinality choices. The task: graph navigation. Start at a node, follow relationships toward a goal target entity, path goal or general task , one hop at a time, and have the model — not hand-written heuristics — decide which relationship to follow at each step. For testing I used Neo4j’s public Companies knowledge graph 15 labels, 28 relationship types available on https://demo.neo4jlabs.com:7473 https://demo.neo4jlabs.com:7473 in the “companies2” database. Why navigation is a useful test case If you try to use LLM for graph traversals, i.e. predicting a path through a dataset — they do not great, as the generated paths, nodes, or relationships might actually not exist. They are quite good at query generation turning a user question with a graph schema into a graph query, which we use in Text2Cypher. But for this use-case of interactive navigation, they are too slow. Traversal at any given node is not a generation problem. It is a choice between of the current state, possibly history and a concrete, finite set of options : the relationships that actually leave this node. That fits an API that returns probabilities over options much better than one that returns prose. How does Jev operate The system one API takes a state arbitrary JSON describing the situation and a set of questions , and returns answers with probabilities. The question types that matter here: - Choice — “which of these options?” You pass a map of keys to descriptions. The answer includes the winner, a confidence score, and the full probability distribution over every option. - Noul — a 0..1 float, basically “how true is this statement?” We use it as a goal-reached check. - Score — numeric scoring, not needed here. You can ask several questions in one call they run in parallel, no extra latency or cost , so one round-trip per hop both picks the next edge and checks whether we’ve arrived. And a beam search needs what Choice returns: a distribution to branch on. Start somewhere and follow the trace The database config and typesafe API key are loaded from a .env file. The neo4j connector loads the schema, for start node selection you pick a label and then can find entries via exact, fulltext or vector search. E.g. in our case an Company like Apple Then you specify a target mode - Reaching a target node, e.g. a board member like Larry Page - A path intent , conceptually follow this kind of path, e.g. find articles mentioning this company - A free text task , e.g. find all people who are on the board of this company and the other companies they are advicing Then the app iterates a loop , until the threshold 1. From the current node, fetch its outgoing and incoming relationships — type, properties, and the label + properties of the target node on the other side. 2. Present them as Choice options: “which relationship should the traversal follow next?” Option keys are opaque ids e0, e1, … with a side table back to the real edges. 3. In the same call, ask a Noul: “has the goal been reached at the current node?” 4. Follow the top-k options above a probability cutoff, branch, repeat. Each branch accumulates the sum of log-probabilities of its edges log-sums avoid underflow and don’t penalize longer paths the way products do . candidates = list fetch candidates state.node id budget.spend view = goal view goal, state.depth hop = await execute hop client, node, candidates, view, settings=config, hop index=state.depth, path=state.path,model=None expansion = Expansion candidates=hop.candidates if view.goal reached by noul hop.noul, config.goal threshold : expansion.terminated.append NavPath steps= state.path, terminal step state.node id, hop , cumulative log prob=state.cumulative log prob, terminated reason=TerminationReason.GOAL REACHED, return expansion for candidate, probability in hop.chosen: next id = candidate.next element id if not next id or next id in state.visited: continue step = NavStep node id=state.node id,chosen= candidate , probabilities=hop.probabilities, log prob=math.log max probability, LOG FLOOR , candidates=hop.candidates,noul=hop.noul child = state.extend step, next id if view.is target next id : expansion.terminated.append NavPath steps=list child.path , cumulative log prob=child.cumulative log prob, terminated reason=TerminationReason.GOAL REACHED, else: expansion.children.append child expansion.nodes next id = NodeContext element id=next id, label=candidate.next label, properties=candidate.next props, if not expansion.children and not expansion.terminated: expansion.terminated.append as path state, TerminationReason.NO CANDIDATES return expansion A visited set blocks cycles, max depth,and an API-call budget keep the search finite, a beam width neighbours caps live branches to the max Choice entries count. The result is the best-scoring path or paths, plus the explored-but-not-taken branches as context. A dead-end node still gets its call — the Noul alone, since an empty Choice has nothing to pick. So “reached the goal and stopped” is distinguishable from “ran out of edges”. How to reach the the goal based on target mode - Free text — “find a company that competes with the start node.” The description goes into the state, the Noul checks it each hop. - Target node — navigate to a specific node, picked via a lookup UI. The Noul is trivial here “is this it?” ; the Choice does the wayfinding. - Path intent — describe the shape of the path rather than a destination: “from the patient to the gene expressions for their diseases.” The description is split into stages that bias each hop’s Choice; the Noul checks the final stage. This mode returns the top-N paths. What actually mattered The beam search was the easy part. These decisions had much more effect on whether Jev performed well or badly: The model can only choose between options it can read. Ensure to send correct and sensible data to the model, and not opaque identifiers. Send the schema as a “map” along with the local edges. A hop’s candidates only show what’s at the current node. Without more context, the model can’t reason about a detour — e.g. going via a news article to reach a competitor when there’s no direct edge. It would go along tangents currently no backtracking Keep the payload reasonably small. Long text properties and embedding vectors bloat the request and bury the fields that matter. Smaller state, better probabilities, lower cost. Offer incoming edges too. Initially only outgoing edges were candidates, which made certain nodes unreachable. The traversal now offers both directions, tagged explicitly, so the model can walk backwards along an edge when the goal is upstream. Cap candidates fairly. Real graphs are uneven, skewed — one company has thousands of supplier edges and a handful of competitors. A naive total cap starves the rarer, more interesting relationship types. We cap per edge type first, then fill the remaining budget round-robin, and report “N of M edges considered” so truncation is visible. The system The code around the core pattern is minimal, just 5 python files. https://github.com/jexp/neo4jev/tree/main/src/neo4jev https://github.com/jexp/neo4jev/tree/main/src/neo4jev - neo4j access — everything Neo4j: label and index introspection, candidate fetching with the capping above, identity-property derivation, the schema snapshot. - types — static types for holding the graph results and the choices and API payload for the Typsafe API - navigator — the beam search and the TypeSafe boundary: builds the per-hop system one call, turns probabilities into branches, scores paths. - viz — renders paths and neighborhood context with neo4j-viz, colored by label/type, path colors on top, with legends, details, layots provided out of the box - Notebooks — three notebooks explore, single-hop, full traversal over all goal modes and - Streamlit app — an app that shows the per-hop trace: every option Jev was offered with its probability, what it picked, and the Noul verdict. Does the idea hold up? So far, yes, with caveats. When the payload is clean and the schema is included, Jev navigates sensibly: From Microsoft, asked to find a competitor, it takes HAS COMPETITOR → Amazon.com, Inc. at p 0.85 — and the full distribution shows why , which no prose answer would. The three goal modes all produce coherent paths. The caveats are: - decision quality tracks payload quality closely garbage properties in, indifferent choices out , - high-degree nodes need capping to stay within the 255-option Choice limit and reasonable token cost, and - the goal-reached Noul is the weakest link for vague free-text goals. The broader point stands: if each step of a task can be phrased as a decision over real, fetched options, you don’t need to let a model improvise queries or narrate a walk. You get traversal that is - grounded every edge walked exists , - inspectable the probability distribution is recorded for every hop , - steerable goals are just state , and - cheap one API call per hop, questions multiplexed within it . That pattern should transfer to query planning, workflow routing, model/tool choices, and other kinds of decision making. Graph navigation is just a very literal version of it. Try it GitHub Repository is here: https://github.com/jexp/neo4jev https://github.com/jexp/neo4jev/tree/main The demo runs against Neo4j’s public Companies knowledge graph - URI https://demo.neo4jlabs.com:7473 https://demo.neo4jlabs.com:7473 - readonly username, password, database: companies2 Point .env at any other Neo4j instance and labels, indexes, identity properties and schema are all discovered live. The sky is the limit They have a waiting list but you get in within a day. You should definitely join their Discord https://discord.gg/typesafe , it’s super active, they have regular town hall AMAs and a very interesting show-and-tell channel https://discord.com/channels/1483217544214085663/1483217545040232493 with thousands of demos and applications. Some things I wanted to try out are: - Entity Resolution my colleague Kervin Hu https://medium.com/u/ba7a59bb3190 wrote about it I tested Jev on entity resolution https://kervinhu.medium.com/i-tested-jev-on-entity-resolution-e7249f219ca6 - Tool routing/selection incl. parameter extraction - Decision making for coding and database harnesses e.g. for compaction, model routing, determining criticality of changes, code-review I had Jev rank some ideas from Claude for using decision models, it’s what you expect, typical decision taking that you need in code, but more dynamic than deterministic code could give us. Soo many sites listing Jev projects. - Made with Jev – What people are building with Jev https://madewithjev.com/ - Awesome Jev https://www.awesome-jev.xyz/ - Creative uses of Jev · Jevfast https://jevfast.com/ - Jev AI Tools – Directory of Jev Tools & Projects Built on Jev AI https://jevaitools.com/ - https://github.com/yibie/awesome-jev https://github.com/yibie/awesome-jev - https://iambraun.com/jevreports/shipped/ https://iambraun.com/jevreports/shipped/ - https://github.com/valentynkit/awesome-jev-typesafe https://github.com/valentynkit/awesome-jev-typesafe There are already a lot of Alternatives/Clones https://www.latent.space/p/ainews-here-are-6-clones-of-jev-in like Laya https://laya.convaiinnovations.com/ MLX https://aiidelist.com/blog/what-is-laya-mlx , BERT, Qwen LoRA trained Kev https://github.com/jaredpalmer/kev decision models, and OpenJev https://openjev.com/ . If you haven’t, go try it out Navigating a Neo4j Knowledge Graph with Jev https://medium.com/neo4j/navigating-a-neo4j-knowledge-graph-with-jev-a72b728d1767 was originally published in Neo4j Developer Blog https://medium.com/neo4j on Medium, where people are continuing the conversation by highlighting and responding to this story.