Skip to contents

Drop-in schema-first variant of llm_mutate(). Produces parsed columns.

Usage

llm_mutate_structured(
  .data,
  output,
  prompt = NULL,
  .messages = NULL,
  .config,
  .system_prompt = NULL,
  .before = NULL,
  .after = NULL,
  .schema = NULL,
  .fields = NULL,
  .validate_local = TRUE,
  .rows_per_prompt = 1L,
  .rowpack_payload = c("user", "system"),
  .rowpack_recovery = c("halve_recursive", "halve_once", "singletons", "retry_same",
    "none"),
  ...
)

Arguments

.data

A data.frame / tibble.

output

Unquoted name that becomes the new column (generative) or the prefix for embedding columns. In shorthand form, omit this argument and pass newcol = "<glue prompt>" or newcol = c(system = "...", user = "...") through ....

prompt

Optional glue template string for a single user turn; reference any columns in .data (e.g. "{id}. {question}\nContext: {context}"). Ignored if .messages is supplied.

.messages

Optional named character vector of glue templates to build a multi-turn message, using roles in c("system","user","assistant","file"). Values are glue templates evaluated per-row; all can reference multiple columns. For multimodal, use role "file" with a column containing a path template.

.config

An llm_config object (generative or embedding).

.system_prompt

Optional system message sent with every request when .messages does not include a system entry.

.before, .after

Standard dplyr::relocate helpers controlling where the generated column(s) are placed.

.schema

Optional JSON Schema (R list). When provided, this schema is sent to the provider for strict validation and used for local parsing. When NULL, only JSON mode is enabled (no strict schema validation). The schema should follow JSON Schema specification (e.g., with type, properties, required).

.fields

Optional character vector of fields to extract from parsed JSON. Supports:

  • Character vector: c("name", "score") - extract these fields

  • Named vector: c(person_name = "name", rating = "score") - extract and rename

  • Nested paths: c("user.name", "/data/items/0") - dot notation or JSON Pointer

  • NULL (default): auto-extracts all top-level properties from .schema

  • FALSE: skip field extraction (keep only structured_data list-column)

.validate_local

If TRUE (default) and .schema is provided, each parsed object is validated locally against the schema (requires the jsonvalidate package), adding structured_valid and structured_error columns, exactly as llm_fn_structured() does.

.rows_per_prompt

Integer scalar, or Inf. Number of rows packed into a single generative request. The default, 1, sends one request per row (the historical behaviour). When greater than 1, rows are grouped and sent in one call wrapped in numbered <row_1>...</row_1> tags (see Row batching below); Inf sends all rows at once. Works in generative, tag, and structured modes; not applicable to embedding configurations.

.rowpack_payload

One of c("user","system"). Channel to which the <row_i> data block is appended when batching. The default "user" keeps a static system prompt cacheable; the imperative instruction is always placed in the system message.

.rowpack_recovery

How to handle rows a batched call leaves unresolved. One of "halve_recursive" (default), "halve_once", "singletons", "retry_same", or "none"; see llm_fn() for the precise meaning of each.

...

Passed to the underlying calls: call_llm_broadcast() in generative mode, get_batched_embeddings() in embedding mode.

Value

.data with the output column, the diagnostic columns, and the parsed structured columns (structured_ok, structured_data, one column per hoisted field, and structured_valid/structured_error when .schema is validated locally).

Shorthand syntax

Like llm_mutate(), this function supports shorthand syntax:


df |> llm_mutate_structured(result = "{text}", .config = cfg, .schema = schema)
df |> llm_mutate_structured(result = c(system = "Be brief.", user = "{text}"), .config = cfg, .schema = schema)