LangChain is the most popular framework for building LLM-powered applications. It gives you composable building blocks โ prompt templates, chains, memory, agents, and retrievers โ so you can ship AI apps in hours instead of days. Let's build one right now.
Installation & Setup
Start with a fresh virtual environment:
bashpython -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install langchain langchain-openai langchain-community python-dotenv
Create a .env file with your OpenAI key:
.envOPENAI_API_KEY=sk-your-key-here
Prompt Templates
Hard-coding prompts is a rookie mistake. Use PromptTemplate to keep your prompts reusable and testable:
Pythonfrom langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from dotenv import load_dotenv load_dotenv() # Define a reusable prompt template prompt = ChatPromptTemplate.from_messages([ ("system", "You are a senior {role}. Answer concisely and accurately."), ("human", "{question}") ]) llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.0) chain = prompt | llm response = chain.invoke({ "role": "Python developer", "question": "What is the difference between a list and a tuple?" }) print(response.content)
Use gpt-4o-mini for development
It's 20x cheaper than gpt-4o and good enough for 90% of tasks. Switch to gpt-4o only when you hit a quality ceiling.
Building Chains
Chains connect multiple steps. LangChain uses the | pipe operator (LCEL โ LangChain Expression Language) to compose them:
Pythonfrom langchain_core.output_parsers import StrOutputParser # Chain: prompt โ LLM โ parse output to plain string chain = prompt | llm | StrOutputParser() # Stream the output token by token for chunk in chain.stream({"role": "data scientist", "question": "Explain p-value in one sentence."}): print(chunk, end="", flush=True)
Adding Memory
By default, LLMs are stateless. Each call knows nothing about the previous one. Add memory to enable real conversations:
Pythonfrom langchain_community.chat_message_histories import ChatMessageHistory from langchain_core.runnables.history import RunnableWithMessageHistory history_store = {} def get_session_history(session_id: str): if session_id not in history_store: history_store[session_id] = ChatMessageHistory() return history_store[session_id] chat_prompt = ChatPromptTemplate.from_messages([ ("system", "You are a helpful assistant."), ("placeholder", "{history}"), ("human", "{input}") ]) chain_with_memory = RunnableWithMessageHistory( chat_prompt | llm | StrOutputParser(), get_session_history, input_messages_key="input", history_messages_key="history" ) # Same session_id = remembers previous messages config = {"configurable": {"session_id": "user-123"}} print(chain_with_memory.invoke({"input": "My name is Junaid."}, config=config)) print(chain_with_memory.invoke({"input": "What's my name?"}, config=config))
Simple RAG Pipeline
The most powerful LangChain use case: answer questions using your own documents.
Pythonpip install langchain-chroma # vector store --- from langchain_community.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_openai import OpenAIEmbeddings from langchain_chroma import Chroma # 1. Load document loader = TextLoader("my_docs.txt") docs = loader.load() # 2. Split into chunks splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) chunks = splitter.split_documents(docs) # 3. Embed and store vectorstore = Chroma.from_documents(chunks, OpenAIEmbeddings()) # 4. Retrieve + answer retriever = vectorstore.as_retriever(search_kwargs={"k": 3}) rag_chain = ( {"context": retriever, "question": RunnablePassthrough()} | ChatPromptTemplate.from_template("Answer based on context:\n{context}\n\nQuestion: {question}") | llm | StrOutputParser() ) print(rag_chain.invoke("What does the document say about pricing?"))