Society Module

This module provides the core orchestrator and auxiliary tools for the simulation.

AgentSociety

class agentsociety2.society.AgentSociety(agent_specs, agent_class_name, env_router, start_t, run_dir=None, *, service_proxy=None, batch_size=None, enable_replay=True, env_module_types=None, env_kwargs=None)[source]

Bases: object

Record-based simulation orchestrator that does not hold agent objects.

AgentSociety is the core class of the framework and is responsible for managing the simulation life cycle:

  • Holds agent_specs (metadata: {"id","profile","config"}) and agent_ids, and never keeps resident agent objects in the main process.

  • On every tick, step splits agents into batches and submits step_agent_batch Ray Tasks for parallel execution across workers. Agents within a batch run sequentially; each agent is LLM-bound, so this is acceptable.

  • ask / intervene / run_questionnaire / dump are low-frequency external queries. They rebuild the target agent in the main process with from_workspace on demand; the workspace is on local disk.

Example:

from datetime import datetime
from pathlib import Path
from agentsociety2.society import AgentSociety

society = AgentSociety(
    agent_specs=[{"id":1,"profile":{...},"config":{...}}, ...],
    agent_class_name="PersonAgent",
    env_router=env_proxy,
    service_proxy=proxy,
    start_t=datetime.now(),
    run_dir=Path("./run"),
)

async with society:
    await society.run(num_steps=100, tick=3600)
__init__(agent_specs, agent_class_name, env_router, start_t, run_dir=None, *, service_proxy=None, batch_size=None, enable_replay=True, env_module_types=None, env_kwargs=None)[source]

Create a record-based simulation orchestrator.

Parameters:
  • agent_specs (list[dict]) – Agent metadata list. Each item has the form {"id": int, "profile": dict, "config": dict}. This is metadata only; agents are not instantiated during construction.

  • agent_class_name (str) – Agent class name resolved through the registry, such as "PersonAgent".

  • env_router (RouterBase) – Environment router, either in-process or EnvRouterProxy.

  • start_t (datetime) – Simulation start time.

  • run_dir (Optional[Path]) – Run directory; run_dir/agents is the root for agent workspaces.

  • service_proxy (Optional['ServiceProxy']) – Shared service handles (env / llm / trace / replay). Required for streaming tasks: runner tasks use it to access LLM clients and the env actor. When provided, init() reuses it directly; close closes its trace / replay actor.

  • batch_size (Optional[int]) – 每 step_agent_batch Ray Task 处理的 agent 数; None 时回落到 Config.BATCH_SIZE``(环境变量 ``AGENTSOCIETY_BATCH_SIZE,缺省 256)。

  • enable_replay (bool) – Whether to enable playback recording.

property current_time: datetime

Returns the current simulation time.

property step_count: int

Returns the number of executed simulation steps.

property agent_ids: list[int]

Return all agent ids without exposing agent objects.

property agent_specs: list[dict]

Return agent specs as a metadata snapshot.

async init()[source]

Initialize: Ray / LLM dispatcher -> service_proxy -> replay -> batched workspace creation -> env init.

async close()[source]

Close: env router, trace / replay actors in service_proxy, and the LLM dispatcher.

async to_workspace(*, tick=None)[source]

持久化 society + env 状态(每步调用,无状态 resume)。

让 env router 落盘各模块状态,并写 run_dir/SOCIETY_STEP.json``(仅少量 标量:当前时间 / 步数 / 已完成前置步数 / terminated)。不可变的大字段 (agent_specs 等)只在 :meth:`init` 写一次到 ``SOCIETY.json,避免每步 重序列化。run_dir 为空时 no-op;env 落盘失败只告警,不中断 step。

Parameters:

tick (int | None) – 保留以兼容旧调用签名(不再单独持久化)。

mark_step_completed(step_idx)[source]

标记第 step_idx 个顶层 step 已完成并立即持久化进度。

由 CLI 在每个顶层 step(含 Ask/Intervene/Questionnaire)成功后调用—— 否则连续的非 RunStep 完成后若崩溃,resume 会把它们当作未执行而重跑。

async classmethod from_workspace(run_dir, *, env_router, service_proxy=None)[source]

run_dir 重建 society(resume)。

SOCIETY.json``(不可变:agent specs、env 模块类型+kwargs)+ ``SOCIETY_STEP.json``(每步标量:当前时间、步数、已完成前置步数)。 ``env_router 必须由调用方(CLI)预先构造(actor 不可在此重建); env 模块状态由 actor 在自身 init() 中恢复。

返回的 society 的 init() 会跳过 agent workspace 创建与 profile 重写 (原 run 已存在),也不会覆盖已有的 SOCIETY.json

Raises:
async step(tick)[source]

Advance one simulation step: sync clock -> batch into step_agent_batch -> env.step -> advance clock.

Parameters:

tick (int) – Time span of this step (seconds).

async run(num_steps, tick)[source]

Run multi-step simulations.

Parameters:
  • num_steps (int) – The upper limit of running steps.

  • tick (int) – Time span per step (seconds).

async ask(question)[source]

Ask questions to the simulation system (helper coordinates agents/env to answer).

Parameters:

question (str) – Question text.

Returns:

Answer text.

Return type:

str

async intervene(instruction)[source]

Intervene in the simulation (coordinated by a helper).

Parameters:

instruction (str) – Intervention instruction text.

Returns:

Execution results/feedback text.

Return type:

str

async run_questionnaire(questionnaire, target_agent_ids=None)[source]

Send questionnaires to target agents and return structured results.

Target agents are batched by id, and each batch submits one questionnaire_agent_batch Ray Task, using the same distributed batch processing pattern as step. Inside the worker process, from_workspace rebuilds the batch of agents, runs the full questionnaire concurrently, persists with to_workspace, and returns structured results. A failed individual agent is isolated and does not interrupt the whole batch, matching the fault-tolerance semantics of step_agent_batch.

Parameters:
  • questionnaire (Questionnaire) – Questionnaire definition.

  • target_agent_ids (list[int] | None) – Target agent ids; defaults to all.

Returns:

Aggregated questionnaire responses.

Return type:

QuestionnaireResponse

AgentSocietyHelper

class agentsociety2.society.helper.AgentSocietyHelper(env_router, society, max_steps=8, max_replans=2, max_llm_call_retry=10)[source]

Bases: object

Plan-and-Execute helper that answers external questions or executes interventions by first creating a plan, then executing steps, with support for dynamic replanning.

__init__(env_router, society, max_steps=8, max_replans=2, max_llm_call_retry=10)[source]

Create a plan-and-execute helper bound to a record-based society.

The helper holds the AgentSociety handle and reconstructs target agents on demand via society._reconstruct_agent / society._reconstruct_agents (low-volume external queries; workspaces are on local disk). Filter-by-profile over the full population works on the society’s specs (no reconstruction) when the profile field is directly readable from the spec.

Parameters:
  • env_router (RouterBase) – Environment router (in-process or EnvRouterProxy).

  • society (AgentSociety) – The record-based AgentSociety (holds specs/ids + reconstruction callbacks). Required.

  • max_steps (int) – Max plan steps per ask/intervene.

  • max_replans (int) – Max replan attempts on failure.

  • max_llm_call_retry (int) – Max LLM retries per planning/summary call.

async ask(question)[source]
async intervene(instruction)[source]

PlanStep

class agentsociety2.society.helper.PlanStep(*, description, tool, args, expected_output)[source]

A single step in the execution plan.

description: str

Clear description of what this step does.

tool: str

The name of the tool to use.

args: Dict[str, Any]

Arguments to pass to the tool.

expected_output: str

What information or result this step should produce.

model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].