Core Concepts and Workflow Patterns#

In the Quick Start notebook, you built a working workflow and learned the basics hands-on. This notebook deepens your understanding and teaches you three powerful workflow patterns.

What’s covered:

  • How data flows between nodes

  • Connection types (solid vs dotted lines)

  • Expressions in more detail

  • Test mode vs production

  • Three workflow patterns: Prompt Chaining, Routing, Parallelization


How Data Flows#

In Quick Start, you saw data move from Edit Fields to Basic LLM Chain. Here’s a deeper look at how this works.

Items#

n8n passes data as a list of items. Each item is a JSON object:

[
  { "topic": "coffee", "style": "funny" },
  { "topic": "rain", "style": "sad" }
]

When a node receives 2 items, it processes each one and outputs 2 results.

Input and Output#

Every node has:

  • Input — what it receives from the previous node

  • Output — what it sends to the next node

[Node A] ──output──▶ [Node B] ──output──▶ [Node C]
              (input)             (input)

Click any node after running to see both tabs in the Output Panel.


Connection Types#

You’ve seen two types of lines connecting nodes:

Line Type

What it means

Example

Solid line

Data flows from one node to the next

Edit Fields → LLM Chain

Dotted line

Capability connection (no data flows)

Chat Model → LLM Chain

Solid Lines = Data Flow#

When you connect nodes with a solid line, the output of the left node becomes the input of the right node. Data always flows left-to-right.

Dotted Lines = Capabilities#

Dotted lines connect sub-nodes that provide capabilities:

  • Chat Model → provides AI capability to LLM Chain

  • Memory → provides conversation history to AI Agent

  • Tools → provide actions to AI Agent

No data flows through dotted lines. They just say “this node can use that capability.”


Triggers#

Every workflow starts with a Trigger — the leftmost node that defines what starts the workflow.

Trigger

When it fires

Manual Trigger

You click “Execute Workflow”

Schedule Trigger

On a timer (hourly, daily, etc.)

Webhook Trigger

When another service sends a request

Chat Trigger

When a user sends a chat message

In this course: We use Manual Trigger for most examples. Chat Trigger appears in the AI Agent examples for conversations.


Test Mode vs Activated#

Mode

How it runs

When to use

Test

Click “Execute Workflow” manually

While building

Activated

Runs automatically when triggered

Production

Stay in Test mode while learning. This gives you control and lets you use pinned data.

To activate a workflow for production, toggle the Active switch in the top-right. But don’t do this while learning — you might trigger unexpected API calls.


Expressions Deep Dive#

In Quick Start, you used {{ $json.topic }} to pass data. Here’s a closer look at expressions.

The Basics#

Expression

What it does

{{ $json.field }}

Read a field from the previous node

{{ $json.user.name }}

Read a nested field

Hello {{ $json.name }}

Mix text with data

Fixed vs Expression Mode#

Every input field has two modes:

  • Fixed — literal text, {{ }} is treated as text

  • Expression — {{ }} is evaluated as code

If your expression isn’t working, check that you’re in Expression mode (click the field to toggle).

Referencing a Specific Node#

Sometimes you need data from a node that isn’t directly before the current one. There are two equivalent syntaxes:

{{ $node["Edit Fields"].json.topic }}
{{ $('Edit Fields').item.json.topic }}

Both work the same way. The $('Node Name') syntax is newer and shorter. Use whichever you prefer — just be consistent.

You’ll see this pattern in the Routing example, where specialists access the original input directly.


Common Expressions#

Beyond reading fields, n8n has built-in expressions for common tasks.

Date and Time:

Expression

Result

{{ $now }}

Current date and time

{{ $today }}

Today at midnight

{{ $now.format('yyyy-MM-dd') }}

Formatted: 2025-01-25

{{ $now.format('HH:mm') }}

Formatted: 14:30

Conditionals:

Expression

What it does

{{ $if($json.age > 18, "adult", "minor") }}

If-then-else

{{ $ifEmpty($json.name, "Anonymous") }}

Default if empty

Text Manipulation:

Expression

Result

{{ $json.name.toUpperCase() }}

JOHN

{{ $json.name.toLowerCase() }}

john

{{ $json.text.replace("old", "new") }}

Replace text

{{ $json.email.split("@")[0] }}

Get part before @

Workflow Info:

Expression

What it returns

{{ $workflow.name }}

Name of current workflow

{{ $execution.id }}

Unique ID of this run

{{ $itemIndex }}

Current item index (0, 1, 2…)

Tip: These work anywhere you can write expressions. Combine them: {{ $now.format('yyyy-MM-dd') }}: {{ $json.message.toUpperCase() }}


Quick Troubleshooting#

Problem

Solution

Expression shows literally

Switch from Fixed to Expression mode

Field not found

Check spelling and case in JSON view

Data seems stale

Check if a node is pinned

Node has red error

Click it and read the error in Output Panel


Core Concepts Summary#

Concept

Key Point

Items

Data flows as a list of JSON objects

Solid lines

Data flow between nodes

Dotted lines

Capability connections (no data)

Triggers

What starts the workflow

Test mode

Manual runs while building

Expressions

{{ $json.field }} to pass data dynamically

Common expressions

$now, $if(), .toUpperCase() for dates, logic, text

Pinning

Save output to avoid re-running


Workflow Examples: Three Patterns#

This section demonstrates three common workflow patterns. Import the pre-built workflows, run them, and observe how the nodes work together.

Note on credentials: These workflows require API credentials for an AI provider (OpenRouter, OpenAI, or Google). If you do not have credentials set up, you can still explore the workflow structure and understand what each node would do.


How to Import and Run a Workflow#

Each workflow provides a URL to import it:

Import from URL (recommended):

  1. Copy the URL from the workflow section (starts with https://raw.githubusercontent.com/...)

  2. In n8n, click Workflows → Add Workflow

  3. Click the three-dot menu (⋮) in the top-right

  4. Select Import from URL

  5. Paste the URL and click Import

  6. Click Save

Run:

  1. Open the workflow in the editor

  2. Make sure credentials are set up (Settings → Credentials)

  3. Click Execute Workflow in the top toolbar

  4. Click any node to see its output in the right panel

Cost safety: Keep workflows Inactive (toggle OFF) while learning. After the first successful AI call, Pin data (📌) on that node before editing downstream nodes — this prevents repeated API charges.


Pattern 1: Prompt Chaining#

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  Manual Trigger │────▶│   Edit Fields   │────▶│  Basic LLM #1   │────▶│  Basic LLM #2   │──...
└─────────────────┘     └─────────────────┘     └─────────────────┘     └─────────────────┘

Import via URL (copy and paste in n8n → Import from URL):

https://raw.githubusercontent.com/ezponda/ai-application-course-materials/main/_static/workflows/01_prompt_chaining.json

Nodes in This Pattern#

This pattern uses nodes you already know from Quick Start:

Node

What it does

Manual Trigger

Starts the workflow when you click “Execute Workflow”

Edit Fields (Set)

Creates or transforms data fields

Basic LLM Chain

Sends a prompt to an AI model and returns the response

The difference here: we chain multiple Basic LLM Chains in sequence, where each uses the previous one’s output.

What Problem This Solves#

Breaking a complex writing task into smaller steps improves quality. Instead of asking an LLM to “write a memo” in one shot, you ask it to: (1) create an outline, (2) improve the outline, (3) write the final draft. Each step builds on the previous result.

Node-by-Node Walkthrough#

┌──────────────────┐     ┌────────────────────────┐     ┌────────────────────────┐     ┌──────────────────┐
│   Manual Trigger │────▶│ Input — Writing Brief  │────▶│  Step 1 — Outline      │────▶│   Store Outline  │
└──────────────────┘     └────────────────────────┘     └────────────────────────┘     └──────────────────┘
                                                                                                │
        ┌───────────────────────────────────────────────────────────────────────────────────────┘
        ▼
┌────────────────────────┐     ┌────────────────────────┐     ┌────────────────────────┐     ┌────────────────────────┐
│  Step 2 — Improve      │────▶│   Store Improved       │────▶│  Step 3 — Draft Memo   │────▶│  Output — Final Memo   │
└────────────────────────┘     └────────────────────────┘     └────────────────────────┘     └────────────────────────┘

Node

Type

What it does

Run: Prompt Chaining

Manual Trigger

Starts the workflow

Input — Writing Brief

Set

Creates fields: topic, audience, constraints

Step 1 — Create Outline

Basic LLM Chain

Generates an outline → outputs text

Store Outline

Set

Saves {{ $json.text }} as outline

Step 2 — Improve Outline

Basic LLM Chain

Refines the outline using {{ $json.outline }} → outputs text

Store Improved Outline

Set

Saves {{ $json.text }} as improved_outline

Step 3 — Draft Memo

Basic LLM Chain

Writes final memo using {{ $json.improved_outline }} → outputs text

Output — Final Memo

Set

Saves {{ $json.text }} as final_memo (uses keepOnlySet to remove other fields)

Sub-node: One OpenRouter Chat Model is shared by all three LLM Chain nodes (connected via dotted lines).

Prompts Used#

Each step uses a different role and rules. This is why chaining works better than one big prompt.

Step 1 — Create Outline:

System: You are a writing assistant.
Create a clear outline for the memo.

Rules:
- 5–7 sections
- Include where the benefits bullets and risks bullet will go
- Output ONLY the outline

Step 2 — Improve Outline:

System: You are a strict editor.
Improve the outline using this checklist:
- Logical flow
- Clear headings
- Covers constraints (benefits + risks)
- Non-technical wording

Output ONLY the improved outline (no commentary).

Step 3 — Draft Memo:

System: You are a business writer.
Write the memo based on the outline.

Rules:
- Follow the outline order
- Keep under 400 words
- Use clear, non-technical language
- Include exactly: 3 benefit bullets + 1 risk bullet

Output ONLY the memo text.

Why this works: Each step has a focused role (assistant → editor → writer), specific constraints, and ends with “Output ONLY…” to prevent extra commentary.

Data Flow#

INPUT                          OUTPUT
─────                          ──────
Trigger: { }
    ↓
Writing Brief: { topic, audience, constraints }
    ↓
Step 1 LLM: { text: "1. Introduction..." }
    ↓
Store Outline: { outline: "1. Introduction..." }
    ↓
Step 2 LLM: { text: "1. Executive Summary..." }
    ↓
Store Improved: { improved_outline: "1. Executive Summary..." }
    ↓
Step 3 LLM: { text: "MEMO: Why We Should..." }
    ↓
Final Output: { final_memo: "MEMO: Why We Should..." }

What to Observe#

  1. Click Input — Writing Brief → see the starting data

  2. Click Step 1 — Create Outline → see the LLM’s outline in text

  3. Click Store Outline → see the same content now saved as outline

  4. Follow this pattern through each step to see how data transforms

Why do we need “Store” nodes?#

When a Basic LLM Chain runs, it replaces the previous data with only its output. This diagram shows what happens:

 STEP 1: Input                    STEP 2: LLM generates outline       STEP 3: Store saves it
┌─────────────────────┐          ┌─────────────────────┐             ┌─────────────────────┐
│ Input — Writing     │─────────▶│ Step 1 — Outline    │────────────▶│ Store Outline       │
│ Brief               │          │ (Basic LLM Chain)   │             │ (Edit Fields)       │
└─────────────────────┘          └─────────────────────┘             └─────────────────────┘
         │                                │                                   │
         ▼                                ▼                                   ▼
┌─────────────────────┐          ┌─────────────────────┐             ┌─────────────────────┐
│ {                   │          │ {                   │             │ {                   │
│   "topic": "AI",    │          │   "text":           │             │   "text":           │
│   "audience":       │          │     "1. Intro       │             │     "1. Intro...",  │
│     "doctors",      │          │      2. Benefits    │             │   "outline":        │
│   "constraints":    │          │      3. Risks..."   │             │     "1. Intro       │
│     "benefits,      │          │ }                   │             │      2. Benefits    │
│      risks"         │          │                     │             │      3. Risks..."   │
│ }                   │          │ ⚠️ topic, audience, │             │ }                   │
│                     │          │ constraints are     │             │                     │
│                     │          │ GONE!               │             │ 💡 Store adds       │
│                     │          │                     │             │ "outline" field     │
└─────────────────────┘          └─────────────────────┘             └─────────────────────┘

Key insight:

  • The LLM outputs only { "text": "..." } — original fields are lost

  • The Store node adds outline to save the result with a meaningful name

  • Step 2 only needs {{ $json.outline }} so it works without the original fields

Why this pattern? Each LLM step has a focused task. Step 2 doesn’t need topic or audience — it only needs the outline to improve it.


Pattern 2: Routing#

                                                 ┌─────────────────┐
                                            ┌───▶│ LLM: Refund     │
┌─────────────────┐     ┌─────────────────┐ │    └─────────────────┘
│  Manual Trigger │────▶│  LLM: Classify  │─┼───▶│ LLM: Order      │
└─────────────────┘     └─────────────────┘ │    └─────────────────┘
                                            └───▶│ LLM: Support    │
                                                 └─────────────────┘

Import via URL (copy and paste in n8n → Import from URL):

https://raw.githubusercontent.com/ezponda/ai-application-course-materials/main/_static/workflows/02_routing.json

Meet the Node: Switch#

This pattern introduces a new node: Switch.

Property

Description

Purpose

Routes data to different branches based on conditions

How it works

Checks a value and sends data to the matching output

Multiple outputs

Each condition creates a separate output branch (solid line)

Configuration:

  1. Mode: Choose “Rules” for condition-based routing

  2. Data Type: Usually “String” when routing on text values

  3. Value 1: The field to check, e.g., {{ $json.route }}

  4. Operation: Usually “Equals” for exact matching

  5. Value 2: The value to match, e.g., refund

Add more rules to create more branches. The Switch sends data only to the branch where the condition matches.

What Problem This Solves#

Different inputs need different handling. A support ticket about refunds should go to a refund specialist prompt, while an order status question goes elsewhere. Routing uses an LLM to classify the input, then a Switch node sends it down the right path.

Node-by-Node Walkthrough#

┌──────────────────┐     ┌────────────────────────┐     ┌──────────────────────┐     ┌───────────────┐     ┌────────────────┐
│   Manual Trigger │────▶│ Input — Support Ticket │────▶│  Router — Classify   │────▶│  Store Route  │────▶│ Switch — Route │───┐
└──────────────────┘     └────────────────────────┘     └──────────────────────┘     └───────────────┘     └────────────────┘   │
                                                                                                                                │
        ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
        │
        ├────▶┌─────────────────────────────┐────▶┌───────────────────────┐
        │     │   Refund Specialist         │     │   Output — Refund     │
        │     └─────────────────────────────┘     └───────────────────────┘
        │
        ├────▶┌─────────────────────────────┐────▶┌───────────────────────┐
        │     │   Order Status Specialist   │     │   Output — Order      │
        │     └─────────────────────────────┘     └───────────────────────┘
        │
        └────▶┌─────────────────────────────┐────▶┌───────────────────────┐
              │   Support Specialist        │     │   Output — Support    │
              └─────────────────────────────┘     └───────────────────────┘

Node

Type

What it does

Run: Ticket Routing

Manual Trigger

Starts the workflow

Input — Support Ticket

Set

Creates fields: ticket_subject, ticket_body

Router — Choose Route

Basic LLM Chain

Classifies ticket → outputs text (e.g., refund)

Store Route

Set

Saves {{ $json.text.trim() }} as route

Switch — Route

Switch

Checks {{ $json.route }} and sends to one branch

Refund Specialist

Basic LLM Chain

Writes refund-specific reply → outputs text

Order Status Specialist

Basic LLM Chain

Writes order status reply → outputs text

Support Specialist

Basic LLM Chain

Writes general support reply → outputs text

Prompts Used#

Router — Choose Route (the classifier):

System: You route customer support tickets.

Choose exactly ONE route label, lowercase, no punctuation:
- refund
- order_status
- support

Return ONLY the label.

Why this works: The prompt forces clean output (lowercase, no punctuation, ONLY the label) so the Switch node can match exactly.

Refund Specialist:

System: You are a customer support specialist for refunds.
Write a short, professional reply.

Rules:
- Acknowledge the issue
- Ask for any missing info (only if needed)
- Explain next steps and expected timeline
- Keep it under 120 words

Output ONLY the reply.

Key Expression: Accessing Earlier Node Data#

The specialist nodes need the original ticket data, but they come after the Switch. They use this expression pattern:

{{ $node['Input — Support Ticket'].json.ticket_subject }}
{{ $node['Input — Support Ticket'].json.ticket_body }}

This accesses data from a specific earlier node by name. Useful when you need to “reach back” past intermediate nodes.

How does the Switch node route data?#

The Switch node checks a field value and sends data to only one matching branch:

                         ┌─────────────────────────────────────────────┐
                         │ DATA BEFORE SWITCH                          │
                         │ {                                           │
                         │   "text": "refund",                         │
                         │   "route": "refund"                         │
                         │ }                                           │
                         └─────────────────────────────────────────────┘
                                              │
                                              ▼
                                    ┌───────────────────┐
                                    │      SWITCH       │
                                    │  Checks: route    │
                                    └───────────────────┘
                                     /        |        \
                         "refund"  /    "order_status"   \  "support"
                                  /           |           \
                                 ▼            ▼            ▼
                    ┌──────────────────┐ ┌──────────────┐ ┌──────────────┐
                    │ ✅ HAS DATA      │ │ ❌ EMPTY     │ │ ❌ EMPTY     │
                    └──────────────────┘ └──────────────┘ └──────────────┘

Key insights:

  • Only ONE branch receives data — the others are empty

  • Specialist nodes “reach back” to get original data using $node['Input — Support Ticket'].json

Data Flow#

INPUT                          OUTPUT
─────                          ──────
Trigger: { }
    ↓
Support Ticket: { ticket_subject, ticket_body }
    ↓
Router LLM: { text: "refund" }
    ↓
Store Route: { text: "refund", route: "refund" }
    ↓
Switch: routes to ONE branch based on {{ $json.route }}
    ↓
[Refund Specialist]: { text: "Dear Jamie, I apologize..." }
    ↓                 (accesses original ticket via $node['Input — Support Ticket'])
Output — Refund Reply: { reply: "Dear Jamie, I apologize...", route: "refund" }

What to Observe#

  1. Click Router — Choose Route → see the classification in text (e.g., refund)

  2. Click Store Route → see route field added

  3. Click Switch — Route → only ONE output branch has data

  4. Click the active specialist node → see the tailored reply


Pattern 3: Parallelization#

                        ┌─────────────────┐
                   ┌───▶│ LLM: Facts      │───┐
┌─────────────────┐│    └─────────────────┘   │    ┌─────────────────┐
│  Manual Trigger │┼───▶│ LLM: Sentiment  │───┼───▶│     Merge       │────▶ ...
└─────────────────┘│    └─────────────────┘   │    └─────────────────┘
                   └───▶│ LLM: Draft      │───┘
                        └─────────────────┘

Import via URL (copy and paste in n8n → Import from URL):

https://raw.githubusercontent.com/ezponda/ai-application-course-materials/main/_static/workflows/03_parallelization.json

Meet the Node: Merge#

This pattern introduces a new node: Merge.

Property

Description

Purpose

Combines data from multiple branches into one

Multiple inputs

Receives data from 2+ parallel branches

Output

One combined item (or list) with all fields

Key Modes:

Mode

What it does

Combine by Position

Pairs items by index (1st + 1st, 2nd + 2nd). Best when each branch outputs one item.

Combine by Fields

Matches items by a common field value

Append

Puts all items into one list

In this workflow, we use Combine by Position because each branch outputs exactly one item.

What Problem This Solves#

Some tasks have independent parts that can be analyzed separately. Analyzing a customer email for facts, sentiment, and drafting a reply are independent—they don’t need each other’s results. Splitting them into branches keeps your workflow organized, and you can combine the results at the end for a final, informed response.

Not true parallel execution. Despite the visual layout, n8n executes branches sequentially (A, then B, then C), not simultaneously. True parallel execution would require sub-workflows with webhook triggers — significantly more complex to set up.

This pattern is still valuable for code organization and clarity, even without the speed benefit of real parallelization.

Node-by-Node Walkthrough#

┌──────────────────┐     ┌────────────────────────┐
│   Manual Trigger │────▶│ Input — Customer Email │───┬────▶ Branch A — Facts ────▶ Store Facts ────┐
└──────────────────┘     └────────────────────────┘   │                                             │
                                                      ├────▶ Branch B — Sentiment ────▶ Store Sentiment ├──▶ Merge ──▶ Finalize
                                                      │                                             │
                                                      └────▶ Branch C — Draft ────▶ Store Draft ────┘

Node

Type

What it does

Input — Customer Email

Set

Creates fields: email_subject, email_body

Branch A — Extract Facts

Basic LLM Chain

Extracts facts as JSON → outputs text

Branch B — Sentiment & Urgency

Basic LLM Chain

Analyzes sentiment → outputs text

Branch C — Draft Reply

Basic LLM Chain

Drafts initial reply → outputs text

Merge

Merge

Combines all three fields (mode: Combine by Position)

Finalize — Improved Reply

Basic LLM Chain

Uses all three fields → outputs text

Prompts Used#

Branch A — Extract Facts:

System: Extract key facts from the email.
Return STRICT JSON with keys:
customer_name, issue, deadline, requested_action, missing_info (array).
Return JSON only.

Branch B — Sentiment & Urgency:

System: Classify sentiment and urgency.
Return STRICT JSON with keys:
sentiment (positive|neutral|negative), urgency (low|medium|high), risk_flags (array).
Return JSON only.

Branch C — Draft Reply:

System: Draft a helpful customer support email reply.
Rules:
- Friendly and concise
- Ask for missing info only if needed
- Offer 1–2 concrete next steps
- Under 140 words

Output ONLY the reply text.

Finalize — One Improved Reply:

System: You are a senior support agent.
You will receive:
- facts_json (extracted facts)
- sentiment_json (sentiment & urgency)
- draft_reply (initial draft)

Task:
1) Improve the draft to match urgency and include any critical missing info questions.
2) Keep it under 160 words.
3) Output ONLY the final reply text.

How does Merge combine branches?#

The Merge node waits for all branches to complete, then combines their outputs into one item.

                    ┌─────────────────────────────────┐
                    │        INPUT (same for all)     │
                    │ { "email_subject": "Help!",     │
                    │   "email_body": "Can't login" } │
                    └─────────────────────────────────┘
                                    │
                     ┌──────────────┼──────────────┐
                     ▼              ▼              ▼
            ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
            │  Branch A    │ │  Branch B    │ │  Branch C    │
            │  (Facts)     │ │  (Sentiment) │ │  (Draft)     │
            │  runs 1st    │ │  runs 2nd    │ │  runs 3rd    │
            └──────────────┘ └──────────────┘ └──────────────┘
                     │              │              │
                     └──────────────┼──────────────┘
                                    ▼
                          ┌─────────────────┐
                          │      MERGE      │
                          │  (Combine by    │
                          │   Position)     │
                          └─────────────────┘
                                    │
                                    ▼
                    ┌─────────────────────────────────┐
                    │         MERGED OUTPUT           │
                    │ {                               │
                    │   "facts_json": "{...}",        │
                    │   "sentiment_json": "{...}",    │
                    │   "draft_reply": "Hi Sam..."    │
                    │ }                               │
                    │                                 │
                    │ ✅ All three fields combined!   │
                    └─────────────────────────────────┘

Key insight: Even though execution is sequential, the pattern is valuable for organizing independent analyses. The Merge node combines all results so the final LLM can use all the information.

Data Flow#

INPUT                          OUTPUT
─────                          ──────
Trigger: { }
    ↓
Customer Email: { email_subject, email_body }
    ↓ ↓ ↓ (splits into 3 branches — executed sequentially)
    
Branch A: { text: '{"customer_name":"Sam",...}' }
    ↓
Store Facts: { facts_json: '{"customer_name":"Sam",...}' }

Branch B: { text: '{"sentiment":"negative","urgency":"high",...}' }
    ↓
Store Sentiment: { sentiment_json: '{"sentiment":"negative",...}' }

Branch C: { text: "Hi Sam, I understand..." }
    ↓
Store Draft Reply: { draft_reply: "Hi Sam, I understand..." }
    
    ↓ (merge all three)
After Merge: { facts_json, sentiment_json, draft_reply }
    ↓
Finalize LLM: { text: "Dear Sam, I sincerely apologize..." }
    ↓
Final Output: { final_reply: "Dear Sam, I sincerely apologize..." }

What to Observe#

  1. Click Input — Customer Email → see the starting data

  2. Click each Branch node → see different analyses running on the same input

  3. Click Merge → switch to JSON view to see all three fields combined

  4. Click Finalize → see how the final LLM uses all three fields


Pattern Summary#

Pattern

When to use

Key nodes

Prompt Chaining

Complex tasks that benefit from step-by-step refinement

Multiple LLM Chains in sequence

Routing

Different handling based on input type

LLM (classifier) + Switch

Parallelization

Independent analyses that can run simultaneously

Multiple branches + Merge


Tips for Building Your Own Workflows#

  1. Start simple. Build one node at a time and test frequently.

  2. Use descriptive node names. “Step 1: Create Outline” is better than “LLM Chain.”

  3. Pin data often. After any successful LLM call, pin the result before working on the next node.

  4. Check the Output panel. Switch between Table and JSON views to understand your data.

  5. Use Set nodes as checkpoints. Save intermediate results with clear field names.

  6. Test routing with different inputs. Make sure all branches work, not just the happy path.


Recap#

In this notebook, you learned:

Core Concepts:

  • Data flows as JSON items through solid lines

  • Dotted lines connect capabilities (Chat Model, Memory, Tools)

  • Expressions ({{ $json.field }}) pass data between nodes

  • Pinning saves output to avoid re-running expensive operations

Three Workflow Patterns:

  • Prompt Chaining: Break complex tasks into sequential LLM steps

  • Routing: Classify input and route to specialized handlers with Switch

  • Parallelization: Run independent analyses and merge results

These patterns are your foundation for building more sophisticated AI systems with n8n.