Build OpenAI batch JSONL lines for paired comparisons
Source:R/openai_batch_api.R
build_openai_batch_requests.RdThis helper constructs one JSON object per pair of writing samples,
suitable for use with the OpenAI batch API. It supports both
/v1/chat/completions and /v1/responses endpoints.
Usage
build_openai_batch_requests(
pairs,
model,
trait_name,
trait_description,
prompt_template = set_prompt_template(),
endpoint = c("chat.completions", "responses"),
temperature = NULL,
top_p = NULL,
logprobs = NULL,
reasoning = NULL,
include_thoughts = FALSE,
request_id_prefix = "EXP",
store = NULL,
max_output_tokens = NULL,
prompt_caching = NULL,
...
)Arguments
- pairs
A data frame or tibble with columns
ID1,text1,ID2, andtext2.- model
Character scalar giving the OpenAI model name. Supports standard names (e.g.
"gpt-4.1","gpt-5.6-sol") and date-stamped versions (e.g."gpt-5.4-2026-01-15").- trait_name
Short label for the trait (e.g., "Overall Quality").
- trait_description
Full-text definition of the trait.
- prompt_template
Character template containing the placeholders
{TRAIT_NAME},{TRAIT_DESCRIPTION},{SAMPLE_1}, and{SAMPLE_2}. Defaults toset_prompt_template().- endpoint
Which OpenAI endpoint to target. One of
"chat.completions"(default) or"responses".- temperature
Optional temperature parameter. If
NULL, it is omitted so the model/provider default applies. Must beNULLfor reasoning modes that do not support it.- top_p
Optional top-p parameter. If
NULL, it is omitted so the model/provider default applies.- logprobs
Optional logprobs parameter.
- reasoning
Optional reasoning effort for GPT-5 series when using the
/v1/responsesendpoint. For"gpt-5"and"gpt-5-mini","none"is normalized to"minimal". For later GPT-5.x reasoning models, use model-supported efforts such as"none","low","medium","high","xhigh", or"max".- include_thoughts
Logical; if TRUE and using
responsesendpoint with reasoning, requests a summary. Defaultsreasoningto"low"for GPT-5 series models if not specified.- request_id_prefix
String prefix for
custom_id; the full ID takes the form"<prefix>_<ID1>_vs_<ID2>".- store
Optional logical scalar for either endpoint.
TRUEandFALSEare forwarded unchanged; omitted orNULLleaves the field absent.- max_output_tokens
Optional positive whole numeric scalar, at most
.Machine$integer.max, for the Responses endpoint only. Includes visible output and reasoning tokens. Omitted orNULLleaves the field absent.- prompt_caching
Batch caching policy:
NULL(model-aware default),"disabled", or"implicit". See the compatibility rules below.- ...
Reserved; must be empty. Raw provider caching controls are not accepted. Use
prompt_cachinginstead.
Value
A tibble with one row per pair and columns:
custom_id: ID string used by the batch API.method: HTTP method ("POST").url: Endpoint path ("/v1/chat/completions"or"/v1/responses").body: List column containing the request body.
Details
Invalid controls fail even for empty pairs. Responses are stored
for later API retrieval by default; set store = FALSE to disable response
storage. For Chat Completions, store controls storage for distillation or
evaluations. Omitting it preserves that endpoint's provider default.
This parameter does not control Batch input/output/error file retention
and does not imply zero data retention. See
https://developers.openai.com/api/docs/guides/your-data.
Batch prompt caching
The default disables prompt caching for these verified model IDs:
gpt-5.6-luna, gpt-5.6-terra, gpt-5.6-sol, gpt-6-luna,
gpt-6-sol, gpt-6-astra, and gpt-6.1-sol. Each request body gets
prompt_cache_options = list(mode = "explicit"), with no breakpoints,
on both endpoints. Set prompt_caching = "implicit" to omit that field
and retain provider caching when prefix reuse is expected to be worthwhile.
Recognized earlier OpenAI models retain their historical request bodies
when the policy is omitted or NULL; explicitly disabling caching on
those models errors. Unknown IDs (including unlisted snapshots, future
models and custom aliases) require an explicit "implicit" opt-in or a
verified model ID. Support is an offline allowlist; version numbers and
snapshot suffixes never establish support for disabling caching. Older
GPT-3.5/4, GPT-5 through GPT-5.5 and o-series naming forms, including
recognized legacy date-suffixed names, retain provider defaults.
Invalid policies and manual cache controls fail before submission, even
with zero pairs. Raw prompt_cache_options, prompt_cache_breakpoint,
prompt_cache_key, retention and TTL controls are not accepted by these
builders. Keys affect cache routing/accounting; retention and TTL affect
lifetime; store = FALSE affects response storage. None substitutes for
disabling implicit cache breakpoints. Prompt text and keys are not rewritten.
This policy affects future package-built Batch requests only, not live
requests or already submitted jobs. See the
prompt-caching guide
and vignette("advanced-batch-workflows") for usage-based cost comparisons.
See also
llm_submit_pairs_batch(), llm_resume_multi_batches()
Other batch backends:
anthropic_create_batch(),
anthropic_download_batch_results(),
anthropic_get_batch(),
anthropic_poll_batch_until_complete(),
build_anthropic_batch_requests(),
build_gemini_batch_requests(),
gemini_create_batch(),
gemini_download_batch_results(),
gemini_get_batch(),
gemini_poll_batch_until_complete(),
llm_download_batch_results(),
llm_resume_multi_batches(),
llm_submit_pairs_batch(),
llm_submit_pairs_multi_batch(),
openai_create_batch(),
openai_download_batch_errors(),
openai_download_batch_output(),
openai_get_batch(),
openai_poll_batch_until_complete(),
openai_upload_batch_file(),
run_anthropic_batch_pipeline(),
run_gemini_batch_pipeline(),
run_openai_batch_pipeline(),
write_openai_batch_file()
Examples
data("example_writing_samples", package = "pairwiseLLM")
pairs <- example_writing_samples |>
make_pairs() |>
sample_pairs(n_pairs = 3, seed = 123) |>
randomize_pair_order(seed = 456)
td <- trait_description("overall_quality")
tmpl <- set_prompt_template()
# 1. Basic chat.completions batch with no thoughts
batch_tbl_chat <- build_openai_batch_requests(
pairs = pairs,
model = "gpt-4.1",
trait_name = td$name,
trait_description = td$description,
prompt_template = tmpl,
endpoint = "chat.completions"
)
# 2. GPT-5.6 Sol Responses Batch with Reasoning
batch_tbl_resp <- build_openai_batch_requests(
pairs = pairs,
model = "gpt-5.6-sol",
trait_name = td$name,
trait_description = td$description,
prompt_template = tmpl,
endpoint = "responses",
include_thoughts = TRUE, # implies reasoning="low" if not set
reasoning = "medium",
store = FALSE,
max_output_tokens = 1024
)
batch_tbl_chat
#> # A tibble: 3 × 4
#> custom_id method url body
#> <chr> <chr> <chr> <list>
#> 1 EXP_S17_vs_S12 POST /v1/chat/completions <named list [2]>
#> 2 EXP_S19_vs_S15 POST /v1/chat/completions <named list [2]>
#> 3 EXP_S01_vs_S15 POST /v1/chat/completions <named list [2]>
batch_tbl_resp
#> # A tibble: 3 × 4
#> custom_id method url body
#> <chr> <chr> <chr> <list>
#> 1 EXP_S17_vs_S12 POST /v1/responses <named list [6]>
#> 2 EXP_S19_vs_S15 POST /v1/responses <named list [6]>
#> 3 EXP_S01_vs_S15 POST /v1/responses <named list [6]>