Pick path optimisation is a routing problem, not a language problem — so before reaching for an "AI agent," it's worth being precise about what actually needs solving. The sequencing math (which aisle order minimises travel distance) is a classic combinatorial optimisation problem that deterministic algorithms handle well and LLMs handle badly. The place an agent genuinely earns its keep is one layer up: reasoning about exceptions, re-prioritising on the fly, and orchestrating the optimiser rather than replacing it.
Picking strategies, briefly
Three picking models cover most warehouse operations, and they set the context for where optimisation applies. Discrete (single-order) picking sends one picker after one order, simple but travel-heavy. Batch picking groups several orders into one pick run so a picker collects multiple SKUs for multiple orders in a single pass, cutting travel at the cost of a sortation step afterward. Zone picking assigns pickers to fixed areas of the warehouse and passes totes between zones (or picks in parallel and consolidates). Wave picking is an orchestration layer on top of any of these — releasing batches of orders together, usually timed to a shipping cutoff or carrier pickup.
In Acumatica's Warehouse Management edition, pick lists are generated from Shipments and can be configured for wave, batch, or zone strategies depending on warehouse setup. None of that configuration involves an LLM — it's rules and thresholds. The optimisation question that's left over, for any of these strategies, is: given a set of pick locations, what order minimises travel time?
Why routing is an algorithm problem, not a prompting problem
Sequencing N pick locations to minimise travel distance is a variant of the travelling salesman problem. It has known, cheap, well-understood solutions: for single-block layouts, an S-shape (serpentine) heuristic that walks each aisle in a snake pattern beats naive nearest-neighbour in most cases; nearest-neighbour with a 2-opt local-search pass gets close to optimal for irregular layouts; for multi-block or multi-zone layouts, dynamic programming over aisle-crossing points works well at the scale of a typical pick list (10-40 lines).
An LLM asked to sequence twenty bin locations will produce a plausible-looking ordering that is not verified against actual distances, has no guarantee of even being a valid permutation of the input, and cannot be trusted to beat a five-line heuristic. This isn't a prompting problem that better instructions fix — arithmetic and combinatorial search are outside what a language model is built to do reliably. If a pick-path feature description mentions "the AI figures out the optimal route," that's the tell to ask what deterministic algorithm sits underneath it, because something has to.
def nearest_neighbour_route(start, stops, distance):
route = [start]
remaining = set(stops)
current = start
while remaining:
nxt = min(remaining, key=lambda s: distance(current, s))
route.append(nxt)
remaining.remove(nxt)
current = nxt
return route
def two_opt(route, distance):
improved = True
while improved:
improved = False
for i in range(1, len(route) - 2):
for j in range(i + 1, len(route) - 1):
a, b, c, d = route[i-1], route[i], route[j], route[j+1]
if distance(a, c) + distance(b, d) < distance(a, b) + distance(c, d):
route[i:j+1] = reversed(route[i:j+1])
improved = True
return route
# route = two_opt(nearest_neighbour_route(dock, pick_locations, warehouse_distance), warehouse_distance)
That's the whole "optimiser." It runs in milliseconds for a pick list of realistic size and produces a route that's easy to explain to a warehouse supervisor: it's just distances.
Where an agent actually helps
The optimiser above assumes a static problem: fixed stops, fixed distances, solve once. Real warehouses are not static — a picker hits a stockout mid-route, an aisle is blocked by a forklift, a rush order lands after the wave already released, a second picker in the same zone creates congestion. This is where a lightweight agent layer is worth building, not because it computes better routes, but because it decides when to recompute and what changed.
Concretely: an agent watching pick-confirmation events and location-status signals can detect a stockout the moment a picker scans "not found," pull the next-best bin from cycle-count data, splice it into the remaining route, and re-run the same 2-opt pass on the shortened stop list — instead of leaving the picker to walk back and ask a supervisor. It can re-rank an in-flight wave when a rush shipment lands, deciding whether to interrupt the current pick run or queue the order for the next wave, based on cutoff times and picker load. None of that is arithmetic the LLM is doing — the distance calculation still goes to the same deterministic function. What the agent contributes is judgment about exceptions and timing that would otherwise be hardcoded rules or a person on the radio.
A workable split: the optimiser owns "given these stops, what's the shortest path" and stays a pure function you can unit test. The agent owns "which stops are still valid, has anything changed, should this wave interrupt that one" — and calls the optimiser again when the answer is yes.
A natural-language layer on top
The other place an agent fits is the interface, not the algorithm. Pickers and supervisors asking "why is bin A-14-3 not in today's route" or "show me every pick list touching zone B that's behind schedule" is a query-answering problem over structured pick data — well suited to an LLM with read access to the pick list and location tables, badly suited to writing a new report screen for every question someone thinks of. Acumatica's generic inquiry and reporting screens already cover the fixed questions; an agent with tool access to the same data covers the ad hoc ones, and it should have no write access to route sequencing at all — it explains the route, it doesn't set it.
If an LLM-backed assistant has a tool that lets it directly reorder pick lines, you've reintroduced the exact failure mode you were avoiding — an unverified permutation replacing a distance-checked one. Keep the write path to "flag for re-optimisation" and let the deterministic pass own the actual ordering.
Measuring whether it helped
Before adding any agent layer, get a baseline from the deterministic optimiser alone: average travel distance per pick list, picks per hour, and how often a route goes stale mid-pick (stockout, blocked aisle, priority interrupt). The agent layer is only worth the added complexity if it measurably reduces the second number — how often a picker is stuck with a route that's now wrong — or reduces the time-to-resolution when it happens. If your warehouse rarely has mid-route exceptions, the payoff is small and a simpler "flag and notify a supervisor" rule may cover it without any agent at all.
| Layer | Owns | Right tool |
|---|---|---|
| Pick sequencing | Given N stops, shortest order | S-shape / nearest-neighbour + 2-opt |
| Wave/batch/zone rules | How orders group into pick runs | Configuration in the WMS, not AI |
| Exception handling | Stockouts, blocked locations, congestion | Agent that re-triggers the optimiser |
| Priority re-ranking | Rush orders vs. in-flight waves | Agent reasoning over cutoffs and load |
| Ad hoc queries | "Why," "show me," "what's behind" | Agent with read-only tool access |
The pattern that holds up: keep the routing math boring, deterministic, and testable, and spend the "AI" budget on the parts of the problem that are actually about judgment under changing conditions — not on asking a language model to do arithmetic it was never good at.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.