# Your LLM Is Not Deterministic

Run the same report twice and the second result may reorder sections, rename a heading, or round a number differently. Add more instructions and the prompt starts looking like a brittle program written in prose. We don't want that.

This is usually the point where you should write an actual program (remember the times when you used to write programs manually? Good, old times, huh?).

# Move the Deterministic Boundary

Instead of sending raw data to an LLM and asking for the final artifact:

```plaintext
data -> LLM -> report.out
```

make the model produce structured input for a deterministic tool:

```plaintext
data -> LLM -> input.data -> generate-report.sh -> report.out
```

The LLM still handles the ambiguous work: understanding the request, collecting information, preparing the input, choosing the tool, and recovering from failures.

The script owns validation, calculations, ordering, and formatting.

```plaintext
./scripts/generate-report.sh input.data > reports/report.out
```

One script with a documented input format and useful exit codes is often enough. It can be tested, versioned, and run by developers, CI, or an agent.

See? Everyone is using the same tool. Outcome is always the same.

# Let the LLM Build the Missing Tool

If the script doesn't exist, ask LLM to create it once instead of asking it to regenerate the report every time. A larger workflow can expose the same commands through a Makefile:

```plaintext
validate:
    ./scripts/validate-input.sh ${INPUT}

report: validate
    ./scripts/generate-report ${INPUT} > reports/report.out
```

Now everyone uses the same interface:

```plaintext
make report INPUT=input.data
```

There's no separate AI workflow to maintain.

Deterministic code still needs discipline. Pin tool versions, and timezone. Sort collections explicitly. Pass timestamps in as input instead of the current clock. Otherwise, the nondeterminism merely moves into the script.

Use the LLM where ambiguity is unavoidable. Use code where repeatability matters. If your prompt keeps growing to control exact output, stop refining it and give the model a tool instead.

Cheers!
