Skip to main content

Notes / AI Engineering / Agent Systems

Beyond Prompt Engineering: The Five Layers of Reliable AI Systems

A capable model is not a complete system. This is a practical way to think about the five layers—prompt, context, harness, loop, and graph—that turn a clever one-shot answer into work you can actually verify and ship.

By William Lodge 10 min read

A model can write a genuinely impressive answer in one shot. That is not the same thing as a system you can trust to do real work unattended, and conflating the two is where a lot of AI-assisted projects go wrong.

A clever prompt is not a complete AI system

Ask a good model a well-framed question and you'll often get a good answer. That's genuinely useful, and it's also the easiest part of building with AI. The harder, less demonstrated part is making that same capability show up reliably on the fifth run, the fiftieth run, and the run where the input is messier than the demo.

A one-shot answer proves the model can do the task once, with a human reading every word before anything happens. A system has to keep working when nobody is watching each token: it needs to know what "done" means, verify its own output against something other than its own confidence, recover from a bad step, and stop when it should stop instead of when it feels like stopping.

I've found it useful to break that gap into five layers. This isn't an industry standard or a certification—it's a practical model I use to figure out what a given piece of AI-assisted work actually needs, and what it's missing when it breaks.

The five layers at a glance

Each layer answers a different question. Skipping one doesn't make the model fail outright—it produces a specific, recognizable kind of failure instead.

Layer What it controls Question it answers Typical failure without it
Prompt The instruction for this specific request What exactly is being asked for? Vague, generic, or subtly-off output
Context The working knowledge available to the model What does the model actually know right now? Confident answers built on stale or missing facts
Harness Tools, permissions, sandbox, state, logs What is the model actually allowed to do? An unsafe action taken with no guardrail
Loop Execution, observation, verification, correction How does it know when it's actually done? False success, silent failure, or an endless retry
Graph Coordination across workers, reviewers, and people Who else needs to check or approve this? One agent grading its own work, unchecked

Prompt engineering: define the job

Prompt engineering is still the innermost layer, and it still matters. A prompt earns its keep when it states the actual goal, the relevant background the model needs to know it's being asked for, real constraints (a framework it must use, a pattern it must not introduce, a file it should not touch), the required output format, and—the part most prompts skip—acceptance criteria. What does "done" look like, specifically, and how would you check?

A prompt without a definition of done is a request for effort, not a request for a result. "Fix the bug" invites the model to fix a bug—any bug, possibly not yours. "Fix the null-pointer error on checkout when the cart is empty, confirmed by the existing checkout test passing" gives it something to aim at and something to verify against.

Where prompt engineering runs out of road is scope. It shapes one request. It has nothing to say about what the model knows beyond that request, what it's allowed to touch, whether it checks its own work, or who else needs to sign off. Those are the other four layers, and no amount of prompt polish substitutes for them.

Context engineering: give the model the right world

Context is everything the model can actually see when it generates a response: repository files, documentation, code examples, prior decisions, the current state of the system, anything retrieved for the task, and—often the most useful signal—what was already tried and didn't work.

The instinct to paste in everything that might be relevant is understandable and usually wrong. Models don't have infinite, uniform attention across a huge context window; long, cluttered context measurably degrades a model's ability to find and use the specific fact that matters, an effect sometimes called context rot. Irrelevant files, outdated documentation, or a wall of unrelated history don't just waste tokens—they actively compete with the information that's actually load-bearing for the current task.

The practical goal is closer to what you'd hand a competent new contractor: the relevant files, not the whole repository; the current state, not every historical version of it; the design rules that apply, not a stack of superseded ones. More context is not automatically better context. Curated, current, and relevant beats large every time.

Harness engineering: control what the model can do

The harness is the scaffolding around the model: which tools it can call, which files and directories it can touch, the sandbox boundary it can't cross, what permissions it holds, what it remembers between steps, what gets logged, what budget or time limit it operates under, which tests and validators actually run, how it recovers from a failed step, and which actions require explicit approval before they happen.

This is the layer that turns raw model capability into controlled action. A model with no harness and full file-system access is not more capable, it's less predictable—it can do more things, including the wrong ones, with no record of what happened and no boundary stopping it. A well-built harness doesn't make the model smarter. It makes the range of things it can do match the range of things it should be trusted to do, and it leaves a trail when something goes wrong.

In practice this looks like: read access to the working files, no access to production credentials; a test command it can run and read the output of, not just claim passed; a log of every file it touched; a hard stop on destructive operations without a human step in between.

Loop engineering: work until the evidence says it's done

A single pass through a model rarely gets a nontrivial task exactly right on the first try, and treating the first draft as the final answer is one of the more common ways AI-assisted work goes wrong quietly. Loop engineering is the discipline of running a bounded cycle instead: inspect the current state, plan the next step, execute it, verify the result against something outside the model's own opinion, correct if it failed, and stop—on success, on a clear failure it can't resolve, or on a retry limit, whichever comes first.

The verification step is the one that actually earns trust. "The model says it works" is not evidence. A test that passed, a build that compiled, a page that returned the expected status code—those are evidence. A loop worth relying on defines a pass condition before it starts, feeds real test output back into the next attempt instead of a summary of it, bounds the number of retries so a stuck task fails loudly instead of burning time silently, and reports what actually happened rather than letting the model declare success without anything to back it up.

Without this layer, you get one of two failure modes: the model stops after a plausible-looking first draft that doesn't actually work, or it loops indefinitely, making changes without converging on anything verifiable. Both look like progress. Neither is.

Graph engineering: coordinate the operation

Some work genuinely needs more than one loop. Graph engineering coordinates that: nodes doing distinct jobs, transitions between them, shared state everyone can read, conditional routes based on what happened, work that can run in parallel, a reviewer stage that's independent of the stage it's reviewing, failure paths that don't just dead-end, terminal states that mean the operation is actually finished, and human approval gates at the points that matter.

A common, useful shape is worker, reviewer, evaluator: one loop implements something, a second loop reviews it without sharing the first loop's assumptions, and a third check—automated, human, or both—decides whether the result is good enough to move forward. The value of the separation is specific: a model reviewing its own output tends to defend the decisions it already made, the same way a person does. An independent second pass catches a different set of problems than the one that produced the work.

This is also the layer easiest to over-build. Most tasks do not need a graph. A single well-scoped prompt inside good context is the right tool far more often than a multi-agent pipeline is, and reaching for orchestration by default tends to add failure points instead of removing them. Graph engineering earns its complexity when a task has genuinely separable stages, a real need for independent review, or a decision serious enough that more than one check should see it before it ships—not by default.

How the five layers fit together

The five layers nest rather than stack end to end. A prompt operates inside whatever context is currently loaded. The harness is what assembled that context in the first place, and it controls the tools the prompt can reach for. A loop runs the harness repeatedly—inspecting, executing, verifying, correcting—until the work meets its pass condition. A graph coordinates multiple loops, plus the decisions, reviewers, and people around them, when a task is big enough to need more than one.

  1. GraphCoordinates multiple loops, decisions, reviewers, and people.
  2. LoopRepeatedly runs the work and checks it against evidence, not confidence.
  3. HarnessAssembles context and controls which tools, files, and actions are reachable.
  4. ContextEverything the model can currently see: files, docs, prior decisions, state.
  5. PromptThe specific instruction operating inside all of the above, right now.

Read top to bottom, each layer contains the one below it. A weak inner layer—a vague prompt, thin context—produces a weak result even inside a well-built outer system. A strong prompt inside no harness and no loop is still just a single unverified guess. Reliability comes from all five being appropriately built for the task, not from any one of them being especially clever.

Practical example: shipping a verified website change

Here's roughly how this plays out on an actual website change, the kind of work I do for clients and on my own projects:

Prompt: state the specific change and how it will be judged done—for example, add a new article to the existing blog template, matching the established route, schema, and CSS conventions, with the existing test suite still passing.

Context: the relevant parts of the repository structure, the shared article template and includes it has to reuse, the site's existing design rules, and prior decisions already recorded in the code—not the entire codebase, and not stale documentation that's since been superseded.

Harness: read and write access scoped to the working project directory, a PHP linter and the project's own test files it can actually run, and no path to production—deployment is a separate, deliberate step outside the model's own authority.

Loop: inspect the existing patterns, implement the change, run the linter and the test suite, read the actual output, fix whatever failed, and re-run until the tests pass or a bounded number of attempts is exhausted and the failure gets reported instead of hidden.

Graph: implementation is one stage; a review pass—checking accessibility, security, and whether the change actually matches what was asked—is a separate stage; final deployment approval is a human decision, made by me, after reading the diff. No stage grades its own work, and nothing reaches a live site because a model said it was ready.

That's the same shape described on my AI workflow page: research, build, test, independent review, and a human decision before anything ships. The five-layer breakdown here is a more general way to describe why that process holds up.

How much engineering does a task really need?

Complexity should match risk and ambiguity, not habit. A useful rough guide:

  • Simple brainstorming or a one-off question usually needs only a good prompt.
  • Working with a document or a small, well-understood repository change needs strong context more than anything else.
  • Anything that touches tools, files, or external systems needs a real harness, even if the task itself is simple.
  • Multi-step work with a verifiable outcome—tests, a build, a status code—benefits from a bounded loop.
  • Genuinely complex operations with separable specialist stages and a real approval path may justify a graph.

Most tasks stop at the second or third layer. Reaching for a multi-agent graph on a task a single verified loop would have handled is not thoroughness, it's overhead—more coordination surface, more places for something to go quietly wrong, and no corresponding gain. Build the layer the task needs and stop there.

Human control is part of the architecture

A handful of actions deserve an approval gate as a matter of course, not as an afterthought: deploying to production, spending money, deleting data, publishing something publicly, sending a message on someone's behalf, or modifying a customer's records. These aren't edge cases to handle later—they're exactly the actions where a confident model and a wrong model look identical from the outside until the damage is already done.

Treating human approval as one more node in the graph, rather than something bolted on after the fact, is what keeps a fast AI-assisted process from becoming a fast way to ship a mistake. The point of the other four layers is to make that final human decision fast and well-informed—not to make it unnecessary.

Conclusion

None of this is about picking the fanciest prompt or the newest orchestration framework. It's about recognizing that a reliable AI system is produced by everything around the model—what it knows, what it can touch, how it checks its own work, who else reviews it, and who ultimately decides—not by the model alone, and not by a single well-worded instruction.

If you're weighing whether a project needs a careful prompt or a genuinely engineered system around one, that's exactly the kind of scoping conversation worth having before any of it gets built. See how I structure this work on my AI workflow page, or get in touch to talk through a specific project.

Scoping an AI-assisted build?

I can help figure out which of these layers your project actually needs—and which ones would just be overhead. See my development capabilities or reach out directly.

Start a conversation

Further reading

This framing was prompted by a five-part series on emergingai.substack.com; the wording, structure, and examples throughout this article are my own, not paraphrased from theirs. Access to individual posts may vary.

  1. Emerging AI: How to master prompt engineering
  2. Emerging AI: Context engineering, full course
  3. Emerging AI: Harness engineering
  4. Emerging AI: Loop engineering
  5. Emerging AI: Graph engineering
  6. Emerging AI: Context, harness, loop, graph

Primary references on the underlying mechanics:

  1. Anthropic: Effective context engineering for AI agents
  2. Anthropic: Building effective agents
  3. LangChain: Workflows and agents
  4. LangChain: LangGraph graph API
  5. OpenAI: Harness engineering
  6. OpenAI: Unrolling the Codex agent loop