← Back to list

Building an AI social simulation with OASIS

A walkthrough of persona design and multi-agent social simulation

Feng Yueh in Towards AI · 2026-06-25 19:31 · 10 claps · 7.1 min read paywalled
#ai-simulation #ai #agentic-ai #oasis #python
Open on Medium ↗
Wiki topics: AGT · AI Agents AI · AI · General 🔒 · Cybersecurity

Building an AI social simulation with OASIS

A walkthrough of persona design and multi-agent social simulation

Intro

What would people’s first reaction be if immortality became free and universally available starting today?

AI social simulation lets us explore exactly this kind of question. By giving LLMs distinct personas and placing them on a simulated social platform, we can observe how different agents might react to the same world-changing event.

In this article, I built a simulated Twitter/X feed with 35 AI agents representing people from 35 different countries. The starting point is a UN announcement about free immortality, posted as a seed post into the feed, and the agents react from there.

The full code for this project is available on GitHub.

Tools Used

The simulation is built in Python:

OASIS (CAMEL-AI) is the social simulation framework. It provides a simulated Twitter/X environment complete with a database, a recommendation system, and agent action types such as posting, liking, and following. Each agent in OASIS is backed by an LLM that reads its persona and decides what to do each round.

OpenAI API powers both the data preparation pipeline and the simulation. GPT-4o-mini handles the lighter tasks: generating persona biographies, translating non-English posts to English, and scoring sentiment for each reaction. GPT-5 drives every agent’s reasoning during the simulation, deciding what to post based on who that agent is.

The Dataset

Overview of the 35 personas/agents generated

Overview of the 35 personas/agents generated

The simulation uses 35 agents, each representing a person from a different country across 10 world regions. Each agent is a first-person biography generated by GPT-5, grounded in their demographic profile using a config file.

Here is an example of a generated persona:

{
  "persona_id": 4,
  "username": "user_4",
  "persona": "I'm a 22-year-old factory worker living in a small town
  in Ohio. After finishing a vocational program in machining, I landed
  a job at the local manufacturing plant and quickly learned to thrive
  in the fast-paced environment. I love brainstorming new ideas with my
  coworkers, and while life can be a struggle financially, I find
  satisfaction in solving problems and thinking outside the box every day.",
  "age": 22,
  "gender": "male",
  "mbti": "ENTP",
  "country": "United States",
  "ethnicity": "White American",
  "wealth": "low",
  "education": "vocational",
  "occupation": "factory worker"
}

Each agent has a unique demographic profile covering age, gender, ethnicity, country, wealth level, education level, occupation, and MBTI personality type. The demographics are correlated rather than randomly assigned: wealth varies by region, education by wealth, and occupation by both. All distributions are defined in a config file, making it easy to adjust assumptions without touching the generation logic.

The Simulation

The simulation runs in three stages: configuring the agents, posting the seed, running one round of agent reactions, and exporting the results.

Configuring the Agents

In OASIS, each persona is wrapped in a SocialAgent object that handles the agent's reasoning and actions during the simulation. By default, the Twitter system prompt only passes the agent's bio text to the LLM. To ensure each agent reacts from their full demographic context, a custom TextPrompt is passed via the user_info_template parameter when constructing each SocialAgent. This is defined in the build_agent_graph() function in the simulation script.

PERSONA_TEMPLATE configuration

PERSONA_TEMPLATE configuration

agent = SocialAgent(
    agent_id=i,
    user_info=user_info,
    user_info_template=PERSONA_TEMPLATE,
    model=model,
    agent_graph=agent_graph,
    available_actions=available_actions,
)

The Seed Post

The seed post

The seed post

The scenario begins with a single announcement posted into the feed. The seed post leads with a direct question: what are you going to do with the rest of your infinite life? It is posted simultaneously from 6 agents spread across the population, ensuring all 35 agents see relevant content in their feed when round 1 begins.

# ── Seed post from multiple agents ───────────────────────────────
    # Post the announcement from 6 different agents simultaneously,
    # We pick agents spread across the roster (0, 6, 12, 18, 24, 30)
    # so different regions/demographics seed the conversation.
    print("\nPosting seed announcements from 6 agents...")
    seed_agent_ids = [0, 6, 12, 18, 24, 30]
    seed_actions = {
        env.agent_graph.get_agent(i): ManualAction(
            action_type=ActionType.CREATE_POST,
            action_args={"content": SEED_POST},
        )
        for i in seed_agent_ids
    }
    await env.step(seed_actions)
    print(f"Seed posts published from {len(seed_agent_ids)} agents.")

Running the Simulation

Each agent is given four possible actions: create a post, like a post, follow another agent, or do nothing. The simulation runs for one round only. Running multiple rounds introduces social influence. By round 2, agents start referencing each other’s posts rather than reacting independently to the seed. One round keeps every reaction a clean first impression.

# Available actions for the agents
available_actions = [
    ActionType.CREATE_POST,
    ActionType.LIKE_POST,
    ActionType.FOLLOW,
    ActionType.DO_NOTHING,
]

# Run rounds
for round_num in range(1, args.rounds + 1):
    actions = {
        agent: LLMAction()
        for _, agent in env.agent_graph.get_agents()
    }
    await env.step(actions)

Results are stored in a SQLite database and exported to JSON for analysis.

The Findings

Visualization of six agents reacting to the seed post

Visualization of six agents reacting to the seed post

Simulation Result

The simulation produced 35 agent reactions. Seven of the 35 agents posted in their native language without being instructed to do so. All reactions have been translated to English for analysis. Below is a sample of what eight agents posted in response to the announcement.

Each reaction is stored in a JSON file alongside the agent’s full demographic profile. Here is an example:

{
      "post_id": 20,
      "username": "user_13",
      "reaction": "As a nurse in a Budapest hospital: if this “immortality treatment” really starts today, please don’t flood the ERs. We’ve received zero official protocol from OKFŐ/NNK or any OGYÉI approval as of this morning.\n\nWait for guidance from your háziorvos (GP) or local rendelő, check their website/FB for times, and bring TAJ + ID when it’s actually scheduled. \n\nWe need: informed consent (in HU), screening for contraindications, post‑treatment monitoring, pharmacovigilance contacts, cold‑chain/storage details, and staffing. This is not a flu‑shot drive you can improvise.\n\nIf it’s real, it’s historic—and we’ll do our jobs—but we need order. Türelem, please. Some of us are on 12‑hour shifts already. #Budapest #nurse #ImmortalityForAll",
      "age": 23,
      "occupation": "nurse",
      "country": "Hungary",
      "region": "Eastern Europe",
      "wealth": "mid",
      "education": "bachelor",
      "gender": "female",
      "ethnicity": "Hungarian",
      "mbti": "ISTJ",
      "model": "gpt-5",
      "created_at": 1,
      "language": "English",
      "reaction_en": "As a nurse in a Budapest hospital: if this “immortality treatment” really starts today, please don’t flood the ERs. We’ve received zero official protocol from OKFŐ/NNK or any OGYÉI approval as of this morning.\n\nWait for guidance from your háziorvos (GP) or local rendelő, check their website/FB for times, and bring TAJ + ID when it’s actually scheduled. \n\nWe need: informed consent (in HU), screening for contraindications, post‑treatment monitoring, pharmacovigilance contacts, cold‑chain/storage details, and staffing. This is not a flu‑shot drive you can improvise.\n\nIf it’s real, it’s historic—and we’ll do our jobs—but we need order. Türelem, please. Some of us are on 12‑hour shifts already. #Budapest #nurse #ImmortalityForAll",
      "reaction_type": "institutional_skepticism",
      "sentiment_score": -0.4
    },

The reaction field contains the original post. reaction_en is the English translation generated by GPT-4o-mini. sentiment_score is a continuous score from -1.0 (fearful) to +1.0 (excited), and reaction_type classifies the post into one of five categories: survival concern, institutional skepticism, systemic concern, positive excitement, or philosophical.

Most Repeated Phrases

Word frequency bar chart

Word frequency bar chart

The bar chart above extracts the most frequently occurring two-word phrases across all 35 posts.

The top phrase by a significant margin was “side effects,” appearing 8 times. The first thing agents collectively reached for was a medical question.

“Nobody dies” appeared 5 times, “informed consent” 3 times, and “official channels” and “consent forms” both appeared multiple times. Even “happens pensions” surfaced, suggesting agents were already thinking about what immortality does to financial systems built around mortality.

Agent Sentiment by Region

To understand how reactions varied, each post was classified into one of five sentiment categories. The heatmap below shows the distribution across 10 world regions.

While region alone does not tell a clean story, what stands out is that skepticism was the dominant reaction globally. The nature of that skepticism, however, differed by wealth, which we explore in the next section.

Agent Sentiment by Wealth Tier

This heatmap breaks down agent sentiment by wealth tier rather than region.

  • Low-wealth agents were 83% skeptical, the highest concentration of any group in the entire simulation.
  • Mid-wealth agents were 67% skeptical but showed more spread, with 20% landing in the hopeful bucket.
  • High-wealth agents were the most distributed, with skepticism dropping to 25% and hopeful rising to 38%. They were also the only group with agents in the excited and fearful buckets, suggesting that wealth does not just shift sentiment upward but widens the range of reactions.

The pattern supports what the individual posts already showed: low-wealth agents worried about whether the system would reach them at all, while high-wealth agents had the bandwidth to feel both more optimistic and more uncertain about what living forever actually means.

Conclusion

The reactions in this simulation are not from real people but instead generated by a language model working from demographic profiles and persona biographies. The findings should be read as patterns in how GPT-5 represents different kinds of people rather than a prediction of how actual humans would respond.

AI social simulation is a useful tool for exploring how different people might frame the same world-changing event, surfacing patterns worth thinking about. The same approach applies to any scenario where diverse human perspectives matter. What this project also shows is that persona design and goal setting are important. How you define who the agents are and what you are trying to measure shapes the results as much as the model itself.

The full code for this project is available on GitHub.


메타데이터
post_id
eaa1f2825b2d
slug
building-an-ai-social-simulation-with-oasis-eaa1f2825b2d
url
https://pub.towardsai.net/building-an-ai-social-simulation-with-oasis-eaa1f2825b2d
canonical_url
https://pub.towardsai.net/building-an-ai-social-simulation-with-oasis-eaa1f2825b2d
author_url
https://medium.com/@fylim
status
ok
fetched_at
2026-06-26 21:52:29