OpenAI provides a number of chat-based models, mostly under the ChatGPT brand. Note that a ChatGPT Plus membership does not grant access to the API. You will need to sign up for a developer account (and pay for it) at the developer platform.
chat_openai(
system_prompt = NULL,
base_url = Sys.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1"),
api_key = openai_key(),
model = NULL,
params = NULL,
seed = lifecycle::deprecated(),
api_args = list(),
api_headers = character(),
echo = c("none", "output", "all")
)
models_openai(base_url = "https://api.openai.com/v1", api_key = openai_key())A system prompt to set the behavior of the assistant.
The base URL to the endpoint; the default uses OpenAI.
API key to use for authentication.
You generally should not supply this directly, but instead set the OPENAI_API_KEY environment variable.
The best place to set this is in .Renviron,
which you can easily edit by calling usethis::edit_r_environ().
The model to use for the chat (defaults to "gpt-4.1").
We regularly update the default, so we strongly recommend explicitly specifying a model for anything other than casual use.
Use models_openai() to see all options.
Common model parameters, usually created by params().
Optional integer seed that ChatGPT uses to try and make output more reproducible.
Named list of arbitrary extra arguments appended to the body
of every chat API call. Combined with the body object generated by ellmer
with modifyList().
Named character vector of arbitrary extra headers appended to every chat API call.
One of the following options:
none: don't emit any output (default when running in a function).
output: echo text and tool-calling output as it streams in (default
when running at the console).
all: echo all input and output.
Note this only affects the chat() method.
A Chat object.
Other chatbots:
chat_anthropic(),
chat_aws_bedrock(),
chat_azure_openai(),
chat_cloudflare(),
chat_databricks(),
chat_deepseek(),
chat_github(),
chat_google_gemini(),
chat_groq(),
chat_huggingface(),
chat_mistral(),
chat_ollama(),
chat_openrouter(),
chat_perplexity(),
chat_portkey()
chat <- chat_openai()
#> Using model = "gpt-4.1".
chat$chat("
What is the difference between a tibble and a data frame?
Answer with a bulleted list
")
#> - **Printing behavior**:
#> - Tibbles print a preview (first 10 rows and columns that fit on screen),
#> whereas data frames print ALL data unless told otherwise.
#>
#> - **Data type preservation:**
#> - Tibbles never convert strings to factors by default, whereas data.frames
#> (in base R <4.0) automatically convert strings to factors unless instructed not
#> to.
#>
#> - **Subsetting output:**
#> - Tibbles always return another tibble when subsetting with `[ ]`, while data
#> frames may simplify the output (e.g., as a vector) depending on usage.
#>
#> - **Column name handling:**
#> - Tibbles allow non-syntactic column names (e.g., names with spaces or
#> special characters) without backticks, whereas data frames require syntactic
#> names or backticks.
#>
#> - **Partial matching:**
#> - Tibbles do **not** support partial column name matching, while data frames
#> do.
#>
#> - **Enhanced printing:**
#> - Tibbles display data types next to column names when printed; data frames
#> do not.
#>
#> - **Creation:**
#> - Tibbles are created with `tibble()` or `as_tibble()`, while data frames use
#> `data.frame()`.
#>
#> - **Row names:**
#> - Tibbles do not support row names; data frames do.
#>
#> - **Package:**
#> - Tibbles are part of the tidyverse (`tibble` package); data frames are a
#> base R structure.
chat$chat("Tell me three funny jokes about statisticians")
#> Sure! Here are three funny jokes about statisticians:
#>
#> 1. **Why did the statistician bring a ladder to the bar?**
#> Because he heard the drinks were on the house!
#>
#> 2. **How do you tell the difference between a statistician and an accountant?**
#>
#> Ask them to calculate the average salary: the accountant will give you the
#> mean, the statistician will ask “what do you want it to be?”
#>
#> 3. **Why do statisticians love the jungle?**
#> Because of all the *sample* trees!