AI TOOLS

LangChain Tutorial: Build Powerful AI Applications with LLMs

Building sophisticated AI applications with large language models requires more than simple API calls. You need a framework that handles conversation memory, connects to external data sources, manages multi-step reasoning, and orchestrates complex workflows. LangChain has emerged as the leading open-source framework for exactly this purpose. This tutorial walks you through everything you need to know to start building production-grade AI applications with LangChain.

What is LangChain?

LangChain is an open-source Python and JavaScript framework designed to simplify the development of applications powered by large language models. Rather than writing boilerplate code to handle prompts, memory, tool integrations, and data retrieval, LangChain provides modular, composable components that you snap together like building blocks.

The framework was created by Harrison Chase and has grown into one of the most actively maintained AI projects with over 90,000 GitHub stars. It supports every major LLM provider including OpenAI, Anthropic, Google, Meta, Mistral, and local models through Ollama and Hugging Face.

Core Concepts You Need to Understand

Prompts and Prompt Templates

Prompt engineering is the foundation of any LLM application. LangChain provides prompt templates that let you create reusable, parameterized prompts. Instead of hardcoding strings, you define templates with variables that get filled in at runtime.

from langchain_core.prompts import ChatPromptTemplate # Create a prompt template prompt = ChatPromptTemplate.from_messages([ ("system", "You are an expert {domain} tutor. Explain concepts clearly."), ("human", "{question}") ]) # Format the prompt with variables formatted = prompt.format_messages( domain="machine learning", question="What is gradient descent?" )

Models and Chat Models

LangChain wraps LLM providers behind a uniform interface, so you can swap providers without changing your application code. Chat models accept message lists and return message responses, while raw LLMs accept plain text strings.

from langchain_openai import ChatOpenAI from langchain_anthropic import ChatAnthropic # OpenAI model openai_model = ChatOpenAI(model="gpt-4o", temperature=0.7) # Anthropic model — same interface anthropic_model = ChatAnthropic(model="claude-sonnet-4-20250514", temperature=0.7) # Both work identically in chains response = openai_model.invoke("Hello, how are you?")

Output Parsers

LLMs return raw text, but your application needs structured data. Output parsers convert LLM responses into Pydantic objects, JSON, lists, or other structured formats.

from langchain_core.output_parsers import JsonOutputParser from pydantic import BaseModel, Field class MovieReview(BaseModel): title: str = Field(description="Movie title") rating: float = Field(description="Rating from 1 to 10") summary: str = Field(description="Brief summary") parser = JsonOutputParser(pydantic_object=MovieReview)

Building Chains: The Core Workflow

Chains are the heart of LangChain. A chain connects multiple components — prompts, models, parsers, and other chains — into a linear workflow. The LCEL (LangChain Expression Language) makes building chains intuitive using the pipe operator.

from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser # Build a chain with the pipe operator chain = ( ChatPromptTemplate.from_messages([ ("system", "You are a helpful assistant."), ("human", "{input}") ]) | ChatOpenAI(model="gpt-4o-mini") | StrOutputParser() ) # Run the chain result = chain.invoke({"input": "What is LangChain?"}) print(result)

💡 Key Insight: The pipe operator reads left to right — data flows from the prompt template to the model and then to the output parser. This makes chains easy to read, debug, and extend.

Adding Memory for Conversations

Without memory, every LLM call is stateless. LangChain provides several memory types to maintain conversation context across turns.

ConversationBufferMemory

Stores the entire conversation history. Best for short conversations where you want full context.

ConversationBufferWindowMemory

Keeps only the last K exchanges. Useful for long-running conversations where you want to limit token usage.

ConversationSummaryMemory

Uses an LLM to summarize the conversation history, compressing long conversations into shorter summaries that fit within context windows.

from langchain_community.chat_message_histories import ChatMessageHistory from langchain_core.chat_history import BaseChatMessageHistory from langchain_core.runnables.history import RunnableWithMessageHistory store = {} def get_session_history(session_id: str) -> BaseChatMessageHistory: if session_id not in store: store[session_id] = ChatMessageHistory() return store[session_id] chain_with_history = RunnableWithMessageHistory( chain, get_session_history, input_messages_key="input", history_messages_key="history" ) # Each session_id maintains its own conversation config = {"configurable": {"session_id": "abc123"}} result = chain_with_history.invoke({"input": "Hi, my name is Alice"}, config=config)

Retrieval-Augmented Generation (RAG)

RAG lets your LLM answer questions based on your own documents. Instead of relying solely on training data, the model retrieves relevant information from your knowledge base before generating a response.

Document Loaders

LangChain supports over 100 document loaders for PDFs, HTML pages, databases, Notion, Google Drive, and more.

Text Splitters

Documents get split into chunks that fit within the model's context window. Common strategies include recursive character splitting, HTML section splitting, and semantic splitting.

Vector Stores

Text chunks get converted to embeddings and stored in a vector database for fast similarity search. Popular options include ChromaDB, Pinecone, Weaviate, and Qdrant.

from langchain_community.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.vectorstores import Chroma from langchain_openai import OpenAIEmbeddings # Load documents loader = PyPDFLoader("knowledge_base.pdf") docs = loader.load() # Split into chunks splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200) chunks = splitter.split_documents(docs) # Create vector store vectorstore = Chroma.from_documents(chunks, OpenAIEmbeddings()) # Create retriever retriever = vectorstore.as_retriever(search_kwargs={"k": 3})

RAG Chain

Combine the retriever with a prompt and model into a complete RAG chain that answers questions from your documents.

from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_core.output_parsers import StrOutputParser template = """Answer the question based on the context below. If you cannot find the answer, say you don't know. Context: {context} Question: {question} Answer:""" prompt = ChatPromptTemplate.from_template(template) rag_chain = ( {"context": retriever | format_docs, "question": RunnablePassthrough()} | prompt | ChatOpenAI(model="gpt-4o") | StrOutputParser() ) result = rag_chain.invoke("What are the main topics covered?")

Building AI Agents with Tools

Agents are AI systems that reason about which tools to use and in what order. Unlike fixed chains, agents dynamically decide their workflow based on the user's request.

from langchain_openai import ChatOpenAI from langchain.agents import create_tool_calling_agent, AgentExecutor from langchain_core.tools import tool from langchain_core.prompts import ChatPromptTemplate @tool def calculate(expression: str) -> str: """Evaluate a math expression. Example: '2 + 2 * 3'""" return str(eval(expression)) @tool def search_web(query: str) -> str: """Search the web for current information.""" # Your search implementation here return f"Search results for: {query}" tools = [calculate, search_web] prompt = ChatPromptTemplate.from_messages([ ("system", "You are a helpful assistant with access to tools."), ("human", "{input}"), ("placeholder", "{agent_scratchpad}") ]) llm = ChatOpenAI(model="gpt-4o") agent = create_tool_calling_agent(llm, tools, prompt) executor = AgentExecutor(agent=agent, tools=tools, verbose=True) result = executor.invoke({"input": "What is 15 * 37 + 128?"})

LangChain vs LlamaIndex vs Semantic Kernel

Several frameworks compete in the LLM orchestration space. Here's how LangChain compares:

Feature LangChain LlamaIndex Semantic Kernel
Primary Focus General LLM orchestration Data indexing and RAG Enterprise AI integration
Agent Support Excellent Good Good
RAG Capabilities Good Excellent Good
Languages Python, JavaScript Python, TypeScript Python, C#, Java
Ecosystem Largest Growing Microsoft-backed
Learning Curve Moderate Moderate Steeper

LangSmith: Debugging and Monitoring

LangSmith is LangChain's companion platform for debugging, testing, and monitoring LLM applications in production. It provides trace logging for every chain execution, allowing you to inspect inputs, outputs, token usage, latency, and errors at each step.

⚠️ Production Tip: Enable LangSmith tracing during development to debug complex chains. Set the LANGCHAIN_TRACING_V2 environment variable to "true" and provide your API key. This visibility is invaluable when chains don't behave as expected.

Best Practices for Production Applications

Conclusion

LangChain transforms the complexity of building LLM applications into manageable, composable components. Whether you're building a simple chatbot, a RAG system over your company's documents, or a multi-agent workflow, LangChain provides the tools and abstractions to get you there efficiently. Start with the core concepts of chains and prompts, add memory for conversational applications, integrate your data with RAG, and deploy with LangSmith for production monitoring. The framework's active community and rapid development mean new capabilities arrive regularly, making it a solid long-term investment for any AI development team.

← Back to Articles

Frequently Asked Questions

What is LangChain and why should I use it?

LangChain is an open-source framework for building applications powered by large language models. It provides modular components for chaining together LLM calls, managing conversation memory, connecting to external tools and data sources, and building autonomous agents. You should use it when you need to go beyond simple API calls and create complex AI workflows with retrieval-augmented generation, multi-step reasoning, or tool-use capabilities.

Is LangChain free to use?

Yes, LangChain is completely free and open-source under the MIT license. You can install it via pip install langchain or npm install langchain. However, you will still need API keys for the LLM providers you want to use, such as OpenAI, Anthropic, or local models via Ollama, which have their own pricing.

Can I use LangChain with local LLMs?

Absolutely. LangChain supports local LLMs through integrations with Ollama, llama.cpp, Hugging Face Transformers, and vLLM. This lets you run models like Llama 3, Mistral, or Phi-3 on your own hardware without sending data to external APIs, which is ideal for privacy-sensitive applications.

What is the difference between LangChain and LlamaIndex?

LangChain is a general-purpose framework for building LLM applications with chains, agents, and tool integrations. LlamaIndex is more focused on data indexing and retrieval for question-answering systems. Many developers use both together — LlamaIndex for building search indexes and LangChain for orchestration and agent workflows.

How do I deploy a LangChain application to production?

Deploy a LangChain application by wrapping your chains or agents in a FastAPI or Flask web server. Use LangSmith for monitoring and debugging in production. Implement proper error handling, rate limiting, and caching with LangChain's built-in cache mechanisms. For scaling, consider using LangServe to deploy chains as REST APIs with automatic documentation.