Getting Started with LangChain for AI Apps
HOW TO GUIDES Dec. 12, 2025, 1:38 p.m.

Getting Started with LangChain for AI Apps

LangChain has quickly become the go‑to framework for building AI‑powered applications that combine language models with external data, tools, and custom logic. In this guide we’ll walk through the core concepts, set up a development environment, and build a few end‑to‑end examples you can run today. By the end you’ll understand how to stitch together LLMs, memory, and agents to create robust, production‑ready AI apps.

What Is LangChain?

At its heart, LangChain is a modular toolkit that lets you chain together language model calls, prompt templates, and utilities such as vector stores or APIs. Think of it as a “Lego set” for LLM workflows—each piece is reusable, testable, and can be swapped without rewriting the whole app.

Key building blocks include:

  • LLM wrappers – abstract over OpenAI, Anthropic, Hugging Face, etc.
  • Prompt templates – reusable, parameterized prompts that keep your prompts DRY.
  • Chains – sequential pipelines that feed the output of one component into the next.
  • Memory – stateful objects that remember prior interactions.
  • Agents – dynamic planners that decide which tool or chain to invoke next.

Because these components are loosely coupled, you can start with a simple one‑liner and gradually add sophistication as your product evolves.

Installation & Basic Setup

First, make sure you have Python 3.9+ installed. Then create a virtual environment and install LangChain along with a language‑model provider of your choice. The example below uses OpenAI’s GPT‑4, but you can swap in any compatible model.

# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate

# Install LangChain and the OpenAI SDK
pip install langchain openai

Set your API key as an environment variable so LangChain can authenticate automatically.

import os
os.getenv("OPENAI_API_KEY")  # Should return your key if set

If you prefer a different provider, replace openai with anthropic, cohere, etc., and adjust the import accordingly.

Your First LangChain: LLM + Prompt Template

Let’s start with the classic “summarize a paragraph” use case. We’ll define a prompt template that receives a text variable, feed it to the LLM, and return the summary.

from langchain import PromptTemplate, LLMChain
from langchain.llms import OpenAI

# Define a simple prompt with a placeholder for the input text
template = """
You are a concise writer. Summarize the following text in 2-3 sentences:

{text}
"""

prompt = PromptTemplate(
    input_variables=["text"],
    template=template,
)

# Initialize the LLM (default temperature = 0.7)
llm = OpenAI(model="gpt-4")

# Build the chain: Prompt -> LLM
summary_chain = LLMChain(prompt=prompt, llm=llm)

# Run the chain
article = """Artificial intelligence has transformed many industries, from healthcare to finance. 
However, ethical concerns about bias, privacy, and job displacement remain unresolved."""
print(summary_chain.run(text=article))

The LLMChain abstracts away the boilerplate of formatting the prompt and calling the model. You can reuse summary_chain across your codebase, ensuring consistent prompting.

Why Prompt Templates Matter

Hard‑coding strings leads to duplication and makes it hard to experiment with wording. Prompt templates let you inject variables, keep your prompts version‑controlled, and even combine multiple templates in a single chain.

Adding Memory: Stateful Conversations

Most real‑world apps need to remember prior interactions. LangChain’s ConversationBufferMemory stores a rolling transcript that you can prepend to each new prompt.

from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain

# Memory that keeps the last 5 exchanges
memory = ConversationBufferMemory(k=5)

# A simple conversational chain
chat = ConversationChain(
    llm=OpenAI(model="gpt-4"),
    memory=memory,
    verbose=True  # Prints intermediate steps
)

# Simulate a short dialogue
print(chat.predict(input="Hi, I'm Alex."))
print(chat.predict(input="Can you recommend a good sci‑fi book?"))
print(chat.predict(input="What about something by Asimov?"))

Notice how each call automatically includes the previous messages, enabling context‑aware responses without manual concatenation.

Pro tip: For long‑running bots, consider ConversationSummaryMemory which summarizes older turns to keep token usage low while preserving gist.

Agents: Dynamic Tool Use

Agents are the most powerful LangChain feature. An agent receives a user query, decides which tool (e.g., a web search, calculator, or database) to call, and then crafts a final answer. This mimics how a human might look up information before responding.

Setting Up a Simple Calculator Agent

We’ll build an agent that can both answer general questions and perform arithmetic when needed. First, define the tool.

from langchain.tools import Tool
from langchain.utilities import PythonREPL

# A REPL tool that safely evaluates Python expressions
python_tool = Tool(
    name="PythonREPL",
    func=PythonREPL().run,
    description="Executes a Python expression and returns the result. Use for math or quick data manipulation."
)

Next, create the agent with the OpenAI LLM and register the tool.

from langchain.agents import initialize_agent, AgentType

tools = [python_tool]

agent = initialize_agent(
    tools,
    OpenAI(model="gpt-4"),
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)

# Try a mixed query
print(agent.run("What is the sum of the first 20 prime numbers?"))

The agent first decides that a calculation is required, calls the PythonREPL tool, and then formats the result in natural language.

Extending Agents with External APIs

Suppose you want a travel‑assistant bot that can fetch flight prices. You can wrap any HTTP request in a Tool and let the agent invoke it.

import requests
from langchain.tools import StructuredTool
from pydantic import BaseModel, Field

class FlightQuery(BaseModel):
    origin: str = Field(..., description="IATA code of departure city")
    destination: str = Field(..., description="IATA code of arrival city")
    date: str = Field(..., description="Travel date in YYYY‑MM‑DD format")

def get_flight_price(origin: str, destination: str, date: str) -> str:
    # Dummy endpoint – replace with a real API in production
    resp = requests.get(
        "https://api.example.com/flights",
        params={"from": origin, "to": destination, "date": date}
    )
    data = resp.json()
    return f"${data['price']} USD"

flight_tool = StructuredTool.from_function(
    func=get_flight_price,
    name="GetFlightPrice",
    description="Fetches the cheapest flight price for a given route and date.",
    args_schema=FlightQuery,
)

Register the new tool alongside the calculator, and the agent can now answer queries like “Find me the cheapest flight from NYC to LON next Friday.”

Real‑World Use Cases

LangChain shines in scenarios where raw LLM output isn’t enough. Below are three common patterns you can adapt to your product.

1. Customer Support Bot with Knowledge Base Retrieval

  • Store FAQ documents in a vector store (e.g., FAISS or Pinecone).
  • When a user asks a question, retrieve the top‑k relevant chunks.
  • Pass the retrieved context to the LLM via a prompt template.
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.chains import RetrievalQA

# Load pre‑indexed FAQ embeddings
embeddings = OpenAIEmbeddings()
vector_store = FAISS.load_local("faq_index", embeddings)

# RetrievalQA chain combines vector search + LLM answer generation
qa = RetrievalQA.from_chain_type(
    llm=OpenAI(model="gpt-4"),
    chain_type="stuff",
    retriever=vector_store.as_retriever(search_kwargs={"k": 3}),
)

print(qa.run("How do I reset my password?"))

This pattern reduces hallucinations because the LLM only answers based on verified knowledge base excerpts.

2. Data Extraction from PDFs or Scanned Invoices

Combine a PDF loader, a text splitter, and a structured output parser to turn messy documents into clean JSON.

from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field

# Define the schema we expect
class Invoice(BaseModel):
    vendor: str = Field(..., description="Name of the supplier")
    total: float = Field(..., description="Total amount due")
    due_date: str = Field(..., description="Payment due date in YYYY‑MM‑DD")

parser = PydanticOutputParser(pydantic_object=Invoice)

loader = PyPDFLoader("sample_invoice.pdf")
pages = loader.load_and_split()

splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = splitter.split_documents(pages)

# Build a chain that extracts structured data from each chunk
from langchain.chains import LLMChain
extract_chain = LLMChain(
    llm=OpenAI(model="gpt-4"),
    prompt=PromptTemplate(
        input_variables=["text"],
        template="""
Extract the following fields from the invoice text. Return JSON that matches the schema.

{text}

{format_instructions}
""".format(format_instructions=parser.get_format_instructions())
    ),
    output_parser=parser,
)

# Process each chunk (in practice you’d filter empty results)
results = [extract_chain.run(text=chunk.page_content) for chunk in chunks]
print(results[:1])  # Show first parsed invoice

Using a Pydantic parser guarantees the output conforms to a strict schema, making downstream processing reliable.

3. Personal AI Assistant with Calendar Integration

Imagine an assistant that can schedule meetings, check the weather, and answer trivia—all in one conversation. You’d combine:

  • Calendar tool (Google Calendar API wrapper).
  • Weather tool (OpenWeatherMap API).
  • General knowledge agent (zero‑shot react).

Each tool is exposed as a Tool object, and the agent decides which one to call based on the user’s intent. The result is a seamless, multi‑modal experience without writing separate UI flows.

Pro Tips for Production‑Ready LangChain Apps

1. Keep prompts version‑controlled. Store them in .json or .yaml files and load with PromptTemplate.from_file(). This makes A/B testing trivial. 2. Cache expensive calls. Use langchain.cache or an external Redis layer to memoize LLM responses for identical inputs, cutting costs dramatically. 3. Monitor token usage. Wrap your LLM with a custom subclass that logs prompt_tokens and completion_tokens. Alert when a request exceeds your budget. 4. Secure tool execution. When exposing REPL‑style tools, sandbox the environment (e.g., use restrictedpython) to prevent arbitrary code execution. 5. Deploy with async support. LangChain’s AsyncLLMChain and AsyncRetriever let you handle high‑throughput traffic without blocking the event loop.

Testing & Debugging Your Chains

LangChain ships with a CallbackManager that fires events at each step (prompt creation, LLM call, tool execution). Register a simple logger to see the full trace.

from langchain.callbacks import CallbackManager, StdOutCallbackHandler

callback = CallbackManager([StdOutCallbackHandler()])

# Pass the callback manager to any chain or agent
debug_chain = LLMChain(
    llm=OpenAI(model="gpt-4", callback_manager=callback),
    prompt=prompt,
    callback_manager=callback
)

debug_chain.run(text="Explain quantum entanglement in plain English.")

The console will show the rendered prompt, the raw model response, and any post‑processing steps, making it easy to spot prompt engineering bugs.

Deploying LangChain Apps

For production you typically wrap your chain in a lightweight web framework—FastAPI is a popular choice because it supports async endpoints out of the box.

from fastapi import FastAPI, Request
from pydantic import BaseModel

app = FastAPI()

class Query(BaseModel):
    text: str

@app.post("/summarize")
async def summarize(payload: Query):
    # Async version of the earlier summary chain
    result = await summary_chain.arun(text=payload.text)
    return {"summary": result}

Deploy to a container platform (Docker, Kubernetes, or serverless) and set environment variables for API keys. Remember to enable request‑level timeouts; LLM calls can occasionally stall.

Conclusion

LangChain transforms the chaotic world of prompt engineering into a disciplined, testable codebase. By mastering prompts, memory, agents, and tool integration you can build AI applications that are both powerful and reliable. Start small—wrap a single LLM call in a chain—then iterate: add memory, plug in external APIs, and finally orchestrate complex agents. With the patterns and tips covered here, you’re ready to turn ideas into production‑grade AI products that delight users and stay under control.

Share this article