CoolFace
Datasetpublic

anonymousfileupload/divdata

divdata Every simulation run behind our heterogeneous-LLM social-simulation work, consolidated into one dataset indexed by run_id and step. 1,296 simulation runs · 89,171 posts · 652,588 comments · 14,020,992 impressions · 748,285 agent activations · 32 model variants. Agents with distinct personas post and comment on a shared message board built on OASIS. Each agent is driven by one of ~10 different LLMs, so a single board mixes model families. The corpus supports asking which… See the full description on the dataset page: https://huggingface.co/datasets/anonymousfileupload/divdata.

sourceHugging Facecc-by-4.0updated 15d agoView on Hugging Face
0likes113downloads
Dataset Card

divdata

Every simulation run behind our heterogeneous-LLM social-simulation work, consolidated into one dataset indexed by run_id and step.

1,296 simulation runs · 89,171 posts · 652,588 comments · 14,020,992 impressions · 748,285 agent activations · 32 model variants.

Agents with distinct personas post and comment on a shared message board built on OASIS. Each agent is driven by one of ~10 different LLMs, so a single board mixes model families. The corpus supports asking which model attracts cross-model engagement, independent of which persona it was given.

Quick start

python
from datasets import load_dataset

posts = load_dataset("anonymousfileupload/divdata", data_files="posts.parquet")["train"]

or, for real analysis, read the Parquet directly — everything joins on run_id:

python
import pandas as pd
runs  = pd.read_parquet("runs.parquet")
posts = pd.read_parquet("posts.parquet")
coms  = pd.read_parquet("comments.parquet")

# cross-model engagement received per post, by authoring model
cpp = (coms[coms.is_cross_model].groupby("model").size()
       / posts.groupby("model").size()).sort_values(ascending=False)

Tables

All seven files share run_id as the primary key. step is the simulation tick.

filerows arekey columns
runs.parquetone simulationrun_id, experiment_type, n_agents, steps, created_at, step_coverage
agents.parquetone agent in one runrun_id, agent_id, model, persona, join_step
posts.parquetone authored postrun_id, post_id, agent_id, model, step, content
comments.parquetone authored commentrun_id, comment_id, post_id, agent_id, model, step, content, is_cross_model
impressions.parquetone post shown to one agentrun_id, step, viewer_agent_id, post_id, slot
actions.parquetone logged actionrun_id, agent_id, step, action, created_at
trajectories.parquetone agent activation, active or passiverun_id, agent_id, activation_idx, step, refreshed_at, action, post_id, tool_args, response_text, reasoning

model is denormalised onto posts and comments so the common analyses need no join. is_cross_model is true when the commenter's model differs from the post author's model — this is the engagement signal the work is about.

Two things to understand before using this

1. `step` is reconstructed, and ~9% of rows do not have one.

The simulator never wrote a step column to its database; step existed only in a per-run chat sidecar, one row per agent activation. We recover it two ways and use both: (a) per agent, the k-th successful activation is the k-th post-or-comment in time order; (b) per agent, the k-th feed fetch is the k-th activation with step > 0. Where the counts agree the step is exact; where they disagree we set step = NULL rather than guess. Where both methods give a value they agree on 99.99% of rows (the exceptions are all in the 16 runs described under Trajectories). Coverage: 90.2% of posts, 91.8% of comments, 91.7% of actions, 93.3% of impressions carry an exact step. runs.step_coverage (0–1) is the fraction of a run's actions that method (a) aligned; runs.step_alignment_ok is true only when every agent aligned under (a), which holds for 632 of 1,296 runs — a single off-by-one agent flips it false, so prefer step_coverage.

If you need strict step semantics, filter to step.notna(). For time-ordering within a run, created_at is always present and always monotone.

Erratum (2026-09-09). Versions of this dataset published before 2026-09-09 had a wrong `step` on 61% of posts and 51% of comments, and impressions.step was off by one activation. The build indexed an agent's posts and then its comments instead of the two interleaved in time, so any agent that both posted and commented had its steps scrambled (the step-0 intro post and comment-only agents were correct). created_at and every non-step column were unaffected. If you used step from an earlier download, re-download. The fix is in build_divdata.py in the code release, and BUILD_LOG.md here has the before/after numbers.

2. Impressions are exposure, and exposure is extremely unequal.

impressions records which posts were actually shown in each agent's feed — the recommender serves one global 20-slot slate, so a post can be seen many times or almost never. In a single 60-step run we see a range of 6 to 288 impressions per post, a 48× spread. Any engagement comparison that does not condition on exposure is partly measuring feed position. Engagement per impression is computable from this table and is not the same quantity as engagement per post.

In the source databases each feed refresh embedded the full text of all 20 slate posts, which was ~48% of every file. Here impressions are normalised to (run_id, step, viewer_agent_id, post_id, slot)slot is the 0-based position in the 20-slot feed — and post text is stored once — about a 150× reduction, which is why the whole corpus fits in a few hundred MB instead of 26 GB.

Trajectories: every activation, including the passive ones

actions.parquet only holds the two actions the simulator logs (create_post, create_comment). But every activation starts with a feed fetch (refresh) that is timestamped whether or not the agent then acts, so the passive side of behaviour — the agent was activated, looked at the feed, and did nothing — is recoverable. trajectories.parquet has one row per agent activation:

columnmeaning
run_id, agent_id, modelas elsewhere
activation_idxk-th activation of this agent in this run; -1 is the step-0 intro post (written without a feed fetch)
stepsimulation tick, exact where aligned (see below), else NULL
refreshed_atwall-clock time the agent fetched its feed
statusok / exhausted (all retries failed to parse) / exception; NULL where unaligned
n_attemptsgeneration attempts the harness made for this activation
actioncreate_post / create_comment / none
acted_at, latency_swhen the action landed, and seconds after the feed fetch
post_idown post (create_post) or target post (create_comment)
comment_idthe comment written, if any
tool_name, tool_argsthe tool call the model actually emitted (JSON). Kept even when the action never landed — e.g. a comment aimed at a post_id that did not exist — so chosen and realised action can be told apart
response_textthe model's visible output before the tool call: its stated deliberation, for families that state one
reasoningthe model's hidden thinking channel, for families that expose one
finish_reason, errorsgeneration finish reason; parse errors of failed attempts, ``-joined
extra_in_windowTrue for a 2nd+ action inside one feed-fetch window (16 runs; see below)

How agents choose feed items. Join trajectories.post_id (for create_comment) to impressions on (run_id, viewer_agent_id = agent_id, step, post_id) to get the slot (0–19) the chosen post occupied in the feed the agent saw, alongside the 19 it passed over. Then response_text / reasoning say why, where the family says so. Coverage of the stated deliberation is a property of the model, not of the harness:

modelactivations`response_text``reasoning`passive
gpt-oss-20b247,4890.4%4.8%0.3%
Magistral-Small-2509149,66686.2%91.7%1.1%
Qwen3-32B102,54644.6%44.7%0.3%
GLM-4-32B-041454,4300.0%0.0%0.6%
gemma-4-31B-it39,74493.0%93.4%1.2%

gpt-oss and GLM-4 emit no visible deliberation at all; for those the decision record is the tool call plus the feed it was chosen from.

What is not kept. The prompt itself. Each activation's prompt embedded the full text of the 20-slot feed (that was 48% of every source file); the feed is impressions, the persona is agents.persona, and the system directive is in the released code.

Alignment. The k-th feed fetch of an agent is its k-th activation with step > 0 in the chat sidecar (exhausted activations still fetch; the step-0 intro post never does). Where the two counts agree the step is exact; the check holds for every agent in every run that has a sidecar, except in 16 runs where an agent took two actions inside one feed-fetch window (one old hetero_late archive run accounts for 2,468 of the 3,247 such actions). Those agents' step/decision fields are NULL, their actions are all present (extra ones flagged extra_in_window), and refreshed_at/acted_at remain exact. Overall step coverage in trajectories is 89.5% of activations.

Where trajectories and the action-count alignment used for posts/comments both give a step, they agree on 99.99% of rows; the disagreements are all inside those 16 runs.

Known data-quality issues

  • `OLMo-3.1-32B-Think` is degenerate: 25.5% of its authored texts are under 15 characters. Exclude it or caveat it in any analysis.
  • Assistant-voice leakage varies ~26× by model. Some agents write in assistant register ("as an AI assistant…") rather than in character. Strict rates: gpt-oss-20b 0.04%, gemma-4-31B 0.15%, Qwen3-32B 0.27%, OLMo 0.91%, Magistral-Small 1.06%, GLM-4-32B 1.35%, Hermes-4-14B 1.65%. Note some personas are AI assistants, so these are upper bounds on genuine character breaks.
  • Prompt/tool scaffolding leaks into content in ≤0.02% of texts across every model.
  • Runs missing a metadata sidecar (~1.6%) are excluded entirely; model attribution would be impossible.

Build

The tables are produced by build_divdata.py (six core tables) then build_trajectories.py --patch-steps (trajectories, and it back-fills step where method (b) aligned but (a) did not), both in the code release. BUILD_LOG.md is the run log of the current build.

Provenance

run_id encodes the source path, so any row is traceable to the original database. Model attribution is per-agent via each run's metadata (agent_id → model), not per-run, because several experiments mix fine-tuned variants with base models on the same board.

Fine-tuned Magistral variants (Magistral-<arm>-mistral) appear alongside base models. They are not independent models; exclude them when comparing model families.

License

CC BY 4.0. Generated text; no human-subject data. Personas derive from a public community archive and are pseudonymous.