Alexey Shurov.Insights
Architecture

Put a Rules Engine Next to Your LLM Before You Regret Not Doing It

Deterministic logic and language model judgment are not rivals. Knowing which one owns each decision is the whole game in production AI.

13 July 2026 . 7 min read . Alexey Shurov
Put a Rules Engine Next to Your LLM Before You Regret Not Doing It

The Mistake I See Most Often in Enterprise AI Builds

Teams hand the LLM a pricing policy document and ask it to apply the rules. The model reads the document, reasons over it, and produces an answer that is correct about eighty percent of the time. Leadership sees the demo, approves the build, and six months later someone finds a contract that was underpriced by eleven percent across four hundred line items because the model interpreted a volume tier boundary differently than the policy intended.

That is not a model failure in the dramatic sense. The model did something reasonable. The failure is architectural. You asked a probabilistic system to be a compliance system, and it behaved like a probabilistic system.

The fix is not to find a better model. The fix is to stop asking the model to do the thing a rules engine does better.

What Determinism Is Actually Good For

A rules engine does one thing perfectly. Given the same inputs, it produces the same output every single time, and you can audit exactly why. That property is not optional in certain parts of enterprise operations. It is the entire point.

In distribution, minimum margin floors are not suggestions. A customer discount cannot legally exceed a contractual cap. A hazardous materials surcharge either applies or it does not, based on a classification code. These are not judgment calls. They are lookups and comparisons, and a language model has no business making them from scratch on every request.

In manufacturing finance, a standard cost variance that crosses a threshold triggers a specific approval workflow. Always. The threshold is in the policy. The workflow is in the system. There is nothing to interpret. If you let a model decide whether the threshold was crossed, you have introduced variance into a process that was designed to have none.

In field operations, a technician cannot be dispatched to a site without a valid certification for the equipment type on that work order. That is a hard constraint. It does not flex based on context or urgency. A rules engine checks it in milliseconds and blocks the dispatch or passes it. A model might reason its way to an exception that the organization never intended to allow.

What Judgment Is Actually Good For

Now here is where language models earn their place. The moment a decision requires reading unstructured input, weighing competing factors, or generating a response that a human will read and act on, the rules engine runs out of road.

A freight distribution company I worked with had a pricing agent that needed to handle spot quote requests arriving by email. The request might say the shipment is urgent, or mention that the customer is moving a new product line, or note that the pickup window is tight because of a plant shutdown. None of that fits neatly into a rules table. A rules engine cannot read the email and decide whether the urgency claim warrants a capacity surcharge or whether the new product line context should be flagged for the account team.

A language model can do all of that. It can extract the relevant signals, assess the situation, draft a response, and recommend a course of action. What it should not do is compute the final price. That number comes from the rules engine, which applies the margin floor, the fuel surcharge schedule, the lane-specific rate card, and the customer tier discount in strict order.

The model handles the judgment. The rules engine handles the arithmetic that has to be right.

How the Two Work Together in a Pricing or Validation Pipeline

The architecture I use most often in production looks like this. The language model sits at the intake and at the output. The rules engine sits in the middle.

  1. The model reads the incoming request, extracts structured parameters, and flags anything ambiguous for human review.
  2. The rules engine receives those parameters and applies every deterministic constraint in sequence, producing a validated output with a full audit trail.
  3. The model takes the validated output and generates the customer-facing response, the internal summary, or the recommendation memo.

In a manufacturing context, this pattern handles purchase order validation well. The model reads the PO, which might be a PDF or an email or a structured EDI file with errors, and normalizes it into a clean set of fields. The rules engine then checks every field against the approved supplier list, the part number catalog, the price tolerance bands, and the delivery lead time commitments. If something fails a check, the rules engine flags it with a specific reason code. The model then drafts the exception notice to the supplier or the buyer, using the reason code as its source of truth rather than reasoning about the underlying policy from scratch.

This separation matters for a reason that goes beyond accuracy. When something goes wrong, and something always eventually goes wrong, you need to know whether the failure was in the extraction step, the rule application step, or the response generation step. If the model is doing all three, you cannot isolate the failure. If they are separated, you can.

Where Teams Get the Boundary Wrong

The most common mistake is letting the model validate its own outputs against policy. I have seen this framed as the model checking its work, which sounds reasonable until you realize that the model is applying the same probabilistic reasoning to the check that it applied to the original answer. You have not added a constraint. You have added another roll of the same dice.

The second mistake is building the rules engine after the model is already in production. At that point, the model has been handling the deterministic checks informally, the team has tuned prompts around its behavior, and introducing a hard constraint layer breaks things in ways that are annoying to untangle. Build the rules engine first, or at least in parallel. Treat it as infrastructure, not as a patch.

The third mistake is over-specifying the rules engine to handle cases that genuinely require judgment. I have seen rules tables with hundreds of conditional branches trying to capture every possible customer situation. That is the wrong tool for that job. If the logic requires reading context and weighing factors, that is what the model is for. The rules engine should be narrow, fast, and non-negotiable. The model should be broad, contextual, and always subject to the rules engine's final word on anything that has a hard constraint attached to it.

A Field Operations Example Worth Sitting With

A utility sector client had a field service scheduling agent. The model was good at reading work order notes, understanding what the job actually required, and suggesting which technician was the best fit based on skills, location, and current workload. That judgment layer added real value. Dispatchers trusted it.

But the model was also making certification checks. It would read the technician profile, see that the person had relevant experience, and recommend the dispatch. Sometimes the formal certification had lapsed. The model did not catch this consistently because it was reasoning from the profile text rather than querying a live certification record and applying a binary pass or fail.

We moved the certification check into a rules engine that queried the HR system directly. The model still made the judgment call about fit. The rules engine made the compliance call about eligibility. Dispatchers stopped getting callbacks from the field about technicians who could not legally perform the work.

The manual work removed was not just the dispatcher's time. It was the rework, the reschedule, the customer call, and the compliance documentation that followed every bad dispatch. That is the real cost of putting probabilistic logic where deterministic logic belongs.

The Practical Takeaway

Before you build your next AI agent, take your decision flow and mark every node with one of two labels. The first label is non-negotiable, meaning the answer is always the same given the same inputs and there is a policy, a contract, or a regulation that defines it. The second label is judgment, meaning the answer depends on context, unstructured input, or tradeoffs that require weighing.

Every non-negotiable node belongs in a rules engine. Every judgment node is a candidate for a language model. The model feeds the rules engine. The rules engine constrains the model. Neither one operates alone on decisions that touch the other's domain.

If you cannot label every node in your flow, you are not ready to build. That labeling exercise is the design work. Do it on a whiteboard before you write a single line of code, and your production system will be easier to debug, easier to audit, and harder to break in the ways that actually cost money.

Common questions

Can a well-prompted LLM just apply the rules itself without a separate rules engine

It can approximate rule application, and for low-stakes decisions that approximation might be acceptable. For anything with a compliance requirement, a financial consequence, or an audit trail obligation, approximation is not good enough. The model will be correct most of the time, which means it will be wrong some of the time, and you will not always know which is which. A rules engine is correct every time for the cases it covers, and it tells you exactly why.

How do you handle rules that change frequently, like fuel surcharge schedules or tax rates

You update the rules engine, not the model. This is one of the clearest advantages of the separation. When a rate table changes, you change the table. You do not retrain, reprompt, or re-evaluate the model. The model does not know the rates and does not need to. It knows how to read a request and what to do with a validated output. The rules engine knows the rates.

What happens when a request falls outside the rules engine's coverage

The rules engine should return an explicit exception rather than a best-guess answer. The model can then handle that exception by routing it to a human, requesting more information, or applying a conservative default that the rules engine does recognize. The worst outcome is a rules engine that silently passes an out-of-scope case as if it were validated. Build your exception handling before you build your happy path.

Is this architecture only relevant at large enterprise scale

No. I have used this pattern on relatively small deployments where the team had maybe two hundred rules and a modest request volume. The value is not about scale, it is about auditability and reliability. The moment you have a hard constraint that cannot be wrong, you need deterministic enforcement of that constraint. That is true whether you are processing fifty quotes a day or fifty thousand.

Want this in your operation

I build and run production AI agents that take repetitive work off operational teams. Tell me what your team spends too long on.

Tool guides

Choosing software for this problem space, see the guides on bottleneck detection tools and AI analytics tools for mid-size companies.

More insightsshurco.ai