Skip to main content

LlamaIndex: RAG Pipelines, Indexes & LLM Integration

LlamaIndex is the data framework for LLM applications. Ingest any document, index it into a vector store, and build retrieval-augmented generation (RAG) pipelines that answer questions over your own data — with any LLM backend.

✓ 40+ data loaders (PDF/CSV/web/DB) ✓ VectorStore / KnowledgeGraph indexes ✓ OpenAI / Claude / Ollama support ✓ Advanced RAG (reranking, HyDE, sub-queries)
Share this tool: X / Twitter LinkedIn
✓ 60,000+ developers use DevPlaybook ★★★★★ 4.8 / 5 on Gumroad ✓ MIT licensed · Instant download ✓ No login required

Related Products

on Gumroad

You Might Also Need

More Free Tools

Enjoying this tool? Get more like it.

Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.

DevPlaybook Pro 7 days free

Unlock AI-Powered Dev Tools

  • ⚡ AI Code Review, Doc Generator & SQL Builder
  • ⚡ All premium templates & early access
  • ⚡ Member discounts on Gumroad products
Start Free Trial →

$9/mo after trial · Cancel anytime

Want the full toolkit?

Get DevPlaybook Pro

Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.

$79
$241 separately Save $162 (67% off)
Get DevPlaybook Pro — $79 →

MIT licensed · Instant download · No subscription

See what's included → Browse all deals →

Quickstart: Build a RAG Pipeline in 10 Lines

Install with pip install llama-index. Load documents, index, and query:

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding

# Configure LLM and embedding model globally
Settings.llm = OpenAI(model="gpt-4o-mini", temperature=0.1)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
Settings.chunk_size = 512
Settings.chunk_overlap = 50

# Load all documents from a directory (PDFs, .txt, .md, .docx)
documents = SimpleDirectoryReader("./docs").load_data()
print(f"Loaded {len(documents)} documents")

# Build a VectorStoreIndex — chunks docs, embeds, stores vectors
index = VectorStoreIndex.from_documents(
    documents,
    show_progress=True,
)

# Create a query engine
query_engine = index.as_query_engine(
    similarity_top_k=5,          # retrieve top 5 most relevant chunks
    response_mode="compact",     # compact | refine | tree_summarize
)

# Ask questions
response = query_engine.query("What are the main product features?")
print(response)
print(f"Sources: {[n.node.metadata['file_name'] for n in response.source_nodes]}")

Advanced RAG: Reranking, HyDE & Sub-Questions

Improve retrieval quality with advanced patterns beyond basic top-K similarity search:

from llama_index.core import VectorStoreIndex
from llama_index.core.postprocessor import SentenceTransformerRerank
from llama_index.core.query_engine import SubQuestionQueryEngine
from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.core.retrievers import VectorIndexRetriever

# --- Pattern 1: Reranking (retrieve more, rerank to top-K) ---
retriever = VectorIndexRetriever(index=index, similarity_top_k=20)  # fetch 20

# Rerank the 20 results down to the best 5 using a cross-encoder
reranker = SentenceTransformerRerank(
    model="cross-encoder/ms-marco-MiniLM-L-2-v2",
    top_n=5,
)

from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.response_synthesizers import get_response_synthesizer

query_engine = RetrieverQueryEngine(
    retriever=retriever,
    response_synthesizer=get_response_synthesizer(),
    node_postprocessors=[reranker],
)

# --- Pattern 2: HyDE (Hypothetical Document Embeddings) ---
from llama_index.core.indices.query.query_transform import HyDEQueryTransform
from llama_index.core.query_engine import TransformQueryEngine

base_engine = index.as_query_engine(similarity_top_k=5)
hyde_transform = HyDEQueryTransform(include_original=True)
# HyDE: LLM generates a hypothetical answer, embed that instead of the query
hyde_engine = TransformQueryEngine(base_engine, query_transform=hyde_transform)

# --- Pattern 3: Sub-Question Decomposition ---
# For complex multi-part queries, decompose into sub-questions
tools = [QueryEngineTool(query_engine=index.as_query_engine(), metadata=ToolMetadata(
    name="product_docs", description="Company product documentation"
))]
sub_question_engine = SubQuestionQueryEngine.from_defaults(query_engine_tools=tools)
response = sub_question_engine.query(
    "Compare the pricing and features of our starter vs enterprise plans"
)

Local RAG with Ollama (No API Keys)

Run a fully local RAG pipeline using Ollama and persisted vector store:

import os
from llama_index.core import (
    VectorStoreIndex, SimpleDirectoryReader,
    StorageContext, load_index_from_storage, Settings
)
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.ollama import OllamaEmbedding

# Configure local models (Ollama must be running: ollama pull llama3)
Settings.llm = Ollama(model="llama3", request_timeout=60.0)
Settings.embed_model = OllamaEmbedding(model_name="nomic-embed-text")

PERSIST_DIR = "./storage"

if not os.path.exists(PERSIST_DIR):
    # First run: build and persist the index
    documents = SimpleDirectoryReader("./docs").load_data()
    index = VectorStoreIndex.from_documents(documents)
    index.storage_context.persist(persist_dir=PERSIST_DIR)
    print("Index built and persisted")
else:
    # Subsequent runs: load from disk (no re-indexing)
    storage_context = StorageContext.from_defaults(persist_dir=PERSIST_DIR)
    index = load_index_from_storage(storage_context)
    print("Index loaded from disk")

# Chat engine with memory (multi-turn conversation)
chat_engine = index.as_chat_engine(
    chat_mode="condense_plus_context",
    verbose=True,
)
response = chat_engine.chat("What does our return policy say?")
follow_up = chat_engine.chat("And what about international orders?")  # remembers context

LlamaIndex vs LangChain vs Haystack vs DSPy

Feature LlamaIndex LangChain Haystack DSPy
RAG / indexingBest-in-classGood (LCEL chains)Good (Pipeline DAG)Module-based
Agent supportLlamaAgents (beta)LangGraph (mature)Agent pipelineReAct via modules
Index typesVector/KG/SQL/SummaryVector retrieversDense/sparse/hybridNo explicit indexes
Prompt optimizationManualManualManualAutomatic (compile)
Local LLM supportOllama/LlamaCPPOllama/LlamaCPPOllama/HFAny LM
Best forRAG over documentsAgents, general LLMNLP search pipelinesPrompt optimization

Frequently Asked Questions

What is LlamaIndex and how does it differ from LangChain?▼

LlamaIndex (formerly GPT Index) is a data framework specialized for building LLM applications over custom data. Its core strength is the indexing, retrieval, and query pipeline for RAG (Retrieval-Augmented Generation). LangChain is a broader orchestration framework covering agents, chains, tools, memory, and RAG. LlamaIndex has deeper index types (VectorStoreIndex, KnowledgeGraphIndex, SQLStructStoreIndex) and better abstractions for document ingestion, chunking, and structured retrieval. Many production systems use both: LlamaIndex for retrieval and LangChain for agent orchestration.

What is RAG and why is it better than fine-tuning?▼

RAG (Retrieval-Augmented Generation) retrieves relevant documents at query time and passes them as context to the LLM, instead of baking knowledge into model weights via fine-tuning. RAG advantages: (1) knowledge can be updated without retraining — just add documents to the index; (2) the model can cite sources; (3) it works with any LLM (OpenAI, Claude, Ollama, Mistral); (4) it is cheaper — fine-tuning a large model costs thousands of dollars. RAG is the right choice for question-answering over evolving document collections.

How does LlamaIndex handle document chunking?▼

LlamaIndex splits documents into Nodes (chunks) before indexing. The default SimpleNodeParser splits on sentence boundaries with a chunk_size of 1024 tokens and chunk_overlap of 20 tokens (to preserve context at chunk boundaries). You can configure chunking with SentenceSplitter, TokenTextSplitter, or SemanticSplitterNodeParser (which uses embeddings to find natural semantic boundaries). Chunk size is a key hyperparameter: smaller chunks (256-512 tokens) give more precise retrieval; larger chunks (1024+ tokens) give more context per retrieved node.

What is the difference between a query engine and a chat engine in LlamaIndex?▼

A QueryEngine handles single-turn queries: given a question, retrieve relevant nodes and synthesize an answer. A ChatEngine handles multi-turn conversations: it maintains conversation history and can answer follow-up questions that reference previous exchanges ('what did you just say about X?'). Use QueryEngine for Q&A search tools and ChatEngine for conversational assistants. Both can use the same underlying index.

How do I use LlamaIndex with local models (Ollama)?▼

LlamaIndex supports local models via the Ollama integration. Install llama-index-llms-ollama and llama-index-embeddings-ollama, then configure them as the default LLM and embedding model. This enables fully local RAG pipelines with no API costs or data leaving your machine. Popular local models for RAG: Llama 3 8B/70B, Mistral 7B, Phi-3 Mini, and Nomic-Embed-Text for embeddings.

How do I persist and reload a VectorStoreIndex?▼

By default, VectorStoreIndex stores vectors in memory and is lost when the process exits. For persistence, save to disk with index.storage_context.persist(persist_dir='./storage'), then reload with StorageContext.from_defaults(persist_dir='./storage') and load_index_from_storage(). For production, use an external vector store (Pinecone, Qdrant, Chroma, Weaviate) via the VectorStore abstraction — vectors persist in the database and survive process restarts without re-indexing.