Learning Objectives
- Work with Chat Models from different providers
- Create dynamic prompts using Prompt Templates
- Parse LLM outputs into structured data
- Understand LangChain Expression Language (LCEL)
- Build your first chain by composing components
2.1 Chat Models
Chat Models are the foundation of LangChain applications. They provide a unified interface for interacting with LLMs from any provider.
Key Concepts
Chat Model
A wrapper around an LLM that provides a consistent interface for sending messages and receiving responses. All chat models support the same core methods: invoke(), stream(), and batch().
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
# Initialize a chat model
llm = ChatOpenAI(
model="gpt-4",
temperature=0.7, # Creativity level (0-1)
max_tokens=500 # Maximum response length
)
# Messages are the input format for chat models
messages = [
SystemMessage(content="You are a helpful coding assistant."),
HumanMessage(content="Write a Python function to calculate factorial."),
]
# invoke() - Get a single response
response = llm.invoke(messages)
print(response.content)
# stream() - Get response as it's generated
for chunk in llm.stream(messages):
print(chunk.content, end="", flush=True)
# batch() - Process multiple inputs efficiently
batch_messages = [
[HumanMessage(content="What is 2+2?")],
[HumanMessage(content="What is 3+3?")],
]
responses = llm.batch(batch_messages)
for r in responses:
print(r.content)
Message Types
| Message Type | Purpose | Example |
|---|---|---|
SystemMessage |
Set behavior/persona | "You are a helpful assistant" |
HumanMessage |
User input | "Explain quantum computing" |
AIMessage |
Model's previous response | Used for conversation history |
2.2 Prompt Templates
Prompt Templates allow you to create reusable, parameterized prompts:
from langchain_core.prompts import ChatPromptTemplate
# Create a template with variables
template = ChatPromptTemplate.from_messages([
("system", "You are an expert in {topic}. Explain concepts clearly."),
("human", "{question}")
])
# Format with specific values
messages = template.invoke({
"topic": "machine learning",
"question": "What is gradient descent?"
})
print(messages)
# Output: [SystemMessage(content="You are an expert in machine learning..."),
# HumanMessage(content="What is gradient descent?")]
# Use with a model
from langchain_openai import ChatOpenAI
llm = ChatOpenAI()
response = llm.invoke(messages)
print(response.content)
Advanced Template Features
from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate
# Define examples
examples = [
{"input": "happy", "output": "sad"},
{"input": "tall", "output": "short"},
{"input": "fast", "output": "slow"},
]
# Create example prompt
example_prompt = ChatPromptTemplate.from_messages([
("human", "{input}"),
("ai", "{output}"),
])
# Create few-shot prompt
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt,
examples=examples,
)
# Final template
final_prompt = ChatPromptTemplate.from_messages([
("system", "You give the opposite of words."),
few_shot_prompt,
("human", "{input}"),
])
# Use it
messages = final_prompt.invoke({"input": "big"})
response = llm.invoke(messages)
print(response.content) # Expected: "small"
2.3 Output Parsers
Output Parsers convert LLM text responses into structured data:
Raw Text] --> B[Output Parser] B --> C[Structured Data
dict, list, Pydantic] style B fill:#667eea,color:#fff
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field
# Define the output structure
class MovieReview(BaseModel):
title: str = Field(description="The movie title")
rating: int = Field(description="Rating from 1-10")
summary: str = Field(description="Brief summary of the review")
# Create model with structured output
llm = ChatOpenAI(model="gpt-4")
structured_llm = llm.with_structured_output(MovieReview)
# Create prompt
prompt = ChatPromptTemplate.from_messages([
("system", "You are a movie critic. Analyze the given movie."),
("human", "Review the movie: {movie}")
])
# Chain and invoke
chain = prompt | structured_llm
result = chain.invoke({"movie": "Inception"})
# Result is a Pydantic object!
print(f"Title: {result.title}")
print(f"Rating: {result.rating}/10")
print(f"Summary: {result.summary}")
2.4 LangChain Expression Language (LCEL)
LCEL is a declarative way to compose chains using the pipe (|) operator:
LCEL (LangChain Expression Language)
A syntax for composing LangChain components into chains. Components connected with | pass their output as input to the next component. All LCEL chains support invoke, stream, and batch automatically.
Template] -->|pipe| B[Chat
Model] -->|pipe| C[Output
Parser] style A fill:#667eea,color:#fff style B fill:#11998e,color:#fff style C fill:#f093fb,color:#fff
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# Define components
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant."),
("human", "Translate '{text}' to {language}.")
])
model = ChatOpenAI(model="gpt-4")
parser = StrOutputParser() # Extracts string from AIMessage
# Compose with LCEL (pipe operator)
chain = prompt | model | parser
# Use the chain
result = chain.invoke({
"text": "Hello, world!",
"language": "Japanese"
})
print(result) # Output: "γγγ«γ‘γ―γδΈηοΌ"
# Streaming works automatically!
for chunk in chain.stream({"text": "Good morning", "language": "French"}):
print(chunk, end="", flush=True)
# Output: "Bonjour" (streamed character by character)
LCEL Benefits
- Automatic streaming: Stream support comes free
- Automatic batching: Process multiple inputs efficiently
- Automatic retries: Built-in error handling
- Automatic logging: LangSmith integration
- Parallel execution:
RunnableParallelfor concurrent operations
When to Use LCEL vs LangGraph
Use LCEL for simple, linear chains (prompt β model β parser). For complex workflows with branching, cycles, or state management, use LangGraph instead. You can always use LCEL within LangGraph nodes.
Exercises
Exercise 1: Custom Prompt Template
Create a prompt template for a code review assistant. It should accept language (programming language) and code as parameters, and ask the model to review the code for bugs and improvements.
Exercise 2: Structured Output
Create a chain that extracts structured information from a job posting. Define a Pydantic model with fields: job_title, company, salary_range (optional), and required_skills (list of strings).
Summary
- Chat Models provide a unified interface for all LLM providers
- Use
invoke(),stream(), andbatch()for different use cases - Prompt Templates create reusable, parameterized prompts
- Output Parsers convert text to structured data
- LCEL composes components with the pipe (
|) operator - LCEL chains automatically support streaming, batching, and logging