LangChain Tutorial: The Most Popular Framework for Building LLM Applications

# Tutorial LangChain: Framework Paling Populer untuk Membangun Aplikasi LLM LangChain adalah framework open-source yang dirancang untuk mempermudah pengembangan aplikasi berbasis Large Language Model...

By Ruby Abdullah · · tutorial
LangChainLLMRAGAI AgentsPython

LangChain Tutorial: The Most Popular Framework for Building LLM Applications

LangChain is an open-source framework designed to simplify the development of applications powered by Large Language Models (LLMs). With a mature ecosystem and a large community, LangChain has become the go-to choice for developers building chatbots, RAG systems, AI agents, and various other AI applications. This tutorial covers LangChain comprehensively, from installation to advanced usage patterns.

Why LangChain?

Building LLM applications from scratch requires significant boilerplate code: managing prompts, connecting to various model providers, implementing memory, orchestrating chains of thought, and much more. LangChain simplifies all of this by providing consistent and modular abstractions.

Key advantages of LangChain:

  • Consistent Model Abstraction: A single interface for OpenAI, Anthropic, Google, Ollama, and dozens of other providers
  • Composable Chains: Build complex pipelines by combining simple components
  • Complete Ecosystem: Integrations with vector databases, document loaders, tools, and external services
  • LangChain Expression Language (LCEL): Declarative syntax for building chains that natively support streaming and async
  • Large Community: Thousands of third-party integrations and comprehensive documentation

Installation and Setup

Basic Installation

pip install langchain langchain-core langchain-community

Provider-Specific Installation

# For OpenAI

pip install langchain-openai

For Anthropic (Claude)

pip install langchain-anthropic

For Google (Gemini)

pip install langchain-google-genai

For local models via Ollama

pip install langchain-ollama

For vector stores

pip install langchain-chroma # ChromaDB

pip install langchain-pinecone # Pinecone

pip install faiss-cpu # FAISS

API Key Configuration

import os

Set API keys as environment variables

os.environ["OPENAIAPIKEY"] = "sk-..."

os.environ["ANTHROPICAPIKEY"] = "sk-ant-..."

Or use .env file with python-dotenv

from dotenv import loaddotenv

loaddotenv()

Core Concepts

1. Chat Models

Chat models are the core component of LangChain. Here's how to use various providers:

from langchainopenai import ChatOpenAI

from langchainanthropic import ChatAnthropic

from langchainollama import ChatOllama

OpenAI GPT-4

llmopenai = ChatOpenAI(model="gpt-4o", temperature=0.7)

Anthropic Claude

llmclaude = ChatAnthropic(model="claude-sonnet-4-20250514", temperature=0.7)

Ollama (local models)

llmollama = ChatOllama(model="llama3.1")

Call the model

response = llmopenai.invoke("Explain what machine learning is in 2 sentences")

print(response.content)

2. Prompt Templates

Prompt templates allow you to create dynamic and reusable prompts:

from langchaincore.prompts import ChatPromptTemplate, MessagesPlaceholder

Simple prompt

prompt = ChatPromptTemplate.frommessages([

("system", "You are an AI assistant specialized in {domain}."),

("human", "{question}")

])

Use the prompt

formatted = prompt.invoke({

"domain": "data science",

"question": "What is the difference between supervised and unsupervised learning?"

})

print(formatted)

3. Output Parsers

Output parsers help transform LLM outputs into structured formats:

from langchaincore.outputparsers import JsonOutputParser, StrOutputParser

from langchaincore.pydanticv1 import BaseModel, Field

String output parser (simplest)

parser = StrOutputParser()

JSON output parser with schema

class BookReview(BaseModel):

title: str = Field(description="Book title")

rating: int = Field(description="Rating 1-5")

summary: str = Field(description="Review summary")

jsonparser = JsonOutputParser(pydanticobject=BookReview)

prompt = ChatPromptTemplate.frommessages([

("system", "Provide a book review in JSON format.\n{formatinstructions}"),

("human", "Review the book: {booktitle}")

])

chain = prompt | llmopenai | jsonparser

result = chain.invoke({

"booktitle": "Clean Code",

"formatinstructions": jsonparser.getformatinstructions()

})

print(result) # {'title': 'Clean Code', 'rating': 5, 'summary': '...'}

LangChain Expression Language (LCEL)

LCEL is the modern way to build chains in LangChain. Using the pipe operator (|), you can combine components declaratively:

from langchainopenai import ChatOpenAI

from langchaincore.prompts import ChatPromptTemplate

from langchaincore.outputparsers import StrOutputParser

Define a chain with LCEL

chain = (

ChatPromptTemplate.frommessages([

("system", "You are a professional translator."),

("human", "Translate the following text to {language}: {text}")

])

| ChatOpenAI(model="gpt-4o-mini")

| StrOutputParser()

)

Invoke (synchronous)

result = chain.invoke({

"language": "Japanese",

"text": "Good morning, how are you?"

})

print(result)

Streaming

for chunk in chain.stream({

"language": "Japanese",

"text": "Good morning, how are you?"

}):

print(chunk, end="", flush=True)

Batch processing

results = chain.batch([

{"language": "Japanese", "text": "Hello"},

{"language": "Korean", "text": "Thank you"},

{"language": "Mandarin", "text": "Goodbye"},

])

RunnablePassthrough and RunnableParallel

from langchaincore.runnables import RunnablePassthrough, RunnableParallel

RunnableParallel - run multiple chains in parallel

analysischain = RunnableParallel(

sentiment=ChatPromptTemplate.fromtemplate(

"Analyze the sentiment of this text (positive/negative/neutral): {text}"

) | llmopenai | StrOutputParser(),

summary=ChatPromptTemplate.fromtemplate(

"Summarize this text in one sentence: {text}"

) | llmopenai | StrOutputParser(),

language=ChatPromptTemplate.fromtemplate(

"Detect the language of this text: {text}"

) | llmopenai | StrOutputParser(),

original=RunnablePassthrough()

)

result = analysischain.invoke({

"text": "This product is amazing, I'm very satisfied with the quality!"

})

print(result)

{

'sentiment': 'positive',

'summary': 'Customer is very satisfied with product quality.',

'language': 'English',

'original': {'text': 'This product is amazing...'}

}

Retrieval-Augmented Generation (RAG)

RAG is one of the most popular use cases in LangChain. Here's a complete implementation:

Setting Up the Vector Store

from langchaincommunity.documentloaders import PyPDFLoader, TextLoader

from langchain.textsplitter import RecursiveCharacterTextSplitter

from langchainopenai import OpenAIEmbeddings

from langchainchroma import Chroma

1. Load documents

loader = PyPDFLoader("companyreport.pdf")

documents = loader.load()

2. Split documents into chunks

textsplitter = RecursiveCharacterTextSplitter(

chunksize=1000,

chunkoverlap=200,

separators=["\n\n", "\n", ".", " "]

)

chunks = textsplitter.splitdocuments(documents)

3. Create embeddings and store in vector store

embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

vectorstore = Chroma.fromdocuments(

documents=chunks,

embedding=embeddings,

persistdirectory="./chromadb"

)

4. Create retriever

retriever = vectorstore.asretriever(

searchtype="similarity",

searchkwargs={"k": 5}

)

RAG Chain

from langchaincore.prompts import ChatPromptTemplate

from langchaincore.runnables import RunnablePassthrough

from langchaincore.outputparsers import StrOutputParser

RAG template

ragprompt = ChatPromptTemplate.frommessages([

("system", """You are an assistant that answers questions based on the provided context.

Answer ONLY based on the context. If the information is not in the context, say "Information not found."

Context:

{context}"""),

("human", "{question}")

])

def formatdocs(docs):

return "\n\n".join(doc.pagecontent for doc in docs)

RAG Chain with LCEL

ragchain = (

{

"context": retriever | formatdocs,

"question": RunnablePassthrough()

}

| ragprompt

| llmopenai

| StrOutputParser()

)

Ask questions

answer = ragchain.invoke("What was the company's total revenue last year?")

print(answer)

Memory and Conversation History

LangChain provides several ways to manage conversation history:

from langchaincore.prompts import ChatPromptTemplate, MessagesPlaceholder

from langchaincore.messages import HumanMessage, AIMessage

from langchaincommunity.chatmessagehistories import ChatMessageHistory

from langchaincore.runnables.history import RunnableWithMessageHistory

Setup prompt with history

prompt = ChatPromptTemplate.frommessages([

("system", "You are a friendly and helpful AI assistant."),

MessagesPlaceholder(variablename="history"),

("human", "{input}")

])

chain = prompt | llmopenai | StrOutputParser()

Store for managing per-session history

store = {}

def getsessionhistory(sessionid: str):

if sessionid not in store:

store[sessionid] = ChatMessageHistory()

return store[sessionid]

Chain with memory

chainwithhistory = RunnableWithMessageHistory(

chain,

getsessionhistory,

inputmessageskey="input",

historymessageskey="history"

)

Multi-turn conversation

config = {"configurable": {"sessionid": "user123"}}

response1 = chainwithhistory.invoke(

{"input": "My name is Alex, I'm a data engineer"},

config=config

)

print(response1)

response2 = chainwithhistory.invoke(

{"input": "What's my name and what do I do?"},

config=config

)

print(response2) # The model will remember the name and occupation

Tool Calling and AI Agents

Defining Tools

from langchaincore.tools import tool

from langchainopenai import ChatOpenAI

@tool

def getweather(city: str) -> str:

"""Get weather information for a specific city."""

return f"Weather in {city}: Sunny, 28°C, Humidity 65%"

@tool

def calculate(expression: str) -> str:

"""Calculate a mathematical expression."""

try:

result = eval(expression)

return f"Result: {result}"

except Exception as e:

return f"Error: {str(e)}"

@tool

def searchdatabase(query: str) -> str:

"""Search for information in the company database."""

data = {

"revenue": "Total revenue Q1 2026: $3.2 Million",

"employees": "Number of employees: 150",

"products": "3 main products: AI Platform, Data Consulting, Training"

}

for key, value in data.items():

if key in query.lower():

return value

return "Data not found"

Bind tools to model

llmwithtools = ChatOpenAI(model="gpt-4o").bindtools(

[getweather, calculate, searchdatabase]

)

Building an Agent with LangGraph

from langgraph.prebuilt import createreactagent

Create a ReAct agent

agent = createreactagent(

model=ChatOpenAI(model="gpt-4o"),

tools=[getweather, calculate, searchdatabase]

)

Run the agent

result = agent.invoke({

"messages": [("human", "What's the weather in Tokyo and calculate 15% of the company revenue")]

})

for message in result["messages"]:

print(f"{message.type}: {message.content}")

Advanced Usage

Custom Chain with Branching Logic

from langchaincore.runnables import RunnableBranch

Different chains based on input language

classificationchain = (

ChatPromptTemplate.fromtemplate(

"Classify the language of this text (english/spanish/other): {text}\nAnswer in one word only."

)

| llmopenai

| StrOutputParser()

)

englishchain = (

ChatPromptTemplate.fromtemplate("Summarize this English text: {text}")

| llmopenai

| StrOutputParser()

)

spanishchain = (

ChatPromptTemplate.fromtemplate("Resume este texto en español: {text}")

| llmopenai

| StrOutputParser()

)

branch = RunnableBranch(

(lambda x: "english" in x["language"].lower(), englishchain),

(lambda x: "spanish" in x["language"].lower(), spanishchain),

englishchain # default

)

fullchain = (

RunnableParallel(

text=RunnablePassthrough(),

language=lambda x: classificationchain.invoke(x)

)

| branch

)

Structured Output with Pydantic

from pydantic import BaseModel, Field

from typing import List, Optional

class CompanyAnalysis(BaseModel):

companyname: str = Field(description="Company name")

industry: str = Field(description="Company industry")

strengths: List[str] = Field(description="Key strengths")

weaknesses: List[str] = Field(description="Key weaknesses")

recommendation: str = Field(description="Recommendation")

confidencescore: float = Field(description="Confidence score 0-1")

Use withstructuredoutput

structuredllm = ChatOpenAI(model="gpt-4o").withstructuredoutput(CompanyAnalysis)

result = structuredllm.invoke(

"Analyze Tesla based on current market conditions"

)

print(f"Company: {result.companyname}")

print(f"Industry: {result.industry}")

print(f"Strengths: {result.strengths}")

print(f"Score: {result.confidencescore}")

Callbacks and Observability

from langchaincore.callbacks import BaseCallbackHandler

from langchaincore.outputs import LLMResult

class CustomCallback(BaseCallbackHandler):

def onllmstart(self, serialized, prompts, kwargs):

print(f"[LLM Start] Model: {serialized.get('name', 'unknown')}")

def onllmend(self, response: LLMResult, kwargs):

tokenusage = response.llmoutput.get("tokenusage", {})

print(f"[LLM End] Tokens: {tokenusage}")

def ontoolstart(self, serialized, inputstr, kwargs):

print(f"[Tool Start] {serialized.get('name')}: {inputstr}")

def ontoolend(self, output, kwargs):

print(f"[Tool End] Output: {output}")

Use the callback

llm = ChatOpenAI(model="gpt-4o", callbacks=[CustomCallback()])

response = llm.invoke("Hello, how are you?")

Best Practices

1. Use the Right Model for the Right Task

# Small model for simple classification

classifier = ChatOpenAI(model="gpt-4o-mini", temperature=0)

Large model for complex reasoning

reasoner = ChatOpenAI(model="gpt-4o", temperature=0.2)

Local model for prototyping

localllm = ChatOllama(model="llama3.1")

2. Implement Error Handling

from tenacity import retry, stopafterattempt, waitexponential

@retry(stop=stopafterattempt(3), wait=waitexponential(min=1, max=10))

def invokewithretry(chain, inputdata):

return chain.invoke(inputdata)

3. Optimize Token Usage

import tiktoken

def counttokens(text: str, model: str = "gpt-4o") -> int:

encoding = tiktoken.encodingformodel(model)

return len(encoding.encode(text))

def trimcontext(docs, maxtokens=3000):

total = 0

trimmed = []

for doc in docs:

tokens = counttokens(doc.pagecontent)

if total + tokens > maxtokens:

break

trimmed.append(doc)

total += tokens

return trimmed

4. Use Caching

from langchaincore.globals import setllmcache

from langchaincommunity.cache import InMemoryCache, SQLiteCache

In-memory cache (for development)

setllmcache(InMemoryCache())

SQLite cache (for production)

setllmcache(SQLiteCache(databasepath=".langchaincache.db"))

Now identical responses will be cached

llm = ChatOpenAI(model="gpt-4o")

response1 = llm.invoke("What is AI?") # Hits API

response2 = llm.invoke("What is AI?") # From cache (instant)

5. Async for High Performance

import asyncio

async def processbatchasync(texts: list[str]):

chain = (

ChatPromptTemplate.fromtemplate("Summarize: {text}")

| ChatOpenAI(model="gpt-4o-mini")

| StrOutputParser()

)

tasks = [chain.ainvoke({"text": t}) for t in texts]

results = await asyncio.gather(*tasks)

return results

Run

texts = ["Long text 1...", "Long text 2...", "Long text 3..."]

results = asyncio.run(processbatch_async(texts))

Conclusion

LangChain is a powerful framework for building LLM-powered applications. Key takeaways:

  • Start with LCEL: LangChain Expression Language is the modern and recommended way to build chains
  • Choose the right components: Use Chat Models, Prompt Templates, Output Parsers, and Retrievers as needed
  • RAG for knowledge-grounded apps: Combine retrievers with LLMs for accurate applications
  • Agents for complex tasks: Use tool calling and LangGraph for agents that can take actions
  • Production readiness matters: Implement caching, error handling, observability, and async processing
  • LangChain evolves rapidly. Always check the official documentation at python.langchain.com for the latest features. For more complex agent orchestration, consider exploring LangGraph, which is part of the LangChain ecosystem.

    Related Articles

    Complete LangGraph Tutorial: Building Complex AI Agents

    Tutorial Lengkap LangGraph: Membangun AI Agents yang Kompleks LangGraph adalah library dari LangChain untuk membangun st...

    DSPy: Stop Hand-Tuning Prompts, Let the Compiler Optimize Them

    DSPy: Berhenti Ngoprek Prompt Manual, Biarkan Compiler yang Optimasi Halo temen-temen, kali ini aku mau ngenalin satu li...

    Zep Tutorial: Long-Term Memory for AI Agents with a Temporal Knowledge Graph

    Zep: Bikin AI Agent Punya Memori Jangka Panjang dengan Temporal Knowledge Graph Temen-temen, pernah ngobrol sama chatbot...

    Complete Dify Tutorial: Open-Source Platform for Building AI Applications

    Tutorial Lengkap Dify: Platform Open-Source untuk Membangun Aplikasi AI Dify adalah platform open-source yang memungkink...