agent_urban_planning.HybridDecisionEngine¶
- class HybridDecisionEngine(params, elicitor=None, *, llm_client=None, **kwargs)[source]¶
Bases:
objectLLM-elicited preferences + closed-form mixed-logit choice (V4).
The hybrid pattern: an LLM is queried once per agent cluster to elicit the cluster’s per-agent preference weights (β: housing share; κ: commute disutility). The closed-form mixed-logit choice then computes discrete zone selection deterministically. This pattern keeps the LLM in the role of parameter provider rather than decision maker — much cheaper than the full-LLM V5 approach while still capturing demographic-driven preference heterogeneity.
- Parameters:
params (
Any) – AnAhlfeldtParamsinstance carrying structural elasticities (alpha,beta,epsilon,kappa_eps).llm_client (
Any) – Anagent_urban_planning.llm.LLMClientinstance (or anything with a.complete(user, system="")method returning a string).**kwargs (
Any) – Forwarded to the underlyingAhlfeldtArgmaxHybridEngine. Common kwargs:cluster_k(default 50),clustering_algo(default"kmeans"),num_agents,batch_size,seed,llm_concurrency,cache_dir.elicitor (Any)
- Raises:
ValueError – If
llm_clientis None.
Examples
V4 reproduction with codex-cli:
>>> import agent_urban_planning as aup >>> engine = aup.HybridDecisionEngine( ... params=scenario.ahlfeldt_params, ... llm_client=aup.llm.CodexCliClient(), ... cluster_k=50, ... num_agents=1_000_000, ... seed=42, ... ) >>> # sim = aup.SimulationEngine(scenario, agent_config, engine=engine) >>> # results = sim.run()
V4 with claude-code (alternate provider):
>>> engine = aup.HybridDecisionEngine( ... params=scenario.ahlfeldt_params, ... llm_client=aup.llm.ClaudeCodeClient(), ... )
See also
agent_urban_planning.UtilityEngine— closed-form V1/V2/V3 baselines (no LLM involvement).agent_urban_planning.LLMDecisionEngine— V5 full-LLM-as- decision-maker pattern.- decide_batch(*args, **kwargs)[source]¶
Forward to the underlying implementation’s
decide_batch.Transparently forwards to
AhlfeldtArgmaxHybridEngine.decide_batch(). Calling this triggers (and caches) LLM elicitation of per-type preference weights on the first invocation; subsequent calls reuse the cached weights.- Parameters:
- Return type:
- Returns:
List of
agent_urban_planning.LocationChoice, one per input agent and in the same order.
Examples
>>> import agent_urban_planning as aup >>> # engine = aup.HybridDecisionEngine(params, elicitor=elicitor) >>> # choices = engine.decide_batch(agents, env, zones, prices)