Skip to content
BlogPublished 1 September 20265 min read

MySQL Development When the Model Needs Reliable Data

AI productsMySQL developmentagentic workflowsdata integrityRAG

The failure mode I see most often in AI product builds is not a bad prompt. It is a database that was never designed to be queried by a machine. The model returns confident answers built on stale joins, missing foreign keys, and columns that mean different things to different services. MySQL development, done with that constraint in mind from the start, is what separates an AI product that ships from one that stays in demo mode.

The schema is the contract, not the prompt

When I start an engagement, the first document I write is not a system prompt. It is an entity-relationship diagram with nullability rules and indexing decisions written out explicitly. The model will only ever be as precise as the data it reads. If a column can be null for historical reasons, the model has to be told that, or it will hallucinate a default. If two tables use the same field name for different concepts, every RAG retrieval that touches both tables will produce noise.

On the Fursa visa eligibility product, the core challenge was that route data came from multiple upstream sources with overlapping but inconsistent schemas. Before any prompt engineering happened, I normalised the destination table, enforced referential integrity on the route-to-requirement joins, and added a verified_at timestamp to every requirement row. The model was never allowed to read a row where verified_at was null. That single constraint, enforced at the query layer, removed an entire class of hallucination.

Structured outputs changed what the query layer has to do

Until recently, getting a model to write a well-formed SQL fragment or return a structured result meant wrestling with regex parsers and hoping the model stayed on format. That is gone now. JSON schemas enforced at the API level, and libraries like Instructor and Pydantic on the application side, mean the output either conforms or the call fails fast and retries. The query layer no longer has to do defensive parsing. It has to do something harder: validate semantic correctness, not just syntactic shape.

What that means in practice is that I write explicit validation logic between the model's output and the database write. The model returns a structured object. The application checks it against business rules. Only then does it hit the database. On OptimalTax, where the system automated tax return calculations for a public sector client, a wrong write was not a UX problem. It was a compliance failure. Every model-generated value was validated against the tax rule engine before any INSERT ran. The 99% calculation accuracy that product reached was not a prompt engineering achievement. It was a data integrity achievement.

Agentic workflows put new pressure on MySQL development

The shift from single-prompt calls to compound AI systems and multi-agent workflows has changed what the database has to absorb. A stateful agent running across multiple turns needs to persist its context somewhere. A workflow that fans out to three specialist agents and then reconciles their outputs needs a place to store intermediate state without race conditions.

I use MySQL for this differently than I use it for application data. Agent state tables are append-only. Reconciliation writes go through a transaction that locks the relevant rows. The workflow orchestrator, whether that is LangGraph or a custom state machine, never assumes the database is consistent mid-run. It checks.

The Job Hunter outreach engine crawled over 185 career pages daily and then ran matching and drafting agents across the results. The database had to hold crawl state, match scores, draft history, and outreach status for every candidate-job pair, without losing data when a crawl agent timed out mid-batch. The solution was a status column with a small finite set of valid transitions, enforced by a check constraint, not by application logic alone. If an agent crashed, the row stayed in its last valid state. The recovery agent picked up from there.

Prompt caching made deep RAG economically viable

For a long time, building a retrieval-augmented generation system on top of a large MySQL corpus was expensive. Every query re-sent the same system context and retrieved chunks to the model, and input token costs added up fast. Prompt caching from the major API providers has changed that calculation. Input token costs for long-context calls are down by as much as 90% for cached prefixes, which means it is now practical to keep a rich system context in cache and only vary the retrieval results per query.

The design implication for MySQL development is that retrieval queries have to be fast and deterministic enough to serve as the variable part of a cached prompt. I index aggressively on the columns used in retrieval filters. I use covering indexes where the query only needs a small set of columns. I avoid full-text search in MySQL for anything that needs ranking by semantic similarity, and instead keep a vector store in sync with the MySQL source of truth, writing to both in the same transaction where consistency matters.

Human approval gates are not optional

Every AI product I have built has at least one point where a human has to approve before the system acts on a model output. This is not a philosophical position. It is a product requirement that comes from the client in almost every engagement. The model is one component of a workflow. It is often the most capable component for a specific task, and it is also the component most likely to be confidently wrong in a way that is hard to detect.

The approval gate has a database representation. There is a table that holds pending actions, the model's output, the context it was given, and a status field. An operator reviews it. The status changes. The downstream action runs. That table is auditable. You can go back and see exactly what the model said, what context it had, and who approved it.

This is the pattern I used on ProPost AI, where the system generated LinkedIn content at scale, 365 drafts per user per year. No draft was published without a human review step. The approval queue was a MySQL table. The audit trail was a MySQL table. The model was fast. The human was the gate.

What the first conversation covers

If you are comparing partners for an AI product build, the question I would ask any of them is: what happens when the model is wrong and the database has already been written to? If they do not have a specific answer, the database was an afterthought.

My answer is a combination of append-only writes, explicit rollback paths, and approval gates before any irreversible action. The work on the case studies shows how that plays out across fintech, public sector, and AI product contexts.

If you are close to starting and want to talk through the architecture before you commit to a direction, the contact form is the right place to start. Bring the constraint that worries you most. That is usually where the real design work begins.

Want to talk about something here?

Let’s talk about it.

Start a conversation