← Back to list

How I Stopped Arguing with LLMs and Built a Zero-Hallucination Engineering Loop

If you use Large Language Models (LLMs) to write code for anything more complex than a basic CRUD API or a standard Tailwind button, you…

Li Derek · 2026-05-21 11:16 · 0 claps · 4.4 min read
#ai-coding #ai-agents-in-action #software-architecture
Open on Medium ↗
Wiki topics: LLM · Large Language Models AGT · AI Agents SAF · Safety & Alignment 💻 · Programming 🌐 · Web Development 🏛️ · Architecture

How I Stopped Arguing with LLMs and Built a Zero-Hallucination Engineering Loop

If you use Large Language Models (LLMs) to write code for anything more complex than a basic CRUD API or a standard Tailwind button, you have probably hit the context wall.

It usually starts smoothly. You open a fresh chat session, paste a snippet of your codebase, and the AI confidently pumps out exactly what you need. But as the business logic deepens — especially in a zero-tolerance environment like financial engineering — the cracks begin to show.

You try to explain a multi-layered constraint that you established days ago. The AI misunderstands. You correct it. It over-corrects, breaking an edge case it fixed twenty minutes ago. As the chat history grows, the session slows to a painful crawl. Eventually, you face a brutal choice: sit and wait ten minutes for the AI to process its own bloated history, or open a fresh session and spend an hour explaining your entire architectural universe all over again.

For a long time, I thought this “AI tax” was an inescapable reality of working with text-prediction engines. LLMs are naturally stateless; they don’t have episodic memory. They are probabilistic, meaning they guess what code should look like based on open-source patterns, which makes them inherently dangerous when dealing with highly specific, non-standard business rules.

But after months of fighting this bottleneck in a complex, double-entry financial system, I realized I was doing the heavy lifting that my code was already doing for me. By restructuring how my frontend and backend sessions talk to each other, and weaponizing my production defenses, I turned a forgetful chatbot into a high-speed, zero-hallucination compiler.

Here is the blueprint of how to build an AI-first engineering loop that actually works.

Phase 1: Decoupling the AI Layers (The Shared Contract)

My first major realization was that I was giving the AI too much to look at. When building a user interface, I would routinely feed the frontend AI my messy backend database history, transactional logic, and long text notes. The result was severe context dilution. The frontend AI would start hallucinating UI state management rules based on backend database constraints.

The frontend AI doesn’t need to know why a backend rule exists; it just needs to know the exact shape of the data it is allowed to interact with.

To solve this, I completely decoupled the layers using an automated pipeline. We already have a local script that reads the backend’s OpenAPI specs to automatically generate our frontend API layer. This means that whenever a new endpoint or schema update is ready on the backend, the exact JavaScript functions and strict TypeScript definitions are compiled into our frontend codebase with 100% mathematical precision — completely bypassing the AI.

By automating this data contract, the frontend AI suddenly had the easiest job on earth. When I open a fresh, blazing-fast frontend session to build a new feature, I don’t write a single line of manual explanation. I just tell it where to look:

“Build a responsive table component for the new /invoices view. Read our auto-generated API files, use the api.getInvoices() function, and wire it directly into the UI components.”

Because TypeScript types are strictly bounded, they carry an immense amount of implicit semantic context — or what I like to call “salt” — right inside the code files. When the frontend AI reads an auto-generated union type like status: 'pending' | 'cleared' | 'frozen', its pre-trained dataset instantly implies the business logic (e.g., disable buttons on frozen states, show loading indicators on pending states).

Instead of debating logic, the frontend AI plays LEGO games. It snaps UI components straight to deterministic, typed functions, completely shielded from the backend noise.

Phase 2: Weaponizing Defensive Code as the Ultimate AI Memory

The real breakthrough, however, happened on the backend.

Financial systems are easy to make syntactically correct, but incredibly difficult to make structurally honest. We use an immutable double-entry ledger linked to explicit causal IDs (like invoice hashes) to make sure money never “grows” out of nowhere. To enforce this, I wrote a suite of automated operational monitors that run daily as cronjobs.

For a long time, I treated these monitors purely as a production safety net. When debugging a discrepancy, my workflow was highly manual: I would feed the AI the core functional processor code, explain what we wanted to change, pull up documentation, and spend hours answering the AI’s confused questions.

Then it clicked: Every single piece of exhausting, back-and-forth business logic explanation was already baked directly into my monitors.

The actual production processor code is filled with procedural noise — database queries, error catching, and complex routing logic. An LLM gets completely bogged down in the how and loses sight of the what.

A monitor, by contrast, strips away the noise and isolates pure truth. It focuses entirely on declarative state audits: Based on the invoices we have, and the claims we imported, are these exact sub-accounts holding the right money for subsidies and tax?

I realized that these monitors are the ultimate, token-efficient knowledge graph of my system. They provide high-density negative context — a concentrated list of boundaries, assertions, and catastrophic states that the AI is mathematically forbidden to cross.

The New Workflow: An AI-First Architecture

Now, when a backend chat session inevitably slows down due to context bloat, I kill it without remorse. I open a fresh, instant-response session, drop in the specific file I want to change, and attach the relevant automated monitor cronjobs.

The onboarding prompt is entirely hands-off:

“We are starting a fresh session to modify our invoice parsing logic. I have attached the active Open Invoice Monitor. This file contains the strict mathematical and business-logic invariants of our financial universe. Parse these steps first, and ensure your new code never causes this monitor to fail.”

Instead of acting as a manual translator debating human language with a machine, I let the data do the talking. The AI reads the monitor’s assertions and instantly absorbs a 360-degree mental model of the system’s limits. It shifts the AI’s behavior from guessing generic patterns on GitHub to writing highly constrained, defensive code that respects my specific database reality.

Stop Writing Docs, Start Writing Observers

We have been told that the secret to working with AI is writing better, longer documentation files. But text files degrade, become obsolete, and confuse semantic search models.

The secret to scaling complex logic with LLMs is separating state from generation. By enforcing strict, auto-generated TypeScript contracts on the frontend, and feeding live, declarative audit monitors into the backend, you effectively build a deterministic cage around a probabilistic engine.

You stop teaching the AI how to build things in abstract human prose. You give it the mathematical definition of perfection, and tell it to fill in the blanks.


메타데이터
post_id
3bb5d1276d82
slug
how-i-stopped-arguing-with-llms-and-built-a-zero-hallucination-engineering-loop-3bb5d1276d82
url
https://medium.com/@dereksangshi2000/how-i-stopped-arguing-with-llms-and-built-a-zero-hallucination-engineering-loop-3bb5d1276d82
canonical_url
https://medium.com/@dereksangshi2000/how-i-stopped-arguing-with-llms-and-built-a-zero-hallucination-engineering-loop-3bb5d1276d82
author_url
https://medium.com/@dereksangshi2000
status
ok
fetched_at
2026-06-09 15:37:30