Duration: 5 hours | Difficulty: Intermediate–Advanced | Prerequisites: Modules 01–08
Learning Objectives
By the end of this module, you will be able to:
- Build composable chains using LangChain Expression Language (LCEL)
- Use prompt templates, output parsers, and document loaders effectively
- Implement retrieval chains and conversational RAG with LangChain
- Build agents with LangChain's agent framework
- Monitor and debug with LangSmith tracing
1. LangChain Architecture
LangChain is a library of primitives (prompts, models, retrievers, tools) plus composition rules. LCEL (|) is the default glue in v0.2+ stacks.
┌────────────────────────────────────────────┐
│ LangChain Stack │
│ ┌──────────┐ ┌────────────┐ ┌──────────┐│
│ │ Prompts │→ │ Models │→ │ Parsers ││
│ └──────────┘ └────────────┘ └──────────┘│
│ ↕ ↕ ↕ │
│ ┌──────────┐ ┌────────────┐ ┌──────────┐│
│ │Retrievers│ │ Tools │ │ Memory ││
│ └──────────┘ └────────────┘ └──────────┘│
└────────────────────────────────────────────┘| Piece | You bring |
|---|---|
| Integrations | API keys, vector DB URLs |
| Observability | LangSmith project (optional) |
| Your code | Business logic around invoke / stream |
Try This! Draw your app as boxes: data → chain → UI. If you can’t name each arrow, LangChain won’t fix that.
2. LCEL (LangChain Expression Language)
LCEL composes runnables with |: prompt → model → parser. Same object supports .invoke, .stream, .batch.
Streaming with LCEL
Same chain object: for chunk in chain.stream(inputs): ... — no separate “streaming API” class needed.
Batch Processing
chain.batch(list_of_dicts) runs concurrent workers—great for offline eval; watch rate limits.
Chaining Multiple Steps
Feed output of step A into prompt B using RunnablePassthrough, lambdas, or assign patterns—think Unix pipes with dict payloads.
Key Example: The smallest useful LCEL chain—parameterized prompt, chat model, string output.
[object Object], langchain_openai ,[object Object], ChatOpenAI
,[object Object], langchain_core.prompts ,[object Object], ChatPromptTemplate
,[object Object], langchain_core.output_parsers ,[object Object], StrOutputParser
llm = ChatOpenAI(model=,[object Object],, temperature=,[object Object],, api_key=,[object Object],)
prompt = ChatPromptTemplate.from_messages(
[
(,[object Object],, ,[object Object],),
(,[object Object],, ,[object Object],),
]
)
chain = prompt | llm | StrOutputParser()
,[object Object],(chain.invoke({,[object Object],: ,[object Object],, ,[object Object],: ,[object Object],}))3. Prompt Templates
ChatPromptTemplate keeps roles explicit. MessagesPlaceholder is handy for chat history injection. Few-shot templates store example messages—same psychology as Module 02, now as code objects.
| Pattern | When |
|---|---|
from_messages | Most chat models |
Partial with .partial() | Freeze system prompt, vary user slot |
4. Output Parsers
StrOutputParser — plain text. Structured parsers (JSON, Pydantic) ask the model for machine-readable shapes; always validate in code afterward.
Concept: Parsers are contracts; the LLM is a sloppy contractor—inspect the work.
5. Document Loaders and Text Splitters
Loaders turn files/URLs into Document objects (page_content + metadata). Splitters break them for embedding:
| Splitter | Good for |
|---|---|
RecursiveCharacterTextSplitter | General text / markdown |
MarkdownTextSplitter | Headers-aware splits |
Without code: point loader at source → split_documents → embed → add to vectorstore.
6. RAG Chain with LangChain
Key Example:
retriever | formatfeeds context into a chat prompt;RunnablePassthroughpasses the raw question through.
[object Object], langchain_openai ,[object Object], ChatOpenAI, OpenAIEmbeddings
,[object Object], langchain_chroma ,[object Object], Chroma
,[object Object], langchain_core.prompts ,[object Object], ChatPromptTemplate
,[object Object], langchain_core.output_parsers ,[object Object], StrOutputParser
,[object Object], langchain_core.runnables ,[object Object], RunnablePassthrough
llm = ChatOpenAI(model=,[object Object],, api_key=,[object Object],)
emb = OpenAIEmbeddings(model=,[object Object],, api_key=,[object Object],)
texts = [
,[object Object],,
,[object Object],,
,[object Object],,
]
vs = Chroma.from_texts(texts, emb)
retriever = vs.as_retriever(search_kwargs={,[object Object],: ,[object Object],})
,[object Object], ,[object Object],(,[object Object],):
,[object Object], ,[object Object],.join(d.page_content ,[object Object], d ,[object Object], docs)
prompt = ChatPromptTemplate.from_messages(
[
(,[object Object],, ,[object Object],),
(,[object Object],, ,[object Object],),
]
)
rag = (
{,[object Object],: retriever | format_docs, ,[object Object],: RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
,[object Object],(rag.invoke(,[object Object],))7. LangChain Agents
Agent constructors (names change between versions) combine: model + tool list + executor loop. Same lessons as Module 08: cap iterations, log tool calls, validate args.
| Tip | Why |
|---|---|
| Return errors to the model once | Lets it self-correct |
| Structured tools | Fewer parse failures |
8. LangSmith Tracing
LangSmith records each runnable step: latency, tokens, prompts. Flip it on with env vars (LANGCHAIN_TRACING_V2, LANGCHAIN_API_KEY, project name).
| You get | You do |
|---|---|
| Trace tree | Click into slow steps |
| Datasets | Regression tests from prod logs |
Key Takeaway
If you wouldn’t debug blind for HTTP microservices, don’t do it for chains either.
Practice Exercises
Exercise 1: Multi-Step LCEL Chain (Beginner)
Draft → edit → headline, three prompts in one composed chain.
Exercise 2: RAG Chatbot (Intermediate)
Add MessagesPlaceholder for history; retrieve per turn.
Exercise 3: Custom Output Parser (Intermediate)
Parse model output into a dataclass with validation.
Exercise 4: Multi-Tool Agent (Advanced)
Three tools with conflicting args—test recovery.
Exercise 5: Evaluation Pipeline (Advanced)
Batch run golden questions; push traces to LangSmith.
Mini-Project: LangChain Documentation Assistant
Index your project docs in Chroma; expose FastAPI endpoint running the RAG LCEL chain; trace in LangSmith.
Key Takeaways
Key Takeaway
- LCEL is composable, streamable, and batch-friendly—learn the pipe idiom first.
- Templates + parsers formalize prompts and outputs.
- Loaders + splitters are chunk-quality levers.
- RAG in LangChain is “retriever dict merge → prompt → LLM.”
- Agents inherit all Module 08 discipline.
- LangSmith (or similar) is how you ship with confidence.
Resources for Further Learning
- LangChain docs
- LangGraph — next module
- LangSmith