Why this exists
The short version: I wanted an honest answer.
US: 334.8M · Census ACS · 35 metros · World: 211 countries · World Bank · News: GDELT +
NewsAPI · Macro: FRED/BLS · Bills: Congress.gov + Open States + GovTrack · Claude reasons
each one in character
I wanted to know if you could point an LLM at real Census and World Bank data and get
something more honest back than the usual AI-simulates-the-public demo. Most of those just
generate plausible sounding text and call it insight. Nothing underneath it, no way to
check if it's even right.
So the actual test was this: seed a synthetic population from real demographic marginals,
have Claude reason as those people instead of about them, then score the result
against real elections and polls instead of just trusting it. Turns out you can get
something calibrated out of that. Not perfect. Checked, and it says so up front every
time, right in the interface: a simulation, not a poll.
Everything past that first test grew because the answer was interesting enough to keep
pulling on: a globe you can drop a scenario on and watch the reaction spread, real bills
instead of hypothetical ones, a scorecard so the model can't hide from being wrong —
see the live results →
What feeds the engine
Pheme names its sources on every surface it can. Optional API keys unlock more feeds; the
setup wizard walks through which keys do what. When a feed isn't
configured, the engine falls back gracefully (LLM news wire, no macro strip) instead of
pretending live data exists.
Demographics (Ask, globe, bills)
~10,000 synthetic residents are drawn to match marginal distributions: age, race,
income, education, party lean where available. US uses Census ACS state and national
marginals; city scope uses metro-level marginals for 35 US metros. World scope
uses World Bank indicators for 211 countries over 2M population.
Census ACS · World Bank
Live reasoning (Ask)
Stratified clusters become exemplars. Claude answers in character for each
cluster, not as a pundit summarizing "what Americans think." Responses are tallied and
re-weighted to the full population. Crosstabs break out who moved by age, race, income,
and region. Economy-tagged questions can inject a live CPI/unemployment line from FRED
(BLS when configured) into the persona prompt.
Claude via OpenRouter · FRED · BLS (optional)
Voices & newsroom spin (Ask)
Every live Ask returns real first-person voices — individual synthetic residents
answering in character, with their own stated confidence. When the live model runs, one
extra pass shows how different newsrooms would headline the same result and names
the framing move each uses. It invents no numbers; it's a media-literacy lens on the data
you just generated.
Claude · same result, reframed
Deterministic scenarios (globe)
Scenario reactions on the US and world globes use the same demographic weights but
no live LLM call per click. Distance from origin, local poverty/unemployment
(real Census where available), and scenario type drive a graded reaction ladder. Fast,
repeatable, honest about being a model pattern — not a prophecy.
Canonical engine.js · Census deepening
News wire (live page, digest, globe)
Headlines are collected GDELT first, then NewsAPI when a key is set, then an LLM wire
as last resort. Stories are cached daily, filterable on /us/live,
and any headline can be dropped onto the globe as a scenario. The homepage digest groups
threads and asks Claude what each could mean for public opinion.
GDELT · NewsAPI · Perplexity fallback
Macro backdrop (forecast, economy Ask)
When FRED is configured, /us/forecast shows a live
CPI/unemployment strip above the swingometer. The same snapshot can color economy
questions in Ask so personas aren't reasoning in a vacuum. USGS earthquake counts ride
along in the economic API for disaster-adjacent context.
FRED · BLS (optional) · USGS
Real bills (Bills → Real Bills)
Federal bills list from Congress.gov, enriched with GovTrack sponsor/status/links. State
bills from Open States (coverage varies by legislature). "Simulate the country's
reaction" runs the same Ask engine against the bill's real title — that's
public support for the text, not a passage forecast.
Congress.gov · GovTrack · Open States
Calibration (accuracy, 2028)
The 2024 presidential result is the fixed baseline on the swingometer. Issue
majorities and state margins are scored against real polls and election returns on
/us/accuracy. 2028 match-ups are explicitly hypothetical —
the point is seeing how demographic levers move shares, not publishing a forecast.
AP/FEC baselines · internal scorecard
What the numbers mean
Shares and margins are re-weighted synthetic tallies, not sampled humans. A 58%
"support" line means the model's calibrated electorate leans that way given the question
and scope — check the crosstabs to see who drove it.
MOE (±) on Ask comes from bootstrap resampling of exemplar weights, not
from polling margin of error. The band brackets how much the cluster draw matters, not
survey uncertainty.
Scenario colors on the globe are relative reaction intensity (panic, concern,
support) mapped to demographics and distance. They compare states to each other inside
the simulation; they don't predict real-world behavior.
Bill simulations estimate whether the synthetic public would favor the legislation's
text. Committee status, whip counts, and parliamentary procedure are out of scope.
Every page repeats the same disclaimer because it matters: a simulation, not a poll.
The scorecard exists so you can decide whether to trust it for your use case.
I write long fiction for a living over at
Phaenex. Pheme
is maybe the one thing I've built that isn't allowed to be fiction.