Naar inhoud
lightbulb Welkom op de nieuwe kennisbank | We hebben de docs volledig vernieuwd met meer dan 160 features. Bekijk wat nieuw isarrow_forward

LlamaIndex met de Gemini API

Bouw RAG-pipelines en kennisbank-chatbots met LlamaIndex en Gemini als LLM en embedding-model via de google-genai-integratie.

LlamaIndex en Gemini

LlamaIndex is een framework dat specifiek is gebouwd voor RAG (Retrieval-Augmented Generation) en data-gebaseerde AI-applicaties. Waar LangChain algemener is, focust LlamaIndex op het efficient doorzoekbaar maken van grote hoeveelheden documenten voor gebruik als context in LLM-prompts.

Je combineert Gemini hierin op twee plekken: als LLM dat de antwoorden genereert, en als embedding-model dat je documenten omzet naar vectoren voor retrieval.

warning

Pakketnamen zijn gewijzigd

De oude pakketten llama-index-llms-gemini en llama-index-embeddings-gemini worden niet meer onderhouden. Gebruik de nieuwe llama-index-llms-google-genai en llama-index-embeddings-google-genai, met de klassen GoogleGenAI en GoogleGenAIEmbedding. Oudere tutorials die nog from llama_index.llms.gemini import Gemini tonen, zijn verouderd.

Installatie

pip install llama-index llama-index-llms-google-genai llama-index-embeddings-google-genai

Basisinstellingen

import os
from llama_index.llms.google_genai import GoogleGenAI
from llama_index.embeddings.google_genai import GoogleGenAIEmbedding
from llama_index.core import Settings

Settings.llm = GoogleGenAI(
    model="gemini-2.5-flash",
    api_key=os.environ["GEMINI_API_KEY"],
    temperature=0.1
)

Settings.embed_model = GoogleGenAIEmbedding(
    model_name="gemini-embedding-001",
    api_key=os.environ["GEMINI_API_KEY"],
    embed_batch_size=100
)
info

Welke modellen kies je in 2026?

gemini-2.5-flash is een stabiel, snel en betaalbaar model voor RAG-antwoorden. Voor zwaardere redeneertaken kun je een Pro-variant inzetten. Voor embeddings is gemini-embedding-001 het GA-tekstmodel. Wil je ook afbeeldingen, audio of video in dezelfde vectorruimte doorzoekbaar maken, kijk dan naar het multimodale Gemini Embedding 2. Let op: gemini-2.0-flash en text-embedding-004 zijn uitgefaseerd en niet meer geschikt voor nieuwe projecten.

Documenten indexeren

from llama_index.core import SimpleDirectoryReader, VectorStoreIndex

documenten = SimpleDirectoryReader("./documenten/").load_data()

index = VectorStoreIndex.from_documents(
    documenten,
    show_progress=True
)

index.storage_context.persist(persist_dir="./opgeslagen_index")

SimpleDirectoryReader leest een hele map met documenten in en herkent automatisch veelvoorkomende bestandstypen. Met persist schrijf je de index naar schijf, zodat je niet bij elke run opnieuw hoeft te embedden.

Query engine gebruiken

from llama_index.core import StorageContext, load_index_from_storage

storage_context = StorageContext.from_defaults(persist_dir="./opgeslagen_index")
index = load_index_from_storage(storage_context)

query_engine = index.as_query_engine(
    similarity_top_k=3,
    response_mode="tree_summarize"
)

response = query_engine.query("Wat zijn de openingstijden van de klantenservice?")
print(response)

print("Bronnen:")
for node in response.source_nodes:
    print(f"Score: {node.score:.4f} | {node.metadata.get('file_name', 'onbekend')}")

De source_nodes op het antwoord laten zien welke chunks zijn gebruikt en met welke score. Dat is essentieel om te controleren of het model zijn antwoord echt op je documenten baseert en niet hallucineert.

lightbulb

Kies de juiste similarity_top_k

Gebruik similarity_top_k=3 tot 5 voor de meeste use cases. Te weinig chunks mist context, te veel voegt ruis toe en verhoogt je tokenkosten. Experimenteer met waarden tussen 3 en 8 voor jouw specifieke corpus en meet de antwoordkwaliteit.

Chat engine voor conversationele RAG

chat_engine = index.as_chat_engine(
    chat_mode="condense_plus_context",
    similarity_top_k=3,
    system_prompt="Je bent een expert over onze producten. Gebruik alleen informatie uit de documenten."
)

response1 = chat_engine.chat("Wat is de garantie op laptops?")
print(response1)

response2 = chat_engine.chat("En geldt dat ook voor tablets?")
print(response2)

De modus condense_plus_context herschrijft de vervolgvraag eerst tot een zelfstandige vraag (zodat "geldt dat ook voor tablets" begrijpelijk wordt) en haalt daarna pas relevante context op. Zo blijft een gesprek met meerdere beurten coherent.

Documenten per type laden

from llama_index.core import Document
from llama_index.readers.file import PDFReader
from llama_index.readers.web import SimpleWebPageReader

pdf_reader = PDFReader()
pdf_docs = pdf_reader.load_data("handleiding.pdf")

web_reader = SimpleWebPageReader()
web_docs = web_reader.load_data(["https://docs.example.com/api"])

custom_doc = Document(
    text="Onze retourpolicy: 30 dagen retourneren zonder opgaaf van reden.",
    metadata={"bron": "retourbeleid", "datum": "2024-01"}
)

alle_docs = pdf_docs + web_docs + [custom_doc]
index = VectorStoreIndex.from_documents(alle_docs)

Metadata filtering

Met metadata-filters beperk je het zoeken tot een specifieke deelverzameling, bijvoorbeeld alleen documenten in een bepaalde categorie. Dat maakt antwoorden preciezer en sneller.

from llama_index.core.vector_stores import MetadataFilters, ExactMatchFilter

query_engine = index.as_query_engine(
    filters=MetadataFilters(
        filters=[
            ExactMatchFilter(key="categorie", value="garantie")
        ]
    ),
    similarity_top_k=5
)

response = query_engine.query("Hoe lang is de garantietermijn?")

Geavanceerde retrieval: HyDE

Hypothetical Document Embeddings (HyDE) verbetert retrieval door eerst een hypothetisch antwoord te genereren en dat te embedden. De embedding van een volzin lijkt vaak meer op je documenten dan de embedding van een korte vraag, waardoor je relevantere chunks terugvindt.

from llama_index.core.indices.query.query_transform import HyDEQueryTransform
from llama_index.core.query_engine import TransformQueryEngine

hyde_transform = HyDEQueryTransform(include_original=True)
hyde_engine = TransformQueryEngine(query_engine, hyde_transform)

response = hyde_engine.query("Welke producten hebben 2 jaar garantie?")

Index opslaan in een vectordatabase

Voor productie wil je je vectoren niet op schijf in losse bestanden, maar in een echte vectordatabase. Hieronder een voorbeeld met Chroma.

import chromadb
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.core import StorageContext

chroma_client = chromadb.PersistentClient(path="./chroma_db")
collection = chroma_client.get_or_create_collection("kennisbank")

vector_store = ChromaVectorStore(chroma_collection=collection)
storage_context = StorageContext.from_defaults(vector_store=vector_store)

index = VectorStoreIndex.from_documents(
    documenten,
    storage_context=storage_context
)

Praktisch voorbeeld: kennisbank-chatbot

Een complete minimale flow voor een interne kennisbank ziet er zo uit:

Van documenten naar werkende RAG-chatbot

  1. Installeer de pakketten en zet GEMINI_API_KEY in je omgeving.
  2. Configureer Settings.llm (GoogleGenAI) en Settings.embed_model (GoogleGenAIEmbedding).
  3. Lees je documenten in met SimpleDirectoryReader en bouw een VectorStoreIndex.
  4. Sla de index op in Chroma zodat je niet opnieuw hoeft te embedden bij een herstart.
  5. Maak een chat-engine met chat_mode="condense_plus_context" en een duidelijke system_prompt.
  6. Controleer bij elk antwoord de source_nodes om hallucinaties te herkennen.
Wat is het verschil tussen LlamaIndex en LangChain voor RAG?

LlamaIndex is ontworpen specifiek voor RAG, met betere data-connectors, meer retrieval-strategieen en eenvoudigere indexering. LangChain is algemener en sterker voor complexe multi-step agents. Kies LlamaIndex als RAG je hoofddoel is, en LangChain als je veel verschillende tools en agent-logica wilt combineren.

Welk Gemini-model gebruik ik in 2026?

Gebruik gemini-2.5-flash als snel en betaalbaar standaardmodel voor de generatie, en een Pro-variant voor zwaardere redeneertaken. Voor tekst-embeddings is gemini-embedding-001 het stabiele GA-model. Het oudere gemini-2.0-flash en text-embedding-004 zijn uitgefaseerd.

Hoe groot mogen mijn chunks zijn?

Standaard gebruikt LlamaIndex chunks van ongeveer 1024 tokens met een kleine overlap. Voor technische documentatie werkt 512 tot 1024 tokens goed. Voor verhalen en narratieve content zijn grotere chunks (richting 2048) vaak beter omdat de context dan minder versnipperd raakt.

Kan ik LlamaIndex gebruiken met Vertex AI Gemini?

Ja. De google-genai-integratie ondersteunt Vertex AI via een vertexai_config op zowel de LLM- als de embedding-klasse. Je authenticeert dan met Application Default Credentials in plaats van met een losse API-sleutel.

Hoe ververs ik de index als documenten veranderen?

Gebruik index.refresh_ref_docs(bijgewerkte_docs) om gewijzigde documenten te herindexeren zonder alles opnieuw te verwerken. LlamaIndex vergelijkt hash-waarden en embedt alleen de documenten die echt zijn veranderd, wat veel API-kosten bespaart.

Hoe controleer ik of het model niet hallucineert?

Inspecteer altijd response.source_nodes. Daar staan de chunks en hun scores die het antwoord onderbouwen. Lage scores of irrelevante bronnen zijn een signaal dat je retrieval (chunk-grootte, similarity_top_k of je embedding-model) moet bijstellen, of dat het antwoord niet in je corpus staat.