Design multi-service architectures with RAW workflows as components
Installation
Details
Usage
After installing, this skill will be available to your AI coding assistant.
Verify installation:
npx agent-skills-cli listSkill Instructions
name: system-architecture description: Design multi-service architectures with RAW workflows as components
System Architecture Patterns
Use this skill when the user's requirements span multiple days, require webhooks, scheduling, or long-running state.
When to Build a System (vs Single Workflow)
Single RAW Workflow
Use for:
- Data processing tasks
- API integrations (fetch β transform β save)
- Report generation
- One-time executions
Multi-System Architecture
Use when you need:
- Long-running state (track entities across days/weeks)
- Multiple entry points (webhooks, scheduled triggers)
- Event-driven coordination (webhook β workflow β callback)
- Process orchestration (multi-step processes with waiting)
Architecture Components
1. RAW Workflows (The Workers)
RAW workflows are pure functions that:
- Take inputs
- Process data (API calls, transformations, LLM operations)
- Return outputs
- Are stateless and reusable
Example:
# .raw/workflows/analyze-cv/run.py
class AnalyzeCVWorkflow(BaseWorkflow[CVParams]):
@step("analyze")
def analyze(self) -> dict:
cv_text = self.params.cv_text
score = self.llm.score_candidate(cv_text)
return {"score": score, "qualified": score > 0.7}
2. FastAPI (The Coordinator)
FastAPI app provides:
- Webhooks for external triggers (form submissions, calendar events)
- REST API for status queries
- Database connection for state persistence
- Calls to RAW workflows via
subprocessor Python imports
Example:
# api/main.py
from fastapi import FastAPI
import subprocess
app = FastAPI()
@app.post("/webhooks/cv-submission")
async def handle_cv_submission(cv: CVSubmission):
# Save to database
candidate = await db.candidates.create(cv)
# Run RAW workflow for analysis
result = subprocess.run([
"raw", "run", "analyze-cv",
"--cv-text", cv.text
], capture_output=True)
# Update state based on result
await update_candidate(candidate.id, result)
return {"status": "processing"}
3. Temporal (The Orchestrator)
Temporal workflows manage:
- Multi-day processes
- Reliable scheduling (with retries)
- Durable state across service restarts
- Long-running processes with human interaction
Example:
# workflows/temporal/hiring_process.py
@workflow.defn
class HiringProcess:
@workflow.run
async def run(self, candidate_id: str) -> str:
# Step 1: Analyze CV (RAW workflow)
analysis = await workflow.execute_activity(
run_raw_workflow,
args=["analyze-cv", f"--id={candidate_id}"],
start_to_close_timeout=timedelta(minutes=5)
)
if not analysis["qualified"]:
await send_rejection_email(candidate_id)
return "rejected"
# Step 2: Schedule call
await send_scheduling_email(candidate_id)
# Wait for calendar event (webhook will signal workflow)
call_scheduled = await workflow.wait_condition(
lambda: self.call_scheduled,
timeout=timedelta(days=7)
)
# Step 3: Day of call (sleep until call time)
await workflow.sleep_until(call_scheduled.call_time)
# Trigger Twilio call
await make_outbound_call(candidate_id)
# Wait for call completion webhook
await workflow.wait_condition(lambda: self.call_completed)
# Step 4: Generate summary (RAW workflow)
summary = await workflow.execute_activity(
run_raw_workflow,
args=["generate-call-summary", f"--id={candidate_id}"],
start_to_close_timeout=timedelta(minutes=3)
)
return "completed"
4. Deployment (Docker + K8s)
Production deployment requires:
- Docker Compose for local development
- Kubernetes manifests for production
- Helm charts for configuration management
Example structure:
docker-compose.yml # Local dev environment
k8s/
deployment.yml # API deployment
service.yml # API service
ingress.yml # External access
postgres.yml # Database
temporal.yml # Temporal server
Common System Patterns
Pattern 1: Webhook β RAW β Database
Use case: Form submission triggers analysis and saves results
Components:
- FastAPI webhook endpoint
- RAW workflow for processing
- PostgreSQL for state
Flow:
- User submits form β POST /webhooks/submit
- FastAPI saves to database (status: pending)
- FastAPI calls
raw run analyze --id=123 - RAW workflow processes and returns result
- FastAPI updates database (status: complete)
Pattern 2: Temporal + RAW Multi-Day Process
Use case: Process spans multiple days with external events
Components:
- Temporal workflow for orchestration
- RAW workflows for data processing
- FastAPI for webhooks
- Database for state
Flow:
- Trigger starts Temporal workflow
- Workflow runs RAW workflow for initial processing
- Workflow schedules reminder (sleeps until date)
- External event triggers webhook β signals Temporal
- Workflow continues execution
- Workflow runs another RAW workflow for final step
Pattern 3: Scheduled Reports
Use case: Daily/weekly reports generated and sent
Components:
- Kubernetes CronJob
- RAW workflow for report generation
- Email/Slack integration
Flow:
- CronJob triggers at scheduled time
- Runs
raw run generate-report --date=today - RAW workflow queries database, generates report
- Saves to S3 and sends notification
Decision Tree
Does it need state across days? ββββNOββββ Single RAW Workflow
β
YES
β
β
Does it need webhooks? ββββNOββββ Temporal + RAW Workflows
β
YES
β
β
FastAPI + Temporal + RAW Workflows + Deployment
Code Generation Checklist
When generating a multi-system architecture:
- Create RAW workflows for data processing
- Create FastAPI app with webhook endpoints
- Add database models (SQLAlchemy or Pydantic)
- Create Temporal workflows for orchestration
- Add Docker Compose for local dev
- Create Kubernetes manifests for production
- Add tests for each component
- Document the architecture in README.md
Validation Gates
For multi-system architectures, add these gates:
builder:
gates:
default:
- validate # RAW workflow validation
- dry # RAW workflow dry run
optional:
api-test:
command: "pytest api/tests/ -v"
timeout_seconds: 60
temporal-validate:
command: "temporal workflow validate"
timeout_seconds: 30
docker-validate:
command: "docker-compose config"
timeout_seconds: 10
Key Principles
- RAW workflows are pure functions - No state, no side effects beyond outputs
- FastAPI coordinates - Handles webhooks, database, calls RAW workflows
- Temporal orchestrates - Manages multi-day processes reliably
- Deploy everything together - Docker Compose for dev, K8s for prod
This pattern keeps RAW workflows simple and reusable while building complex systems around them.
More by mpuig
View allDiscover AWS infrastructure and save to JSON. Use when user asks to "discover AWS", "explore AWS account", "scan AWS infrastructure", or "create infrastructure JSON".
Generate AWS architecture diagrams from infrastructure JSON. Use when user asks to "generate diagram", "create AWS diagram", "visualize infrastructure", or "draw architecture".
Understanding and passing workflow quality gates (validate, dry, pytest, ruff, typecheck)
Create reusable RAW tools that workflows can import. Use when the user asks to create a tool, extract reusable functionality, or build a new capability for workflows.
