My Profile Photo

Chang Min Park


Senior Software Engineer at Yahoo!



Who Picks the Next Step: Loops vs Graphs

Prerequisites

Read these first if prompts, agent loops, orchestration graphs, harnesses, or agentic design patterns are new.

The wrong question

I do not need a DAG (directed acyclic graph) to fix a Kotlin null in Cursor. The session is already a loop: read, edit, run the test, repeat until the test or I say stop. Nobody draws LangGraph for that.

In July 2026 two announcements landed in the same week. DeepLearning.AI released a course with “graph” in the title. Linear released a product called Loops. On X, people treated that coincidence as a fork you had to pick: build agents as loops, or build them as graphs.

That is the wrong question. The useful one is simpler: who picks the next step, and when? A loop answers that at inference time — the model chooses the next tool while it runs. A graph answers it at authoring time — you already named the legal hops in code. Everything else in this post is that distinction, plus the layers people keep stacking next to it as if they were rival products.

Two words, four jobs

The July argument mashed four jobs under two nouns:

Phrase people used Actual job Example
Knowledge graph Data: entities and edges you store Neo4j course on building a product-issue graph from CSVs and reviews
Orchestration graph Control flow: which node runs next LangGraph, a state machine, a CI DAG
Agent loop Control flow: model picks the next tool Claude Code, Cursor, a ReAct while
Linear Loop Product: cron or trigger plus an agent Recurring triage, doc updates

A knowledge graph answers what is related. An orchestration graph answers who runs next. Mix those and a course about storing related facts sounds like a vote for LangGraph. Linear’s Loops is closer to cron plus an agent than to either.

Andrew Ng did not write the “graduate from loops to graphs” ladder people attributed to him. He published design patterns — reflection, tool use, planning, multi-agent — and iteration beats one-shot. Those fit inside a loop or a graph. The course that started the noise, Agentic Knowledge Graph Construction, is Kollegger / Neo4j filling a knowledge graph. Ng hosts the platform.

So forget the fork. Keep the question: who picks the next step, and when?

Loop vs graph

A coding-agent session is one model, tools, a budget, a stop. Each turn the model chooses a tool. The next step does not exist until it emits it.

# The model chooses the next action. Edges are not in your repo.
while not done and steps < budget:
    action = model.decide(state)   # billed every iteration
    state = env.step(action)
    done = harness.should_stop(state)

Use a loop when you cannot draw the workflow without running it: debugging, open-ended research, “make this Compose preview compile.” A graph cannot discover a step you did not author.

An orchestration graph is the other end. You wrote the legal next steps when you drew the nodes. The model still works inside a node — often as its own loop — and it may still pick among declared successors. It does not invent a hop that is not on the map.

# You chose the next node. The model does the work inside one.
g.add_edge("triage", "android")
g.add_conditional_edges("critic", {"pass": "human", "fail": "android"})

That buys inspectability and a real checkpoint — a human step before a store-facing side effect. You pay in coordination cost and bugs in the graph itself.

flowchart LR
  M[Model] -->|picks tool| T[Tool]
  T -->|observe| M

Figure 1. A loop: the model owns the next hop. There is no edge list in the repo.

flowchart LR
  A[Triage] --> B[Android specialist]
  B --> C[Critic]
  C -->|fail| B
  C -->|pass| H[Human gate]

Figure 2. A graph: the edge list owns the next hop. The Android node may still run a loop inside.

A loop is already a graph with one node and an edge back to itself. The interesting difference is when routing is decided, not whether you can draw a circle.

Layers, not a ladder

Vendor decks also stack prompt, loop, graph, and harness as if you pick one. They answer different questions. They stack under the same “who picks next?” problem; they are not four products.

Term Question it answers What you write What it cannot do
Prompt What should this model call do? System / user text, few-shots Call a tool, retry, veto “done”
Loop Who picks the next tool? while + model + tools Declare illegal hops; enforce a stop
Graph Which named step may run next? Nodes, edges, joins, human gates Discover a step you did not draw
Harness What may execute, and when is it actually done? Tool allowlists, hooks, observe, budgets Invent product intent (that is the spec / prompt)

The prompt is an input to a turn. The loop is who picks the next tool. The graph is which named step may start. The harness is the machine that runs a loop or a graph — hooks, permissions, max steps — and can refuse both. A loop without a harness stops when the model writes an essay. A graph without a harness still has no honest “done” on a node. The harness is not a fourth topology.

flowchart LR
  H[Harness] --> G[Graph]
  H --> L[Loop]
  G --> L
  L --> P[Prompt]

Figure 3. Layers, not a ladder. The harness can run a graph or a loop. A graph still bottoms out in a loop. Every turn still has a prompt.

You do not need all four on every task. Almost every useful agent has a prompt and a harness. Then you choose a control-flow shape: usually a loop; a graph only when the path is real.

Take the Kotlin null. The prompt names the file. The loop reads, edits, and runs the test. The harness refuses “done” until the test exits 0. Drawing a graph here is leftover ceremony.

For example, in a mail-style Android client, a crash that must be grouped, attributed to a module, checked against a release flag, and only then allowed to file a public bug is a path: triage → specialist → critic → human. Different duties, different stop rules, a human before anything leaves the building. That is graph-shaped even if you implement it with three scripts and a queue. Each node still has a prompt and a loop. The harness is what blocks the public-bug file until the human step runs.

If a chat failed, name the layer. Wrong wording is a prompt bug. The model wandering into the wrong module is a loop with a thin harness. A missing human approval step is a graph you never drew. A long “done” write-up over a failing test is a missing harness, not a reason to buy LangGraph.

So when do I draw edges?

Situation Prefer Why
One module, one verifier, same retry Loop Topology is overhead
Research → write → skeptic → ship or return Graph Different duties and stop rules
Parallel audit, then a veto Graph Fan-in is a real join
Human approval before a store/side effect Graph + gate The checkpoint is an edge

A personal Cursor session on one Gradle module stays a loop. Recurring Linear triage is a triggered loop with a review step — closer to cron plus an agent than to a knowledge graph or to LangGraph.

Do not buy a graph framework to feel current. Buy it when you can name the nodes, the illegal transitions, and the join you will debug at 2 a.m. Until then the interesting engineering is still the loop: tools, budgets, and a stop that is not the model’s essay. Same default Ng and Anthropic point at — start with iteration inside a loop; add named nodes when a branch, a join, or a human gate is a real requirement.

References