Programming with LLM APIs
A Beginner’s Guide in R and Python
posit::conf(2025)
2025-09-16
It’s okay to treat LLMs as black boxes.
We’re not going to focus on how they work internally
Just try it! When wondering if an LLM can do something,
experiment rather than theorize
You might think they could not possibly do things
that they clearly can do today
Don’t worry about ROI during exploration.
Focus on learning and engaging with the technology
Failure is valuable!
those are some of the most interesting conversations that we have
It doesn’t have to be a success.
Attempts that don’t work still provide insights
We’re going to focus on the core building blocks.
All the incredible things you see AI do
decompose to just a few key ingredients.
Our goal is to have fun and build intuition
through hands-on experience.

| Role | Description |
|---|---|
system_prompt |
Instructions from the developer (that’s you!) to set the behavior of the assistant |
user |
Messages from the person interacting with the assistant |
assistant |
The AI model’s responses to the user |

R

Python
ellmer
❓ What are the user and assistant roles in this example?
ellmer
❓ What about the system prompt?
ellmer
<Chat OpenAI/gpt-4.1 turns=3 tokens=25/28 $0.00>
── system [0] ───────────────────────────────────────
You are a dad joke machine.
── user [25] ────────────────────────────────────────
Tell me a joke about R.
── assistant [28] ───────────────────────────────────
Why did the letter R get invited to all the pirate parties?
Because it always knows how to *arr-r-ive* in style!02_word-gameSet up a chat with a system prompt:
You are playing a word guessing game. At each turn, guess the word and tell us what it is.
Ask: In British English, guess the word for the person who lives next door.
Ask: What helps a car move smoothly down the road?
Create a new, empty chat and ask the second question again.
How do the answers to 3 and 4 differ? Why?
clearbot👨💻 _demos/03_clearbot/app.py
System prompt:
First question:
Second question:

You write some words
The ChatGPT continues writing words
You think you’re having a conversation
Chatting with a Generative Pre-trained Transformer
LLM → Large Language Model
If you read everything
ever written…
Books and stories
Websites and articles
Poems and jokes
Questions and answers
…then you could…
un|con|ventionaltoken-possibilities👨💻 _demos/04_token-possibilities/app.R
| Console | Browser | |
|---|---|---|
![]() |
live_console(chat) |
live_browser(chat) |
![]() |
chat.console() |
chat.app() |
05_liveYour job: write a groan-worthy roast of Hadley Wickham
Bonus points for puns, rhymes, and one-liners
Don’t be mean
Share your best on Discord 😉
03:00


Start with the shinyapp snippet
Load {shinychat} and {ellmer}
Use the shinychat chat module
Create and hook up a chat client to use in the app
Why is this not a great idea?


Start with the shinyapp snippet
Remove the parts we don’t need
Create a chatlas chat client
Add the Chat UI and server logic (client and chat aren’t connected yet!)
When the user submits a message…
import chatlas
from shiny import App, ui
app_ui = ui.page_fillable(
ui.chat_ui("chat")
)
def server(input, output, session):
client = chatlas.ChatOpenAI()
chat = ui.Chat("chat")
@chat.on_user_submit
async def _(user_input: str):
# Send input to LLM
# Send response back to UI
app = App(app_ui, server)we’ll send the input to the LLM…
import chatlas
from shiny import App, ui
app_ui = ui.page_fillable(
ui.chat_ui("chat")
)
def server(input, output, session):
client = chatlas.ChatOpenAI()
chat = ui.Chat("chat", client)
@chat.on_user_submit
async def _(user_input: str):
response = await client.stream_async(user_input)
# Send response back to UI
app = App(app_ui, server)…and then stream the response back to the UI.
import chatlas
from shiny import App, ui
app_ui = ui.page_fillable(
ui.chat_ui("chat")
)
def server(input, output, session):
client = chatlas.ChatOpenAI()
chat = ui.Chat("chat", client)
@chat.on_user_submit
async def _(user_input: str):
response = await client.stream_async(user_input)
await chat.append_message_stream(response)
app = App(app_ui, server)06_word-gamesI’ve set up the basic Shiny app snippet and a system prompt.
Your job: create a chatbot that plays the word guessing game with you.
The twist: this time, you’re guessing the word.
07:00
[1] │ The secret word is sandwich.
'The secret word is elephant.'