The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

LLMR

LLMR logo

CRAN status CRAN downloads License: MIT R-CMD-check Website Lifecycle: experimental GitHub issues

LLMR is an R package for running large language model workflows as ordinary R code. It provides one interface for hosted and local providers, with tidy helpers for repeated calls, structured JSON, XML-like tags, embeddings, chat sessions, retries, and parallel experiments.

Installation

install.packages("LLMR") # CRAN
# Development:
# remotes::install_github("asanaei/LLMR")

Quick start

Configure a model

library(LLMR)

cfg <- llm_config(
  provider = "openai",
  model = "gpt-4.1-nano",
  temperature = 0.2,
  max_tokens = 256
)

Store keys in environment variables such as OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY. Reasoning models such as gpt-5-nano often reject custom temperature values. Omit temperature unless the selected model accepts it.

For Gemini on Vertex AI, keep provider = "gemini" and opt in to Vertex routing:

cfg_vertex <- llm_config(
  provider = "gemini",
  model = "gemini-2.5-flash-lite",
  vertex = TRUE,
  project = "my-gcp-project",
  location = "us-central1",
  api_key = "VERTEX_ACCESS_TOKEN"
)

One-shot generation

r <- call_llm(
  config = cfg,
  messages = c(
    system = "You are a branding expert.",
    user = "Six-word catch-phrase for eco-friendly balloons."
  )
)

print(r) # text + status line
as.character(r) # just the text
finish_reason(r)
tokens(r)
is_truncated(r)

Structured output (JSON with schema)

schema <- list(
  type = "object",
  properties = list(
    label = list(type = "string"),
    score = list(type = "number")
  ),
  required = list("label", "score"),
  additionalProperties = FALSE
)

cfg_s <- enable_structured_output(cfg, schema = schema)

resp <- call_llm(cfg_s, c(system = "Reply JSON only.", user = "Label and score for 'MNIST'."))
parsed <- llm_parse_structured(resp)
str(parsed)

Or use higher-level helpers:

words <- c("excellent", "awful", "fine")

out <- llm_fn_structured(
  x = words,
  prompt = "Classify '{x}' and output {label, score in [0,1]} as JSON.",
  .config = cfg,
  .schema = schema,
  .fields = c("label", "score")
)
out

Tidy helpers

Use llm_fn() for vectors and llm_mutate() inside data-frame pipelines. The shorthand form puts the output column and prompt in one argument.

words <- c("excellent", "awful", "fine")
llm_fn(words, "Classify '{x}'.", .config = cfg, .return = "text")

df <- tibble::tibble(
  city = c("Cairo", "Lima"),
  text = c("Cairo is large.", "Lima is coastal.")
)

df |>
  llm_mutate(
    country = "Where is {city}? Answer with only the country.",
    .config = cfg
  )

Strict JSON extraction can be used directly in llm_mutate():

df |>
  llm_mutate(
    out = "{text}",
    .config = cfg,
    .structured = TRUE,
    .schema = schema
  )

For lighter extraction, use XML-like tags:

df |>
  llm_mutate(
    geo = "Where is {city}? Give country and continent in their own tags.",
    .config = cfg,
    .system_prompt = paste(
      "Use XML tags to specify different parts of the answer, but do not nest tags.",
      "Return <country>...</country> and <continent>...</continent>."
    ),
    .tags = c("country", "continent")
  )

Embeddings

sentences <- c(
  one = "Quiet rivers mirror bright skies.",
  two = "Thunder shakes the mountain path."
)

emb_cfg <- llm_config(
  provider = "voyage",
  model = "voyage-3.5-lite",
  embedding = TRUE
)

emb <- call_llm(emb_cfg, sentences) |> parse_embeddings()
dim(emb)

Batch embeddings:

emb <- get_batched_embeddings(
  texts = sentences,
  embed_config = emb_cfg,
  batch_size = 8
)

Conversation with history

chat <- chat_session(cfg, system = "You teach statistics tersely.")
chat$send("Explain p-values in 12 words.")
chat$send("Now give a three-word analogy.")
print(chat)

Parallel runs

setup_llm_parallel(workers = 4)

experiments <- build_factorial_experiments(
  configs = list(cfg),
  user_prompts = c("Summarize in one sentence: The Apollo program."),
  system_prompts = "Be concise."
)

res <- call_llm_par(experiments, progress = TRUE)
reset_llm_parallel()

Which helper should I use?

Notes

Contributions and support

Bug reports, feature requests, and support questions should be opened as GitHub issues. Please include a minimal reproducible example when relevant. Pull requests are welcome for focused improvements. See CONTRIBUTING.md for contribution, support, and reporting guidance. See COPYING for the full MIT license text.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.