beginner30 minutesLesson 2 of 10

LangChain Refresher

Quick refresher on LangChain fundamentals: LLMs, prompts, chains, output parsers, and how they integrate with LangGraph.

LangChain Refresher

LangGraph is built on top of LangChain. Before diving deeper into graphs, let's review the core LangChain components you'll use in every LangGraph application.


LLMs (Language Models)

LangChain provides a unified interface for hundreds of LLMs from OpenAI, Anthropic, Google, Cohere, Hugging Face, and more.

python
from langchain_openai import ChatOpenAI llm = ChatOpenAI(model="gpt-4o", temperature=0.7) response = llm.invoke("What is the capital of France?") print(response.content) # The capital of France is Paris.

Key LLM Parameters

ParameterDescriptionTypical Range
modelModel identifier"gpt-4o", "claude-3-opus"
temperatureRandomness of output0.0 (deterministic) to 2.0 (creative)
max_tokensMaximum output length128 to 4096+
top_pNucleus sampling threshold0.0 to 1.0
timeoutRequest timeout10 to 60 seconds
ℹ️Note

Chat models use invoke() with messages, not strings. The base LLM class uses strings directly. For LangGraph agents, you'll almost always use ChatOpenAI or similar chat models.

python
from langchain_core.messages import HumanMessage, SystemMessage messages = [ SystemMessage("You are a helpful assistant."), HumanMessage("What is LangGraph?") ] response = llm.invoke(messages)

Prompts

Prompts are templates that structure the input to an LLM. LangChain's ChatPromptTemplate is the standard approach.

python
from langchain.prompts import ChatPromptTemplate prompt = ChatPromptTemplate.from_messages([ ("system", "You are an expert in {topic}."), ("human", "Answer this question: {question}") ]) formatted = prompt.format(topic="Python", question="What is a decorator?")

Prompt with Few-Shot Examples

python
examples = [ ("human", "What is 2+2?"), ("assistant", "4"), ("human", "What is 5+3?"), ("assistant", "8"), ] prompt = ChatPromptTemplate.from_messages([ ("system", "You are a math tutor. Answer concisely."), *examples, ("human", "{question}") ])
💡Tip

In LangGraph, you typically put prompt construction inside a node function rather than chaining it externally. This keeps the prompt logic close to where it's used.


Chains

Chains connect components together. The modern approach uses the pipe operator (|):

python
from langchain_core.output_parsers import StrOutputParser # Chain: prompt → LLM → string output chain = prompt | llm | StrOutputParser() result = chain.invoke({ "topic": "AI", "question": "What is an agent?" })

RunnablePassthrough for Intermediate Values

python
from langchain_core.runnables import RunnablePassthrough chain = { "response": prompt | llm | StrOutputParser(), "original_question": RunnablePassthrough() } | RunnablePassthrough() result = chain.invoke({"topic": "AI", "question": "What is RAG?"}) print(result["response"]) print(result["original_question"])
⚠️Warning

In LangGraph, you should not use the pipe operator to build large chains. Instead, put chain logic inside node functions. This gives you better control over state updates and error handling.


Output Parsers

Output parsers transform LLM text output into structured formats.

StrOutputParser

The simplest parser — converts LLM output to a plain string:

python
from langchain_core.output_parsers import StrOutputParser parser = StrOutputParser() chain = prompt | llm | StrOutputParser() result = chain.invoke({"topic": "AI", "question": "Hi"}) # result is a plain string

PydanticOutputParser

Parses JSON output into a Pydantic model:

python
from langchain_core.output_parsers import PydanticOutputParser from pydantic import BaseModel, Field class Recipe(BaseModel): name: str = Field(description="Recipe name") ingredients: list[str] = Field(description="List of ingredients") steps: list[str] = Field(description="Cooking steps") cook_time_minutes: int = Field(description="Total cooking time") parser = PydanticOutputParser(pydantic_object=Recipe) prompt = ChatPromptTemplate.from_messages([ ("system", "Extract recipe info. {format_instructions}"), ("human", "{input_text}") ]).partial(format_instructions=parser.get_format_instructions()) chain = prompt | llm | parser recipe = chain.invoke({"input_text": "To make pasta, boil water..."}) print(recipe.name, recipe.cook_time_minutes)

JsonOutputParser

For simpler cases where you don't need full Pydantic validation:

python
from langchain_core.output_parsers import JsonOutputParser chain = prompt | llm | JsonOutputParser() result = chain.invoke({"input_text": "Extract name and age from: John is 30"}) # result is a dict: {"name": "John", "age": 30}
Success

Output parsers are essential in LangGraph for converting LLM responses into structured state updates that downstream nodes can process reliably.


How LangChain Components Fit into LangGraph

In LangGraph, LangChain components become building blocks inside nodes:

python
from langgraph.graph import StateGraph, START, END from typing_extensions import TypedDict, List from langchain_openai import ChatOpenAI from langchain.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_core.messages import HumanMessage, AIMessage llm = ChatOpenAI(model="gpt-4o") class AgentState(TypedDict): messages: List[dict] response: str def generate_response(state: AgentState) -> dict: prompt = ChatPromptTemplate.from_messages([ ("system", "You are a helpful assistant."), ("human", "{input}") ]) chain = prompt | llm | StrOutputParser() response = chain.invoke({"input": state["messages"][-1]["content"]}) return {"response": response} # Graph construction builder = StateGraph(AgentState) builder.add_node("generate", generate_response) builder.add_edge(START, "generate") builder.add_edge("generate", END) app = builder.compile()
📌Important

LangChain components work inside LangGraph nodes, not as replacements for nodes. Each node is a function that uses LangChain tools internally to process state and return updates.


Key Differences When Using LangChain in LangGraph

AspectPure LangChainLangGraph with LangChain
Flow controlPipe operators (|)Graph edges and conditions
State managementPassed through chainShared State object
LoopingNot possibleAdd edge back to earlier node
Tool useVia ToolChainInside node functions
Error handlingChain breaks on errorPer-node try/except

RunnableConfig in LangGraph

You can pass configuration through LangChain's RunnableConfig when invoking nodes:

python
from langchain_core.runnables import RunnableConfig def configurable_node(state: AgentState, config: RunnableConfig) -> dict: # Access configurable parameters model_name = config.get("configurable", {}).get("model", "gpt-4o") temperature = config.get("configurable", {}).get("temperature", 0.7) llm = ChatOpenAI(model=model_name, temperature=temperature) response = llm.invoke(state["messages"]) return {"response": response.content} # Pass config during invocation app.invoke( {"messages": [HumanMessage("Hello")]}, config={"configurable": {"model": "gpt-3.5-turbo", "temperature": 0.0}} )
ℹ️Note

The config parameter in node functions is optional. Only add it when you need runtime configuration like model selection or user-specific settings.


Common Patterns for LangGraph Nodes

Direct LLM Call

python
def node(state: State) -> dict: response = llm.invoke(state["input"]) return {"output": response.content}

Prompt + LLM + Parser

python
def node(state: State) -> dict: chain = prompt | llm | parser result = chain.invoke({"input": state["input"]}) return {"structured_output": result}

Tool-Enabled LLM

python
def node(state: State) -> dict: llm_with_tools = llm.bind_tools([search_tool, calculator_tool]) response = llm_with_tools.invoke(state["messages"]) return {"messages": state["messages"] + [response]}

Practice Questions

Practice Question

Which LangChain component is used to convert LLM text output into a Pydantic model?

Practice Question

How do LangChain components integrate with LangGraph?

Practice Question

What does the pipe operator (|) do in LangChain?

Practice Question

What is the purpose of the SystemMessage in LangChain?

Practice Question

Which parameter controls the randomness of LLM output?

Practice Question

How do you pass runtime configuration like model selection to a LangGraph node?

Practice Question

What is the output type of ChatOpenAI.invoke()?

Practice Question

What does StrOutputParser do?

Practice Question

Which of the following is NOT a LangChain component commonly used inside LangGraph nodes?

Practice Question

How should you build prompt chains in LangGraph?


Success

Key Takeaways

  • LangChain provides LLMs, prompts, chains, and parsers used inside LangGraph nodes
  • ChatOpenAI is the standard LLM class; use .invoke() with message lists
  • Output parsers (StrOutputParser, PydanticOutputParser) convert LLM text to structured data
  • In LangGraph, LangChain components go inside node functions, not outside the graph
  • The config parameter allows runtime configuration of LLM parameters
  • Avoid the pipe operator for large chains inside LangGraph — prefer explicit function calls
Progress20%