What Is Non-Determinism, and When Should You Use It?

When all you have is a hammer, everything looks like a nail.

Now that we have AI agents, it’s tempting to have them reason through every step of a task. Check a status? Have the agent interpret a record. Calculate a total? Have the agent read the numbers and tell you what they add up to. Decide whether a customer said yes? Have the agent judge the reply.

The agent can handle all three tasks. The question is how you ask it to do each one. It can check a field, use a calculator, or interpret a conversation. Those choices matter when bots start doing work for you and interacting with your customers. Two concepts help explain why: determinism and non-determinism.

A deterministic system produces the same output from the same inputs under the same conditions. A non-deterministic system can produce different results. Language models are generally non-deterministic, so repeating a prompt can produce a different response. Google’s machine learning glossary

That sounds abstract. Let’s make it practical. Suppose you’re building a bot with this instruction: “When the customer says ‘yes’, move to the next step.”

The user responds, “Yes.”, with a capital Y and period. The app checks whether their response matches all lower case “yes”, so the algorithm misses. You decide to account for capitalization and punctuation.

The next person writes “sure.” Then “okay.” Then “sounds good to me.” Damn! Missed again. You add more rules. Those rules are deterministic. You have explicitly defined which responses will match and what happens when it does.

Then someone writes: “I don’t see why we wouldn’t.” Damn Damn. Got me again.

This is where a language model becomes useful. You can ask it to interpret whether the person agreed, using the conversation as context. You no longer have to anticipate every possible phrase yourself. That flexibility is powerful. It also introduces a different kind of decision into your workflow.

There’s a distinction worth making here: interpreting language, inference, and non-determinism are related in these systems, but they describe different things.

Inference is the process of running a trained model on new input to produce an output. It doesn’t specifically mean understanding someone’s intent, and it doesn’t inherently require non-determinism. For our bot, inference is how we run the model. Interpreting the customer’s response is the task we give it. Non-determinism describes the possibility that its answer may vary between runs.

Keeping those ideas separate helps us ask better questions: where does the ability to interpret justify the cost and uncertainty and what did the customer actually approve?

Consider a few more responses:

  • “Sure, if you can deliver by Friday.”
  • “Okay, but send me the revised price first.”
  • “k”
  • “Yah, sometimes…”

It would take a lot of guess work and lists of hardcoded matches to catch all the ways a person could say yes. So we decide to use an agent for non-deterministic results. Even then, these deserve different treatment. A positive tone can may contain a condition, or no approval at all. “Sometimes” is especially revealing. It does not clearly lay out what approval requires to get to the next step. Even “k” can mean different things depending on what came before it. The agent can interpret the words and the context, but it cannot decide your standard for approval on its own every time. That standard is partly a matter of judgment and policy, and different people may draw the line in different places. Human or bot.

If your bot’s instruction is “look for anything that sounds like positive movement,” you may have built a system that turns interest into permission. The work is in telling the agent what counts as approval for this task, and what to do when the answer is unclear.

For a bot suggesting another article, a loose interpretation might be acceptable. For a bot placing an order, you may want explicit confirmation of the item, price, and delivery terms.

The model’s ability to interpret language doesn’t decide how much ambiguity your business should accept. You have to decide that.

This amazing ability to allow for a great deal of flexibility and variation has changed our world of work. That doesn’t mean every problem requires it now. Model calls consume massive compute, and asking an agent to interpret more information can add cost and wait time. Sometimes that expense buys something valuable: understanding an unusual request, connecting ideas across documents, or drafting a useful response. Other times, the answer is already available as a field, a formula, or a rule. I wrote more on how you can balance agentic power with deterministic costs here.

Let’s use a common email bot helper that many are using to increase productibity today. Suppose you ask your agent to find the messages that need your attention (archiving or deleting all the slop). It could read your entire inbox every time you ask. That gives it plenty of context, but it also takes time and uses inference on messages a simple filter could handle.

Instead, ask your agent to create a filter for the obvious parts of that task. It can easily screen out information from site you like but only when it doesn’t meat pattern you’ve seen. Those filters will (deterministically) trim the data your agent needs to interpret down – sometimes to zero. Then it can read what’s left. The agent still does the work. You’ve asked it to spend its reasoning on the messages that need reasoning. Then you can even add a routine to have it create filters based on probably patterns it’s deleted without reading. Each run decreases costs.

Using the customer confirmation example from before, I’d redesign the handoff like this: Have the model interpret the reply as approval, rejection, conditional approval, or unclear. You can even include definitive reply patterns to increase speed and save a cent or two each run.

  • Ask you dev agent to create a deterministic list of positive exact match cases that ignore periods and captialization.
  • Provide explicit non-deterministic rules to understand what each category should permits.
  • Ask the user for clarification when a condition or ambiguity affects the next action.

The filter trims the use of the model, model helps interpret the conversation. The rules establish what the system may do with that interpretation. That’s the design decision that deserves more attention as we put agents to work. Thinking, along with the agent, while developing or setting up our personal bots saved the world time, energy, air quality, speed, cost, and more.

Every request for interpretation should earn its place. What ambiguity is the agent resolving? What flexibility are we gaining? What happens when its interpretation is wrong? How can I trim the list of variations with certainty first? An agent can build and run the whole workflow, including creating the filters, lookups, and calculations that let it focus its judgment where it counts.

Knowing when to remove from you agent with your agent, implement with your rules your agent can reason with, and when to have it check back in to be sure, is part of using all the tools on your toolbelt based on what works best.

When Determinism Is Better Than AI

AI’s superpower is creating deterministic products.

We have become fascinated with AI’s “human-like” level of non-determinism. “I’ll just let AI handle it” is quickly becoming a default answer to problems we haven’t fully thought through, because if AI will figure it out, why should I?

One can ask a chatbot almost anything and marvel at what comes back. Give it a problem and it can find a path you did not anticipate. That unpredictability is part of what makes AI amazingly intelligent, and in many situations it is exactly what makes it the revolution in technology we dreamed of for decades.

But in some cases, we are using a sledgehammer to tap in a nail, and it is costing us a chance to provide the right solutions.

When delivering software as a product, the majority of products are not trying to surprise their users to provide value. Creativity sounds universally desirable, but humans require a surprising amount of consistency to be productive. We don’t generally ask our employees, engineers, doctors, lawyers, or PhDs to be randomly creative. We give them a mission, constraints, and some expectation of what a good result looks like. We want coffee on Tuesday morning at 9 AM, even though all the data points otherwise. Random human + informed AI + creative decisions = unhappy people.

AI doesn’t escape our expectations simply because it is intelligent.

A system that generates a different answer every time it is asked and is told to respond in certain ways with generalized prompts can aspire to be remarkably capable, but it can also be remarkably difficult to control, test, explain, package, interpret, and trust.

I don’t say this philosophically. I say it after years of wrangling AI to do things I hoped would create uniquely powerful products that didn’t exist. Why are the products we see so bad at converting this powerful tech into a powerful value prop? “SaaS is dead” encapsulates that problem. Copying and pasting your work into ChatGPT is often better than using a packaged product that tries to leverage the same AI to complete expected tasks efficiently or effectively. Chat is a bit messy, but it leans into that via the chat experience. That messiness is at odds with a packaged product.

I hear it every week from some aspiring entrepreneur: “Give the AI all your data and let it discover and manage [insert problem here].” It is a magical proposition that is within reach now.

Often it can turn into amazing demos and show unbelievable potential. But getting from a controlled demo to a reliable set of actions and outputs, unmonitored and unaudited by a human, is exceptionally hard. Even big companies with big wallets struggle with the transition. Small amounts of drift compound. Mistakes require review. Sometimes understanding what the AI produced takes nearly as much human effort as doing the work yourself, even if the human would have done the work somewhat worse. And don’t get me started on the cost of answering questions with non-deterministic expectations.

Perhaps we solve this. I hope we do. But in building these systems, I came to appreciate another application of AI that I think we’re underestimating.

Allowing the average person to let AI run their business may be a few years away. Building a business or product with AI tooling is already extraordinarily powerful, and not merely because AI lets us build software faster. It lets us afford complexity we previously couldn’t.

Historically, software has been deliberately simplified.

If a problem had a thousand paths, we rarely implemented a thousand paths. Humans had to anticipate the main cases, write the rules, implement them, test the edge cases, and maintain everything afterward. Eventually the economics would win. We scoped down to three possibilities and ignored the rest so that the software would work well for those cases, slowly building up one case at a time as needed.

AI changes the economics of that equation.

We can now use non-deterministic development tools to explore an enormous possibility space, then turn what we learn into deterministic software. A function that would take an immense level of brainpower to create efficiently, effectively, and robustly was expensive to build, let alone maintain as features were added. Now AI not only helps discover the paths, but can create elegant, hardened functions that deterministically handle all the possibilities you give it. Changing that functionality is no harder.

That distinction is more powerful than it initially sounds.

The power is in the fact that humans don’t typically expect to give or get thousands of outcomes from certain problems. Time and time again, we imagine a waterfall of possibilities when reality only requires an eyedropper’s worth of water.

Because of this tendency to overestimate the useful possibility space, 100 possibilities handled deterministically can feel remarkably intelligent. And with static, scalable, deterministic code, you are paying an infinitely smaller cost to solve these problems. It really is the best of both worlds: scalable software, intelligent-seeming computations, and extraordinarily low complexity to build and manage.

We get much of the richness we associate with AI without requiring an AI to improvise every interaction.

This isn’t an argument against live AI. Some problems genuinely benefit from open-ended answers. Chat obviously does. Search, research, documentation, creative work, and assistance are natural places for a system that can respond to questions nobody anticipated when the product was built. I have five bots running all the time to manage my email, calendar, video creation, socials, and more. They need slapping around now and again and require a lot of guidance, but they are far cheaper than hired help and always running 24 hours a day.

The thing I think nine out of ten people miss when the silver-bullet dream of AI is presented is this: infinite possibility isn’t a requirement for every problem.

Often the customer knows what they are trying to accomplish. Most consumers don’t need an infinite number of possible answers for the mountain of information that surrounds them. They need a sufficiently large number of great ones that consistently provide value.

That is the subtle opportunity I missed when I first started building heavily with AI. I was fascinated by AI’s ability to make software non-deterministic. I now think its ability to make deterministic software vastly more expressive may be just as important.

AI has dramatically lowered the cost of deliberate complexity.

Instead of asking AI to decide what our product should do every time it runs, we can use AI to help us consider far more of what it could do while we build it. We can then deliberately decide which of those possibilities it should handle and save ourselves and the customer more money than they thought possible.

The intelligence moves from improvising the product to constructing it.

And sometimes that is exactly where you want it.

Folks still wonder “why MCP?”. Here is a step-by-step comparison

Not much feels different. And that’s exactly why it confuses people. They expect magic.

I want a list of users. Here’s my pseudo-code way of sorting it out ways of doing it.

Traditional-coder scenario

Human: “I want user data from your system.”

Human goes to the docs
Finds the right endpoint
Sets up auth
Writes code: GET /users
Parses the response and uses it

The human is doing discovery, auth, integration, and parsing.

AI without MCP

Human Prompts: “List users from System X, using this doc [url]”
AI tries to reverse engineer endpoints and payloads
Maybe works, Maybe hallucinates
Human does not get coffee, they have to watch the AI progress and steer it.

The AI is the one reading the docs, but the developer is still doing work.

MCP scenario

Human: “List all users from in a Modal”

That’s it. Human goes to get coffee.

AI checks connected MCP servers
AI asks: “Do I have a tool for this?”
Finds a structured tool like list_users exposed by that service’s MCP server

That tool defines:

  • What it does
  • What inputs it needs
  • How auth works (handled server-side)

AI calls the tool through the MCP client
MCP server executes the call safely
Structured user data comes back
AI keeps going with real data

AI: “Modal with Users is ready for your review”

Human Browsing Web

Human says, “I want to get Users for the [service]”
Human opens Chrome and goes to https://%5Bservice%5D.com
Human click “Users” on the page.
They read list of Users on the page and spams them (or whatever else humans like to do these days.)

You don’t manually open a socket and craft packets. Your browser speaks a standard protocol and every website that follows it “just works.”

MCP is trying to be that layer, but for AI using software tools instead of humans using web pages. The key part is the contract. The AI is not inventing how to call your system. It is using a capability your system formally exposed over a shared protocol.

The time has come. You must adapt to LLM/AI/Agentic based development.

2025 marks a turning point in software development. Incorporating AI or some variation of Large Language Models (LLMs) into development workflows is no longer optional—it’s a competitive necessity. This shift isn’t about following trends; it’s about pragmatic productivity and maintaining a competitive edge.

It isn’t the AI, it is you

Even if the technology stop progressing from this point in time it would still necessitate adoption. Modern AI-powered tools have evolved far beyond simple code suggestions. They now understand context, manage complex refactoring tasks, and can handle entire development workflows from your project’s code base, to its Dev Ops configs, to its integrated terminal CLI commands. You can see a screenshot below of Windsurf’s Agent deploy a Terraform instance (it created) while checking to see if its previous deploy of K8 pods were complete! Agentic IDEs, combining sophisticated code assistance with terminal access, have redefined what’s possible with software development.

I was surprised to hear a few close developer friends tell me how they aren’t comfortable with how the AI “gets in the way” of their development. That made sense a year ago, but we are far past that being a valid excuse. It is tantamount to saying I don’t like looking up issues or solutions on Github, Google, or Stack Overflow because I like to just work it out problems myself. Which is more like saying, “I like reinventing the wheel with painfully slow speed”.

At this point it is no longer a question of whether the quality of the AI workflow fits your patterns, but that you are falling behind on skills your craft requires of you to develop quality code and infrastructure efficiently.

As this panel in Windsurf’s VS Code demonstrates, not only have my files and code been improved but it suggested and executed subsequent deployment plans and ran checks to see if the steps it took were running. Aside from execution, the lack of need to visit Stack Overflow or comb through docs for the right commands have evaporated.

Your Hesitation Is Costing Time and Money

Not adopting LLMs in your development process carries significant costs:

  1. Efficiency Gap: AI-assisted teams can identify and fix issues in minutes, while others might spend hours debugging.
  2. Market Disadvantage: Companies embracing AI-assisted development ship features faster, with fewer bugs, and at lower costs.
  3. Resource Misallocation: Every hour spent on routine tasks is time not invested in innovation.

The question isn’t whether to adopt AI development tools, but how quickly you can integrate them. Every day spent working “the old way” accumulates technical debt in development velocity. The future of software development is here, and it’s AI-assisted.