Building LLM Applications with LangChain and LlamaIndex
Learn how to build LLM applications. Master chaining, prompt templates, indexes, and agentic workflows using LangChain and LlamaIndex in Python.
Introduction
If you want to build a simple chatbot, you can write a short Python script that calls the OpenAI API. But what if you want to build a system that reads a PDF file, splits it into chunks, saves it to a database, remembers the user's chat history, queries a search engine for facts, and automatically formats the output into a Excel sheet?
Writing this from scratch involves hundreds of lines of boilerplate code.
This is why developers use orchestrator frameworks like LangChain and LlamaIndex. These frameworks provide ready-made abstractions (like chains, loaders, and agentic tools) that allow you to connect LLMs to external data, memory states, and software tools with minimal code.
What You Will Learn
- The core differences between LangChain and LlamaIndex.
- How Prompt Templates and Chains work in LangChain.
- How LlamaIndex structures indices for data queries.
- The concept of LLM Agents and tool-calling loops.
- Implementing a simple LangChain chain in Python.
Why This Topic Matters
Orchestration libraries are the backbone of modern AI application development. Knowing how to leverage LangChain and LlamaIndex allows you to build autonomous agents, manage complex state histories, and plug LLMs directly into custom enterprise software pipelines.
Prerequisites
- Prompt Engineering: Techniques, Formats, and Best Practices
- Retrieval-Augmented Generation (RAG): Architecture and Vector DBs
Detailed Explanation
While both libraries help you build applications with LLMs, they focus on different aspects:
graph TD
A[Orchestration Ecosystem]
A --> B[LangChain: General Orchestrator <br> Best for custom workflows, agent logic, multi-step actions]
A --> C[LlamaIndex: Data-centric Framework <br> Best for document search, RAG pipelines, data indices]
1. LangChain: The General-Purpose Orchestrator
LangChain acts like a collection of building blocks:
- Models: Uniform interfaces for OpenAI, Anthropic, Hugging Face, etc.
- Prompt Templates: Dynamic prompts that accept user variables.
- Chains: Combining multiple steps together. For example, taking an LLM response and passing it directly to a translation model.
- Memory: Storing past chat tokens in a Redis database so the LLM remembers previous turns.
2. LlamaIndex: The Data Integrator
LlamaIndex focuses on connecting LLMs to your private data sources.
- Data Connectors: Loaders for PDFs, Slack channels, Google Docs, Notion, or databases.
- Index Structures: Organizes data into query-ready structures (Vector Store Index, Keyword Table Index, Tree Index).
- Query Engines: Highly optimized RAG retrieval interfaces that handle chunking, embedding, and matching.
3. LLM Agents (ReAct Framework)
An Agent is an LLM that has access to a set of Tools (e.g., a Google Search API, a Calculator, a database executor). Instead of following a hardcoded path, the LLM runs in an loop (Reasoning and Acting, or ReAct):
- Thought: The agent decides what steps to take (e.g., "To find the age of the CEO, I need to search the web.")
- Action: The agent calls a tool (e.g., runs a Web Search API with query
"who is the CEO of X"). - Observation: The agent reads the tool's result (e.g.,
"The CEO of X is John Doe, age 45"). - Repeat / Finish: The agent repeats the cycle or returns the final answer to the user.
Visual Diagram (Mermaid)
graph TD
subgraph Agentic ReAct Loop
A[User Request] --> B[Thought: Determine next tool]
B --> C[Action: Invoke Tool/API]
C --> D[Observation: Read Tool Output]
D --> E{Is task complete?}
E -->|No| B
E -->|Yes| F[Final Response]
end
style B fill:#3B82F6,stroke:#fff,color:#fff
style C fill:#F59E0B,stroke:#fff,color:#fff
style F fill:#10B981,stroke:#fff,color:#fff
Python Code Examples
We will write a conceptual script using LangChain structures to format prompts and chain them to mock models.
# Simulating LangChain Chain Operations in Python
class PromptTemplate:
def __init__(self, template_str):
self.template_str = template_str
def format(self, **kwargs):
return self.template_str.format(**kwargs)
class MockLLM:
def __call__(self, prompt):
# Simulating LLM text generation
return f"LLM Response to: '{prompt}'"
class LLMChain:
def __init__(self, prompt_template, llm):
self.prompt_template = prompt_template
self.llm = llm
def run(self, **kwargs):
formatted_prompt = self.prompt_template.format(**kwargs)
# Execute model call
return self.llm(formatted_prompt)
# Setup a LangChain-style pipeline
template = PromptTemplate("Explain the concept of {topic} in simple terms.")
llm = MockLLM()
# Create Chain
chain = LLMChain(prompt_template=template, llm=llm)
# Execute Chain
result = chain.run(topic="Vector Indexing")
print(result)
Industry Use Cases
- AI Database Analysts: Building agents with access to SQL databases, allowing users to query data using natural language.
- Enterprise Customer Portals: Connecting LlamaIndex to Notion documents to automate company ticket responses.
- Automated Research Assistants: Creating agents that search arXiv for research papers, download PDFs, and summarize findings.
Summary
LangChain acts as a general-purpose orchestration framework supporting prompt templates, memory, and multi-step agentic ReAct loops. LlamaIndex compliments this by focusing specifically on document loading, vector storage indexing, and advanced RAG pipeline engines, facilitating the integration of LLMs with custom corporate architectures.