Prompt Chaining & Workflows
Module 07 — Prompt Chaining & Workflows
Goal: Learn to break complex tasks into a sequence (or graph) of smaller prompts, where each step’s output feeds the next. Chaining turns unreliable one-shot mega-prompts into robust, debuggable pipelines.
7.1 Why chain at all?
Stuffing a complex job into one giant prompt (“research this company, analyze competitors, write a 10-page strategy, then format it as a deck outline”) usually produces shallow, error-prone output. The model juggles too much at once, drops requirements, and you can’t tell where it went wrong.
Prompt chaining = splitting the job into a series of focused steps, each its own prompt/LLM call, passing results forward:
[Step 1] ── output ──> [Step 2] ── output ──> [Step 3] ── final result
Benefits:
- Higher quality: each step has one clear job and full attention.
- Debuggable: you can inspect each intermediate output and fix the exact broken step.
- Reliable & testable: you can evaluate and improve steps independently (Module 09).
- Reusable: steps become building blocks across projects.
- Controllable: you can insert validation, tools, or human review between steps.
Principle: Prefer many small, reliable steps over one big, fragile prompt — for the same reason you write small functions instead of one giant one.
7.2 The simplest chain: sequential steps
Each step is a separate model call. The classic three-stage writing pipeline:
Step 1 — OUTLINE:
"Create a detailed outline for a blog post about {topic}. 5–7 sections,
each with a one-line description."
Step 2 — DRAFT (input: the outline):
"Write a full blog post following this outline exactly:
{outline}
Friendly tone, ~800 words."
Step 3 — POLISH (input: the draft):
"Improve this draft: tighten wording, fix flow, add a strong intro and
conclusion. Keep it ~800 words.
{draft}"
Each call is focused; the output of one becomes input to the next. You (or your code) orchestrate the hand-offs.
7.3 Common chaining patterns
Pattern A — Pipeline (linear)
Step 1 → 2 → 3, as above. Best when the task has natural sequential stages (extract → transform → format).
Pattern B — Decompose then combine (map-reduce)
Split input into pieces, process each separately (“map”), then merge (“reduce”). Great for long documents:
MAP: For each chapter, summarize it in 3 bullets. (N calls, one per chapter)
REDUCE: Combine all chapter summaries into one 1-page executive summary.
This beats trying to summarize a huge document in one shot and works around context limits.
Pattern C — Router / classifier first
A cheap first call classifies the request, then routes to a specialized prompt (or model):
Step 1 (router): "Classify this request as: billing, technical, or sales."
Step 2: send to the matching specialized prompt/tools for that category.
Routing keeps each downstream prompt simple and lets you use the right tool/model per category (cost and quality win).
Pattern D — Generate → Evaluate → Refine (self-correction loop)
One step produces, another critiques, a third revises — possibly looping until a quality bar is met:
1. Generate a draft answer.
2. Critique it against a checklist (accuracy, completeness, tone).
3. If issues found, revise and repeat (up to N times).
Use an explicit checklist or even a separate “judge” prompt (Module 09) as the evaluator.
Pattern E — Parallel sampling + selection
Generate several candidates in parallel (e.g., 3 different headlines), then a final step picks or merges the best. Improves quality for creative/subjective tasks.
Pattern F — Orchestrator / agent
A controller LLM decides which steps/tools to run dynamically, rather than a fixed sequence. This shades into agents (Module 08). Fixed chains are predictable; agents are flexible but harder to control.
7.4 Worked example: a customer-feedback pipeline
Goal: turn a pile of raw reviews into an action list for the product team.
Step 1 — EXTRACT (per review, structured output, Module 05):
For each review, output JSON: {theme, sentiment, severity (1-5), quote}
Step 2 — CLUSTER:
Given all extracted items, group them into the top 5 recurring themes with counts.
Step 3 — PRIORITIZE:
Rank the 5 themes by (frequency × average severity). Explain the ranking.
Step 4 — RECOMMEND:
For the top 3 themes, propose one concrete product action each, with effort (S/M/L).
Step 5 — FORMAT:
Produce a one-page summary for the product lead: ranked themes, evidence quotes,
recommended actions.
Notice: structured output (5) at the extract step, a map-reduce shape (1 is per-item, 2 reduces), and a clean final formatting step. Each is independently testable.
7.5 Passing data between steps cleanly
The reliability of a chain depends on clean hand-offs:
- Use structured output (JSON) between steps when the next step needs specific fields. Strings are fine for prose hand-offs (outline → draft), but JSON prevents ambiguity for data.
- Keep each step’s output minimal and well-labeled. Don’t pass an entire chatty response into the next prompt; pass just what’s needed.
- Validate between steps. Parse/validate JSON (Module 05) before feeding it forward; retry or repair on failure so errors don’t cascade.
- Be mindful of context size. In long pipelines, summarize or trim earlier outputs instead of carrying everything forward.
7.6 Orchestration: how steps are run
Two ways to run a chain:
- By hand / in the chat UI: you copy each output into the next prompt. Fine for learning and one-offs.
- In code: your program makes the calls in sequence, passing variables. This is how real systems work.
A code sketch:
outline = model(f"Outline a blog post about {topic} ...")
draft = model(f"Write a post following this outline:\n{outline}\n...")
final = model(f"Polish this draft:\n{draft}\n...")
return final
You can add branching (if classification == "billing": ...), loops (refine until good), parallel calls, tool calls (Module 06), and validation. Frameworks like LangChain, LlamaIndex, DSPy, or provider SDKs help build and manage chains/graphs, but you can go far with plain code — and plain code is easier to debug while learning. Start simple; adopt a framework only when the orchestration genuinely gets complex.
7.7 Chaining vs. one big prompt vs. agents
| Approach | When to use | Trade-off |
|---|---|---|
| Single prompt | Simple, self-contained task | Easiest, but fragile for complex jobs |
| Fixed chain | Complex task with known steps | Reliable, debuggable; you design the flow |
| Agent (dynamic) | Open-ended task, steps unknown in advance | Flexible but less predictable, harder to control/test |
Expert instinct: use the least powerful, most predictable approach that gets the job done. Reach for a fixed chain before an autonomous agent; reach for one good prompt before a chain. Predictability and debuggability are features.
7.8 Pitfalls and how to avoid them
| Pitfall | Fix |
|---|---|
| Errors cascade (a bad step 1 ruins everything) | Validate/repair between steps; add checks early |
| Over-engineering (a 9-step chain for a simple task) | Start with one prompt; split only when it actually fails |
| Losing track of intermediate state | Log every step’s input/output; name variables clearly |
| Context bloat in long chains | Summarize/trim outputs before passing forward |
| Inconsistent formats between steps | Use JSON contracts between steps; validate |
| Higher cost/latency (each step is a call) | Use cheaper/smaller models for easy steps (routing, extraction); cache repeats |
| Hard to debug as a black box | Inspect each intermediate output; test steps in isolation |
Exercises
- Build a 3-step chain (by hand). Pick a topic and run the Outline → Draft → Polish chain manually in a chatbot. Compare the final result to asking for the whole post in one prompt.
- Map-reduce. Take a long article. Split it into 3 parts; summarize each separately; then combine the three summaries into one. Compare to a single-shot summary of the whole thing.
- Router. Write a step-1 classifier prompt that labels a support message as billing/technical/sales, and three specialized step-2 prompts. Trace two example messages through the chain.
- Refine loop. Write a generate→critique→revise chain for a product tagline. Use an explicit 3-point checklist as the critique step. Do two refine passes.
- JSON hand-off. Make step 1 output JSON (
{theme, sentiment}) and step 2 consume those fields. Confirm the hand-off is unambiguous.
Key takeaways
- Chaining splits complex tasks into focused steps, each its own prompt, with outputs feeding forward.
- It improves quality, debuggability, testability, and control versus one giant prompt.
- Know the patterns: pipeline, map-reduce, router, generate-evaluate-refine, parallel-select, orchestrator.
- Pass data cleanly (JSON contracts), validate between steps, watch context/cost, and log everything.
- Prefer the simplest, most predictable approach that works: one prompt < fixed chain < agent.