Generative ABM · Pasture

About this demo

A generative agent-based model of a Mongolian pasture, built as an interview demo. The starting conditions are synthetic; the runs, decisions and metrics are produced by the simulation and, in LLM mode, by real model calls.

Research question

Do generative agents (LLM herders reasoning in natural language) allocate grazing differently from classical rule-based herders when both act on an identical landscape, identical weather series and an identical random seed?

The comparison is the point: same seed, same grid, same 26 or 52 weeks — only the decision layer changes. Headline outcomes are cumulative intake energy, the Gini coefficient of grazing pressure across cells, and final mean biomass.

Agent architecture

Decisions are layered. A herder household perceives its own zones, neighbours' messages, the weather bulletin and the market price, then assigns a target zone to each of its herds. Each herd is itself an agent: it picks a cell inside that zone and may stray one zone away, which is recorded as non-compliance.

Everything below that is mechanistic and has no LLM: vegetation regrowth, intake, body condition, deaths, water and degradation. Wildlife (a gazelle herd) and a grasshopper layer can each be run as rule or LLM, or switched off. Climate is scripted from the seed; an optional narrator turns the scripted weather into a weekly bulletin the herders read.

Decision flow

Climate (scripted)
Narrator (LLM, optional)
Herder household (LLM or rule)
bulletin
Herd (LLM or rule)
target zone
Vegetation & livestock (mechanistic)
chosen cell
Gazelles · grasshoppers (rule or LLM)
Metrics & snapshot
statestate

What is synthetic here, and what is not

The 32×32 grid, its zones, terrain and initial biomass, the three households and their personalities, the herd sizes and the weather series are generated from a seed. No field data, no remote sensing product and no household survey went into this build. What happens after week 0 is not synthetic: the decisions, movements, grazing, messages and metrics are computed by the engine and, in LLM mode, by live model calls, and every recorded run keeps the model name behind each decision.

The map is anchored near Bulgan, Mongolia only so the GIS view has plausible satellite imagery underneath. Nothing on it is a measurement.

Baseline check against Yoshihara et al. (2025)

The rule herders, and the way every herd picks its cell inside its zone, use the seven herder-controlled grazing rules of the Bulgan sheep ABM (Yoshihara, Horie, Miyasaka, Kono & Shinoda, Scientific Reports 15:35906, 2025). Bmax / Pmax / Nmax move to the neighbouring cell with the highest biomass / palatability / nutrition; Bprob / Pprob / Nprob draw it with probability proportional to that value; Random is uniform. The rule is a parameter, so the paper's baselines can be run one against another and against the LLM herders on the same seed and weather.

To check the implementation we re-ran the paper's own experiment through the same code path: 240 m cells in an 8×8 km outline, two families of 2005 and 1380 sheep units, 60 summer days of sixty 12-minute steps with 10 h of grazing, a morning start point drawn from the top 25 % cells 5–15 cells from the ger, a well every third day, no return to the previous cell, no two flocks in one cell, the paper's intake curve (160.77 ln biomass + 52.6 g/sheep/day), 25 % palatability weighting per rank, energy = intake × ME, and 10.65 kg/cell/day regrowth. The authors' per-cell data are not public, so the study area is synthesised to their published statistics: 976 cells, biomass 894 ± 176 kg/cell, palatability 3.69 ± 0.73, ME 2.34 ± 0.13, the Table 1 species shares and their west / north-east pattern.

RuleP25 ×1P25 ×2P25 ×0.5
ourspaperourspaperourspaper
Bmax115.5 ± 0.3109.2 ± 0.6111.1 ± 0.3106.6 ± 0.6117.2 ± 0.3110.3 ± 0.5
Pmax91.7 ± 2.696.5 ± 2.167.0 ± 1.780.1 ± 2.5113.6 ± 2.7109.5 ± 1.2
Nmax88.7 ± 1.690.7 ± 1.468.9 ± 1.679.2 ± 2.0106.0 ± 1.1101.1 ± 1.1
Bprob116.2 ± 0.5108.1 ± 0.6111.0 ± 0.5105.1 ± 0.7118.7 ± 0.5109.4 ± 0.7
Pprob118.9 ± 0.5109.0 ± 0.9109.4 ± 1.0103.0 ± 1.3122.4 ± 0.5111.1 ± 0.9
Nprob115.0 ± 0.6104.9 ± 1.0107.6 ± 0.9101.3 ± 1.3117.8 ± 0.6106.7 ± 1.1
Random115.8 ± 0.7105.1 ± 1.0109.2 ± 0.9100.7 ± 1.3118.6 ± 0.6106.7 ± 1.0
Total energy intake, Mcal per sheep over 60 days, mean ± SD over 30 repeats on a 956-cell synthetic study area; paper values from Table 2 (100 repeats, real field).

Reading: the collapse of Pmax and Nmax with stocking rate is reproduced (both keep returning to the same palatable or nutritious cells and strip them), the ranking at double stocking matches the paper (Bmax > Bprob > Pprob, Pmax and Nmax last) and absolute intake sits 5–10 % above the paper's. What does not reproduce is Bmax's 4 % edge over Random at normal stocking, which depends on the real field's spatial heterogeneity. With the authors' CSV, `pnpm benchmark -- --cells <file>` regenerates this table on the real landscape.

Extending the ecology: gazelles, grasshoppers, grazing losses

The Bulgan grazing paper names its own gaps: biomass lost to insects, trampling and fouling rather than to intake, and within-cell heterogeneity. Two of those are now agent slots here. The gazelle herd competes for the same grass and avoids livestock pressure. The grasshopper layer is one density index per zone: it grows where it is warm and dry and the grass is short and trampled, spreads a little into neighbouring zones, collapses in winter, and above 0.5 it is an outbreak that strips biomass fast. A grazing-loss coefficient removes extra biomass per unit eaten (trampling, fouling, dropped forage) without adding to intake.

Each of these is configurable: off, rule, or LLM (for the swarm the LLM only decides whether the core shifts to an adjacent zone; growth and damage stay mechanistic). Because every run shares the seed and weather series, switching a slot on shows its effect on the headline metrics directly: with default settings a normal year peaks around 0.4 and never breaks out, a drought year crosses 0.5 around week 10 and the pasture ends the season at a third of its baseline biomass. The growth constants are hand-tuned magnitudes, not calibrated values. The point is the mechanism for adding variables in a controlled way, not the realism of any one of them.

What a real study would swap in

Biomass would come from Sentinel-2 derived NDVI or a fitted biomass product rather than a logistic regrowth toy, resampled to roughly an 80 m grid instead of 250 m cells.

Herd movement would be fitted to GPS collar tracks, and herder decisions calibrated against household interviews and off-take records. Weather would be reanalysis plus station data, and dzud years taken from the historical record rather than a preset.

Providers

Agents are routed by how much reasoning they need. Herders (multi-step trade-offs, negotiation) go to Kimi (OpenAI-compatible, JSON mode, thinking always on, about 2–5 s per call, 5-hour usage quota). Herds, wildlife and the climate narrator go to a self-hosted Ollama qwen3:8b (thinking off, JSON format, 8 parallel slots, about 1 s per call). If one provider fails three times in a row its tier is rerouted to the other; if both fail the demo replays a recorded run. Roughly eleven agent calls run concurrently on a herder week: three herders, six herds, one wildlife agent and the climate narrator. By default herders re-plan every other week (the interval is a parameter), so a 26-week season costs about 39 Kimi calls instead of 78.

Every LLM call has a rule-based policy behind it. On timeout or malformed JSON the rule policy answers and the decision is tagged FALLBACK; if failures pile up, the app drops to replaying a recorded run so the demo never stalls.