Skip to contents

One call per persona x item, through LLMR's parallel engine by default. The persona is the system message; the item and its (possibly reordered) options are the user message; replies are matched to the offered options, with failures kept as NA – a refusal or an essay instead of an option is data about the instrument.

Usage

panel_administer(panel, instr, config, .runner = NULL, ...)

Arguments

panel

A panel_from_margins() or panel_from_data() result.

instr

A panel_instrument().

config

An LLMR::llm_config() for a generative model.

.runner

Optional runner for offline or deterministic testing: a function(experiments, ...) that returns the experiments with a response_text column. Defaults to a live LLM call via LLMR::call_llm_par().

...

Passed to the runner (e.g. tries, progress).

Value

A panel_responses tibble: persona_id, item_id, type, option_order (what this respondent saw, |-separated), response (matched option or NA; verbatim text for open items), score (1-based scale position for Likert items). Carries the panel and instrument as attributes and an empty calibration slot: every print shows the UNCALIBRATED banner until panel_calibrate() fills it.

Examples

set.seed(110)   # the panel draw is local; the model call is not
panel <- panel_from_margins(list(party = c(left = .5, right = .5)), n = 6)
instr <- panel_instrument(
  item_likert("wk4", "A four-day work week would benefit society."),
  randomize = character(0))
cfg <- LLMR::llm_config("groq", "openai/gpt-oss-20b")
if (FALSE) { # \dontrun{
resp <- panel_administer(panel, instr, cfg)
resp                       # UNCALIBRATED banner, by design
} # }

# The `.runner` seam answers without a provider, for tests or for a
# deterministic or external respondent:
deterministic <- function(experiments, ...) {
  experiments$response_text <- "agree"
  experiments
}
panel_administer(panel, instr, cfg, .runner = deterministic)