Here’s a workflow I keep seeing. Someone has a database full of rankings data. They point an LLM at it with a schema file and ask “what changed week over week?” The model reads the tables, compares the numbers, and spits out a summary.

This works. For a while.

Then the model gets updated and the output format shifts. Or it hallucinates a trend that isn’t there. Or you can’t reproduce last week’s analysis because the model was feeling different that day. Or you’re paying per-token for what amounts to arithmetic.

The right way to do this: have AI help you write the SQL query once. Run that query every week, forever. It gives you the same structured output every time. Then hand those final numbers to an LLM and say “explain what happened here.” The model does the one part that actually requires language ability. Everything else is code.

The division looks obvious on paper. Plenty of workflows still send every step through a model.

LLMs everywhere, for no good reason

The rankings example is one instance of a pattern that’s everywhere right now. People are building multi-step workflows where every single step is an LLM call. Summarize the input. Classify the results. Compare two datasets. Format the output. Generate a report. Five steps, five model calls, five chances to introduce variance.

Here’s the math on that. If each LLM step is 95% reliable (generous, honestly), five steps compounds to about 77% reliability. Ten steps gets you to 60%. That’s a coin flip with extra steps. And you’re paying for every one of those flips.

The compounding problem gets worse as models change. I wrote about the “pragmatism” rebrand a few weeks ago, and one thing I didn’t get into is what model updates do to workflows that depend on specific model behavior. Every time a provider ships a new version or adjusts weights, your carefully tuned pipeline can drift quietly. Output formats change slightly. Classification thresholds move. The summary that used to be three paragraphs is now five. Your downstream steps, also LLM calls, now have different inputs than they were tuned for.

The whole chain is only as reliable as its least stable step, and every step is a model call. This is fragile by design.

Meanwhile, most of these steps are doing things that code handles perfectly. String matching. Date comparison. Arithmetic. Filtering rows. Sorting by a column. Formatting output into a template. These are solved problems. A Python script does them the same way every time, runs in milliseconds, costs nothing, and won’t change behavior because someone at OpenAI tweaked a hyperparameter.

Why people build this way

Coding ability explains only part of it. A lot of the people building these LLM-heavy workflows are perfectly capable of using AI to write code. I can’t really code either, and I build tools all the time with AI assistance.

Proximity to software changes how you see these tasks. If you’ve spent time around codebases, around databases, around the kinds of problems that developers solve daily, you develop an instinct for what can be deterministic. You hear “compare two weeks of data” and your brain says “that’s a query.” You hear “find the rows where this value dropped more than 10%” and your brain says “that’s a WHERE clause.”

Those same tasks can sound like reasoning when you have less exposure to software. “Compare these two datasets and tell me what changed” feels like it requires understanding. Underneath the language, the operation is subtraction.

And then there’s the path of least resistance. Typing “tell me what changed this week” into a chat window is easier than writing a query. It just is. The overhead of figuring out the right approach, writing the code, testing it, making sure it works. That’s effort. Asking the LLM to just do it all? That’s a sentence.

Convenience this week can create maintenance work every week after it. The sentence you type today might produce a different format next time. Code gives the workflow one defined behavior until someone deliberately changes it.

The tooling doesn’t help. n8n, Make, Zapier, LangChain - they all push you toward “just add another AI node.” That’s their business model. Every integration they build makes it easier to chain another model call into your workflow and harder to drop down to actual code. The path of least resistance runs straight through the LLM.

Where LLMs belong

So where should you actually use a model? The boundary becomes clear when you ask one question: does this task require judgment about language?

Explaining what a set of numbers means to a human. Writing a narrative summary that adapts tone for the audience. Interpreting ambiguous user input where the intent isn’t clear from the text alone. Drafting something that needs to sound like a person wrote it. These are language tasks. Models are good at them.

Math, comparison, filtering, transformation, formatting, deduplication, schema validation, and rule-based routing all have deterministic solutions. Put them in code.

The test I use: could a Python script do this if I gave it the right inputs? If yes, it should be a Python script. Use the LLM to help you write that script, then let the script own the task.

The taste question comes back here. AI made building easy. Building the right way still requires understanding the job. Knowing that “compare two datasets” belongs in code and “explain the business consequence” belongs in a language model is a judgment call. That judgment stays with the person designing the workflow.

Build the durable pattern

A durable workflow uses AI to write code, runs that code for the deterministic work, and hands the LLM only the part that requires language ability.

For the rankings workflow, that looks like:

  1. A SQL query pulls the week-over-week changes. It runs in milliseconds and returns the same calculation every time.
  2. The query writes the results to JSON, CSV, or whatever clean format the downstream process needs.
  3. The LLM reads the numbers and writes the narrative: “Rankings for [keyword cluster] dropped 12% this week, concentrated in informational intent pages. Commercial pages held steady.” Language ability earns its keep in that interpretation.

One model call replaces five. A model update can change the wording of the summary while the SQL and data format keep running the same way. Wording is cheap to adjust.

This takes more work up front. You have to decide what the query should return, get the code right, and test it. You do that work once. The all-LLM approach makes you do it every time because you’re re-prompting the same tasks and hoping for consistent output.

And this pattern scales. Every workflow where people are chaining LLM calls can be decomposed the same way. Figure out which steps are actually language tasks. Write code for everything else. You’ll end up with fewer model calls, lower costs, faster execution, and a pipeline that doesn’t drift when Anthropic ships a new version of Claude.

Build software instincts

Most people draw the line between “needs a model” and “can be code” way too far toward the model because they have limited exposure to what code can do. The tools reinforce that instinct by putting another AI node one click away.

Get close enough to software to learn what deterministic tools can do. Databases compare things. Scripts filter and format. Code does math without hallucinating.

I am still technical-adjacent, and the useful skill for me is recognizing when I’m reaching for a language model to do something a for loop handles. Build that instinct, and your workflows have a much better chance of holding up.