Architecture Overview
EconSimulacra is built around four primary abstractions:
Simulator,
Environment,
Agent, and
Event.
┌─────────────────────────────────────────────────────────┐
│ Simulator │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Environment │ │
│ │ ┌─────────┐ ┌────────────────┐ ┌───────────┐ │ │
│ │ │GridSpace│ │ SocialNetwork │ │ Items │ │ │
│ │ └─────────┘ └────────────────┘ └───────────┘ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Agents │ │ │
│ │ │ (Household / Retailer / LLMAgent / …) │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ EventManager │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Simulation Loop
The Simulator drives the following loop (simplified):
env.reset(seed=seed)
for step in range(num_steps):
obs_per_agent = {id: env.get_observations(id) for id in env.agent_ids}
actions = {id: await agent.act(obs_per_agent[id]) for ...}
env.step(actions)
Concurrency is achieved by batching agent act calls with
asyncio.gather(), enabling multiple LLM inference requests to proceed
in parallel while the environment step itself remains synchronous.
Spatial Layer — GridSpace
Agents occupy a cell \((x, y) \in \{0,\ldots,W-1\} \times \{0,\ldots,H-1\}\) of a discrete 2-D grid. At each step an agent can move to an adjacent cell or stay in place.
Market Layer — Items and Orders
Each tradable good is represented by an Item
that carries a current price \(p_t\). An Order
is a bilateral trade request:
where \(q\) is the quantity and \(p\) is the agreed price. Orders expire after a configurable time-to-live (TTL).
Agent Layer
Agent is an abstract base class. All concrete
agents must implement:
async def act(self, obs: ObsT) -> dict[str, Any]: ...
The built-in LLMAgent delegates action
generation to a language model via the following services:
LLMClient — wraps the underlying model and manages inference.
PromptBuilder — constructs the text prompt from the agent’s observation.
PersonaBuilder — assigns a role-playing persona at reset time.
MemoryHandler — stores past experiences and retrieves relevant context.
Event Layer
Event subclasses implement exogenous shocks or
policy interventions. An EventTrigger
specifies when the event fires using four independent conditions that are
combined with logical AND:
at— specific step indices.every— periodic cadence \(k\).between— a step-range guard.with— reaction to a particular log type.probability— probabilistic gate \(p\).
Logging
Every state change is recorded as a typed Log
dataclass (e.g., OrderLog,
ConsumptionLog). A
Logger collects these records and persists them
at the end of the simulation.
Social Layer — SocialNetwork
The social network is a directed graph \(G = (V, E)\) where each vertex \(v \in V\) corresponds to an agent and each directed edge \((u, v) \in E\) indicates that agent \(u\) follows agent \(v\).
Each agent is subject to an optional follow cap \(c\): the out-degree of every vertex is bounded by \(c\).
A
RecommenderSystemcan suggest new edges at each step. The built-inTwoHopRecommenderSystemconsiders the two-hop neighbourhood of each agent and scores candidates using a softmax over edge weights:where \(w_{uv}\) is a relevance score and \(\tau > 0\) is the temperature parameter.