Skip to contents

llm_config() builds a provider-agnostic configuration object that call_llm() (and friends) understand. You can pass provider-specific parameters via ...; LLMR forwards them as-is, with a few safe conveniences.

Usage

llm_config(
  provider,
  model,
  api_key = NULL,
  troubleshooting = FALSE,
  base_url = NULL,
  embedding = NULL,
  no_change = FALSE,
  ...
)

Arguments

provider

Character scalar naming the backend. Known providers: "openai", "anthropic", "gemini", "groq", "together", "deepseek", "xai", "xiaomi", "alibaba" (Alibaba Cloud DashScope, OpenAI-compatible mode; serves the Qwen models), "zhipu", "moonshot", "voyage" (embeddings only), and "ollama" (local server, usually keyless). Other names are accepted and routed through the OpenAI-compatible path.

When api_key is omitted, LLMR reads the key from the environment using a formulaic default: it tries <PROVIDER>_API_KEY and then <PROVIDER>_KEY, upper-cased (e.g. OPENAI_API_KEY, or ALIBABA_API_KEY/ALIBABA_KEY). The one exception is Gemini with vertex = TRUE, which reads VERTEX_ACCESS_TOKEN.

model

Character scalar. Model name understood by the chosen provider. (e.g., "gpt-4.1-nano", "gpt-5-nano", "gemini-2.5-flash-lite", "openai/gpt-oss-20b", etc.)

api_key

Provider API key. Preferred form is llm_api_key_env("VAR"), referencing an environment variable by name (see provider for the formulaic defaults). A bare environment-variable name or "env:VAR" string also works, as does a character vector of variable names tried in order. Supplying a literal key string is accepted but discouraged and triggers a warning. When omitted (or given as an empty string, which is what Sys.getenv() returns for an unset variable), the provider default is used. Printing a config never reveals the key.

troubleshooting

Logical. If TRUE, prints the messages and the config for debugging. The API key is masked in this output, not shown.

base_url

Optional character. Back-compat alias; if supplied it is stored as api_url in model_params and overrides the default endpoint.

embedding

NULL (default), TRUE, or FALSE. If TRUE, the call is routed to the provider's embeddings API; if FALSE, to the chat API. If NULL, LLMR infers embeddings when model contains "embedding".

no_change

Logical. If TRUE, LLMR never auto-renames/adjusts provider parameters. If FALSE (default), well-known compatibility shims may apply (e.g., renaming OpenAI's max_tokens -> max_completion_tokens after a server hint; see call_llm() notes).

...

Additional model parameters. LLMR understands a small canonical set spelled the OpenAI way and translates it per provider, so you can keep one vocabulary across backends:

  • temperature, top_p, top_k, max_tokens, frequency_penalty, presence_penalty, repetition_penalty – sampling controls. Parameters a provider does not accept are dropped with a console note (e.g., repetition_penalty for Gemini); spellings a provider renames are renamed (e.g., max_tokens becomes maxOutputTokens for Gemini).

  • seed – request reproducible sampling where supported (OpenAI-compatible providers and Gemini; Anthropic has no seed). Determinism is not guaranteed; record model_version from the response for the full picture.

  • logprobs, top_logprobs – token log-probabilities where supported (OpenAI-compatible chat APIs and Gemini). Retrieve them tidily with llm_logprobs().

  • thinking_budget, include_thoughts – reasoning controls for Gemini and Anthropic. thinking_budget caps reasoning tokens (thinkingConfig.thinkingBudget on Gemini, thinking.budget_tokens on Anthropic, where it must be smaller than max_tokens). include_thoughts = TRUE asks Gemini to return its reasoning; Anthropic returns thinking blocks whenever thinking is on. Returned reasoning lands in the response's thinking field.

  • timeout – total request timeout in seconds (default 600; also settable globally via options(llmr.timeout = ...)).

  • cache – set cache = TRUE to mark the system prompt and tools as cacheable for Anthropic (prompt caching). OpenAI, Gemini, DeepSeek, and several compatible providers cache long prompt prefixes automatically; cached token counts are reported in tokens(x)$cached either way.

  • Anything else (e.g., reasoning_effort, api_url, provider-specific flags) is forwarded verbatim on the OpenAI-compatible providers, so new provider features work without waiting for an LLMR release. Anthropic and Gemini have stricter request shapes: their builders send recognized fields only, and quietly note (once per session) anything they drop. The req_builder / request_modifier hooks remain the escape hatch for arbitrary fields on those providers.

Value

An object of class c("llm_config", provider). Fields: provider, model, api_key, troubleshooting, embedding, no_change, and model_params (a named list of extras). print() masks the API key.

Advanced hooks

Three optional functions in ... customize the HTTP exchange when a provider needs something unusual (a gateway header, an exotic body field, a nonstandard response envelope). All are applied on every request for every provider:

  • request_modifier: function(body) -> body, edits the JSON body before serialization (OpenAI-compatible chat paths).

  • req_builder: function(req) -> req, edits the httr2 request (headers, URL, auth) just before it is performed.

  • response_modifier: function(content) -> content, edits the parsed JSON before LLMR interprets it.

Temperature range clamping

Anthropic temperatures must be in [0, 1]; others in [0, 2]. Out-of-range values are clamped with a warning. Reasoning or thinking-oriented models may reject custom temperature values; omit temperature unless the selected model accepts it.

Endpoint overrides

You can pass api_url (or base_url= alias) in ... to point to gateways or compatible proxies.

Vertex Gemini

Use provider = "gemini", vertex = TRUE for Gemini on Vertex AI. Supply project and optionally location; when api_key is omitted, LLMR looks for VERTEX_ACCESS_TOKEN and sends it as a Bearer token.

Examples

if (FALSE) { # \dontrun{
# Basic OpenAI config
cfg <- llm_config("openai", "gpt-4.1-nano",
temperature = 0.7, max_tokens = 300)

# Generative call returns an llmr_response object
r <- call_llm(cfg, "Say hello in Greek.")
print(r)
as.character(r)

# Embeddings (inferred from the model name)
e_cfg <- llm_config("gemini", "gemini-embedding-001")

# Force embeddings even if model name does not contain "embedding"
e_cfg2 <- llm_config("voyage", "voyage-3.5-lite", embedding = TRUE)

# Gemini through Vertex AI. VERTEX_ACCESS_TOKEN should contain a Bearer token.
v_cfg <- llm_config(
  "gemini", "gemini-2.5-flash-lite",
  vertex = TRUE,
  project = "my-gcp-project",
  location = "us-central1",
  api_key = "VERTEX_ACCESS_TOKEN"
)
} # }