Introduction
dsprrr is built on top of ellmer, Posit’s R package for LLM interactions. This vignette explores advanced integration patterns that leverage ellmer’s full capabilities.
Parallel Processing
dsprrr supports two concurrent backends for batch operations. Batch
execution is sequential unless you supply
concurrency_control().
Method 1: mirai
Use mirai for multi-process parallelism:
mod <- module(signature("text -> sentiment"))
# Process multiple items in parallel using mirai
results <- run(
mod,
text = c("I love this!", "This is terrible", "It's okay"),
.concurrency = concurrency_control(
backend = "mirai",
max_active = 3L
)
)Method 2: ellmer Native
For more efficient parallelism, use ellmer’s native
parallel_chat_structured():
results <- run(
mod,
text = c("I love this!", "This is terrible", "It's okay"),
.concurrency = concurrency_control(
backend = "ellmer",
max_active = 3L
)
)The ellmer method is more efficient because: - Single process (no R subprocess overhead) - Native async HTTP requests - Better error handling - Automatic rate limit handling
Converting Modules to ellmer Tools
dsprrr modules can be converted to ellmer tools for use in agentic workflows:
# Create a sentiment analysis module
sentiment_mod <- module(
signature("text -> sentiment: enum('positive', 'negative', 'neutral')"))
# Convert to an ellmer tool
sentiment_tool <- as_ellmer_tool(
sentiment_mod,
name = "analyze_sentiment",
description = "Analyze the sentiment of text"
)
# The tool can now be registered with any Chat
chat <- chat_openai()
chat$register_tool(sentiment_tool)
# The LLM can now use the sentiment tool
chat$chat("Analyze the sentiment of: 'I love this product!'")Leveraging ellmer’s Cost Tracking
ellmer provides robust token and cost tracking. dsprrr integrates with this via accessor functions:
# After running some predictions
mod <- module(signature("question -> answer"))
result <- run(
mod,
question = "What is 2+2?",
.llm = chat_openai(),
.return_format = "structured"
)
# Get cost and token info from results using public accessors
get_cost(result) # Cost in dollars
get_tokens(result) # Token counts
# For session-wide aggregates
session_cost()Advanced Chat Patterns
Using Chat Objects Across Multiple Calls
# Create a Chat and reuse it
chat <- chat_openai()
mod <- module(signature("q -> a"))
# Reuse the same runtime across calls
result1 <- run(mod, q = "What is R?", .llm = chat)
result2 <- run(mod, q = "What about Python?", .llm = chat)Default Chat Management
# Set a default Chat for module execution
set_default_chat(chat_openai(model = "gpt-4o"))
# run() uses the default when neither the call nor module supplies a Chat
result <- run(module(signature("q -> a")), q = "What is 2+2?")
# Check current configuration
dsprrr_sitrep()
# Clear when done
clear_default_chat()Multimodal Support
dsprrr inherits ellmer’s multimodal capabilities:
mod <- module(
signature("image, question -> answer"))
# Pass an image via ellmer Content objects
result <- run(
mod,
image = ellmer::ContentImageRemote("https://example.com/image.jpg"),
question = "What is in this image?"
)Streaming Responses
For long-form generation, use streaming:
mod <- module(
signature("topic -> essay"))
# Stream with callback - pass named arguments directly
mod$stream(
topic = "The future of AI",
callback = function(chunk) cat(chunk)
)
# Or use async streaming with promises
library(promises)
stream_async(mod, topic = "The future of AI") %...>%
print() # Prints the final result when completeError Handling and Retries
ellmer handles retries automatically. Configure via options:
# Set max retries (default is 3)
options(ellmer_max_tries = 5)
# Set timeout (default is 60 seconds)
options(ellmer_timeout = 120)
# dsprrr wraps errors with helpful context
tryCatch(
run(module(signature("q -> a")), q = "test"),
error = function(e) {
# Error includes model info, suggestions, etc.
print(e)
}
)Summary
Key integration points with ellmer:
- Parallel processing: Choose between mirai (multi-process) or ellmer native (async HTTP)
-
Tool integration: Convert modules to ellmer tools
with
as_ellmer_tool() -
Cost tracking: Use
get_cost(),get_tokens(), andsession_cost()for usage tracking -
Chat management: Use
set_default_chat()for session-wide defaults - Multimodal: Pass ellmer Content objects for images, PDFs, etc.
-
Streaming: Use
stream()orstream_async()for long-form generation - Error handling: Benefit from ellmer’s automatic retries and dsprrr’s context-rich errors