# Persona Sim

> Simulate feedback from statistically grounded virtual human populations. Use when the user wants to get product or copy feedback from a panel of diverse personas, predict group opinions or voting behavior, run social-experiment sandboxes, or compute a semantic gradient (SGO) for A/B ranking. Also triggers on mentions of Nemotron-Personas, PersonaHub, synthetic population, generative agents, silic…

- **Type:** Skill
- **Install:** `agentstack add skill-yrzhe-claude-skills-persona-sim`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Yrzhe](https://agentstack.voostack.com/s/yrzhe)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Yrzhe](https://github.com/Yrzhe)
- **Source:** https://github.com/Yrzhe/claude-skills/tree/main/plugins/persona-sim/skills/persona-sim

## Install

```sh
agentstack add skill-yrzhe-claude-skills-persona-sim
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Persona Sim

Simulate feedback from census-grounded virtual populations. Five layers, each independently replaceable:

```
L5 Scenario adapters (product-feedback-sim / vote-predict / social-sandbox)   thin wrappers
L4 Simulation engine (sim_engine.py — SGO: panel -> score -> persuadable middle -> anchored gradient)
L3 LLM router        (llm_router.py — config-driven; default Haiku 4.5 + prompt cache; Sonnet for gradient)
L2 Persona sampler   (sampler.py    — unified sample_personas(n, filters, source, mode))
L1 Persona store     (~/.claude/data/personas/ + manifest.json)
```

## First-time setup (not optional)

Dependencies and config live **outside the skill** under `~/.claude/data/personas/` so sharing the skill never leaks keys. See `SETUP.md` for the full walk-through. Short version:

```bash
mkdir -p ~/.claude/data/personas
cp ~/.claude/skills/persona-sim/data/config.example.json ~/.claude/data/personas/config.json
cp ~/.claude/skills/persona-sim/data/manifest.json ~/.claude/data/personas/manifest.json
# Edit config.json — set `provider` and fill api_key / base_url for your chosen block

python3 -m venv ~/.claude/data/personas/.venv
~/.claude/data/personas/.venv/bin/pip install -r ~/.claude/skills/persona-sim/requirements.txt
```

Always invoke with the venv interpreter:
```bash
~/.claude/data/personas/.venv/bin/python 
```

## When to use

- "Score this copy/feature with 100 virtual target users" → `sim_engine.panel_score()`
- "Find the persuadable middle for this tweet" → `sim_engine.sgo()`
- "Predict the US opinion distribution for this policy" → `panel_score()` + segment breakdown
- "Which of these two pricing variants wins?" → `sgo()` with anchored counterfactual probes

## In-code API

```python
from persona_sim import sampler, sim_engine

# Sample 30 targeted personas (streaming — no local download needed)
panel = sampler.sample_personas(
    n=30,
    filters={"occupation_isco": "software", "age": (22, 55)},  # see filter semantics below
    source="nemotron_usa",
    mode="stream",
)

# Single-version scoring
result = sim_engine.panel_score(panel, target="Copy or product description here")
# -> {"n", "results", "aggregate": {"histogram", "median", "iqr", "entropy",
#    "multi_modal", "disagreement_flag", "by_gender", "by_age", "by_region"},
#    "warning": "Simulation only..."}

# SGO gradient — rank candidates by how much they shift the persuadable middle
ranked = sim_engine.sgo(
    panel,
    target="original version",
    candidates=["variant A", "variant B"],
    goal="maximize paid conversions",
)
# -> {"base", "persuadable_middle", "ranking": [{"candidate", "avg_score_lift", ...}]}
```

## Filter semantics (commonly misused)

`sample_personas(filters={...})` interprets values by Python type:

| Filter value | Match behavior |
|---|---|
| `(low, high)` tuple of numbers | inclusive range (`low  demographic stub.** Park et al. 2024 proved demographic-only prompts amplify stereotypes. `_persona_card` puts Nemotron's long `professional_persona` narrative FIRST; demographics are a footnote.
2. **Never output a single mean.** Output distribution + segment breakdown + `disagreement_flag`. High variance = signal, not noise.
3. **Prompt caching is mandatory for panels.** System + task are identical across N personas; with cache_read at 10% of base, a 50-persona panel costs ~1/10 of naive. Cache breakpoint goes BEFORE the persona card (which varies per row).
4. **SGO uses ANCHORED counterfactuals.** The probe re-injects the persona's original score + reason so the delta is causal (attribution to the change), not two independent scorings. See `_anchored_delta_one` in `sim_engine.py`.
5. **Persuadable middle = score 4–7 only.** 1–3 never buys; 8+ already sold. Don't waste LLM calls on extremes.
6. **Calibration disclaimer is required.** Tjuatja 2311.04076 + Bisbee 2024 proved LLM synthetic samples lack human response biases (acquiescence, anchoring, framing). Every public-facing result must include the `warning` field.

## Empirical validation

Smoke-tested on Nemotron-USA + Haiku 4.5:

| Panel | Filter | Median | IQR | Persuadable middle |
|---|---|---|---|---|
| Generic (n=5) | none | 2 | — | 0/5 |
| Software devs (n=30) | `occupation_isco~"software", age (22,55)` | **7** | (7, 8) | **19/30** |

Same product, different panel → median shifts from 2 to 7. Personas play roles faithfully; single dissenter at 3 had concrete reasoning. SGO has enough signal when targeting is correct.

## LLM routing

Active provider set in `~/.claude/data/personas/config.json` → `provider` field. Three shapes supported:

- `anthropic` (native) — Anthropic SDK with `ANTHROPIC_API_KEY`; supports prompt caching
- `anthropic` with `base_url` override — for custom Anthropic-compatible gateways (enterprise proxies, Vertex-routed gateways, etc.)
- `openai` (gateway-compatible) — OpenRouter, vLLM, Together, Groq, etc.

Escalate to `gradient_model` (default Sonnet 4.5) for:
- SGO anchored counterfactual (fine-grained semantic judgment)
- Bias audit probes (framing / order / authority)
- Long-narrative fidelity eval

See `data/config.example.json` for template config blocks.

## Data fetch flow (streaming works without any download)

MVP runs entirely on HF streaming — no local copy needed. Only fetch when you're running many panels and want the speed:

```bash
~/.claude/data/personas/.venv/bin/python -m persona_sim.fetch nemotron_usa
```

`manifest.json` per-dataset `default_mode`:
- `local` → prompts to download on first use
- `stream` → direct HF streaming (default for MVP)
- `ask` → shows license + manual-download URL

`redistribute: false` entries (most Nemotron / PersonaHub / WVS / CGSS) are NEVER bundled when sharing the skill — each user fetches them per license terms.

## Bias audit

`lib/bias_audit.py` tests whether LLM personas reproduce four known human biases:

| Probe | What it measures | Human typical | LLM typical |
|---|---|---|---|
| framing | Tversky-Kahneman gain/loss reframe | +0.25 to +0.50 shift | ~0 (none) |
| acquiescence | agree-bias on symmetric statements | +0.10 to +0.20 excess | ~0 (logical) |
| order | primacy/recency on option list | 0.05-0.15 TV distance |  200)

```python
Task(subagent_type="general-purpose",
     prompt=f"Run persona_sim.panel_score on ids {ids[0:50]}, target={target!r}. Return distribution only.")
```
Main agent aggregates per-slice distributions to avoid context bloat.

## Known gaps

- Chinese persona data pipeline is scaffolded (`references/chinese_pipeline.md`) but not implemented — see that file for the 3-source recipe (census + WVS + LLM narrative).
- `demo_corr` suite requires persona income field (not in Nemotron); currently skips that dimension.
- ANES demographic correlation reference values are approximations — re-verify against the official codebook before publishing.

## Resources

- `lib/{fetch,sampler,llm_router,sim_engine,aggregator,bias_audit,ipf}.py` — core layers
- `prompts/persona_system.md` — narrative-first system prompt with anti-agreeable guardrails
- `prompts/sgo_gradient.md` — anchored counterfactual template
- `eval/run_eval.py` + `eval/*.json` — 6-suite score card (gss_20q, bfi44, test_retest, diversity, demo_corr, bias_audit)
- `references/methodology.md` — Park 2024, Santurkar, SGO, CoBRA, Tjuatja synthesis
- `references/datasets.md` — dataset inventory + field maps
- `references/chinese_pipeline.md` — scaffold for Chinese persona synthesis
- `scripts/smoke_test.py`, `scripts/smoke_test2.py` — minimal working examples
- `SETUP.md` — venv + config bootstrap
- `requirements.txt` — pinned deps
- `data/manifest.json` — dataset registry (safe to share)
- `data/config.example.json` — sanitized LLM config template

## Eval loop

```bash
cd ~/.claude/skills/persona-sim
~/.claude/data/personas/.venv/bin/python eval/run_eval.py \
    --suite gss_20q,bfi44,test_retest,diversity,demo_corr,bias_audit \
    --n 30
# -> eval/reports/score_card_YYYYMMDD.json
```

Target: overall >= 0.75. If any dimension fails, that dimension is the highest-priority edit target for the next iteration.

## Scenario skills

Three thin scenario wrappers ship alongside the core. They route into `persona-sim`'s API with opinionated defaults for common use cases:

- **`product-feedback-sim`** — SGO ranking for product/copy/pricing candidates
- **`vote-predict`** — categorical opinion prediction with IPF post-stratification
- **`social-sandbox`** — what-if experiments with open-ended narrative clustering

Each has its own `SKILL.md` with a full recipe.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Yrzhe](https://github.com/Yrzhe)
- **Source:** [Yrzhe/claude-skills](https://github.com/Yrzhe/claude-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-yrzhe-claude-skills-persona-sim
- Seller: https://agentstack.voostack.com/s/yrzhe
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
