Learn/LangChain Mastery/Part 3 · 2. LCEL & Prompt Architecture
Lesson 11 of 68
SyllabusLangChain Mastery · Part 3

Pipe Operator & Data Flow

LangChain's pipe operator explained simply using a kitchen analogy.

Course outline & contents
LangChain Mastery
Your First Chatbot: Talking to an LLMLCEL: Why LangChain Is a Composition EngineThe Runnable Protocol (invoke, batch, stream)Pipe Operator & Data FlowRunnableLambda & Custom LogicRunnableParallel & BranchingPromptTemplate vs ChatPromptTemplateSystem, Human, AI MessagesPrompt Architecture & ReusabilityStructured Output with JSON ModePydanticOutputParserOutputFixingParserStreaming Tokens & Async Chains

Think of LangChain like a Kitchen Assembly Line. The pipe operator | is the conveyor belt that moves ingredients from one station to the next.


When you write code with |, you aren't cooking yet. You are just writing the Recipe.

The Recipe (Chain)
chain = Chopping | Cooking | Plating

This says: "First chop the ingredients, then cook them, then put them on a plate." Nothing happens until you yell "Order Up!"


To actually start the machine, you use .invoke().

Start Cooking
chain.invoke("Carrots")

Here is what happens step-by-step:

  1. Carrots go into the Chopping station.
  2. The output (Chopped Carrots) moves to the Cooking station.
  3. The output (Cooked Carrots) moves to the Plating station.
  4. The final dish is served to you.

Important Rule: Each station replaces what it received. The "Cooking" station takes chopped carrots and turns them into stew. The chopped carrots are gone!


Sometimes, you need the original vegetable later in the line (maybe as a garnish). But strict "replacement" means it would be lost!

To fix this, we use .assign. Think of it like putting the chopped carrots in a Side Bowl that travels down the line with the main dish.

Using a Side Bowl
chain = (
  RunnablePassthrough.assign(
      side_bowl = lambda x: chop(x["veggie"])
  )
  | cook_main_dish
)

Now the "Cooking" station receives both:

  1. The main veggie
  2. The side_bowl (chopped veggie)

What if you want to cook a steak AND make a salad at the same time? You use a Dictionary {}.

Two Cooks
meal = {
  "steak": grill_steak,
  "salad": toss_salad
}

LangChain sees this and says "Hey! I can do these at the same time!" It waits for both to finish before putting them on the tray.


Sometimes you don't want to wait for the whole pot to boil. You want to serve soup spoon by spoon as it's ready. This is Streaming.

To keep it streaming, every station must act like a funnel—passing things through immediately.


Sometimes the manager needs to whisper instructions to the cooks, like "This customer is VIP" or "No salt!" You don't want to put these notes inside the food.

So you use a Config object. It's a secret note passed invisibly to every station.

Secret Instructions
chain.invoke(
  "Steak",
  config={"metadata": {"customer": "VIP"}}
)

Any cook can open this note and see: "Ah, VIP customer. Extra garnish!"


  • | (Pipe): The Conveyor Belt.
  • .invoke(): The "Start" button.
  • .assign: The Side Bowl (keep data).
  • {} (Dict): Two cooks working at once.
  • Config: The Manager's secret note.
Track your progressSign in and your progress follows you across devices.
Sign in to track progress Next lesson
← Previous lessonThe Runnable Protocol (invoke, batch, stream)Next lesson →RunnableLambda & Custom Logic