We use cookies to enhance your experience on the site
CodeWorlds

LlamaIndex - RAG Framework

LlamaIndex is a powerful framework for building RAG applications. It simplifies the entire process - from loading documents to generating answers. It is like having a complete toolkit for building an AI system!

LlamaIndex Basics

1from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
2from llama_index.llms.openai import OpenAI
3from llama_index.embeddings.openai import OpenAIEmbedding
4
5# Global configuration
6Settings.llm = OpenAI(model="gpt-4o-mini", temperature=0)
7Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
8
9# Load documents
10documents = SimpleDirectoryReader("./docs").load_data()
11print(f"Loaded {len(documents)} documents")
12
13# Create index
14index = VectorStoreIndex.from_documents(documents)
15
16# Query engine
17query_engine = index.as_query_engine()
18
19# Query
20response = query_engine.query("What is RAG?")
21print(response)

Document Loaders

1from llama_index.core import Document
2from llama_index.readers.web import SimpleWebPageReader
3from llama_index.readers.file import PDFReader, DocxReader
4
5# From text
6doc = Document(text="This is sample text to be indexed.")
7
8# From files
9pdf_reader = PDFReader()
10pdf_docs = pdf_reader.load_data(file="document.pdf")
11
12# From web page
13web_reader = SimpleWebPageReader()
14web_docs = web_reader.load_data(urls=["https://example.com"])
15
16# From multiple sources
17from llama_index.core import SimpleDirectoryReader
18
19reader = SimpleDirectoryReader(
20    input_dir="./data",
21    recursive=True,
22    required_exts=[".pdf", ".docx", ".txt", ".md"]
23)
24documents = reader.load_data()

Node Parsing (Chunking)

1from llama_index.core.node_parser import (
2    SentenceSplitter,
3    SemanticSplitterNodeParser,
4)
5
6# Simple sentence splitting
7sentence_parser = SentenceSplitter(
8    chunk_size=512,
9    chunk_overlap=50
10)
11nodes = sentence_parser.get_nodes_from_documents(documents)
12
13# Semantic splitting
14semantic_parser = SemanticSplitterNodeParser(
15    buffer_size=1,
16    breakpoint_percentile_threshold=95,
17    embed_model=Settings.embed_model
18)
19semantic_nodes = semantic_parser.get_nodes_from_documents(documents)
20
21# Hierarchical splitting
22from llama_index.core.node_parser import HierarchicalNodeParser
23
24hierarchical_parser = HierarchicalNodeParser.from_defaults(
25    chunk_sizes=[2048, 512, 128]
26)
27hierarchical_nodes = hierarchical_parser.get_nodes_from_documents(documents)

Retriever Modes

1from llama_index.core.retrievers import VectorIndexRetriever
2from llama_index.core.query_engine import RetrieverQueryEngine
3from llama_index.core.postprocessor import SimilarityPostprocessor
4
5# Basic retriever
6retriever = VectorIndexRetriever(
7    index=index,
8    similarity_top_k=5
9)
10
11# With postprocessing
12query_engine = RetrieverQueryEngine(
13    retriever=retriever,
14    node_postprocessors=[
15        SimilarityPostprocessor(similarity_cutoff=0.7)
16    ]
17)
18
19# Hybrid retriever
20from llama_index.core.retrievers import BM25Retriever
21from llama_index.core.retrievers import QueryFusionRetriever
22
23vector_retriever = index.as_retriever(similarity_top_k=5)
24bm25_retriever = BM25Retriever.from_defaults(nodes=nodes, similarity_top_k=5)
25
26hybrid_retriever = QueryFusionRetriever(
27    retrievers=[vector_retriever, bm25_retriever],
28    similarity_top_k=5,
29    num_queries=1,
30)

Query Transformations

1from llama_index.core.query_engine import SubQuestionQueryEngine
2from llama_index.core.tools import QueryEngineTool
3
4# Sub-question engine - breaks questions into smaller ones
5tools = [
6    QueryEngineTool.from_defaults(
7        query_engine=index.as_query_engine(),
8        name="documentation",
9        description="Contains project documentation"
10    )
11]
12
13sub_question_engine = SubQuestionQueryEngine.from_defaults(
14    query_engine_tools=tools
15)
16
17# HyDE - Hypothetical Document Embeddings
18from llama_index.core.indices.query.query_transform import HyDEQueryTransform
19from llama_index.core.query_engine import TransformQueryEngine
20
21hyde = HyDEQueryTransform(include_original=True)
22hyde_query_engine = TransformQueryEngine(
23    index.as_query_engine(),
24    query_transform=hyde
25)

Chat Engine

1from llama_index.core.chat_engine import CondenseQuestionChatEngine
2from llama_index.core.memory import ChatMemoryBuffer
3
4# Chat memory
5memory = ChatMemoryBuffer.from_defaults(token_limit=3000)
6
7# Chat engine with history
8chat_engine = index.as_chat_engine(
9    chat_mode="condense_question",
10    memory=memory,
11    verbose=True
12)
13
14# Conversation
15response1 = chat_engine.chat("What is Python?")
16print(response1)
17
18response2 = chat_engine.chat("What are its applications?")
19print(response2)
20
21# Reset memory
22chat_engine.reset()

Integration with Vector Databases

1# Chroma
2from llama_index.vector_stores.chroma import ChromaVectorStore
3import chromadb
4
5chroma_client = chromadb.PersistentClient(path="./chroma_db")
6chroma_collection = chroma_client.get_or_create_collection("llama_index")
7
8vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
9index = VectorStoreIndex.from_vector_store(vector_store)
10
11# Qdrant
12from llama_index.vector_stores.qdrant import QdrantVectorStore
13from qdrant_client import QdrantClient
14
15qdrant_client = QdrantClient(host="localhost", port=6333)
16vector_store = QdrantVectorStore(
17    client=qdrant_client,
18    collection_name="llama_index"
19)
20
21# Pinecone
22from llama_index.vector_stores.pinecone import PineconeVectorStore
23from pinecone import Pinecone
24
25pc = Pinecone(api_key="...")
26pinecone_index = pc.Index("llama-index")
27vector_store = PineconeVectorStore(pinecone_index=pinecone_index)

Evaluation

1from llama_index.core.evaluation import (
2    FaithfulnessEvaluator,
3    RelevancyEvaluator,
4    CorrectnessEvaluator
5)
6
7# Evaluators
8faithfulness = FaithfulnessEvaluator()
9relevancy = RelevancyEvaluator()
10
11# Evaluate response
12query = "What is RAG?"
13response = query_engine.query(query)
14
15faithfulness_result = faithfulness.evaluate_response(response=response)
16print(f"Faithfulness: {faithfulness_result.passing}")
17
18relevancy_result = relevancy.evaluate_response(query=query, response=response)
19print(f"Relevancy: {relevancy_result.passing}")

LlamaIndex is a complete framework for RAG. In the next lesson you will learn about multi-agent systems - when one agent is not enough!

Go to CodeWorlds