Conversational AI met de Gemini API
De Gemini API is stateless: elke API-call staat op zichzelf en het model onthoudt niets tussen calls. Om een chatervaring te bouwen waarbij het model vorige berichten meeneemt, stuur je bij elke call de volledige gespreksgeschiedenis mee. De Google GenAI SDK neemt dit beheer grotendeels over, maar het helpt te begrijpen hoe de datastructuur werkt zodat je context-limieten, kosten en randgevallen goed afhandelt.
Een chatsessie verschilt op drie punten van een enkelvoudige prompt: er zijn meerdere beurten (turns), de rollen wisselen strikt af, en de tokenkosten lopen op naarmate de sessie groeit.
Welke SDK gebruik je?
De oude pakketten google.generativeai (Python) en @google/generative-ai (JavaScript) zijn niet meer in onderhoud; de support eindigde op 30 november 2025. Gebruik de nieuwe, unified Google GenAI SDK: google-genai in Python en @google/genai in JavaScript. Alle voorbeelden hieronder gebruiken die nieuwe SDK.
De contents-structuur begrijpen
De API verwacht een contents-array waarbij elke entry een role heeft (user of model) en een parts-array. De rollen moeten strikt afwisselen en de geschiedenis begint met een user-beurt:
{
"contents": [
{"role": "user", "parts": [{"text": "Hallo, wie ben jij?"}]},
{"role": "model", "parts": [{"text": "Ik ben Gemini, een AI van Google."}]},
{"role": "user", "parts": [{"text": "Wat kun jij voor mij doen?"}]}
]
}
Het model genereert een antwoord op de laatste user-beurt. Na ontvangst voeg je dat model-antwoord toe aan de history voordat je de volgende call doet. De chats-helper van de SDK doet dit toevoegen automatisch voor je.
Snel een chatsessie opzetten
Zo zet je een chatsessie op
- Installeer de SDK:
pip install google-genai(Python) ofnpm install @google/genai(JavaScript). - Zet je sleutel in de omgevingsvariabele
GEMINI_API_KEY, zodat je hem niet hardcodeert. - Maak een client aan en open een chat met
client.chats.create(...)ofai.chats.create(...). - Stuur berichten met
send_message/sendMessage; de SDK houdt de history per sessie bij. - Wil je gesprekken laten hervatten, sla dan de history op en geef die mee bij een volgende
create.
ChatSession in Python
Met de nieuwe SDK maak je eerst een client en daarna een chat-object dat de history beheert:
import os
from google import genai
from google.genai import types
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
chat = client.chats.create(
model="gemini-3.5-flash",
config=types.GenerateContentConfig(
system_instruction="Je bent een behulpzame assistent die beknopt antwoord geeft."
),
)
while True:
user_input = input("Jij: ")
if user_input.lower() in ("stop", "exit"):
break
response = chat.send_message(user_input)
print(f"Gemini: {response.text}")
chat.get_history() geeft na elke beurt de volledige conversatie als lijst van Content-objecten terug. Je kunt die opslaan in een database en later terugzetten via de history-parameter van client.chats.create().
Chatsessie in JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const chat = ai.chats.create({
model: "gemini-3.5-flash",
config: {
systemInstruction: "Antwoord altijd in het Nederlands.",
},
history: [],
});
async function sendMessage(message) {
const result = await chat.sendMessage({ message });
return result.text;
}
const reply1 = await sendMessage("Wat is de hoofdstad van Nederland?");
console.log(reply1);
const reply2 = await sendMessage("En welke rivier stroomt er doorheen?");
console.log(reply2);
Het chat-object bewaart de history intern en voegt elke beurt automatisch toe. Met chat.getHistory() haal je de volledige geschiedenis op.
Sessiegeschiedenis opslaan en herstellen
Voor productietoepassingen sla je de history buiten de SDK op, bijvoorbeeld in een database per gebruiker of per sessie:
import json
def save_history(chat, filepath: str) -> None:
history_data = [
{
"role": turn.role,
"parts": [{"text": part.text} for part in turn.parts],
}
for turn in chat.get_history()
]
with open(filepath, "w", encoding="utf-8") as f:
json.dump(history_data, f, ensure_ascii=False, indent=2)
def load_chat(client, filepath: str):
with open(filepath, "r", encoding="utf-8") as f:
history_data = json.load(f)
return client.chats.create(model="gemini-3.5-flash", history=history_data)
Zo kunnen gebruikers hun gesprekken later hervatten precies waar ze gebleven waren.
Sla alleen tekstturns op als JSON
Bewaar in je database bij voorkeur de tekstdelen van de history. Afbeeldingen en andere binaire parts maken de opgeslagen geschiedenis snel groot en duur. Heb je de afbeeldingen later weer nodig, sla dan een verwijzing (bestandspad of file-id) op in plaats van de ruwe inline data.
Let op de tokenomvang
Houd de totale tokenomvang van de history in de gaten. Een lange chatsessie kan de context-limiet van het model bereiken. De huidige Gemini-3-modellen ondersteunen ongeveer 1 miljoen tokens invoer, maar elke beurt telt mee in de kosten. Gebruik een sliding window of een samenvatting zodra de history te groot wordt.
Context-window beheer
Strategieën om de context binnen de limieten en de kosten beheersbaar te houden:
- Sliding window: bewaar alleen de laatste N beurten. Bouw bij het aanmaken van een nieuwe chat een afgekapte
history-lijst op en geef die mee aanclient.chats.create(...). Laat de eerste entry altijd eenuser-beurt zijn, zodat de rollen blijven afwisselen. - Samenvatting: laat het model de oudere beurten samenvatten en gebruik die samenvatting als
system_instructionbij een nieuwe, kortere sessie. - Context caching: voor vaste systeemcontext zoals handleidingen of kennisbanken gebruik je de Context Caching API, zodat je die tokens niet bij elke call opnieuw betaalt.
Multimodale berichten in chat
Je kunt ook afbeeldingen meesturen in een chatsessie. Met de nieuwe SDK geef je een lijst van delen mee aan send_message:
from google.genai import types
with open("schermafbeelding.png", "rb") as f:
image_bytes = f.read()
image_part = types.Part.from_bytes(data=image_bytes, mime_type="image/png")
response = chat.send_message(["Wat zie je op deze afbeelding?", image_part])
print(response.text)
Gemini behandelt de afbeelding als een extra part in de beurt. In de history wordt die afbeelding als inline data bewaard, wat de omvang van de opgeslagen geschiedenis vergroot. Voor grotere of vaker gebruikte bestanden upload je ze beter eerst met client.files.upload(...) en stuur je de teruggegeven file-referentie mee.
Moet ik de volledige history meesturen bij elke call?
Ja. De API is stateless, dus elke call moet de volledige gespreksgeschiedenis bevatten. Gebruik je het chats-object van de SDK, dan gebeurt dit automatisch en hoef je de history niet handmatig mee te sturen.
Welk model gebruik ik het beste voor een chatsessie?
Voor de meeste chattoepassingen is gemini-3.5-flash een goede standaard: snel en voordelig. Heb je zwaarder redeneerwerk nodig, kies dan gemini-3.5-pro. Controleer de actuele modelnamen altijd in de officiele Gemini API-documentatie, want die wisselen regelmatig.
Hoe lang kan een chatsessie duren?
Totdat de context-limiet van het model bereikt is. De huidige Gemini-3-modellen ondersteunen rond de 1 miljoen tokens invoer. Bij langere sessies implementeer je een samenvatting of een sliding window om binnen de limiet en de kosten te blijven.
Kan ik de history achteraf bewerken?
Ja. Je kunt de opgeslagen history aanpassen voordat je er een nieuwe chat mee opent via client.chats.create(history=...). Verwijder, wijzig of voeg beurten toe, maar houd de afwisseling van rollen intact en begin met een user-beurt, anders ontstaan er inconsistente contexten.
Hoe voorkom ik dat het model zichzelf tegenspreekt?
Geef een duidelijke system_instruction mee die consistentie afdwingt en houd de relevante history zo volledig mogelijk. Bij complexe use cases combineer je de chatsessie met retrieval-augmented generation (RAG), zodat antwoorden op vaste bronnen gebaseerd blijven.
Welke SDK moet ik installeren?
Gebruik de unified Google GenAI SDK: pip install google-genai in Python en npm install @google/genai in JavaScript. De oude pakketten google.generativeai en @google/generative-ai worden niet meer onderhouden sinds eind 2025.