Yak Technologies
← Engineering
Tam Nguyen2 min read

Deterministic first, AI second

How we architect agentic systems so the reliable parts stay reliable and the model only touches what genuinely needs judgment.

AgentsArchitecture

Most "AI systems" fail in production for a boring reason: they hand the model work that plain code should have done. The model is non-deterministic, so the whole system becomes non-deterministic — and non-deterministic systems are hard to trust with real money and real operations.

Our default is the opposite. Deterministic first, AI second. Code owns everything that can be specified. The model is reserved for the small set of decisions that actually require judgment.

The dividing line

When we design an agentic workflow, we sort every step into one of two buckets:

A reconciliation pipeline is a good example. Matching a payment to an invoice by ID is mechanical. Deciding whether a $312.40 short-pay is a contractual adjustment or an error is ambiguous.

The goal isn't to use AI everywhere. It's to use AI only where deterministic software would be worse.

What this looks like in code

The transaction logic runs as ordinary, testable functions. The model is called through a narrow interface, and only when a case falls through the deterministic path:

function reconcile(payment: Payment, invoices: Invoice[]) {
  const exact = invoices.find((i) => i.id === payment.ref && i.total === payment.amount);
  if (exact) return { status: "matched", invoice: exact }; // mechanical — no model

  const candidates = shortlist(payment, invoices); // mechanical — cheap filter
  if (candidates.length === 0) return { status: "unmatched" };

  // ambiguous — hand just this decision to the model, with structure
  return investigate(payment, candidates);
}

The model never sees the whole system. It sees one decision, with the relevant context, and returns a structured result the surrounding code can verify.

Why it holds up

Property Deterministic core Model at the edges
Reproducible Yes No — so we constrain it
Testable Unit tests Golden cases + verification
Auditable Fully Decision + rationale logged
Cost ~0 Only on ambiguous cases

Because the model runs on a fraction of the volume, the system is cheaper, faster, and far easier to reason about when something goes wrong. When a number looks off, you can trace it — the deterministic path is a straight line, and the model's touches are logged with their inputs and rationale.

The takeaway

Reliability isn't the thing you add after the demo. It's the architecture. Put the model where it earns its keep, and let boring, correct code do everything else.

All engineering posts