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.
Arguments
- panel
A
panel_from_margins()orpanel_from_data()result.- instr
- 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 aresponse_textcolumn. Defaults to a live LLM call viaLLMR::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)