# LangGraph's Routing Is LLM-Guessing. I Wrote 50 Lines of Code to Make It Deterministic.

> Source: <https://dev.to/chex0210crypto/langgraphs-routing-is-llm-guessing-i-wrote-50-lines-of-code-to-make-it-deterministic-24oj>
> Published: 2026-06-25 13:18:34+00:00

Every time your LangGraph agent sees "check nginx logs", it might call a different tool.

That's not an exaggeration. LangGraph's routing is driven by an LLM prompt — and prompts aren't reproducible. Same input, different day, different LLM mood, different tool selected.

I spent months debugging this. Every wrong route meant tweaking a prompt, hoping the next call would be better. It never was.

So I wrote something different.

LangGraph is great at orchestrating multi-step agent workflows. But the first step — "what tool should I use?" — is a black box.

You define a prompt, the LLM decides. If it chooses wrong, you can't debug it. You can only guess: was the prompt not specific enough? Too specific? Wrong example?

This is the **routing problem**: given user input, which domain or tool should handle it? LangGraph leaves this to the LLM. I think it shouldn't.

``` python
from decide_router import RouteTable

rt = RouteTable("routes.yaml")
rule, _ = rt.match("check nginx error logs")
# rule.domain → "monitoring" — always, every time
```

No LLM call. No prompt. Just a YAML file and 50 lines of matching logic.

The YAML defines domains with keywords and regex patterns:

```
domains:
  monitoring:
    priority: 100
    keywords: [log, error, nginx, monitor, health, status]
    patterns: ["(check|look).*(log|status|error)"]
  coding:
    priority: 100
    keywords: [code, script, deploy, write]
  human:
    priority: 100
    keywords: [delete production, restart cluster]
    require_confirm: true
```

Plug it into LangGraph as a node:

``` python
from langgraph.graph import Graph
from decide_router import RouteTable

rt = RouteTable("routes.yaml")

def routing_node(state):
    rule, _ = rt.match(state["input"])
    state["domain"] = rule.domain if rule else "unknown"
    return state

graph = Graph()
graph.add_node("decide_route", routing_node)
graph.set_entry_point("decide_route")
```

Your LangGraph agent now routes with **rules**, not guesses. Same input → same domain. Every time.

The best part wasn't planned — it emerged from using it.

I noticed I kept correcting wrong routes. "That's monitoring, not coding." Every correction was a signal. So I added a feedback cache:

```
# User corrects once → remembers immediately
rt.record_feedback("check nginx errors", "monitoring")
```

Same correction 3 times → becomes a permanent routing rule at priority 70. Rules not used in 30 days auto-delete. The system gets smarter with every correction. No fine-tuning. No prompt engineering.

The core module is one file, 200 lines of Python. Read the whole thing in 5 minutes.

```
pip install decide-router
```

Or browse the code: [github.com/chex0210-crypto/decide-router](https://github.com/chex0210-crypto/decide-router)

*I built this because I was tired of guessing why my agent picked the wrong tool. If you've had the same frustration, star the repo — it helps other people find it.*
