RSS Amplifier

Building and Exploring · Jun 10, 2026

Designing for confidence

0
Sign in to vote or save

Michael Spragg · Building and Exploring

There’s a narrative running through much of AI product discourse right now that goes something like this: the frontier models are getting so capable that architecture barely matters anymore. Give the model enough context, enough tools, a good system prompt, and it figures the rest out. Anthropic’s release of Fable has already seen plenty of people show examples of “give it the context and way away for four hours.”

It’s a seductive idea. It’s also probably responsible for a generation of pipelines that are expensive to run, hard to reason about, and opaque when they fail.

It’s also expensive in ways that won’t necessarily be visible until scale forces the question. Frontier model providers have been subsidising inference costs to drive adoption. That subsidy will unwind eventually. Teams that treat “cheap enough to not matter” as a design principle may discover that their pursuit of growth in this manner is not sustainable.

The problem isn’t the models. It’s a category error about what kinds of problems probabilistic systems are actually for, and a failure to be deliberate about where different modes belong in your architecture.

The field has converged on a term for the structure you build around a model: the harness. Claude Code has one. Cursor has one. Codex has one. They differ considerably in design, and those differences probably matter more than the underlying model benchmarks in many production contexts. In terms of software development the harness is where architectural decisions live. Whilst that is the focus of this post, my learnings from creativityprompts.com lead me to believe that the principles apply to any surface where the use of an LLM is an option.

Deterministic systems do the same thing given the same inputs. You can test them, audit them, reason about their cost. When they fail, they fail in ways you can diagnose. They are brittle at the edges: an input outside their specified range breaks them; but within their domain, their behaviour is a contract.

Probabilistic systems, large language models specifically, handle ambiguity gracefully, generalise across unanticipated inputs, and produce outputs that would often be impractical to specify in advance. Their failure modes are different: they don’t break cleanly, they drift. They can be confidently wrong. They overfit and apply the wrong underlying approach to brute force an answer. They’re harder to test.

Neither is better. They’re different tools for different problems. The architecture question isn’t “how much AI should I use?” It’s “where does each mode belong, and how do I build a system I can have confidence in across both?”

A useful frame here, borrowed from physical engineering, is tolerance. In structural engineering you don’t design for the exact load a bridge will carry on a given Tuesday, instead you design for a calculated range, with a safety factor applied. The structure performs correctly anywhere within that envelope. Outside it, behaviour is undefined. The discipline is knowing where tight tolerances are necessary and where loose ones are sufficient, and being explicit about which you’ve chosen and why.

You also need to work within the constraints of both the physical world and the budget available.

Applied to AI systems: a deterministic component has a tolerance of zero, given these inputs, this output, exactly. A probabilistic component has a tolerance range, given these inputs, an output within this distribution. The architecture question becomes: what tolerance is acceptable at each layer, and how do you verify your system is performing within it?

The critical difference from physical engineering is that you can’t calculate the tolerance range of a probabilistic system from first principles. You have to discover it empirically, through evals. Pre-deployment, evals characterise where the model lands: the shape of the distribution, the edges where behaviour starts to drift outside acceptable bounds. Post-deployment, monitoring verifies that production behaviour stays within the range you measured. These are different disciplines requiring different infrastructure, and one of the biggest challenges most teams currently have is building this in a systematic way.

That question, confidence in output, is how I frame the problem. Not elimination of non-determinism. Not maximum determinism. Confidence: the ability to reason about what your system will do, why it did what it did, and what to do when it doesn’t behave as expected.

It helps to think about this concretely across three distinct modes.

Fully deterministic components are places where the behaviour can be fully specified in advance. Routing decisions, state transitions, enforcement logic, cost controls. These should almost always be deterministic, not because determinism is philosophically virtuous, but because it gives you testability and auditability at no meaningful cost. If you can write a function with a reliable contract, you should.

Fully probabilistic components are places where the value is the ambiguity handling. Summarising a complex document where what’s material requires judgement. Generating a response to a customer query that could be phrased ten different ways. Synthesising analysis from unstructured inputs. These are the problems large language models are extraordinary at, precisely because you cannot fully specify the correct output in advance. This is where you want probabilistic behaviour, not where you’re tolerating it.

The interesting and undertheorised middle ground is skills.

Skills, reusable capability definitions that constrain how an agent approaches a specific task, are now a core part of the AI product ecosystem. skills.sh lists over 600,000 installs of community-built skills across agents including Claude Code, Cursor, Copilot, Windsurf, and Cline.

A good example is vercel-react-best-practices: 70 prioritised rules across 8 categories, waterfall elimination, bundle optimisation, re-render patterns, maintained by Vercel Engineering and installed 463,700 times. When an agent operates under this skill, it doesn’t generate arbitrary React code. It generates React code shaped by Vercel’s opinionated, well-tested performance patterns.

This is not deterministic. The model is still making probabilistic judgements about how to apply the rules to your specific code, your specific context. But the probability distribution has been deliberately narrowed by human expertise encoded as structured instruction. Within its designed scope, it’s remarkably reliable, which is why it has 463,700 installs.

The failure mode, though, is worth understanding clearly. When your architecture diverges from the assumptions the skill was written for, when you’re building something the 70 rules didn’t anticipate, the model doesn’t hedge or ask for clarification. It follows the instructions carefully into territory they weren’t designed to cover. In tolerance terms, you’ve exceeded the envelope the skill was characterised for. Those 463,700 installs represent collective empirical evidence that the tolerance range covers a large proportion of standard React work, nobody calculated that, it emerged from use. The edges of that range are still being discovered.

It’s not unreliable in the way a naive prompt is unreliable. It’s confidently unreliable. That’s a different and often worse failure mode.

Skills sit at an interesting architectural seam: more constrained than open-ended generation, less guaranteed than deterministic code. The discipline is knowing what tolerance range they cover, where that range ends, and designing your verification to catch what falls outside it.

At the deterministic end, the design question isn’t whether to use deterministic logic. it’s being deliberate about what you’re enforcing and why.

An example from my own work is Finance Gate, a budget enforcement middleware layer I built for agentic pipelines. The problem it addresses is one most teams are either already feeling or about to: agents optimise for task completion, not cost. Left unmanaged, a complex task will cause an agent to escalate, reaching for expensive models, running extended thinking passes, retrying on failure. There’s no internal pressure toward economy. During the tokenmaxxing subsidy era this is tolerable. Now that tokens are starting to get their own line item on the P&L, it’s an architectural liability.

Finance Gate sits between the orchestration layer and the model API, tracking spend against a configurable budget and downregulating tier selection as budget pressure increases, routing toward less expensive models rather than hard-blocking, and supporting orchestrators to make prioritisation decisions around which activities to execute. When the budget is exhausted, it stops.

The enforcement logic is entirely deterministic. Budget rules, tier thresholds, downregulation behaviour, all explicit, testable, auditable. The model cannot negotiate with the enforcement layer because the enforcement layer isn’t listening. It applies rules.

It’s worth being precise about what this guarantees: spend will not exceed budget, tier selection will reflect available resource. It doesn’t guarantee output quality or task correctness. Those are separate concerns, and conflating them would overstate what any enforcement layer can provide. It is also contextual and needs constant updates, as models evolve and pricing changes, but hey, there’s an agent for keeping that up to date.

The broader point: deterministic components should enforce something specific and well-defined. The value comes from the explicitness of the contract, not from the fact of being deterministic. For teams running agentic pipelines at any meaningful scale, that contract is no longer optional, it’s what you build before the pricing changes, not after.

Shift-left remains one of the most valuable principles in software engineering. Find failures early, catch them cheaply, don’t let problems compound through the development cycle. None of that changes with AI systems, if anything, the discipline matters more.

But shift-left has a fundamental limit when applied to probabilistic systems: you can’t verify an output that doesn’t exist yet. Some verification is irreducibly runtime in nature. The model’s output only exists once inference has happened, which means a whole class of quality checking has no build-time home. Previously, this was also too expensive to happen inline, so it either didn’t happen at all, or it happened in production, which is the worst possible place to discover a problem.

That’s the gap that’s closing. As inference has accelerated, runtime verification is becoming practical as an architectural primitive, not replacing build-time discipline, but filling the space it couldn’t reach.

Shift-left thinking applied to AI systems still means something important: write your evals before you deploy. Define your tolerance range before you ship. Specify what acceptable looks like before production behaviour tells you what unacceptable looks like. That’s the shift-left instinct applied to a new context. The runtime verification layer then checks that production behaviour stays within the range you defined.

Together they’re complementary. Evals characterise the tolerance range at build time. Runtime verification enforces it in production. Rather than asking “is the model good enough to get this right?”, you can ask “what does this output need to satisfy, and can I verify it before it leaves the system boundary?” The second question is actually answerable, and now, increasingly, affordable to answer inline.

A concrete example if you want one — skip ahead if the pattern is already clear.

The most instructive current example is the back-pressure loop in coding agents. Cursor, Claude Code, and similar harnesses expose the agent to deterministic feedback signals in real time: compiler errors, failing tests, linter violations. The agent doesn’t receive a verdict from another model. It receives a pass/fail signal from the test suite, a deterministic system, and iterates probabilistically in response.

This is verification working as an architectural primitive rather than a quality gate. The deterministic signals define what acceptable means. The agent uses them as a continuous feedback loop. Confidence comes not from constraining the model’s reasoning but from anchoring it to signals that cannot be argued with.

In a way this is simply automating what developers were already doing.

For output validation in non-agentic pipelines, structured output validation. Pydantic, JSON Schema, Instructor-style wrappers, is the simplest form: fast, cheap, and sufficient for a large class of problems where the failure you’re guarding against is format non-compliance rather than semantic incorrectness.

For semantic verification, LLM-as-judge, a second model pass evaluating output against a rubric, is increasingly common. It’s useful for catching factual drift, task incompleteness, tone violations. But worth being realistic about what it provides: it’s a probabilistic system evaluating a probabilistic system. It reduces error rates. It doesn’t eliminate them. Two stacked probability distributions give you a narrower envelope, not a deterministic one. That’s worth having, as long as you know what you’ve built.

The rubric, in all cases, is the deterministic element. You define what acceptable means. The evaluation mechanism applies it.

Verification doesn’t make non-deterministic outputs deterministic. It measures whether they fall within an acceptable tolerance range, and stops them exiting the system boundary if they don’t. The interior behaviour remains stochastic. What changes is the contract your system presents to the outside world. That’s a meaningful guarantee, and an increasingly practical one to build.

The practical question all of this leads to is: how do you actually decide where each mode belongs?

A few diagnostic questions that help:

Can this behaviour be fully specified in advance? If yes, it’s a deterministic candidate. Routing logic, cost enforcement, state transitions, these rarely benefit from probabilistic handling and pay a real cost in testability when they get it.

Does this require handling genuine ambiguity or unanticipated inputs? If yes, this is where probabilistic systems earn their place. Don’t try to deterministically encode something that is irreducibly ambiguous, you’ll get brittleness without the testability upside.

Is this in a well-defined, well-understood domain with opinionated best practice? Skills are probably appropriate. The value is reliable behaviour in the common case. Know the edge and design your verification to catch what falls outside it.

What’s the cost of a wrong output here? This determines verification depth. Low-stakes outputs may need only schema validation. High-stakes outputs be they customer-facing, financial, medical, legal, probably warrant semantic verification with explicit rubrics and fallback paths.

Can you write a meaningful test for this? If not, that’s a signal. Either it should be deterministic (in which case, make it so), or it needs a verification layer that gives you confidence without requiring the output to be fully predictable.

The clearest current examples of these patterns come from software development: coding agent harnesses where the feedback loops are tight, the signals are deterministic, and the tooling is maturing fast. Outside that domain, most deployed agents are considerably cruder: an LLM, a prompt, and optimism. The gap between what’s possible and what’s in production remains wide. Gartner estimates only around 14% of organisations have production-ready agentic solutions today.

The trajectory of AI infrastructure tooling is mostly in this direction: better enforcement primitives, richer verification layers, harness designs that make the feedback loop between deterministic signals and probabilistic reasoning explicit and controllable.

LangGraph, Temporal, and similar orchestration tools represent a move away from “LLM in the middle as orchestrator” toward systems where the workflow shape is a deterministic contract and the model executes within it. The back-pressure loop pattern, i.e. deterministic signals driving probabilistic iteration, is being generalised beyond coding contexts. People are finding ways to use the Claude and Codex harnesses to run non-coding workflows. The harness is becoming a first-class architectural concern, not an implementation detail.

The frontier providers will keep improving model capability. That’s their job, and they’re good at it. The architecture question, where each mode belongs, how confidence is built across the boundary between them, is yours.

The builders who will navigate this well aren’t the ones who trust the model most, or the ones who trust it least.

They’re the ones who are most deliberate about where each kind of trust is warranted, who design explicit boundaries between modes, enforce what can be enforced, verify what can be verified, and build the genuinely probabilistic parts with clear eyes about what that means.

The harness is where that deliberateness lives. It’s not a constraint on the model. It’s the structure that makes the model’s capability usable in production.

That’s not a new discipline. It’s software engineering applied carefully to a new class of component. The components are more powerful than what came before, but the discipline is the same.

Thanks for reading Building and Exploring! This post is public so feel free to share it. And if you don’t already, subscribe to get my occasional musings.

Share

No posts

Read the original on buildingandexploring.substack.com

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.