Pipelines
Build composable AI workflows with runnable pipelines - chain models, messages, and transformers for powerful data processing.
Pipelines are the foundation of BoxLang AI's composable architecture. They allow you to chain AI operations, create reusable workflows, and build complex data processing flows with simple, readable code.
π Table of Contents
π― What are Pipelines?
Pipelines are composable workflows where data flows through a sequence of operations. Each operation (called a "runnable") processes the input and passes the result to the next step.
Key Benefits
β Composability - Mix and match components like LEGO blocks β Reusability - Define once, execute with different inputs β Readability - Pipelines read like natural workflows β Flexibility - Swap providers, add steps, modify behavior easily β Testability - Each step can be tested independently β Maintainability - Changes are isolated to specific steps
Real-World Analogy
Think of a pipeline like an assembly line in a factory:
Raw materials (input) enter the line
Each station (runnable) performs a specific operation
Output from one station becomes input to the next
Final product (result) exits the line
ποΈ Pipeline Architecture
The IAiRunnable Interface
All pipeline components implement the IAiRunnable interface:
This consistent interface means everything can be chained with everything else.
Built-in Runnable Components
AiMessage
Message templates
aiMessage().user( "Hello ${name}" )
AiModel
AI provider wrapper
aiModel( "openai" )
AiAgent
Autonomous agent
aiAgent( model, memory, tools )
AiTransformRunnable
Data transformer
aiTransform( r => r.content )
AiRunnableSequence
Pipeline chain
new AiRunnableSequence( [step1, step2] )
Pipeline Flow
Data flows left-to-right:
Input data enters the first step
Each step's output becomes the next step's input
Final step's output is the pipeline result
π¨ Building Pipelines
There are multiple ways to build pipelines, all creating the same underlying AiRunnableSequence.
Method 1: Fluent Chaining with .to()
.to()The most common approach - chain components using .to():
How it works:
Each
.to()call creates a newAiRunnableSequenceThe sequence contains all previous steps + the new step
Pipelines are immutable - chaining creates new sequences
Method 2: Helper Methods
Convenience methods for common patterns:
Method 3: Explicit Sequence
For advanced scenarios, create sequences manually:
When to use:
Building pipelines dynamically
Conditional step inclusion
Complex branching logic
π₯ Input and Output Flow
Understanding how data moves through pipelines is crucial for building complex workflows.
Data Passing
Each step receives the previous step's output as its input:
Step-by-step:
Input
5β Step 1:5 * 2 = 10Input
10β Step 2:10 + 10 = 20Input
20β Step 3:20 / 2 = 10Output:
10
Input Types
Different components accept different input types:
AiMessage
Struct (bindings)
{ name: "Alice", role: "admin" }
AiModel
Messages array or AiMessage
[{ role: "user", content: "Hi" }]
AiTransform
Any type
String, struct, array, etc.
AiAgent
String (user message)
"What's the weather?"
Example - Mixed inputs:
Output Types
The final output depends on the last step in the pipeline:
π Transform Pipelines
Transformations are the glue that connects incompatible steps and shapes data to your needs.
Simple Transformations
Extract, format, or modify data:
Pre-Processing
Clean or enhance input before sending to AI:
Post-Processing
Process AI output after generation:
Bidirectional Processing
Combine pre-processing and post-processing:
π Multi-Step Workflows
Pipelines excel at multi-stage workflows where each step has a specific purpose.
Draft-Refine Pattern
Use a fast model for drafts, then refine with a better model:
Benefits:
Faster initial generation (cheap model)
Higher quality final output (better model)
Cost optimization (only use expensive model for refinement)
Analysis-Enhancement Pattern
Analyze content, then enhance based on analysis:
Validation Pipeline
Generate, validate, and retry if needed:
π Multi-Model Pipelines
Leverage different models' strengths in a single workflow.
Model Specialization
Use each model for what it does best:
Parallel Processing
Run multiple models simultaneously (not sequential pipeline):
Dynamic Model Selection
Choose model based on input characteristics:
β»οΈ Reusable Templates
One of the most powerful features of pipelines is reusability - define once, execute many times.
Parameterized Pipelines
Create templates that accept different inputs:
Pipeline Factories
Generate customized pipelines on demand:
Composable Building Blocks
Build complex pipelines from reusable components:
π‘ Streaming Pipelines
Pipelines support streaming for real-time AI responses.
Stream Execution
Use .stream() instead of .run():
How it works:
All steps except the last execute normally
The last step streams its output
Your callback receives each chunk
Stream Processing
Process chunks in real-time:
Conditional Streaming
Choose streaming vs. normal execution:
Note: Transforms run after streaming completes, not per-chunk:
βοΈ Parameters and Options
Pipelines support default and runtime configuration.
Default Parameters
Set parameters that apply to all executions:
Runtime Parameters
Override defaults at execution time:
Merge behavior:
Runtime parameters override defaults
Unspecified parameters use defaults
Input bindings are separate from parameters
Options vs Parameters
Parameters configure the AI provider (model, temperature, etc.) Options configure the runnable behavior (returnFormat, timeout, logging)
π¬ Pipeline Events
Pipelines emit events during execution for monitoring and debugging.
Available Events
beforeAIPipelineRun
Before pipeline execution
{ sequence, name, stepCount, steps, input, params, options }
afterAIPipelineRun
After pipeline execution
{ sequence, name, stepCount, steps, input, result, executionTime }
Event Interception
Listen to pipeline events in your application:
Use cases:
Performance monitoring
Debugging workflows
Logging and auditing
Cost tracking (count tokens)
Error tracking
π Debugging Pipelines
Tools for understanding and troubleshooting pipelines.
Print Pipeline Structure
Use .print() to see pipeline composition:
Inspect Steps
Get detailed step information:
Step-by-Step Execution
Execute each step manually for debugging:
β‘ Performance Optimization
Tips for building efficient pipelines.
Choose the Right Model
Use cheaper/faster models for simple tasks:
Minimize Steps
Combine transformations when possible:
Cache Results
Cache expensive AI calls:
Parallel Execution
For independent tasks, run pipelines in parallel (using threads):
π Error Handling
Robust error handling for production pipelines.
Try-Catch Patterns
Wrap pipeline execution in error handlers:
Graceful Degradation
Provide fallbacks for AI failures:
Validation Pipelines
Validate at each critical step:
π Best Practices
Design Principles
β Single Responsibility - Each step does one thing well β Immutability - Don't modify pipeline state during execution β Composition - Build complex workflows from simple components β Reusability - Design pipelines as reusable templates β Explicit > Implicit - Be clear about data transformations
Common Patterns
Extract-Transform-Load (ETL)
Template-Execute-Format
Validate-Process-Validate
Anti-Patterns to Avoid
β Overly Long Pipelines (>10 steps) - Break into sub-pipelines β Side Effects in Transforms - Keep transforms pure (no DB writes, no external API calls) β Tight Coupling - Don't hardcode provider-specific logic β Missing Error Handling - Always handle AI failures gracefully β Ignoring Performance - Profile and optimize expensive operations
π Related Documentation
AI Models - Configure and use AI providers
Messages - Build message templates
Transformers - Data transformation patterns
Streaming - Real-time response handling
Agents - Autonomous AI workflows
Events - Event interception and monitoring
Ready to build complex AI workflows? Start with simple pipelines and gradually add complexity as your needs grow. The composable architecture scales from basic scripts to enterprise applications.
Last updated