Next phase. Simulator + LLM

Today in short

  • The MILP, greedy, blind, partial and full-information experiments are done. Next is simulator + LLM.
  • The loop is simple. The simulator lists the possible actions, the LLM picks one, the simulator applies it and updates the mine, and the cycle repeats. All the rules (capacity, slopes, grades) are handled by the simulator, so the LLM only sees what it’s allowed to do.
  • On a 1,000-block mine, describing the whole mine to the LLM is impossible, so only blind and partial will be run with the LLM at large scale.
  • Speed is the main problem. At the current rate one large run would take about 2.5 to 3 hours. The work now is cutting the number of calls and the time per call.
  • First step is a baseline. The current LLM setup runs on the six 27-block mines my MILP results came from, in full, blind and partial.
  • One open question matters most. With only the action list, the LLM can’t tell one extraction from another, so it needs some extra information on each action.

How the loop works

simulator → list of possible actions → LLM picks one → simulator applies it → updated mine → ...

The simulator gives an answer instantly, so almost all of the run time is the LLM. Sending only the available actions, with no rules or full mine description, keeps the prompt short and focused on the choice that actually has to be made. On a 10 × 10 × 10 mine that’s the only option anyway, since the full mine state would not fit. That’s also why the full-information case is left to the MILP.

Fixes to make before running

  1. The “actions only” design isn’t in the code yet. The no-context and partial-context notebooks are still identical to the original, and all three send the full mine state in every prompt.
  2. The full mine state wouldn’t fit anyway. On a 27-block mine the first prompt was already about 956 tokens. At 1,000 blocks the state alone would be far beyond the 8,192-token context limit, and the model would silently lose part of the prompt.
  3. With actions only, every extraction looks the same. An extraction action only carries its mining cost, not the block’s grade, so all extractions show the same number. In blind mode the LLM would effectively be choosing at random. In partial mode the shaft estimates would never reach it. The fix is to add a few facts to each action, such as the estimated grade, how uncertain that estimate is, the layer, and how many blocks it would unlock.
  4. Use the same visibility rules as the MILP runs. The LLM code currently uses a different drilling model from the one in my MILP experiments. It has to use the same shafts and the same “surface plus what’s been revealed” rule, or the comparison isn’t fair.
  5. Blind can get stuck. On the waste-cover and two-pockets mines with no minimum, blind MILP scored 0 because nothing visible looked worth mining. The LLM will face the same trap, so I need to decide up front whether to keep a minimum mining rule that forces it to dig.

Speed. What the earlier run shows

From the saved 27-block LLM run:

  • 58 actions at 11.4 seconds per call on average, 11 minutes in total, finishing 1.7% below greedy.
  • Call time follows how long the model “thinks”. A short reasoning took 3.5 s, and a long one took 22.4 s.

The 1,000-block runs need about 835 to 924 actions. At 11.4 s each that’s 2.5 to 3 hours per run, against 70 to 90 seconds for the rolling MILP on the same mine. A full sweep would take well over 150 GPU hours.

Design choices to settle

Choice Faster option What it costs Evidence
Who picks the amount The simulator always takes the largest allowed amount, and the LLM only picks which action The LLM can’t choose partial amounts The LLM wasted calls on tiny amounts, such as 1 t. Greedy always takes the maximum.
Processing after extraction The simulator processes ore straight after it’s mined The LLM no longer decides when ore is processed Almost every extraction in the log was immediately followed by processing the same block, so this should roughly halve the calls
How much the model thinks Low reasoning effort Possibly weaker choices Thinking length drives call time. A quick probe on the first decision can test this before the full sweep.
Memory of past steps None, since the simulator already holds the state Less continuity between steps (a one-line “your plan” note can restore it) Remembering 3 past steps grew the prompt from about 956 to about 3,000 tokens
Answer format A fixed format that only allows a valid action number Might change how the model reasons, so check with the probe 3 of 58 replies were invalid (about 5%). At 900 steps that’s about 45 retries of around 11 s each.
Facts on each action Estimated grade, uncertainty, layer, blocks unlocked A few more words per action Without them, blind and partial have nothing to rank extractions by
Serving the model A server that handles many requests at once, running several mines in parallel More setup than the current tool The current setup answers one request at a time, so the GPU sits idle between calls

Other things worth doing

  • Show the LLM only the top few actions. The simulator can rank the possible actions and send the best 5 to 20, with simple facts on each. A one-step look-ahead from the simulator, such as how many blocks an action unlocks, gives the LLM something greedy doesn’t consider.
  • Make runs repeatable. Use a fixed random seed and no randomness in the model’s answers.
  • Fall back safely. If the LLM returns an invalid action, the simulator rejects it and uses the greedy choice instead. How often that happens is a result worth reporting.
  • Keep the comparison fair. The LLM must see exactly what MILP and greedy saw at the same information level. In particular, partial runs must not leak true grades through the action facts.
  • Check where any gain comes from. Also run greedy and a random pick on the same short list. If the LLM only matches those, the gain came from the simulator’s ranking, not the LLM.

The main risk

An LLM choosing one action at a time only sees the present, much like greedy. If it does nothing more, it may end up equal to greedy but much slower. The look-ahead facts on each action, or letting the LLM set a strategy for each period while a fast rule picks the blocks, are the most likely ways for it to beat greedy.

First step. A baseline on the small mines

Before touching the large mines, the LLM is run on the same small mines my MILP results came from. That gives a fair starting point, with the current LLM setup exactly as it is.

  • Six 27-block mines (3 × 3 × 3) from my earlier configs: 3D decoy, 3D central pipe, 3D blend lower limit, 3D central cone, 3D waste cover and dipping orebody.
  • Each in full, blind and partial, so 18 LLM runs. Here the mine is small enough that the full-information case fits in the prompt.
  • Same mines, same shaft, same drilling noise and cost as the MILP runs. As a check, greedy reproduces my earlier spreadsheet numbers exactly on all six, so the instances match.
  • Prompts are about 500 tokens, well within the model’s limit.
  • At about 11 seconds per call, each run takes roughly 10 to 30 minutes, so a few hours for all 18. Each result is printed next to my existing MILP and greedy numbers for the same mine.

Then the first large test

Once the baseline is in, try one large mine and one setting before any sweep.

  • Settings. The simulator picks the amount, processing happens automatically, the LLM returns only an action number, low reasoning effort, no step memory, a fixed answer format, and grade estimates on each action.
  • Mine. Opposite gradient, no minimum, in both blind and partial.
  • What would count as success. Landing between greedy (509,329) and the rolling blind MILP (672,628), at a few minutes per run. If it does, scale up to the full set of mines.

What to report for each run

NPV gap to the MILP, total run time, number of LLM calls, words (tokens) used per decision, and how often the LLM gave an invalid answer. All of these for both blind and partial.

Next

  • Run the 18-run baseline on the 27-block mines and compare with the MILP and greedy results.
  • Fix the prompt so it sends only the available actions, with the extra facts on each.
  • Switch the LLM code to the same shaft and visibility rules as the MILP runs.
  • Decide on the minimum mining rule for blind.
  • Run the first test on the opposite-gradient mine.