---
title: "Designed conversations: debates, focus groups, interviews, deliberations"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Designed conversations: debates, focus groups, interviews, deliberations}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include=FALSE}
knitr::opts_chunk$set(
  collapse = TRUE, comment = "#>",
  eval = identical(tolower(Sys.getenv("LLMRAGENT_RUN_VIGNETTES", "false")), "true")
)
```

Social research has spent a century refining conversation formats: the
debate elicits the strongest case each side can muster; the focus group
surfaces how opinions move in company; the interview goes deep on one
person; the deliberation ends in a decision. LLMRagent ships each as a
one-call preset. All four share a structure: agents built with `agent()`, a
shared attributed transcript, and tidy returns. What you learn from one
transfers to the others.

Throughout, one model and one cast:

```{r setup}
library(LLMRagent)
cfg <- LLMR::llm_config("groq", "openai/gpt-oss-20b", temperature = 0.8)
```

## Debate: the strongest case for each side

`debate()` runs opening statements, `rounds` of rebuttals, and closings, in
fixed alternation; an optional judge returns a structured verdict. Because
every statement is labeled with its phase, you can study how arguments
develop: openings state values, rebuttals engage evidence, closings
synthesize.

```{r debate}
d <- debate(
  pro   = agent("Pro", cfg, persona = "You argue FOR the motion. Rigorous, concrete."),
  con   = agent("Con", cfg, persona = "You argue AGAINST the motion. Rigorous, concrete."),
  topic = "Algorithmic screening should be banned from hiring decisions.",
  rounds = 1,
  judge = agent("Judge", cfg, persona = "A strict, impartial debate judge.")
)
d                     # compact print: motion, statements, verdict
d$transcript          # tidy: turn, phase, speaker, text
d$verdict$reasoning
```

## Focus group: opinions in company

`focus_group()` puts each question to every participant; speaking order
rotates across questions so no one speaks first every round, and participants
see the discussion so far, as in a real group. The moderator closes with a
synthesis.

```{r focus-group}
fg <- focus_group(
  moderator = agent("Mod", cfg, persona = "A neutral, probing focus-group moderator."),
  participants = list(
    agent("Maya", cfg, persona = "A 34-year-old nurse; prudent, skeptical of tech."),
    agent("Tom",  cfg, persona = "A 22-year-old gig worker; tech-optimistic."),
    agent("Ines", cfg, persona = "A 58-year-old teacher; worries about fairness.")
  ),
  topic = "Using AI screening in hiring",
  questions = c(
    "How would you feel if an algorithm screened your next job application?",
    "What, if anything, would make that acceptable to you?"
  )
)
fg$summary            # the moderator's synthesis
fg$transcript         # utterance-level frame for content analysis
```

Leave `questions = NULL` and the moderator drafts its own. This helps when
piloting an instrument before you spend human-subjects time on it.

## Interview: depth on one respondent

`interview()` works through a question list with one adaptive probe after
each answer (the interviewer decides whether a probe is warranted; `NONE`
suppresses it). The return is a classed object whose `$qa` field is the frame
interview studies analyze, with one row per question or probe.

```{r interview}
iv <- interview(
  interviewer = agent("Interviewer", cfg,
                      persona = "A careful qualitative researcher."),
  respondent  = agent("Respondent", cfg,
                      persona = "A warehouse worker whose shift assignments are set by software."),
  topic = "Working under algorithmic management",
  n_questions = 3
)
iv$qa[, c("type", "question")]
```

## Deliberation: talk, then decide

`deliberate()` is the format with a dependent variable. Everyone speaks each
round, seeing the discussion so far; then each agent votes privately through
structured output, with a one-sentence reason. Public positions and private
votes can disagree, and that gap is itself measurable.

```{r deliberate}
panel <- list(
  agent("Aila", cfg, persona = "Data-driven; cautious about unintended effects."),
  agent("Bo",   cfg, persona = "Mission-driven; impatient with delay."),
  agent("Cyn",  cfg, persona = "A budget hawk. Blunt.")
)
dl <- deliberate(panel,
                 proposal = "Adopt AI resume screening for all entry-level hiring.",
                 rounds = 2)
dl$votes              # voter, vote, reason
dl$decision
```

## From transcripts to analysis

Each preset exposes its analysis table as a tidy tibble: `$transcript` for the
group formats and `$qa` for an interview. `as.data.frame()` returns that primary
table. Two common moves are to score utterances with a model through LLMR's
tidy verbs and compare runs with [agent_experiment()].

```{r analyze}
# Who spoke most, and how much?
tr <- fg$transcript
aggregate(nchar(text) ~ speaker, data = tr, FUN = sum)

# Score each utterance for stance with a one-line LLMR call:
scored <- LLMR::llm_mutate(
  tr, stance,
  prompt = "One word, support/oppose/neutral. Stance on AI hiring in: {text}",
  .config = cfg
)
table(scored$speaker, scored$stance)
```

To turn any of these into an experiment, vary the personas, the framing, or
the group composition, then wrap the call in a function and hand it to
`agent_experiment()`. The deliberation vignette walks through a complete
factorial study. And for a permanent record of every call these formats
make, switch on `LLMR::llm_log_enable("study.jsonl")` first.
