Metadata-Version: 2.4
Name: agentsociety2
Version: 2.1.1
Summary: A modern, LLM-native agent simulation platform for social science research
Project-URL: Homepage, https://github.com/tsinghua-fib-lab/agentsociety
Project-URL: Documentation, https://agentsociety2.readthedocs.io/
Project-URL: Repository, https://github.com/tsinghua-fib-lab/agentsociety.git
Project-URL: Issues, https://github.com/tsinghua-fib-lab/agentsociety/issues
Project-URL: Changelog, https://github.com/tsinghua-fib-lab/agentsociety/blob/main/CHANGELOG.md
Author-email: Jun Zhang <zhangjun990222@gmail.com>, Boyuan Sun <sunboyuan0124@gmail.com>, Haoyu Huang <2253940186@qq.com>, Keming Zhang <kemingzhang@bupt.edu.cn>, Yuxin Liu <aph.xin@gmail.com>
Maintainer-email: Jun Zhang <zhangjun990222@gmail.com>, Boyuan Sun <sunboyuan0124@gmail.com>, Haoyu Huang <2253940186@qq.com>, Keming Zhang <kemingzhang@bupt.edu.cn>, Yuxin Liu <aph.xin@gmail.com>
License: Apache-2.0
License-File: LICENSE
Keywords: agents,artificial-intelligence,experiment,llm,multi-agent,reinforcement-learning,simulation,social-science
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: aiohttp>=3.10.11
Requires-Dist: aiosqlite>=0.20.0
Requires-Dist: black>=25.12.0
Requires-Dist: chromadb>=1.5.5
Requires-Dist: click>=8.0.0
Requires-Dist: dill>=0.4.0
Requires-Dist: doclayout-yolo>=0.0.4
Requires-Dist: elemental-xenon>=1.1.0
Requires-Dist: faiss-cpu>=1.7.0
Requires-Dist: fastapi>=0.128.0
Requires-Dist: fastmcp>=2.12.2
Requires-Dist: ftfy>=6.3.1
Requires-Dist: geojson>=3.1.0
Requires-Dist: greenlet>=3.0.0
Requires-Dist: json-repair>=0.46.2
Requires-Dist: litellm>=1.82.0
Requires-Dist: mcp[cli]>=1.13.1
Requires-Dist: mem0ai>=1.0.5
Requires-Dist: mineru[core]>=1.0.0
Requires-Dist: numpy<2.0.0,>=1.20.0
Requires-Dist: pandas>=2.0.0
Requires-Dist: prompt-toolkit>=3.0.51
Requires-Dist: pycityproto>=2.4.5
Requires-Dist: pyclipper>=1.4.0
Requires-Dist: pydantic>=2.10.4
Requires-Dist: pyproj>=3.6.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: pyyaml>=6.0.2
Requires-Dist: qdrant-client>=1.7.0
Requires-Dist: ruamel-yaml>=0.18.15
Requires-Dist: shapely>=2.0.6
Requires-Dist: sqlmodel>=0.0.16
Requires-Dist: stringcase>=1.2.0
Requires-Dist: sweetviz>=2.3.0
Requires-Dist: torch>=2.9.1
Requires-Dist: transformers>=4.57.3
Requires-Dist: ultralytics>=8.3.243
Requires-Dist: uvicorn>=0.35.0
Requires-Dist: ydata-profiling>=4.6.0
Provides-Extra: all
Requires-Dist: furo>=2024.8.6; extra == 'all'
Requires-Dist: mypy>=1.14.0; extra == 'all'
Requires-Dist: myst-parser>=4.0.0; extra == 'all'
Requires-Dist: pre-commit>=3.8.0; extra == 'all'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'all'
Requires-Dist: pytest-cov>=5.0.0; extra == 'all'
Requires-Dist: pytest>=9.0.2; extra == 'all'
Requires-Dist: ruff>=0.11.13; extra == 'all'
Requires-Dist: sphinx-autobuild>=2024.9.19; extra == 'all'
Requires-Dist: sphinx-autodoc2>=0.5.0; extra == 'all'
Requires-Dist: sphinx-intl==2.1.0; extra == 'all'
Requires-Dist: sphinx>=7.0.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: mypy>=1.14.0; extra == 'dev'
Requires-Dist: pre-commit>=3.8.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
Requires-Dist: pytest>=9.0.2; extra == 'dev'
Requires-Dist: ruff>=0.11.13; extra == 'dev'
Provides-Extra: docs
Requires-Dist: furo>=2024.8.6; extra == 'docs'
Requires-Dist: myst-parser>=4.0.0; extra == 'docs'
Requires-Dist: sphinx-autobuild>=2024.9.19; extra == 'docs'
Requires-Dist: sphinx-autodoc2>=0.5.0; extra == 'docs'
Requires-Dist: sphinx-intl==2.1.0; extra == 'docs'
Requires-Dist: sphinx>=7.0.0; extra == 'docs'
Description-Content-Type: text/markdown

# AgentSociety 2

[![PyPI Version](https://img.shields.io/pypi/v/agentsociety2.svg)](https://pypi.org/project/agentsociety2/)
[![Python Version](https://img.shields.io/pypi/pyversions/agentsociety2.svg)](https://pypi.org/project/agentsociety2/)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
[![Documentation](https://img.shields.io/badge/docs-latest-brightgreen.svg)](https://agentsociety2.readthedocs.io/)
[![中文文档](https://img.shields.io/badge/docs-%E4%B8%AD%E6%96%87-red.svg)](https://agentsociety2.readthedocs.io/zh_CN/latest/)

> **AgentSociety 2** is a modern, LLM-native agent simulation platform designed for social science research and experimentation.

## Features

- **LLM-Native Design**: Built from the ground up for LLM-driven agents
- **Flexible Environment System**: Modular environment components with hot-pluggable tools
- **Multiple Reasoning Patterns**: ReAct, Plan-Execute, Code Generation, and Two-Tier routers
- **Developer-Friendly**: Pythonic API with type hints and comprehensive documentation
- **Experiment Replay**: Full SQLite-based replay system for analysis and debugging
- **MCP Support**: Model Context Protocol integration for tool extensibility

## Installation

```bash
pip install agentsociety2
```

### Requirements

- Python >= 3.11
- An LLM API key (OpenAI, Anthropic, or any provider supported by litellm)

## Quick Start

### Create Your First Agent

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

async def main():
    # Create an agent with a profile
    agent = PersonAgent(
        id=1,
        profile={
            "name": "Alice",
            "age": 28,
            "personality": "friendly and curious",
            "bio": "A software engineer who loves hiking and reading."
        }
    )

    # Create environment module with agent info
    social_env = SimpleSocialSpace(
        agent_id_name_pairs=[(agent.id, agent.name)]
    )

    # Create environment router
    env_router = CodeGenRouter(env_modules=[social_env])

    # Create the society
    society = AgentSociety(
        agents=[agent],
        env_router=env_router,
        start_t=datetime.now(),
    )

    # Initialize (sets up agents with environment)
    await society.init()

    # Query (read-only)
    response = await society.ask("What's your favorite activity?")
    print(f"Agent: {response}")

    # Close the society
    await society.close()

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

### Create a Custom Environment Module

```python
from agentsociety2.env import EnvBase, tool

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

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

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

# Use the custom module
from agentsociety2.env import ReActRouter

env = ReActRouter()
env.register_module(MyCustomEnvironment())
```

### Run a Complete Experiment

```python
import asyncio
from datetime import datetime
from agentsociety2 import PersonAgent
from agentsociety2.env import CodeGenRouter
from agentsociety2.contrib.env import SimpleSocialSpace
from agentsociety2.storage import ReplayWriter
from agentsociety2.society import AgentSociety

async def main():
    # Setup replay writer for experiment tracking
    writer = ReplayWriter("my_experiment.db")
    await writer.initialize()

    # Create agents first (needed for SimpleSocialSpace)
    agents = [
        PersonAgent(id=i, profile={"name": f"Player{i}", "personality": "friendly"})
        for i in range(1, 4)
    ]

    # Create environment router
    env_router = CodeGenRouter(
        env_modules=[SimpleSocialSpace(
            agent_id_name_pairs=[(a.id, a.name) for a in agents]
        )]
    )
    env_router.set_replay_writer(writer)

    # Create the society with replay enabled
    society = AgentSociety(
        agents=agents,
        env_router=env_router,
        start_t=datetime.now(),
        replay_writer=writer,
    )
    await society.init()

    # Query (read-only)
    answer = await society.ask("What are the names of all agents?")
    print(f"Answer: {answer}")

    # Intervene (read-write)
    result = await society.intervene("Set all agents' happiness to 0.8")
    print(f"Result: {result}")

    await society.close()

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

## Core Concepts

### Agents

Agents are autonomous entities that interact with environments through LLM-powered reasoning:

- **AgentBase**: Abstract base class for all agents
- **PersonAgent**: Ready-to-use person agent with memory and personality
- Agents support two interaction modes:
  - `ask(question, readonly=True)`: Query without side effects
  - `intervene(instruction)`: Make changes to the environment

### Environment Modules

Environment modules encapsulate specific functionality through tools:

- **EnvBase**: Base class for creating custom modules
- **@tool decorator**: Register methods as discoverable tools
- Tool kinds:
  - `observe`: Single-parameter observation functions
  - `statistics`: No-parameter aggregation functions
  - Regular tools: Full read/write operations

### Routers

Routers mediate agent-environment interactions using different reasoning patterns:

- **ReActRouter**: Reasoning + Acting loop
- **PlanExecuteRouter**: Plan-first, then execute
- **CodeGenRouter**: Code generation based tool use
- **TwoTierReActRouter**: Two-level reasoning hierarchy
- **TwoTierPlanExecuteRouter**: Two-level planning hierarchy

### Storage

The ReplayWriter system captures all interactions for analysis:

```python
from agentsociety2.storage import ReplayWriter

writer = ReplayWriter("experiment.db")
await writer.initialize()

# Framework tables (auto-created):
# - agent_profile: Agent profiles
# - agent_status: Agent status over time
# - agent_dialog: Agent LLM interactions

# Custom tables
from agentsociety2.storage import ColumnDef, TableSchema
schema = TableSchema(
    name="custom_metrics",
    columns=[
        ColumnDef(name="metric_id", dtype="INTEGER", primary_key=True),
        ColumnDef(name="value", dtype="REAL"),
    ]
)
writer.register_table(schema)
```

## Configuration

Set your LLM API credentials via environment variables:

**Required Configuration**

```bash
# Default LLM (required - used for most operations)
export AGENTSOCIETY_LLM_API_KEY="your-api-key"
export AGENTSOCIETY_LLM_API_BASE="https://api.openai.com/v1"
export AGENTSOCIETY_LLM_MODEL="gpt-4o-mini"
```

**Optional Configuration**

For specialized tasks, you can configure separate LLM instances:

```bash
# Code Generation LLM (for code-related tasks)
# Falls back to default LLM if not set
export AGENTSOCIETY_CODER_LLM_API_KEY="your-coder-api-key"
export AGENTSOCIETY_CODER_LLM_API_BASE="https://api.openai.com/v1"
export AGENTSOCIETY_CODER_LLM_MODEL="gpt-4o"

# Nano LLM (for high-frequency, low-latency operations)
# Falls back to default LLM if not set
export AGENTSOCIETY_NANO_LLM_API_KEY="your-nano-api-key"
export AGENTSOCIETY_NANO_LLM_API_BASE="https://api.openai.com/v1"
export AGENTSOCIETY_NANO_LLM_MODEL="gpt-4o-mini"

# Embedding Model (for text embeddings and semantic search)
# Falls back to default LLM if not set
export AGENTSOCIETY_EMBEDDING_API_KEY="your-embedding-api-key"
export AGENTSOCIETY_EMBEDDING_API_BASE="https://api.openai.com/v1"
export AGENTSOCIETY_EMBEDDING_MODEL="text-embedding-3-small"
export AGENTSOCIETY_EMBEDDING_DIMS="1536"

# Data directory (optional, default: ./agentsociety_data)
export AGENTSOCIETY_HOME_DIR="/path/to/your/data"
```

Or use a `.env` file:

```bash
cp .env.example .env
# Edit .env with your credentials
```

## Examples

The `examples/` directory contains ready-to-run examples:

- `basics/`: Basic agent and environment usage
- `games/`: Classic game theory simulations
  - Prisoner's Dilemma
  - Public Goods Game
  - Trust Game
  - Volunteer's Dilemma
  - Commons Tragedy
- `advanced/`: Advanced usage patterns
  - Custom environment modules
  - Multi-router setups
  - Experiment replay and analysis

## Documentation

- [English Documentation](https://agentsociety2.readthedocs.io/)
- [中文文档](https://agentsociety2.readthedocs.io/zh_CN/latest/)
- [API Reference](https://agentsociety2.readthedocs.io/en/latest/api.html)

## Development

For development and contribution guidelines, see [DEVELOPMENT.md](DEVELOPMENT.md).

### Contributing

We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

## Citation

If you use AgentSociety 2 in your research, please cite:

```bibtex
@software{agentsociety2,
  title = {AgentSociety 2: A Modern LLM-Native Agent Simulation Platform},
  author = {Zhang, Jun and others},
  year = {2025},
  url = {https://github.com/tsinghua-fib-lab/agentsociety}
}
```

## License

Apache License 2.0 - see [LICENSE](LICENSE) for details.

## Acknowledgments

AgentSociety 2 builds upon excellent open-source projects:

- [litellm](https://github.com/BerriAI/litellm) - Unified LLM API
- [mem0ai](https://github.com/mem0ai/mem0) - Memory management
- [FastAPI](https://fastapi.tiangolo.com/) - Backend API framework
- [Pydantic](https://docs.pydantic.dev/) - Data validation

## Contact

- **Issues**: [GitHub Issues](https://github.com/tsinghua-fib-lab/agentsociety/issues)
- **Discussions**: [GitHub Discussions](https://github.com/tsinghua-fib-lab/agentsociety/discussions)

---

For the original AgentSociety (v1.x) focused on city simulation, see the [agentsociety package](https://pypi.org/project/agentsociety/).
