Quick Start

This guide will help you get started with AgentSociety 2.

Prerequisites

Before running examples, configure LLM environment variables (see Installation), or prepare a .env file in the project directory and load it early at the entry point.

Your First Agent

Create a simple agent with AgentSociety and interact with it. Note that agents are now declared as specs (metadata); the orchestrator creates workspaces in batches during init. They are no longer instantiated directly with PersonAgent(...) (see Using Agents).

import asyncio
from datetime import datetime
from agentsociety2.env import CodeGenRouter
from agentsociety2.contrib.env import SimpleSocialSpace
from agentsociety2.society import AgentSociety

async def main():
    # 1) 声明 agent 元数据(id / profile / config),不实例化 agent 对象
    agent_specs = [
        {
            "id": 1,
            "profile": {
                "name": "Alice",
                "age": 28,
                "personality": "friendly and curious",
                "bio": "A software engineer who loves hiking.",
            },
            "config": {},
        }
    ]
    names = [(s["id"], s["profile"]["name"]) for s in agent_specs]

    # 2) 创建环境模块 + 路由器(进程内 CodeGenRouter 即可;生产环境用 EnvRouterProxy)
    social_env = SimpleSocialSpace(agent_id_name_pairs=names)
    env_router = CodeGenRouter(env_modules=[social_env])

    # 3) 创建 society(agent_specs + agent_class_name + env_router)
    society = AgentSociety(
        agent_specs=agent_specs,
        agent_class_name="PersonAgent",
        env_router=env_router,
        start_t=datetime.now(),
        run_dir=__import__("pathlib").Path("run"),
    )

    # 4) 初始化(批量创建 agent workspace、绑定环境)
    await society.init()

    # 5) 只读查询
    response = await society.ask("What's your favorite activity?")
    print(f"Agent: {response}")

    await society.close()

if __name__ == "__main__":
    asyncio.run(main())

Running this code will produce output similar to:

Agent: I really love hiking! Being in nature, exploring new trails, and enjoying beautiful scenery brings a sense of peace.
It's a great way to relax and stay energized.

Creating Custom Environments

Environment modules allow agents to interact with specific functionality:

import asyncio
from datetime import datetime
from pathlib import Path

from agentsociety2.env import EnvBase, tool, CodeGenRouter
from agentsociety2.society import AgentSociety

class MyEnvironment(EnvBase):
    """A custom environment module."""

    @tool(readonly=True, kind="observe")
    def get_weather(self, agent_id: int) -> str:
        """Get current weather."""
        return "The weather is sunny, temperature 25°C."

    @tool(readonly=False)
    def set_mood(self, agent_id: int, mood: str) -> str:
        """Change agent's mood."""
        return f"Agent {agent_id}'s mood is now {mood}."

async def main():
    agent_specs = [{"id": 1, "profile": {"name": "Bob"}, "config": {}}]
    env_router = CodeGenRouter(env_modules=[MyEnvironment()])
    society = AgentSociety(
        agent_specs=agent_specs,
        agent_class_name="PersonAgent",
        env_router=env_router,
        start_t=datetime.now(),
        run_dir=Path("run"),
    )
    await society.init()
    response = await society.ask("What's the weather like?")
    print(response)
    await society.close()

if __name__ == "__main__":
    asyncio.run(main())

Running Experiments with CLI

AgentSociety 2 provides a powerful CLI for running experiments.

Foreground Execution (Debug):

python -m agentsociety2.society.cli \
    --config my_experiment/init/init_config.json \
    --steps my_experiment/init/steps.yaml \
    --run-dir my_experiment/run \
    --log-level DEBUG

Background Execution (Production):

python -m agentsociety2.society.cli \
    --config my_experiment/init/init_config.json \
    --steps my_experiment/init/steps.yaml \
    --run-dir my_experiment/run \
    --log-level INFO \
    --log-file my_experiment/run/output.log &

Important: When running in background, you must specify the --log-file parameter.

See Command Line Interface for more details.

Running Experiments (Code)

Here’s a complete example of a multi-agent experiment using AgentSociety 2:

import asyncio
from datetime import datetime
from pathlib import Path
from agentsociety2.env import CodeGenRouter
from agentsociety2.contrib.env import SimpleSocialSpace
from agentsociety2.society import AgentSociety

async def main():
    # 1) 声明 agent 元数据
    agent_specs = [
        {"id": i, "profile": {"name": f"Player{i}", "personality": "competitive"}, "config": {}}
        for i in range(1, 4)
    ]
    names = [(s["id"], s["profile"]["name"]) for s in agent_specs]

    # 2) 环境路由器(replay 默认开启,写入 run_dir/replay/)
    env_router = CodeGenRouter(env_modules=[SimpleSocialSpace(agent_id_name_pairs=names)])

    # 3) 创建并初始化 society
    society = AgentSociety(
        agent_specs=agent_specs,
        agent_class_name="PersonAgent",
        env_router=env_router,
        start_t=datetime.now(),
        run_dir=Path("run"),
    )
    await society.init()

    # 4) 逐个询问(低频外部查询,在主进程内按需 from_workspace 重建目标 agent)
    for spec in agent_specs:
        response = await society.ask(
            f"Tell {spec['profile']['name']} to introduce themselves to the group!"
        )
        print(f"{spec['profile']['name']}: {response}")

    await society.close()

if __name__ == "__main__":
    asyncio.run(main())

Note

ReplayWriter now records environment-side replay datasets only. PersonAgent local state, threads, and tool logs live under run/agents/agent_xxxx/, not in SQLite agent_status / agent_profile tables.

Next Steps

Now that you have the basics, you can continue exploring:

Common Patterns

Read-only Queries

For queries that don’t modify state, use society.ask():

# society.ask() ensures read-only access
response = await society.ask("What agents are in the simulation?")

Making Modifications

For operations that modify the environment, use society.intervene():

# society.intervene() allows environment modifications
result = await society.intervene("Make everyone feel better")

Querying Specific Agents

Ask a specific agent:

# Ask a specific agent
response = await society.ask(
    "Alice, what are your thoughts on the current situation?"
)