Projects

Kynd: AI-Powered User Testing with High-Fidelity Synthetic Personas

Creator & Lead Developer

2026-06-18

Next.js 16TypeScriptTailwind v4shadcn/uiZustandHexagonal ArchitecturePlaywrightStagehand

GitHub


Context

Kynd started as DeepBound, a project I began in early 2026. The trigger was a UC Berkeley paper on "deep binding of LLM virtual personas" (Moon, Kang et al., 2024). The paper showed that LLMs produce much more realistic human behavior when you give them rich narrative backstories instead of simple demographic prompts.

At the time, every "AI persona" tool on the market was a chatbot with a character description slapped in the system prompt. They didn't simulate test users. They produced stereotypes.

I'm the sole developer and product lead.


Problem / Product Goal

Early-stage founders need to validate their product with real users before building. But recruiting human test participants is slow, expensive, and doesn't scale. Run five user testing sessions and you get five data points. What if you need feedback on fifty variations of your pricing page? The math doesn't work.

Even worse: a researcher who's run 20 interviews cannot simulate how those 20 people would react to 5 different feature concepts. The insight is locked in transcripts, frozen in time. The feedback loop — the most critical cycle in product development — is bottlenecked by human availability.

Kynd's goal was to close that gap: generate realistic, opinionated synthetic personas from minimal input, then run them against live websites to get structured behavioral feedback at scale.


Thought Process

I started by implementing the Moon et al. technique directly — narrative backstories as extended interview transcripts dropped into an LLM system prompt. It worked better than demographic-only prompts, but not by enough. Personas drifted toward "helpful assistant" behavior after 3-4 conversation turns. They were too agreeable. They didn't push back on pricing pages the way a real budget-conscious user would.

So I spent a month reading the research literature. Everything I could find on persona prompting, inference-time techniques, and LLM evaluation. Here's what I found:

  • Compartmentalized prompts (Wang 2024b): Splitting the persona definition into 4 distinct compartments (<<PERSONA IDENTITY>>, <<PSYCHOGRAPHIC PROFILE>>, <<EPISTEMIC BOUNDARIES>>, <<BEHAVIORAL GUARDRAILS>>) prevents attention dilution. The LLM can't "forget" who it is because the identity is structured, not a blob of text.
  • PB&J scaffolds (Joshi 2025): Psychological frameworks — values, fears, decision-making styles — improve persona adherence by 6-9%. But they cost an extra LLM call to generate.
  • Persona anchors (SyTTA, Atri 2026): 4-16 token identifiers injected every turn reduce drift by 40-60%. Triple injection (header, pre-history, pre-generation) works best.
  • ID-RAG (Tan 2025): Retrieving relevant persona backstory chunks during inference grounds the persona in factual context.

I implemented all of them. It still wasn't enough.

The breakthrough came from an unexpected direction: the r < 0.26 ceiling.

I was working on an interview-to-persona pipeline — the idea that you could upload raw interview transcripts and Kynd would generate personas from them. My naive approach was to extract personality traits (Big Five OCEAN scores) from the transcripts using zero-shot LLM extraction. But research by Zhu et al. (2025) showed this maxes at r < 0.26 correlation with actual personality scores. You literally cannot extract reliable personality traits from interview transcripts. This is a fundamental ceiling, not something you can fix with prompt engineering.

This changed my entire approach. Instead of extracting personality, I extracted only directly observable signals — pain points, goals, values with verbatim quotes. Things an interviewer would actually note down. Then I pooled those signals across all interviews, deduplicated by trigram similarity, and used the resulting frequency distribution to generate personality consistent with those signals.

The pipeline went from "extract → generate" to "extract only what's observable → pool mathematically → sample from distribution → generate personality consistent with the data." It bypasses the r < 0.26 ceiling entirely because it never extracts personality at all.

The second breakthrough came from the pricing analysis feature. I built it as a streaming pipeline — every persona streams its analysis back in real-time. It was unreliable. Weak schema enforcement, brittle timeout handling, Next.js HMR killing server-side stores mid-analysis. Every demo I ran had at least one persona drop out. I spent two weeks trying to fix streaming before admitting the architecture was wrong.

I ripped out the streaming and replaced it with completion-based analysis: Zod schema validation, a strict 3-minute timeout per persona enforced by AbortController, globalThis for store persistence across HMR cycles, and a comprehensive AnalysisLogger. The result was boring, predictable, and stable. It's better to wait 3 minutes for a complete answer than to get 80% in 30 seconds with errors.


Solution

Kynd generates high-fidelity synthetic personas and runs them against live websites for automated user testing.

The Inference Stack

Six research-backed techniques layered into a coherent system:

  • Narrative backstories (Moon 2024) — 14-18% better alignment
  • Compartmentalized prompts (Wang 2024b) — 4 compartments prevent drift
  • PB&J scaffolds (Joshi 2025) — 6-9% better adherence
  • Persona anchors (SyTTA 2026) — 40-60% drift reduction
  • ID-RAG (Tan 2025) — factual grounding via chunk retrieval
  • InCharacter + PICon evaluation — multi-turn consistency checking

Architecture

Hexagonal Architecture with strict dependency flow inward: UI → Actions → Application → Domain (pure TypeScript, zero external deps) → Infrastructure (adapters implement ports).

10 port interfaces define every external dependency. Key adapters include PersonaPromptCompiler (4-compartment prompt builder), IdRagStore (n-gram retrieval), VisionAnalysisAdapter (Qwen VL for pricing page vision), and InCharacterEvaluator (psychometric evaluation).

Key Features

  • Persona Creation Pipeline: text description → brainstorm → narrative backstory → PB&J scaffolds → behavioral insights → ID-RAG ingestion
  • Pricing Analysis Engine: Two-phase flow (Playwright scouting of URL → parallel persona analysis with concurrency 5). Completion-based with Zod validation, 3-min timeout
  • Interview-to-Persona Pipeline: Extract observable signals → trigram-similarity pooling → weighted sampling → persona generation → ID-RAG ingestion. 20 interviews → 40 personas in under 60 seconds
  • Debate Room: Multi-persona round-based debate with streaming, human interjection, any number of participants
  • Chat with ID-RAG: Compartmentalized prompt + anchors every turn + periodic re-grounding

Model Strategy

Tiered LLM selection: DeepSeek V4 Flash (text generation, reasoning, extraction), Qwen VL 30B A3B (vision analysis), Claude Sonnet 4 (browser agent thinking where quality is critical). Concurrency limits: 20 LLM calls max, 5 parallel persona analyses.


Takeaways

The r < 0.26 ceiling taught me to read the literature before building. I spent a week on a feature (personality extraction from transcripts) that research said was impossible. A literature review before implementation would have saved that week. I now start every feature with a targeted literature search.

Streaming is wrong for structured data analysis. Streaming is great for chat. It's terrible for validated, aggregated, dashboard-ready analysis. The completion-based overhaul was painful but necessary. I should have started there instead of chasing the streaming UX dopamine hit.

No single technique carries the whole load. Each inference-time technique contributes a few percentage points. The magic is in the layering — compartmentalized prompts alone aren't enough, PB&J alone isn't enough, anchors alone aren't enough. The system is the combination. I almost shipped with just narrative backstories, and the product would have been mediocre.

The GitHub repo is still jeremykamber/deepbound for backward compatibility. The product name is Kynd. I should rename it but haven't prioritized that over feature work.

What I'd do differently: I'd build the interview-to-persona pipeline first. The pricing analysis engine got the most feature attention early on, but the pipeline is the more interesting technical contribution. It's the feature that actually separates Kynd from every other persona tool.