
Workflow Basics: Linear Chains
workflow-basics.Rmd
Introduction
Workflows in llmr allow you to chain together multiple processing steps to create sophisticated data processing pipelines. The most fundamental workflow pattern is the linear chain, where data flows sequentially through a series of steps.
This vignette introduces the basics of workflows by showing how to create simple linear chains using both regular R functions and AI agents as steps.
What You’ll Learn
By the end of this guide, you’ll understand how to:
- Create workflow steps from R functions
- Create workflow steps from AI agents
- Chain steps together using the
%->%
operator - Execute workflows with input data
- Understand the flexibility of mixing functions and agents
Prerequisites
library(llmr)
#>
#> Attaching package: 'llmr'
#> The following object is masked from 'package:stats':
#>
#> step
Basic Workflow Concepts
Steps
A step is the fundamental building block of a workflow. Steps can be created from: - R functions - For deterministic processing - AI agents - For intelligent, context-aware processing
Example 1: Function-Based Linear Workflow
Let’s start with a simple workflow using regular R functions:
# Define simple processing functions
add_ten <- function(x) {
cat("Adding 10 to", x, "\n")
x + 10
}
multiply_by_two <- function(x) {
cat("Multiplying", x, "by 2\n")
x * 2
}
subtract_five <- function(x) {
cat("Subtracting 5 from", x, "\n")
x - 5
}
# Create workflow steps and chain them together inline
math_workflow <- step(add_ten, name = "add_ten") %->%
step(multiply_by_two, name = "multiply_two") %->%
step(subtract_five, name = "subtract_five")
# View the workflow structure
print(math_workflow)
#> Workflow: <unnamed>
#> Nodes: 3 | Edges: 2
#>
#> ┌─ ⚙️ add_ten
#> │
#> ├─ ⚙️ multiply_two
#> │
#> └─ ⚙️ subtract_five
# Execute the workflow
input_value <- 5
result <- execute(math_workflow, input_value)
#> > 2025-06-19 18:55:22 [WORKFLOW] Executing node: add_ten
#> Adding 10 to 5
#> > 2025-06-19 18:55:22 [WORKFLOW] Executing node: multiply_two
#> Multiplying 15 by 2
#> > 2025-06-19 18:55:22 [WORKFLOW] Executing node: subtract_five
#> Subtracting 5 from 30
print(result) # Should be 25: ((5 + 10) * 2) - 5 = 25
#> [1] 25
Key Points: - Each function takes one input and
returns one output - The step()
function wraps your
function for use in workflows - The %->%
operator chains
steps left-to-right - execute()
runs the entire
workflow
Example 2: Agent-Based Linear Workflow
Now let’s create a workflow using AI agents for text processing:
# Create specialized agents using the factory pattern
summarizer <- new_agent("summarizer", new_anthropic)
analyzer <- new_agent("analyzer", new_anthropic)
formatter <- new_agent("formatter", new_anthropic)
# Configure each agent with specific instructions
set_system_prompt(
summarizer,
"You are a text summarizer. Provide concise, one-sentence summaries."
)
set_system_prompt(
analyzer,
"You are a sentiment analyzer. Analyze the emotional tone and return just the sentiment (positive/negative/neutral)."
)
set_system_prompt(
formatter,
"You are a formatter. Take the previous analysis and format it as: 'Summary: [summary] | Sentiment: [sentiment]'"
)
# Create workflow by chaining agent steps inline
text_workflow <- step(summarizer, name = "summarize") %->%
step(analyzer, name = "analyze_sentiment") %->%
step(formatter, name = "format_output")
# View the workflow structure
print(text_workflow)
# Execute the workflow
input_text <- "The new product launch was incredibly successful, exceeding all our expectations.
Customers are thrilled with the innovative features and the team is celebrating this major milestone."
result <- execute(text_workflow, input_text)
print(result)
Key Points: - Agents work just like functions in workflows - Each agent processes the output from the previous step - System prompts define each agent’s specific role - The workflow creates a sophisticated text processing pipeline
Example 3: Mixed Function and Agent Workflow
The real power comes from mixing functions and agents in the same workflow:
# Function to preprocess text
clean_text <- function(text) {
# Remove extra whitespace and convert to lowercase
cleaned <- trimws(tolower(text))
cat("Cleaned text:", substr(cleaned, 1, 50), "...\n")
cleaned
}
# Function to add metadata
add_metadata <- function(analysis) {
# Add timestamp and word count to the analysis
timestamp <- Sys.time()
word_count <- length(strsplit(analysis, "\\s+")[[1]])
result <- paste0(
"Analysis: ", analysis, "\n",
"Generated: ", timestamp, "\n",
"Word count: ", word_count
)
cat("Added metadata\n")
result
}
# Create an agent for the core analysis
analyzer <- new_agent("text_analyzer", new_anthropic)
set_system_prompt(
analyzer,
"Analyze the given text and provide insights about its main themes, tone, and key messages. Be concise but thorough."
)
# Create mixed workflow: function -> agent -> function
mixed_workflow <- step(clean_text, name = "preprocess") %->%
step(analyzer, name = "analyze") %->%
step(add_metadata, name = "finalize")
# View the workflow structure
print(mixed_workflow)
# Execute the mixed workflow
input_text <- " THE QUARTERLY RESULTS show STRONG GROWTH across all sectors! "
result <- execute(mixed_workflow, input_text)
print(result)
Key Points: - Functions and agents can be mixed freely in workflows - Functions handle deterministic processing (cleaning, formatting) - Agents handle intelligent analysis and interpretation - This creates powerful hybrid processing pipelines
Best Practices
1. Keep Steps Simple
Each step should have a single, clear responsibility:
# Good: Single responsibility
validate_input <- function(x) {
if (!is.numeric(x)) stop("Input must be numeric")
x
}
# Good: Single transformation
double_value <- function(x) x * 2
# Better than one complex function doing both
Common Patterns
Full Processing Pipeline
complete_pipeline <- preprocessing %->% analysis
What’s Next?
Now that you understand linear workflows, you can explore:
- Conditional workflows - Branching based on data or conditions
-
Parallel workflows - Processing multiple paths
simultaneously
- Complex workflows - Combining linear, conditional, and parallel patterns
- Workflow composition - Building larger workflows from smaller ones
Summary
Linear workflows provide a powerful way to chain together processing steps:
- Steps can be created from both functions and agents
-
Chains use the
%->%
operator to connect steps - Mixed workflows combine the deterministic power of functions with the intelligence of agents
- Simple patterns can be composed into sophisticated processing pipelines
The flexibility to mix functions and agents makes llmr workflows incredibly versatile for building everything from simple data processing pipelines to complex AI-powered analysis systems.