Ghost Hat Studio
Blog
June 15, 2026

Frameworks are Training Wheels: When to Use LangGraph and When to Go Rogue

4 min read

A shimmering network of glowing nodes connected by fine threads of light on a black background, brass-gold and steel-blue orbs forming an interconnected graph with one bright central node.

Most teams building an AI agent reach for a framework on reflex. LangGraph, LangChain, the whole shelf. It feels like the responsible choice, the adult one. And for your first few agents it is exactly right, the same way training wheels are exactly right when you are learning to ride.

The catch is that most agent workflows are simpler than a framework assumes. A framework is built to handle the hardest version of the problem for everyone at once, and your version is usually not the hardest version. So you write code to satisfy the framework instead of to do the job, and the thing that made your first mile easy starts dragging by the tenth.

The useful skill is knowing when the wheels are helping you and when they are holding you back. Here is how we make that call.

The framework trap

Frameworks try to be everything to everyone, and they get there by stacking abstraction on abstraction. LangGraph handles real orchestration well, especially when you need cycles and stateful persistence out of the box, and it gives a team one shared vocabulary for talking about agents.

The cost shows up when a simple problem disappears under the framework’s requirements. You write more code to satisfy its schema than to solve your task. Every layer between your prompt and your model is one more place to break and one more source of latency. And when the framework’s authors did not anticipate your case, you spend the afternoon fighting the library to make a basic tool call behave.

A cramped mechanical control panel overloaded with levers, wires, gauges, and glowing screens, brass fittings and tangled cables spilling across a workbench, with a small clean engine almost buried under ornate parts.

When to stay in the graph

This is not framework hate. Training wheels exist for good reasons. Stay with LangGraph when:

  1. The workflow is genuinely complex. Five agents handing off to each other with human approval steps in the middle? LangGraph’s state management earns its keep. Rebuilding that from scratch is a real project on its own.
  2. You need a prototype fast. If the proof of concept is due Tuesday, let the framework handle the plumbing so you can focus on the prompts.
  3. You already live in LangChain. If your stack runs on LangChain integrations, LangGraph is the natural next step and fits the mental model you already use.

When to go rogue

Going rogue means a lean pipeline you write yourself: plain Python, direct calls to your model, a loop you can read top to bottom. Go rogue when:

  1. Performance is the point. When every millisecond counts, a custom pipeline lets you strip the middleware and talk straight to the model. No hidden logging, no extra object wrapping, just speed.
  2. You run on local hardware. If you deploy on your own machines for privacy and cost, you cannot afford cloud-native framework overhead. A lean pipeline spends every GPU cycle on inference instead of managing a graph library.
  3. You need it to keep working. Frameworks move fast and break things. Own the code and it does not fall over because a dependency jumped from 0.1.2 to 0.1.3.

A wall of cascading binary code, streams of glowing ones and zeros raining down a black void, shifting from warm brass-gold on the left to cool steel-blue on the right.

What going rogue actually looks like

People assume a custom agent loop is a big undertaking. It usually is not. Underneath the graph diagrams and the DSLs, most agents are the same small loop: ask the model what to do, do it, feed the result back, repeat until done. Written plainly, that is about a dozen lines.

def run_agent(task, tools, max_steps=6):
    history = [system_prompt(task)]
    for _ in range(max_steps):
        reply  = call_model(history)          # your local model
        action = parse_action(reply)          # validate against your own schema
        if action.done:
            return action.result
        result = tools[action.name](**action.args)
        history.append(format_step(action, result))
    raise AgentError("ran out of steps")

That is the whole engine. No graph object, no config file, no dependency that breaks when it bumps from 0.1.2 to 0.1.3. You can see every step, log exactly what you want, and set your own step budget so a confused agent cannot loop forever. When the model returns something malformed, parse_action catches it at the source and you retry, instead of chasing a generic graph error for three hours. We keep the context that loop runs on lean with the XML Diet approach, so it stays fast on local hardware.

A vintage bicycle leaning against a weathered workshop wall, with a pair of small training wheels just unbolted and lying on the floor beside a wrench.

Take off the training wheels

Frameworks are a good way to learn the road. To win the race you eventually build your own machine, one you understand end to end. Whether you are fighting LangGraph’s overhead or just starting out and trying to dodge the over-engineering trap, the call is the same. Keep the wheels while they help you. Take them off when they slow you down.

Want agents you actually own?
Thirty minutes. We listen, we ask questions, we find out whether there’s a fit.
Book a call
More from the blog →