Lesson 1: LangChain — Chains, Runnables & LCEL
Build composable LLM pipelines using LangChain Expression Language (LCEL). Chain prompt templates, LLMs, and output parsers into reusable Runnables with streaming and async support.
LangChain is the most widely used AI application framework. This lesson covers what actually matters for building production systems: LCEL pipe syntax, chain composition, and custom runnables — skipping the cruft.
What LangChain Actually Is
LangChain is a composition library. Its value is in standardizing how LLMs, prompts, retrievers, tools, and parsers connect to each other — so you can swap components without rewriting the integration code. LCEL (LangChain Expression Language) is the composable core of modern LangChain.
LCEL is LangChain's pipe syntax: compose components with | operator. The result is a Runnable that can be invoked, streamed, or batched uniformly.
from langchain_anthropic import ChatAnthropic
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
model = ChatAnthropic(model="claude-haiku-4-5-20251001")
# LCEL chain: prompt | model | parser
chain = (
ChatPromptTemplate.from_template("Translate to French: {text}")
| model
| StrOutputParser()
)
# Invoke
result = chain.invoke({"text": "Hello, how are you?"})
print(result) # → "Bonjour, comment allez-vous?"
# Stream token by token
for chunk in chain.stream({"text": "The weather is nice today"}):
print(chunk, end="", flush=True)
# Batch (parallel)
results = chain.batch([
{"text": "Good morning"},
{"text": "Good night"},
{"text": "See you later"},
])When to Use LangChain vs. Raw SDK
| Use LangChain when | Use raw SDK when |
|---|---|
| Building a RAG pipeline (retrievers are first-class) | Simple 1–2 step LLM calls |
| Need streaming + batching + caching consistently | Maximum control and minimal dependencies |
| Composing 5+ steps that need easy observability | Learning how LLMs work at the protocol level |
| Integrating with LangSmith for tracing | The LangChain abstraction adds more confusion than value |
LangSmith: Observability
# Set these env vars — LangChain auto-instruments all calls import os os.environ["LANGCHAIN_TRACING_V2"] = "true" os.environ["LANGCHAIN_API_KEY"] = "your-langsmith-key" os.environ["LANGCHAIN_PROJECT"] = "my-rag-app" # Now every chain.invoke() is automatically traced: # - Input/output for every step # - Token counts and latency # - Error traces with full context # All visible in the LangSmith UI at smith.langchain.com
In the next lesson, we move from stateless chains to stateful agents using LangGraph — where the flow of execution depends on the model's decisions.