querychat

{querychat}

  • Embed a natural language interface into your shinyapp for filtering
  • Add context for LLM to understand your data
  • Translates queries to SQL
  • Does not share data with LLM providers

https://posit-dev.github.io/querychat/r/

Why Should You Care?

  • Oftentimes, we can’t always anticipate queries
  • Lets us bridge the gap
  • Gives us a reactive data frame that we can use elsewhere in our app

Demo

Setup: Add your API key to the .Renviron file

usethis::edit_r_environ()
# Uncomment the appropriate line and fill in the API key below
# ANTHROPIC_API_KEY=""
# OPENAI_API_KEY=""

Select your model

Use ellmer::models_anthropic() or ellmer::models_openai() to find a model to use

ellmer::models_anthropic()
                             id              name created_at cached_input input
NA               claude-fable-5    Claude Fable 5 2026-06-07           NA    NA
NA.1            claude-opus-4-8   Claude Opus 4.8 2026-05-28           NA    NA
16              claude-opus-4-7   Claude Opus 4.7 2026-04-14          0.5     5
24            claude-sonnet-4-6 Claude Sonnet 4.6 2026-02-17          0.3     3
14              claude-opus-4-6   Claude Opus 4.6 2026-02-04          0.5     5
13     claude-opus-4-5-20251101   Claude Opus 4.5 2025-11-24          0.5     5
8     claude-haiku-4-5-20251001  Claude Haiku 4.5 2025-10-15          0.1     1
22   claude-sonnet-4-5-20250929 Claude Sonnet 4.5 2025-09-29          0.3     3
10     claude-opus-4-1-20250805   Claude Opus 4.1 2025-08-05          1.5    15
     output
NA       NA
NA.1     NA
16       25
24       15
14       25
13       25
8         5
22       15
10       75

Plug your model it into your app:

library(palmerpenguins)
library(querychat)
data(penguins)
my_data <- penguins
client <- ellmer::chat_anthropic(model="claude-sonnet-4-5")
qc <- querychat(data_source = penguins, client=client)
qc$app()

Adding Context

  • Create a data_description.md file in your directory (see `querychat/app_data_description/data_desscription.md)
client <- ellmer::chat_anthropic(model="claude-sonnet-4-5")
qc <- querychat(
    data_source = penguins, 
    client=client,
    data_description = "data_description.md")
qc$app()

Adding Context

Add a Greeting

client <- ellmer::chat_anthropic(model="claude-sonnet-4-5")
qc <- querychat(
    data_source = penguins, 
    client=client,
    data_description = "data_description.md",
    greeting = "Welcome to exploring the world of penguins!")
qc$app()

Tools: Giving people capabilities

client <- ellmer::chat_anthropic(model="claude-sonnet-4-5")
qc <- querychat(
    data_source = penguins, 
    client=client,
    data_description = "data_description.md",
    greeting = "Welcome to exploring the world of penguins!",
    tools=c("query", "filter"))
qc$app()

Adding visualization to the chat

  • Requires the ggsql package
  • Modify the tool argument to include visualize:
library(palmerpenguins)
library(querychat)
data(penguins)
my_data <- penguins
client <- ellmer::chat_anthropic(model="claude-sonnet-4-5")
qc <- querychat(
    data_source = penguins, 
    client=client,
    data_description = "data_description.md",
    greeting = "Welcome to exploring the world of penguins!",
    tools=c("query", "filter", "visualize"))
qc$app()

How do we integrate it into dashboards?

Hooking up into visualizations

The QueryChat object has a few methods that act as reactives that you can use to plug in to visualizations:

# put this in the server function to access the reactive
qc_vals <- qc$server()

Then you can add this to your code.

  • qc_vals$df() - the actual filtered data from QueryChat
  • qc_vals$sql() - the SQL string
  • qc_vals$title() - The title of the filter

Example

# in server function
  output$avg_mass <- renderText({
    avg <- mean(qc_vals$df()$body_mass_g, na.rm = TRUE)
    paste0(round(avg, 0), "g")
  })

# in ui function
   value_box(
      title = "Avg Body Mass",
      value = textOutput("avg_mass"),
      showcase = bs_icon("speedometer"),
      theme = "info"
    )
runApp("querychat/app_big_example")