--- title: "Data Schemas and Prompt Management" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Data Schemas and Prompt Management} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` This article follows data from source samples to modeling inputs and shows how prompt templates are managed. All examples are deterministic and run without provider credentials. ## Samples and pairs `read_samples_df()` normalizes a data frame and `read_samples_dir()` reads one text file per item. Both return an `ID`/`text` table suitable for the fixed-pair workflow. Existing data frames can be used directly when they already have those columns. ```{r samples-and-pairs} library(pairwiseLLM) data("example_writing_samples", package = "pairwiseLLM") samples <- read_samples_df(example_writing_samples[, c("ID", "text")]) pairs <- samples |> make_pairs() |> sample_pairs(n_pairs = 4L, seed = 10L) |> randomize_pair_order(seed = 11L) pairs[, c("ID1", "text1", "ID2", "text2")] ``` The fixed-pair schema uses `ID1`, `text1`, `ID2`, and `text2`. Reversal helpers preserve the unordered pair while changing presentation order. Keep the identifiers: they are needed to map a provider's `SAMPLE_1` or `SAMPLE_2` decision back to `better_id`. ## Traits and prompt templates Templates require all four placeholders: `{TRAIT_NAME}`, `{TRAIT_DESCRIPTION}`, `{SAMPLE_1}`, and `{SAMPLE_2}`. `build_prompt()` substitutes them but does not submit anything to a provider. ```{r build-prompt} trait <- trait_description("overall_quality") template <- set_prompt_template() prompt <- build_prompt( template = template, trait_name = trait$name, trait_desc = trait$description, text1 = pairs$text1[[1]], text2 = pairs$text2[[1]] ) substr(prompt, 1L, 180L) ``` The named registry lasts only for the current R session. Registration validates placeholders; `overwrite = FALSE` protects an existing name. Persist a custom template by storing its text in your project and registering it from a startup script, not by modifying package files. ```{r template-registry} example_name <- "task07_example" register_prompt_template(example_name, template = template) example_name %in% list_prompt_templates() identical(get_prompt_template(example_name), template) register_prompt_template(example_name, template = template, overwrite = TRUE) remove_prompt_template(example_name) ``` `set_prompt_template()` returns the built-in default or validates an inline/file template. `get_prompt_template()` resolves a user registration before a built-in template of the same name. `remove_prompt_template()` removes only session registrations; it cannot delete built-in files. ## Provider and result schemas The live wrappers accept the fixed-pair rows directly. Batch request builders convert the same rows to provider request records, and their matching parsers convert downloaded output back to package results. Do not send a request table built for one provider to another provider's submission function. The normalized result bundle retains pair identifiers and adds provider metadata, visible content, optional `thoughts`, `better_sample`, `better_id`, and token counts. Row-wise live calls return a list whose valid `results`, unresolved `failed_pairs`, and attempt-level `failed_attempts` components must be inspected separately. Batch parsers may omit unsuccessful rows from their successful result table, so preserve the provider output/error file and job registry for audit and recovery. ```text samples (ID, text) -> pairs (ID1, text1, ID2, text2) -> live call ---------------------> normalized results -> provider request + batch output -> provider parser -> normalized results ``` ## Modeling and adaptive branches For frequentist Bradley--Terry or Elo models, start from rows with `ID1`, `ID2`, and a valid `better_id` and call `build_bt_data()` or `build_elo_data()`. Invalid or missing winners are not valid outcomes; inspect failures before modeling rather than silently treating them as ties. ```{r modeling-schemas} data("example_writing_pairs", package = "pairwiseLLM") bt_data <- build_bt_data(example_writing_pairs) elo_data <- build_elo_data(example_writing_pairs) bayes_data <- build_btl_results_data(example_writing_pairs) names(bt_data) names(elo_data) names(bayes_data) ``` Standalone Bayesian BTL uses the stricter canonical schema returned by `build_btl_results_data()`; see [Standalone Bayesian BTL with CmdStan](https://shmercer.github.io/pairwiseLLM/articles/bayesian-btl.html). Adaptive ranking is a separate branch. `adaptive_rank()` starts from raw items and records each attempt in an adaptive state with canonical step, round, link-stage, and item logs. A normalized fixed-pair result table is not a drop-in replacement for an adaptive session. Use `adaptive_results_history()` only when you need the committed adaptive outcomes in `build_bt_data()` format. ## Failure checks at schema boundaries - Reject missing, blank, or duplicate sample IDs before pairing. - Preserve the original pair IDs and provider `custom_id` through batch submission and parsing. - Model only outcomes whose `better_id` matches one member of the pair. - Treat `thoughts` and raw responses as sensitive submitted/returned text when deciding retention. - Validate persisted adaptive sessions with `validate_session_dir()` rather than editing `.rds` artifacts or coercing their schemas by hand. ## Related documentation See [Getting Started with pairwiseLLM](https://shmercer.github.io/pairwiseLLM/articles/getting-started.html) for the basic fixed-pair workflow, [Provider Controls and Recovery](https://shmercer.github.io/pairwiseLLM/articles/provider-controls-and-recovery.html) for live and batch failures, and [Guide: Adaptive Pairing](https://shmercer.github.io/pairwiseLLM/articles/adaptive-pairing.html) for adaptive state and logs. ## Citation > Mercer, S. H. (2026). *Data schemas and prompt management* [R package vignette]. Comprehensive R > Archive Network. https://doi.org/10.32614/CRAN.package.pairwiseLLM