James Wade

@jameshwade.bsky.social

Analytical chemist in industry working on materials characterization and data science. Interested in #rstats, modeling, & sustainability. Owner of many pets.

Coding agents can explore codebases. But you can't optimize them, compose them, or put them in a pipeline. RLMs can do all of that. They're DSPy modules, not agents. I built a shiny app to understand how they work.

My holiday project was building dsprrr, a package for declarative LLM programming in R, inspired by DSPy. The core idea is to treat LLM workflows as programs you can systematically optimize, not prompt strings you tweak by hand.

dsprrr
Programming—not prompting—LLMs in R
dsprrr brings the power of DSPy to R. Instead of wrestling with prompt strings, declare what you want, compose modules into pipelines, and let optimization find the best prompts automatically.

# Install
pak::pak("JamesHWade/dsprrr")

# That's it. Start using LLMs.
library(dsprrr)
dsp("question -> answer", question = "What is the capital of France?")
#> "Paris"
Getting Started: Configure Your LLM
OpenAI
Anthropic
Gemini
Ollama
Auto-detect

Jumping on the #rstats "we're so back" train 🚂 Here's two fun (unrelated) things I scrolled upon tonight: 📊 tinyplot - base R plotting system with grouping, legends, facets, and more 👀 github.com/grantmcdermo... 🔎 openalexR - Clean API access to search OpenAlex docs.ropensci.org/openalexR/ar...

GitHub - grantmcdermott/tinyplot: Lightweight extension of the base R graphics system

Lightweight extension of the base R graphics system - grantmcdermott/tinyplot

github.com

Having a hard time focusing on code today. Instead of refreshing news sites, tell me about an R package or function that made your life easier recently? I finally figured out how group_modify() works, and it's been a game-changer for some nested data madness. #rstats #dataBS

You can now build a chatbot in shiny in less than 20 lines of code. shinychat and elmer make this much easier than it was even a month ago. elmer nails LLM abstractions. Go check them out if you haven't already!

library(shiny)

ui <- bslib::page_fluid(
  shinychat::chat_ui("chat")
)

server <- function(input, output, session) {
  chat <- elmer::chat_openai(
    model = "gpt-4o-mini",
    system_prompt = "You are a pithy, but helpful assistant."
  )
  observeEvent(input$chat_user_input, {
    stream <- chat$stream_async(input$chat_user_input)
    shinychat::chat_append("chat", stream)
  })
}

shinyApp(ui, server)