The words get mixed together because a working agent usually contains all three. It has a place to run, it keeps taking actions until it reaches some stopping point, and it may hand work from one step to another. The trouble starts when a team tries to solve the wrong problem. A brittle tool permission policy will not be repaired by drawing a prettier workflow. A missing review step will not be fixed by adding more memory.
Start with the harness. This is everything around the model that makes a task possible and bounded: its tools, files, durable instructions, session state, model routing, permissions, logs and sandbox. If an agent can draft a useful answer but cannot reliably find the right repository, retain the right state, or explain which tool changed something, the harness is the weak point. The first repair is usually mundane: narrow the tool allowlist, separate stable instructions from task notes, and keep an audit trail that a human can read.
A loop is a different job. It is the pattern in which the system proposes an action, sees the result, and decides what to try next. Coding agents use this constantly: inspect a failure, change a file, run a test, then either stop or investigate again. A loop is valuable only when it has evidence to react to and a reason to end. ‘Try again’ is not a design. A useful loop names the check, records the result, sets a budget, and says who or what can declare the task finished.
Graphs answer a third question: which work is allowed to happen next? A graph makes the route visible. One node may classify an incoming request, another may gather evidence, two may run in parallel, and a later node may wait for both before preparing a final answer. Official GraphFlow and LangGraph documentation describe this in concrete terms: nodes perform work, state carries what has happened, and edges determine the next step or steps. That explicitness is useful when order, branching, handoffs or human approval matter.
The distinction pays off during debugging. If the agent loses a customer’s preference between sessions, look at persistent state and the harness. If it finds the right file but stops before it checks the test result, add a bounded verification loop. If it sometimes sends a sensitive request to the wrong specialist, or needs research and calculation to finish before a decision, make the routing visible in a graph. These are not rival architectures. A graph normally runs inside a harness, and a loop often lives inside one of the graph’s nodes.
There is also a cost to making everything a graph. A simple request-response task does not become safer merely because it has ten named nodes. Microsoft’s GraphFlow guidance makes the same practical point: use structured flow when you need deterministic order, conditional branching or a multi-step process with cycles; keep an ad-hoc exchange simple when that control is unnecessary. The diagram should explain a real operating constraint, not decorate a product demo.
For a first production agent, choose one consequential task and write down three things before choosing a framework. What resources may the agent touch? What observation tells it that its last action helped? Which transitions require an explicit rule or a human decision? The answers usually reveal the missing layer. That is a more useful starting point than asking whether the system needs to be ‘more autonomous.’
This article is an independent synthesis. It was prompted by a July 25 post from beamnxw, which described a three-layer way of thinking about agent engineering. We reviewed the linked original post, its author’s public Chinese-language mirror, and official workflow documentation; we did not reproduce the original text or illustration.
