Routing workflows — Dispatch by category

9 — Workflows & AgentsTrung cấp15 phút

Social media video script tool. User enters topic: - "programming" → educational content - "surfing" → entertainment content - "Python bug fix" → technical tutorial

Bạn sẽ học được
  • Router + specialized pipelines pattern
  • Claude classify → specialized prompt per category
  • When routing vs parallel
  • Implement với categorical dispatch

Routing pattern

Input goes 1 pipeline, not all.

┌──────────────────────────────────────────────┐
│                                              │
│  User input                                  │
│    │                                         │
│    ▼                                         │
│  Router (Claude) — classify                  │
│    │                                         │
│    ├─ Entertainment → pipeline_entertainment │
│    ├─ Educational  → pipeline_educational   │
│    ├─ Comedy       → pipeline_comedy        │
│    ├─ Personal vlog → pipeline_personal     │
│    ├─ Review       → pipeline_review        │
│    └─ Storytelling  → pipeline_story        │
│                                              │
│  Each pipeline specialized prompt + tools    │
│                                              │
└──────────────────────────────────────────────┘

Categorization step

Haiku — classification simple + cheap.

async def categorize(topic: str) -> str:
    prompt = f"""Categorize this video topic into one of:

Categories:
- Entertainment — high energy, trendy, cultural references
- Educational — clear explanations, concepts
- Comedy — unexpected, clever timing
- Personal vlog — authentic, conversational
- Reviews — decisive, product-focused
- Storytelling — immersive, emotional

Topic: {topic}

Return only the category name."""
    
    response = await client.messages.create(
        model="claude-haiku-4-5",  # fast + cheap for classify
        max_tokens=50,
        messages=[{"role": "user", "content": prompt}],
        temperature=0  # deterministic
    )
    return response.content[0].text.strip()

Specialized pipelines

Each category has its own prompt template:

Each category prompt optimized independently.

PIPELINES = {
    "Educational": """Write educational video script about {topic}.

Style:
- Clear explanations transforming complex → digestible
- Use concrete examples
- Include 1 surprising fact
- Short sentences
- Target audience: curious beginner

Structure:
- Hook (8 sec)
- 3 key points
- Quick recap

Format: markdown with timing cues.""",

    "Entertainment": """Write entertainment video script about {topic}.

Style:
- High energy, trendy language
- Cultural references
- Quick pace
- Strong hook

Target: 15-second attention span audience.""",

    "Comedy": """Write comedy video script about {topic}.

Style:
- Unexpected twists
- Setup-punchline
- Visual gags implied
- Keep it sharp

Length: 30 seconds.""",

    # ... etc
}


async def generate_script(topic: str, category: str) -> str:
    template = PIPELINES.get(category, PIPELINES["Educational"])  # fallback
    prompt = template.format(topic=topic)
    
    response = await client.messages.create(
        model="claude-sonnet-5-20260205",  # Sonnet for quality
        max_tokens=2000,
        messages=[{"role": "user", "content": prompt}]
    )
    return response.content[0].text

Full workflow

async def video_workflow(topic: str):
    # 1. Categorize
    category = await categorize(topic)
    print(f"Category: {category}")
    
    # 2. Generate specialized
    script = await generate_script(topic, category)
    print(f"Script:\n{script}")
    
    return {
        "topic": topic,
        "category": category,
        "script": script
    }


result = await video_workflow("Python functions explained simply")
# category: Educational
# script: [educational-style script]

Advantages

1. Higher quality per category

Each prompt tested + tuned cho its category. Better than generic.

2. Easier to improve

Low output cho "Comedy"? Improve only PIPELINES["Comedy"]. Others unaffected.

3. Add category without break

Don't touch others.

4. Model routing

Educational → Haiku (simpler). Creative → Opus (quality).

PIPELINES["Tutorial"] = "..."  # new

4. Model routing

Save cost via right model.

MODEL_MAP = {
    "Educational": "claude-haiku-4-5",
    "Comedy": "claude-opus-4-8",  # harder
    "Storytelling": "claude-opus-4-8",
    # ...
}

Routing vs parallelization

Parallelization (bài 6.75): analyze cho all categories, pick best.

Routing: classify first, process 1.

Routing cheaper, simpler, more scalable. Use when classification reliable.

ParallelRouting
CostN × cost1 cost
LatencyMax of NSequential (classify → process)
QualityBest of NOnly 1 (must classify correctly)
WhenUnsure category, need bestClear categories, classify reliable

Routing with fallback

Classification confidence low → dùng default pipeline:

async def categorize_with_confidence(topic):
    prompt = f"""Classify: {topic}

Return JSON:
{{"category": "...", "confidence": 0-1}}"""
    
    response = await claude(prompt)
    result = json.loads(response)
    
    if result["confidence"] < 0.7:
        return "Educational"  # safe default
    return result["category"]

Multi-stage routing

Hierarchical routing when categories many/nested.

Input
  │
  ▼
Coarse router: "Is this technical or creative?"
  │
  ├─ Technical → sub-router: "Is this code or concept?"
  │                    │
  │                    ├─ Code → code pipeline
  │                    └─ Concept → concept pipeline
  │
  └─ Creative → sub-router: "Is this entertainment or art?"
                       │
                       ├─ Entertainment → entertainment pipeline
                       └─ Art → art pipeline

Use cases

🎧 Customer support

Router: Bug / Feature / Billing / General → specialized responders.

📝 Content generation

Routes by topic type → specialized prompts.

💼 Sales

Router: Enterprise / SMB / Consumer → different sales scripts.

🏥 Medical triage (simulated, not real)

Router: Urgent / Non-urgent / Scheduled → different protocols.

🎨 Creative apps

Router: Photo / Video / Music / Text → different tool chains.

Implementation checklist

  • [ ] Categorize prompt tested on 20 diverse inputs
  • [ ] Classifier confidence ≥ 0.8 on validation set
  • [ ] Each pipeline has specialized prompt
  • [ ] Fallback pipeline if confidence low
  • [ ] Monitor routing distribution (catch bias)
  • [ ] Eval per pipeline separately

Anti-patterns

❌ Too many categories

20 categories → classification unreliable, pipelines overhead.

Fix: 3-8 categories. Simplify if more.

❌ Overlapping categories

"Educational" vs "Tutorial" — Claude confused.

Fix: Clear, mutually exclusive categories.

❌ No validation set

Never tested classifier accuracy → deploy broken.

Fix: Label 100 diverse examples. Eval classifier against.

❌ Router model overkill

Opus for classify → expensive.

Fix: Haiku for classify. Sonnet/Opus for specialized pipeline.

Áp dụng ngay

Bài tập 1: Implement simple router (30 phút)

Build 2-pipeline router cho app của bạn:

Test với 10 inputs — correct dispatch?

Bài tập 2: Eval routing accuracy (20 phút)

Label 30 inputs với expected category. Run classifier. Compute accuracy.

Target: > 90%. Nếu < 80%, tune classifier prompt.

  • 1 classifier prompt
  • 2 specialized pipelines

Tóm tắt

🎯 Routing = classify first, specialized pipeline second.

🎯 Each pipeline independently optimized. Add/remove easy.

🎯 Classifier cheap (Haiku + temp=0). Pipelines quality (Sonnet).

🎯 Fallback when confidence low.

🎯 3-8 categories sweet spot. Mutually exclusive.

Nội dung này có hữu ích không?