Tutorial Lengkap LlamaIndex: Membangun Aplikasi RAG dengan LLM
LlamaIndex adalah framework data yang powerful untuk membangun aplikasi berbasis LLM. Library ini menyediakan tools untuk mengimpor, menytruktur, dan mengakses data privat atau domain-spesifik, menjadikannya sempurna untuk membangun sistem Retrieval-Augmented Generation (RAG).
Mengapa LlamaIndex?
Keunggulan LlamaIndex:- Mudah impor data: Koneksi ke 100+ sumber data
- Indexing fleksibel: Multiple tipe index untuk berbagai kebutuhan
- Query engines: Natural language querying atas data Anda
- Kemampuan agent: Bangun LLM agents otonom
- Production ready: Scalable dan observable
- Question answering atas dokumen
- Chatbot dengan knowledge base
- Ringkasan dokumen
- Semantic search
- Agent analisis data
Instalasi
pip install llama-index
Dengan OpenAI
pip install llama-index-llms-openai llama-index-embeddings-openai
Dengan model lokal
pip install llama-index-llms-ollama llama-index-embeddings-huggingface
Verify
python -c "import llamaindex; print(llamaindex.version)"
Quick Start
1. Basic RAG Pipeline
from llamaindex.core import VectorStoreIndex, SimpleDirectoryReader
from llama
index.llms.openai import OpenAI
import os
os.environ["OPENAIAPIKEY"] = "your-api-key"
Load dokumen
documents = SimpleDirectoryReader("./data").loaddata()
Buat index
index = VectorStoreIndex.fromdocuments(documents)
Query
queryengine = index.asqueryengine()
response = queryengine.query("Apa topik utama dari dokumen ini?")
print(response)
2. Dengan Custom LLM
from llamaindex.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama
index.llms.openai import OpenAI
from llamaindex.embeddings.openai import OpenAIEmbedding
Konfigurasi settings
Settings.llm = OpenAI(model="gpt-4", temperature=0.1)
Settings.embedmodel = OpenAIEmbedding(model="text-embedding-3-small")
Load dan index
documents = SimpleDirectoryReader("./data").loaddata()
index = VectorStoreIndex.fromdocuments(documents)
Query dengan streaming
queryengine = index.asqueryengine(streaming=True)
response = queryengine.query("Ringkas poin-poin utama")
for token in response.responsegen:
print(token, end="", flush=True)
3. Dengan Model Lokal (Ollama)
from llamaindex.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llamaindex.llms.ollama import Ollama
from llamaindex.embeddings.huggingface import HuggingFaceEmbedding
Gunakan model lokal
Settings.llm = Ollama(model="llama2", requesttimeout=300.0)
Settings.embedmodel = HuggingFaceEmbedding(modelname="BAAI/bge-small-en-v1.5")
Bangun RAG
documents = SimpleDirectoryReader("./data").loaddata()
index = VectorStoreIndex.fromdocuments(documents)
queryengine = index.asqueryengine()
response = queryengine.query("Apa yang dibahas dokumen ini?")
print(response)
Loading Data
1. File Readers
from llamaindex.core import SimpleDirectoryReader
Load dari direktori
documents = SimpleDirectoryReader(
inputdir="./data",
recursive=True,
requiredexts=[".pdf", ".txt", ".md"]
).loaddata()
Load file spesifik
documents = SimpleDirectoryReader(
inputfiles=["doc1.pdf", "doc2.txt"]
).loaddata()
Dengan metadata
documents = SimpleDirectoryReader(
"./data",
filemetadata=lambda filename: {"source": filename}
).loaddata()
2. Web Readers
from llamaindex.readers.web import SimpleWebPageReader, BeautifulSoupWebReader
Simple web reader
reader = SimpleWebPageReader()
documents = reader.loaddata(["https://example.com/page1", "https://example.com/page2"])
BeautifulSoup reader
reader = BeautifulSoupWebReader()
documents = reader.loaddata(
urls=["https://example.com"],
customhostname="example.com"
)
3. Database Readers
from llamaindex.readers.database import DatabaseReader
SQL database
reader = DatabaseReader(
sqldatabase=SQLDatabase.fromuri("postgresql://user:pass@localhost/db")
)
documents = reader.loaddata(query="SELECT FROM articles")
4. API Readers
from llamaindex.readers.notion import NotionPageReader
from llamaindex.readers.slack import SlackReader
Notion
notionreader = NotionPageReader(integrationtoken="secretxxx")
documents = notionreader.loaddata(pageids=["pageid1", "pageid2"])
Slack
slackreader = SlackReader(slacktoken="xoxb-xxx")
documents = slackreader.loaddata(channelids=["C01234567"])
Tipe Index
1. VectorStoreIndex
from llamaindex.core import VectorStoreIndex, StorageContext
from llama
index.vectorstores.chroma import ChromaVectorStore
import chromadb
In-memory
index = VectorStoreIndex.from
documents(documents)
Dengan ChromaDB persistence
chromaclient = chromadb.PersistentClient(path="./chromadb")
chromacollection = chromaclient.getorcreatecollection("mycollection")
vectorstore = ChromaVectorStore(chromacollection=chromacollection)
storagecontext = StorageContext.fromdefaults(vectorstore=vectorstore)
index = VectorStoreIndex.fromdocuments(
documents,
storagecontext=storagecontext
)
2. SummaryIndex
from llamaindex.core import SummaryIndex
Bagus untuk tugas summarization
index = SummaryIndex.from
documents(documents)
queryengine = index.asqueryengine(
responsemode="treesummarize"
)
response = queryengine.query("Berikan ringkasan komprehensif")
3. KeywordTableIndex
from llamaindex.core import KeywordTableIndex
Retrieval berbasis keyword
index = KeywordTableIndex.from
documents(documents)
queryengine = index.asqueryengine()
response = queryengine.query("Temukan dokumen tentang machine learning")
4. KnowledgeGraphIndex
from llamaindex.core import KnowledgeGraphIndex
Bangun knowledge graph
index = KnowledgeGraphIndex.from
documents(
documents,
maxtripletsperchunk=10,
includeembeddings=True
)
queryengine = index.asqueryengine(
includetext=True,
responsemode="treesummarize"
)
Query Engines
1. Basic Query Engine
from llamaindex.core import VectorStoreIndex
index = VectorStoreIndex.from
documents(documents)
Default query engine
queryengine = index.asqueryengine()
Dengan parameter
queryengine = index.asqueryengine(
similaritytopk=5,
responsemode="compact",
streaming=True
)
response = queryengine.query("Apa temuan utamanya?")
2. Response Modes
# Refine: iteratively refine jawaban
queryengine = index.asqueryengine(responsemode="refine")
Compact: padatkan context sebelum menjawab
queryengine = index.asqueryengine(responsemode="compact")
Tree summarize: bangun tree dan ringkas
queryengine = index.asqueryengine(responsemode="treesummarize")
Simple summarize: truncate dan ringkas
queryengine = index.asqueryengine(responsemode="simplesummarize")
No text: kembalikan retrieved nodes saja
queryengine = index.asqueryengine(responsemode="notext")
3. Custom Query Engine
from llamaindex.core.queryengine import RetrieverQueryEngine
from llama
index.core.retrievers import VectorIndexRetriever
from llamaindex.core.responsesynthesizers import getresponsesynthesizer
Custom retriever
retriever = VectorIndexRetriever(
index=index,
similaritytopk=10
)
Custom response synthesizer
responsesynthesizer = getresponsesynthesizer(
responsemode="treesummarize"
)
Custom query engine
queryengine = RetrieverQueryEngine(
retriever=retriever,
responsesynthesizer=responsesynthesizer
)
Chat Engines
1. Basic Chat Engine
from llamaindex.core import VectorStoreIndex
index = VectorStoreIndex.from
documents(documents)
Buat chat engine
chatengine = index.aschatengine(
chatmode="condensequestion",
verbose=True
)
Chat
response = chatengine.chat("Dokumen ini tentang apa?")
print(response)
response = chatengine.chat("Bisa jelaskan lebih detail?")
print(response)
Reset percakapan
chatengine.reset()
2. Chat Modes
# Condense question: reformulasi pertanyaan dengan context
chatengine = index.aschatengine(chatmode="condensequestion")
Context: selalu gunakan context dari index
chatengine = index.aschatengine(chatmode="context")
React: gunakan ReAct agent
chatengine = index.aschatengine(chatmode="react")
OpenAI: gunakan OpenAI function calling
chatengine = index.aschatengine(chatmode="openai")
3. Streaming Chat
chatengine = index.aschatengine(streaming=True)
response = chatengine.streamchat("Ceritakan tentang topik utamanya")
for token in response.responsegen:
print(token, end="", flush=True)
Agents
1. ReAct Agent
from llamaindex.core.agent import ReActAgent
from llamaindex.core.tools import QueryEngineTool, ToolMetadata
Buat tools
queryenginetool = QueryEngineTool(
queryengine=index.asqueryengine(),
metadata=ToolMetadata(
name="documentsearch",
description="Cari informasi dalam dokumen"
)
)
Buat agent
agent = ReActAgent.fromtools(
[queryenginetool],
llm=llm,
verbose=True
)
response = agent.chat("Temukan informasi tentang machine learning")
2. OpenAI Agent
from llamaindex.agent.openai import OpenAIAgent
from llama
index.core.tools import FunctionTool
Definisikan fungsi custom
def multiply(a: int, b: int) -> int:
"""Kalikan dua angka."""
return a b
def add(a: int, b: int) -> int:
"""Tambahkan dua angka."""
return a + b
Buat tools
multiplytool = FunctionTool.fromdefaults(fn=multiply)
addtool = FunctionTool.fromdefaults(fn=add)
Buat agent
agent = OpenAIAgent.fromtools(
[multiplytool, addtool, queryenginetool],
verbose=True
)
response = agent.chat("Berapa 5 * 3 + 2?")
3. Multi-Document Agent
from llamaindex.core import VectorStoreIndex, SummaryIndex
from llamaindex.core.tools import QueryEngineTool
Buat indices untuk setiap dokumen
docagents = {}
for doc in documents:
vectorindex = VectorStoreIndex.fromdocuments([doc])
summaryindex = SummaryIndex.fromdocuments([doc])
vectortool = QueryEngineTool(
queryengine=vectorindex.asqueryengine(),
metadata=ToolMetadata(
name=f"vector{doc.docid}",
description=f"Cari {doc.docid}"
)
)
summarytool = QueryEngineTool(
queryengine=summaryindex.asqueryengine(),
metadata=ToolMetadata(
name=f"summary{doc.docid}",
description=f"Ringkas {doc.docid}"
)
)
docagents[doc.docid] = [vectortool, summarytool]
Buat top-level agent
alltools = [tool for tools in docagents.values() for tool in tools]
agent = ReActAgent.fromtools(alltools, verbose=True)
Fitur Lanjutan
1. Node Postprocessors
from llamaindex.core.postprocessor import (
SimilarityPostprocessor,
KeywordNodePostprocessor,
MetadataReplacementPostProcessor
)
Filter berdasarkan similarity
similarity
processor = SimilarityPostprocessor(similaritycutoff=0.7)
Filter berdasarkan keywords
keyword
processor = KeywordNodePostprocessor(
requiredkeywords=["machine learning"],
excludekeywords=["deprecated"]
)
Terapkan ke query engine
queryengine = index.asqueryengine(
nodepostprocessors=[similarityprocessor, keywordprocessor]
)
2. Hybrid Search
from llamaindex.core.retrievers import (
VectorIndexRetriever,
KeywordTableSimpleRetriever
)
from llama
index.core.queryengine import RetrieverQueryEngine
Vector retriever
vector
retriever = VectorIndexRetriever(index=vectorindex, similaritytopk=5)
Keyword retriever
keyword
retriever = KeywordTableSimpleRetriever(index=keywordindex)
Kombinasikan dengan logic custom
class HybridRetriever:
def init(self, vector
retriever, keywordretriever):
self.vector
retriever = vectorretriever
self.keyword
retriever = keywordretriever
def retrieve(self, query):
vector
nodes = self.vectorretriever.retrieve(query)
keyword
nodes = self.keywordretriever.retrieve(query)
# Kombinasikan dan deduplikasi
all
nodes = {n.node.nodeid: n for n in vectornodes + keywordnodes}
return list(all
nodes.values())
hybridretriever = HybridRetriever(vectorretriever, keywordretriever)
3. Query Transformations
from llamaindex.core.queryengine import TransformQueryEngine
from llama
index.core.indices.query.querytransform import HyDEQueryTransform
HyDE (Hypothetical Document Embeddings)
hyde = HyDEQueryTransform(include
original=True)
queryengine = TransformQueryEngine(
queryengine=index.asqueryengine(),
querytransform=hyde
)
response = queryengine.query("Apa manfaatnya?")
Evaluasi
1. Response Evaluation
from llamaindex.core.evaluation import (
FaithfulnessEvaluator,
RelevancyEvaluator,
CorrectnessEvaluator
)
Buat evaluators
faithfulness
evaluator = FaithfulnessEvaluator()
relevancyevaluator = RelevancyEvaluator()
Evaluasi response
query = "Apa itu machine learning?"
response = queryengine.query(query)
faithfulnessresult = faithfulnessevaluator.evaluateresponse(response=response)
relevancyresult = relevancyevaluator.evaluateresponse(
query=query,
response=response
)
print(f"Faithfulness: {faithfulnessresult.passing}")
print(f"Relevancy: {relevancyresult.passing}")
2. Retrieval Evaluation
from llamaindex.core.evaluation import RetrieverEvaluator
Buat dataset
eval
questions = [
"Apa topik utamanya?",
"Siapa penulisnya?",
"Metodologi apa yang digunakan?"
]
Evaluasi retriever
retriever = index.asretriever(similaritytopk=5)
evaluator = RetrieverEvaluator.frommetricnames(
["mrr", "hitrate"],
retriever=retriever
)
Jalankan evaluasi
results = await evaluator.aevaluatedataset(evalquestions)
Persistence
1. Simpan dan Load Index
from llamaindex.core import VectorStoreIndex, StorageContext, loadindexfromstorage
Simpan index
index.storagecontext.persist(persistdir="./storage")
Load index
storagecontext = StorageContext.fromdefaults(persistdir="./storage")
index = loadindexfromstorage(storagecontext)
2. Dengan Vector Store
from llamaindex.vectorstores.qdrant import QdrantVectorStore
from qdrant
client import QdrantClient
Buat Qdrant client
client = QdrantClient(path="./qdrantdata")
Buat vector store
vectorstore = QdrantVectorStore(
client=client,
collectionname="mycollection"
)
Bangun index dengan vector store
storagecontext = StorageContext.fromdefaults(vectorstore=vectorstore)
index = VectorStoreIndex.fromdocuments(
documents,
storagecontext=storagecontext
)
Load index yang sudah ada
index = VectorStoreIndex.fromvectorstore(vectorstore)
Best Practices
1. Chunking Strategy
from llamaindex.core.nodeparser import (
SentenceSplitter,
SemanticSplitterNodeParser
)
Sentence splitter
splitter = SentenceSplitter(
chunksize=1024,
chunkoverlap=200
)
Semantic splitter
semanticsplitter = SemanticSplitterNodeParser(
buffersize=1,
breakpointpercentilethreshold=95,
embedmodel=embedmodel
)
nodes = splitter.getnodesfromdocuments(documents)
2. Metadata Filtering
from llamaindex.core.vectorstores import MetadataFilters, MetadataFilter
Tambahkan metadata ke dokumen
for doc in documents:
doc.metadata["category"] = "technical"
doc.metadata["year"] = 2024
Filter berdasarkan metadata
filters = MetadataFilters(
filters=[
MetadataFilter(key="category", value="technical"),
MetadataFilter(key="year", value=2024)
]
)
query
engine = index.asqueryengine(filters=filters)
Kesimpulan
LlamaIndex adalah essential untuk membangun aplikasi RAG dengan:
Key takeaways:
- Mulai dengan VectorStoreIndex untuk kebanyakan use case
- Gunakan chat engines untuk aplikasi conversational
- Manfaatkan agents untuk tugas multi-step kompleks
- Evaluasi dan iterasi kualitas retrieval
- Persist indices untuk deployment production