% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/solver.R
\name{generate_structured}
\alias{generate_structured}
\title{Convert a chat to a solver function with structured output}
\usage{
generate_structured(solver_chat = NULL, type = NULL)
}
\arguments{
\item{solver_chat}{An ellmer chat object, such as from
\code{\link[ellmer:chat_anthropic]{ellmer::chat_claude()}}, or a zero-argument function that returns one.}

\item{type}{A type specification for the extracted data, created with
ellmer's \verb{type_*()} functions (e.g., \code{\link[ellmer:type_boolean]{ellmer::type_object()}},
\code{\link[ellmer:type_boolean]{ellmer::type_string()}}). This defines the schema for the structured
output.}
}
\value{
The output of \code{generate()} is another function. That function takes in
a vector of \code{input}s, as well as a solver chat by the
name of \code{solver_chat} with the default supplied to \code{generate()} itself.

See the documentation for the \code{solver} argument in \link{Task} for more
information on the return type.
}
\description{
\code{generate_structured()} is a variant of \code{\link[=generate]{generate()}} that uses
\code{\link[ellmer:parallel_chat]{ellmer::parallel_chat_structured()}} to extract structured data from
the model's responses. This allows you to define a schema for the
expected output using ellmer's \verb{type_*()} functions.

Because \code{parallel_chat_structured()} returns structured data rather than
Chat objects, \code{generate_structured()} creates synthetic Chat objects
for logging purposes. These "mock" chats contain the input and
JSON-serialized output as turns, but won't include actual token usage
or timing metadata from the API.

The \code{result} field contains JSON-serialized strings for compatibility
with existing scorers. The raw structured data is available in
\verb{$get_samples()$solver_metadata} after calling \verb{$solve()} or \verb{$eval()}.
}
\examples{
if (FALSE) {
  library(ellmer)

  type_answer <- type_object(
    answer = type_string(
      "The author's first name, with no other formatting."
    )
  )

  names <- tibble::tribble(
    ~input,                                  ~target,
    "Name's Josiah, how's it going?",        "Josiah",
    "I'm Lin, what's your name?",            "Lin",
    "My name is Em Fields, how about you?",  "Em"
  )

  tsk <- Task$new(
    dataset = names,
    solver = generate_structured(
      solver_chat = chat_anthropic(model = "claude-sonnet-4-20250514"),
      type = type_answer
    ),
    scorer = detect_match("any")
  )

  tsk$eval()

  # the result is JSON-serialized for compatibility with scorers
  tsk$get_samples()$result

  # raw structured data is available in solver_metadata
  tsk$get_samples()$solver_metadata

  # solver_chat contains synthetic turns for logging
  tsk$get_samples()$solver_chat[[1]]
}
}
\seealso{
\code{\link[=generate]{generate()}} for unstructured output, \code{\link[ellmer:type_boolean]{ellmer::type_object()}} and
related functions for defining type specifications.
}
