# AgentSociety: Apache 2.0 with one folder carved out, a Python index pinned to a university mirror, and a Dockerfile that installs two AI CLIs

> AgentSociety is a framework for running large populations of model-driven agents in simulated environments, built at a university lab and used for social science experiments rather than games. Its second generation is a separate package from its first, which is still shipped and still documented. What the repository's own configuration files reveal is more interesting than the feature list: a licence carve-out, a package index nobody chose on purpose, and a container image whose whole purpose is to package an editor extension.

**tsinghua-fib-lab/AgentSociety** — AgentSociety 2 is a modern, LLM-native agent simulation platform designed for social science research and experimental design. It provides a flexible framework for creating and managing intelligent agents in simulated environments.

- Repository: https://github.com/tsinghua-fib-lab/AgentSociety
- Website: https://agentsociety2.fiblab.net
- Stars: 1,321 · Forks: 215
- Language: Python
- License: Apache-2.0
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/tsinghua-fib-lab-agentsociety

## Apache 2.0 except one folder

The licence section is one sentence and it contains an exception:

> AgentSociety is licensed under the Apache License Version 2.0 except for the `packages/agentsociety/commercial` folder.

The platform reports the repository as Apache 2.0, which is what an automated licence check sees, and the exception lives only in that sentence, pointing at a folder inside the legacy package. So there are two answers in the same repository and neither is wrong: the bulk of the code is under a permissive licence, and one directory is not. Nothing in the visible text says what licence applies to that directory instead, whether it is proprietary, whether it is simply a placeholder, or whether the exception is a leftover from a commercial offering that no longer exists. For anyone planning to build on this, or to fork it, that single folder is the thing to ask about in writing, and copying the repository without reading the licence file is how it gets missed.

## The Python index is a university mirror, set as the default

Open the packaging configuration and the first thing in it is an index:

```toml
[tool.uv]
index-url = "https://pypi.tuna.tsinghua.edu.cn/simple"
```

And a few lines later it is declared again as a named index and marked as the default, which means it is not merely available but preferred. The Node side does the same thing in the container build, where the registry is set to a Chinese mirror before any install runs. Neither of these is a mistake; they are the standard way to make a build fast and reliable inside one region. They are also, for anyone outside it, a single point through which every dependency of this project resolves by default, committed to a file that most readers will never open. The override is ordinary, and the fast path works fine, so this is not a reason to avoid the project. It is a reason to know it, because a mirror that is unreachable from your network presents as an install failure rather than as a configuration choice.

## The Dockerfile packages an editor extension and installs two AI CLIs

The container file is not packaging the framework. Read its own header, which is a hand written dependency graph explaining what invalidates what, and the first stage builds a VS Code extension into a packaged archive from the extension directory, installing the packaging tool globally first. The next stage installs global command line tools for two AI coding assistants from a Node image, and the comment beside it explains why: those installs are independent of the Python lockfile and the framework source, so they sit on a separate cache layer. Only after that does the final stage appear, with system packages, an environment manager, office document tooling, the locked Python dependencies, an editable install of the framework source, and the extension archive copied last. The image is therefore a development environment for coding with agents, packaged as a container. Worth knowing if you assumed the Dockerfile was how you run a simulation.

## Three configuration blocks, and each one silently falls back to the first

The environment example is the most informative file in the repository, and it is organised in commented blocks. The first block is required and holds a key, a base URL and a model name. The second block, for the model that writes code, is optional and the comment says that if it is unset it falls back to the default configuration. The third is for embeddings, also optional, also falling back to the default. That design is sensible, because most experiments need one model and the other two are refinements. The cost is that a configuration mistake is invisible. Set the coder block's base URL but leave its key empty and the request goes to the default host with a default key, or to a mismatch, and nothing in the log says which block was used. The example values all point at one vendor's compatible endpoint and one model name, which is a hint about what the defaults were tuned against rather than a stated requirement.

## A thinking toggle built around gateways that reject it

One optional switch deserves a section of its own, because the comments explain a failure mode you would otherwise have to discover. The switch controls whether a thinking parameter is sent at all. Leaving it empty sends nothing and the comment says the behaviour is then completely identical to the feature being off. The accepted values are two, with the older truthy spellings kept for compatibility. Two more settings follow: a reasoning effort value that is only sent when explicitly set, and a private gateway switch that takes a JSON object merged into the request body. Then the sentence that explains the whole design, which is that when the gateway switch is configured, turning thinking off sends only the body switch and deliberately does not send the effort setting, to avoid a gateway receiving both switches and erroring. That is a library author who has been on the receiving end of a gateway error and encoded the fix. It also means behaviour depends on which of two variables you set.

## Two generations, four packages, and one of them in the workspace

The repository ships two packages on the package index. The second generation is the recommended one, described as built from the ground up for model driven agents. The first generation is the original city simulation framework with a remote procedure call based environment integration, and it is still documented, still on the index, and still the subject of its own paper. Two more packages sit alongside: community contributions for custom agents and blocks, and benchmarking utilities. Now look at what the workspace configuration declares:

```toml
members = ["packages/agentsociety2"]
```

One member. So the lock file at the root covers only the current generation, and the other three directories are resolved or installed outside it. That is a reasonable choice for a repository mid migration, and it has a consequence worth naming: an install driven from the root gives you the recommended package and not the rest, so anyone following the quick start is not running the code the legacy documentation describes.

## Agents are stateless records and the runtime hides behind one proxy

The feature list states the execution model in a single sentence, and it is the sentence to read before designing an experiment. Agents are workspace bound stateless records driven by distributed tasks, with the environment, the model clients, and the trace and replay handles all sitting behind one proxy object. The quick start shows what that means in practice: you declare agents as metadata, essentially a list of dictionaries with an identifier, a profile and a config, and the society object creates their workspaces during initialisation. There is no agent object to hold state between calls, which is what makes a distributed run possible, and it is also why the environment module is constructed with an explicit mapping of agent identifiers to names. Reasoning patterns are a separate choice from execution: five routers are named, with code generation as the default, and the example wires a code generation router to a simple social space module from the contributions package.

## The examples are research scenarios and the citation asks you to pick a version

Two details at the end of the file are more substantive than they look. The first is the examples directory, which is not a set of to-do demos but a set of studies: a universal basic income scenario, hurricane impact, inflammatory message spread, polarization, prospect theory, and a rumour spreader, alongside configuration templates and the second generation's own onboarding examples. So a reader can see the framework used the way its authors use it, which is worth more than a hello world. The second is the citation policy, which is explicit rather than casual: cite the second generation when you use the current platform, and cite the first when you are referring to the original large scale city simulator. Machine readable citation files ship for both. That request is unusual and correct, because two papers, two packages and one repository name would otherwise produce a citation pointing at the wrong system.

## Conclusion

AgentSociety fits a research group that wants to run experiments over many agents with a real environment model and needs traces afterwards. It does not fit someone who needs a licence they can rely on without reading a folder exclusion, or who needs their dependencies from a public index. Four things to settle first. The licence, because one subdirectory of the legacy package is explicitly outside the grant and nobody will tell you from the metadata alone. Where packages come from, because the Python index and the Node registry are both set to mirrors in committed configuration, which is a regional convenience that silently becomes a supply chain dependency. Which generation you target, because two packages, two documentation sites and two execution models coexist in one repository and only the newer one is in the workspace. And how you will configure models, because three separate configuration blocks can each fall back to one key, and the fallback is silent.

## FAQ

### what is agent society

AgentSociety is a framework for building agent simulations in urban environments and research workflows. Its current generation, the second, is distributed as the agentsociety2 package on PyPI, and the first generation is kept as a legacy city simulator under its own package and documentation site.

### How do I install AgentSociety?

Install the second generation from the package index for the current platform, or install the first generation package for the legacy city simulator. You need Python 3.11 or newer and a model API key from one of the supported providers, including any provider the model routing layer supports.

### What license is AgentSociety under?

Apache License 2.0, with one exception stated in the readme: the commercial folder inside the legacy package directory is outside that grant. The readme says to see the licence file for details, and does not say which terms apply to that folder.

### Which reasoning patterns does AgentSociety 2 support?

Five routers are named, with code generation as the default, plus a ReAct pattern, a plan then execute pattern, a two tier router and a search router. The quick start wires a code generation router to a social space module taken from the contributions package.

### How does AgentSociety configure language models?

Through environment variables. A required block holds an API key, a base URL and a model name, and two optional blocks configure the code writing model and the embedding model, each falling back to the required block when unset. Separate optional switches control a thinking parameter and a gateway specific request body override.

### Can I replay an AgentSociety experiment?

The second generation lists experiment replay as a feature, described as catalog driven replay of newline delimited JSON records with reads powered by DuckDB, alongside distributed tracing. The handle for both tracing and replay sits behind the single proxy object the runtime exposes.

## Sources

- [License: Apache-2.0](https://github.com/tsinghua-fib-lab/AgentSociety/blob/main/LICENSE)
- [Project website](https://agentsociety2.fiblab.net)
- [README](https://github.com/tsinghua-fib-lab/AgentSociety/blob/main/README.md)
- [Releases](https://github.com/tsinghua-fib-lab/AgentSociety/releases)
- [tsinghua-fib-lab/AgentSociety on GitHub](https://github.com/tsinghua-fib-lab/AgentSociety)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tsinghua-fib-lab-agentsociety
