Anamnesis is a web-based research platform for running opinion surveys on LLM-simulated human personas. Researchers define survey instruments, execute them against large pools of naturalistic backstories via LLM inference, and analyze the resulting response distributions - all through a unified interface.
The platform operationalizes the Virtual Personas methodology, Anthology, enabling systematic, large-scale evaluation of persona simulation at the level of individual response distributions rather than aggregate population statistics.
Anamnesis (ἀνάμνησις): the Platonic concept of recollection - recovering knowledge from within. Here, backstories serve as that inner context, eliciting a specific human perspective from within the model.
- Survey Builder - Create surveys with MCQ, multi-select, open-response, and ranking questions; attach image/audio media to questions and answer options
- Persona Targeting - Filter backstories by demographic dimensions (age, gender, political affiliation, education, etc.) with distribution-balanced or top-K sampling
- Two Inference Algorithms - Anthology (backstory-conditioned, sequential context accumulation) and Zero-Shot Baseline (demographic prompt, N-sample averaging)
- Demographic Survey Tool - Define custom demographic dimensions; populate them across the backstory pool using LLM inference (N-sample or logprobs mode)
- Real-Time Progress - Monitor active runs with live progress and per-task status
- Results & Export - Bar/pie charts, response tables, Borda-score ranking summaries, CSV export with demographic breakdowns
- API Key Vault - Per-user encrypted API key storage (Supabase Vault); supports OpenRouter and self-hosted vLLM
┌───────────────────────────────────────────────────────────────┐
│ Browser (React + TypeScript + Vite) │
│ Survey Builder │ Backstory Browser │ Results Dashboard │
└────────────────────────┬──────────────────────────────────────┘
│ Supabase JS SDK (RLS-enforced)
┌────────────────────────▼──────────────────────────────────────┐
│ Supabase (PostgreSQL + Auth + Vault) │
│ users │ backstories │ surveys │ survey_runs │ survey_tasks │
└──────────┬─────────────────────────────────────────────────────┘
│ Service Role (worker/dispatcher)
┌──────────▼────────────┐ ┌─────────────────────────────────┐
│ Dispatcher (Python) │──────▶ RabbitMQ │
│ Poll → Throttle │ │ survey_tasks queue │
│ → Publish tasks │ └──────────────┬──────────────────┘
└───────────────────────┘ │
┌──────────▼──────────┐
│ Worker(s) (Python) │ ×N
│ Async, scalable │
└──────────┬──────────┘
│ API calls
┌──────────▼──────────┐
│ LLM Providers │
│ OpenRouter / vLLM │
└─────────────────────┘
| Layer | Technology |
|---|---|
| Frontend | React 18, TypeScript, Vite, Tailwind CSS v4, shadcn/ui |
| Charts | Recharts |
| Database | Supabase (PostgreSQL 15, Row-Level Security, Vault) |
| Task Queue | RabbitMQ 3 |
| Worker | Python 3.11, asyncio, aio_pika |
| LLM (cloud) | OpenRouter (OpenAI-compatible API, 70+ models) |
| LLM (local) | vLLM (guided decoding, logprobs) |
| Media Storage | Wasabi (S3-compatible) |
| Containers | Docker Compose |
- Node.js 18+, Python 3.11+
- Supabase project (free tier works)
- Docker + Docker Compose (for worker stack)
- OpenRouter API key or vLLM endpoint
cd frontend
npm install
cp .env.example .env
# Edit .env: add VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY
npm run dev # http://localhost:5173Run migrations in order in your Supabase SQL editor:
ls supabase/migrations/ # apply in filename ordercp .env.example .env
# Edit .env: SUPABASE_URL, SUPABASE_SERVICE_KEY, RABBITMQ_USER, RABBITMQ_PASS
docker compose up -d
docker compose up -d --scale worker=4 # scale to 4 parallel workersLLM API keys are stored per-user in the Supabase Vault via the Settings page.
Replicates the backstory-conditioned approach from our EACL 2024 paper:
- Prepend the full backstory to the first question
- Record the LLM's answer
- For each subsequent question, prepend all prior Q&A pairs (context accumulation)
- Parse answers using structured output (Tier 1) + parser LLM fallback (Tier 2)
This promotes response consistency across questions - the LLM "remembers" what it has said.
Constructs a short demographic description from the backstory's structured attributes (age, gender, education, etc.) and asks each question N times independently. The final answer is the majority vote across N trials. Used for ablation comparison against the full backstory-conditioned method.
Anamnesis can populate custom demographic attributes across the backstory pool by running dedicated demographic surveys:
- Define a dimension (e.g.,
political_affiliationwith optionsDemocrat / Republican / Independent) - Run in N-sample mode (ask N times, compute frequency distribution) or logprobs mode (extract token probability distribution in a single call - ~20× cheaper, requires vLLM)
- The resulting distribution is stored in each backstory's
demographicsJSONB field - Future opinion surveys can filter and sample backstories by this dimension
anamnesis/
├── frontend/src/
│ ├── pages/ # 14 route pages
│ ├── components/ # UI, layout, surveys, results, demographic-surveys
│ ├── lib/ # surveyRunner, backstoryFilters, backstoryScoring,
│ │ # demographicPrompt, hungarianMatching, media, apiKeyUtils
│ ├── hooks/ # useAuth, useSurveyRun
│ └── types/ # database.ts (all TypeScript types)
├── worker/src/
│ ├── main.py # Async event loop + message handler
│ ├── dispatcher.py # DB polling, concurrency throttling
│ ├── worker.py # TaskProcessor + 3 FillingStrategies
│ ├── llm.py # UnifiedLLMClient (OpenRouter + vLLM)
│ ├── prompt.py # Anthology prompt format
│ ├── parser.py # Tier 2 MCQ parser LLM
│ └── logprobs.py # Token log-prob → distribution
├── supabase/migrations/ # 23 SQL migrations
└── docker-compose.yml # RabbitMQ + Dispatcher + Worker
This platform is part of the Virtual Personas research program at UC Berkeley's BAIR lab (Prof. Trevor Darrell, postdoc David Chan), exploring how language models can be conditioned with naturalistic backstories to simulate individual human perspectives rather than aggregate population behavior.
- Anthology (
../anthology/) - Original implementation for "Virtual Personas for Language Models via an Anthology of Backstories" (EACL 2024, arXiv:2407.06576) - Alterity (
../alterity-private-main/) - Follow-up research on belief consistency using LLM-interview-generated backstories
# Unit tests (frontend)
cd frontend && npm run test
# E2E tests (frontend)
npm run test:e2e
# Worker tests
cd worker && pytest
# Full CI equivalent
# See .github/workflows/See docs/DEPLOYMENT.md for production deployment on Ubuntu 24.04.
Updated: 7/14/2026