Multi-Step Workflows
This tutorial covers building complex workflows with branching, composition, and error handling.
Branching Workflows
Route execution based on decisions:
@agent(name="support-router")
class SupportRouter:
@workflow
def handle_ticket(self, ctx):
# Step 1: Classify
category = ctx.call(self.classify)
# Step 2: Route based on classification
if category == "billing":
return ctx.call(self.handle_billing)
elif category == "technical":
return ctx.call(self.handle_technical)
else:
return ctx.call(self.handle_general)
@decision
def classify(self, ctx):
return ctx.llm.classify(ctx.input.message,
categories=["billing", "technical", "general"])
@workflow
def handle_billing(self, ctx):
# Billing-specific workflow
pass
@workflow
def handle_technical(self, ctx):
# Technical-specific workflow
pass
@workflow
def handle_general(self, ctx):
# General handling
pass
Composing Workflows
Workflows can call other workflows:
@agent(name="order-processor")
class OrderProcessor:
@workflow
def process_order(self, ctx):
# Validate
validated = ctx.call(self.validate_order)
# Process payment
payment = ctx.call(self.process_payment, order=validated)
# Fulfill
fulfillment = ctx.call(self.fulfill_order,
order=validated,
payment=payment
)
return fulfillment
@workflow
def validate_order(self, ctx):
# Validation logic
return ctx.input.order
@workflow
def process_payment(self, ctx, order):
# Payment processing
return {"status": "success", "order_id": order["id"]}
@workflow
def fulfill_order(self, ctx, order, payment):
# Fulfillment logic
return {"shipped": True}
Error Handling
Handle errors gracefully:
@workflow
def resilient_workflow(self, ctx):
try:
result = ctx.call(self.risky_operation)
return result
except Exception as e:
# Log and handle error
return ctx.call(self.handle_error, error=str(e))
Next Steps
- Governance Tutorial - Add policies to your workflows
- Production Guide - Deploy workflows