# LangChain met de Gemini API [[TOC]] ## LangChain en Gemini LangChain is een framework voor het bouwen van applicaties met taalmodellen. Het biedt abstracties voor chains (sequentiele prompting), memory (gespreksgeschiedenis), agents (autonome tools) en RAG (retrieval-augmented generation). Gemini werkt als LLM-backend via de officiele integratie in het pakket `langchain-google-genai`. Sinds `langchain-google-genai` 4.0 draait die integratie op de geconsolideerde `google-genai` SDK en kan dezelfde klasse `ChatGoogleGenerativeAI` zowel de Gemini Developer API (met een API-sleutel) als Vertex AI (met een Google Cloud-project) aanspreken. :::warn title="Gebruik een actueel model" `gemini-2.0-flash` is sinds 1 juni 2026 uitgefaseerd en niet meer beschikbaar. Kies voor nieuwe projecten een actueel stabiel model zoals `gemini-2.5-flash` (sterke prijs-prestatie) of `gemini-3.5-flash` (hogere intelligentie voor agent- en codetaken). Controleer de modellenpagina van de Gemini API voor de meest recente lijst. ::: ## Installatie ```bash pip install langchain langchain-google-genai ``` Voor Vertex AI gebruik je het aparte pakket: ```bash pip install langchain langchain-google-vertexai ``` ## Basisgebruik ```python from langchain_google_genai import ChatGoogleGenerativeAI from langchain_core.messages import HumanMessage, SystemMessage import os llm = ChatGoogleGenerativeAI( model="gemini-2.5-flash", google_api_key=os.environ["GEMINI_API_KEY"], temperature=0.7, max_output_tokens=1024, ) messages = [ SystemMessage(content="Je bent een expert in Python-programmeren."), HumanMessage(content="Leg list comprehensions uit met drie voorbeelden."), ] response = llm.invoke(messages) print(response.content) ``` ## Prompt templates ```python from langchain_core.prompts import ChatPromptTemplate template = ChatPromptTemplate.from_messages([ ("system", "Je bent een {rol} specialist. Beantwoord vragen in het {taal}."), ("human", "{vraag}"), ]) chain = template | llm response = chain.invoke({ "rol": "cybersecurity", "taal": "Nederlands", "vraag": "Wat zijn de meest voorkomende SQL injection aanvallen?", }) print(response.content) ``` ## Chains koppelen met LCEL Met LangChain Expression Language (LCEL) koppel je losse stappen tot een pipeline via de `|`-operator. Hieronder vat de eerste chain een tekst samen, waarna de tweede chain die samenvatting naar het Engels vertaalt. ```python from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser samenvatting_chain = ( ChatPromptTemplate.from_template("Vat de volgende tekst samen in 3 punten: {tekst}") | llm | StrOutputParser() ) vertaling_chain = ( ChatPromptTemplate.from_template("Vertaal naar het Engels: {tekst}") | llm | StrOutputParser() ) pipeline = samenvatting_chain | (lambda s: {"tekst": s}) | vertaling_chain result = pipeline.invoke({"tekst": lange_nederlandstalige_tekst}) print(result) ``` :::tip title="Houd pipelines leesbaar" LCEL maakt samengestelde chains overzichtelijk en makkelijk te debuggen. Zet tussenstappen zoals het lambda-mapje (`lambda s: {"tekst": s}`) op een eigen regel, zodat je per stap kunt zien wat erin en eruit gaat. ::: ## RAG-systeem met LangChain en Gemini Een RAG-pipeline laadt documenten, splitst ze in stukken, zet die om naar embeddings en haalt bij elke vraag de relevante stukken op als context voor het model. ```python from langchain_google_genai import GoogleGenerativeAIEmbeddings from langchain_community.vectorstores import Chroma from langchain_community.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.chains import RetrievalQA import os loader = TextLoader("kennisbank.txt") docs = loader.load() text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100) chunks = text_splitter.split_documents(docs) embeddings = GoogleGenerativeAIEmbeddings( model="models/gemini-embedding-001", google_api_key=os.environ["GEMINI_API_KEY"], ) vectorstore = Chroma.from_documents(chunks, embeddings) retriever = vectorstore.as_retriever(search_kwargs={"k": 3}) qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=retriever, return_source_documents=True, ) result = qa_chain.invoke({"query": "Wat is het retourbeleid?"}) print(result["result"]) print("Bronnen:") for doc in result["source_documents"]: print(f"- {doc.metadata.get('source', 'onbekend')}") ``` ## Agents met tool-calling Een agent laat Gemini zelf beslissen welke tools het aanroept om een vraag te beantwoorden. Hieronder krijgt een verkoopassistent een rekenmachine en een productzoeker. ```python from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain.tools import tool from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder @tool def rekenmachine(berekening: str) -> str: """Voer een wiskundige berekening uit. Invoer: wiskundige expressie als string.""" try: return str(eval(berekening)) except Exception as e: return f"Fout: {e}" @tool def zoek_product(product_naam: str) -> str: """Zoek productinformatie op. Invoer: productnaam.""" producten = {"laptop": "999 euro, 16GB RAM, 512GB SSD", "tablet": "499 euro, 64GB"} return producten.get(product_naam.lower(), "Product niet gevonden") tools = [rekenmachine, zoek_product] prompt = ChatPromptTemplate.from_messages([ ("system", "Je bent een verkoopassistent. Gebruik de beschikbare tools."), ("human", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad"), ]) agent = create_tool_calling_agent(llm, tools, prompt) agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) result = agent_executor.invoke({ "input": "Wat kost een laptop en een tablet samen?", }) print(result["output"]) ``` :::warn title="Voer geen model-invoer uit met eval()" De `rekenmachine`-tool hierboven gebruikt `eval()` puur als voorbeeld. In productie is `eval()` op door het model gegenereerde of door gebruikers beinvloede invoer een ernstig veiligheidsrisico, omdat er willekeurige Python mee kan worden uitgevoerd. Gebruik in plaats daarvan een veilige expressie-parser of een sandbox. ::: :::faq ### Moet ik LangChain gebruiken of de Gemini SDK rechtstreeks? Voor eenvoudige generatie volstaat de directe `google-genai` SDK; die heeft minder overhead. LangChain loont zodra je chains, retrieval, geheugen of agents combineert en die bouwblokken wilt hergebruiken. De kwaliteit van het modelantwoord is in beide gevallen gelijk, want LangChain roept dezelfde Gemini API aan. ### Welke versies van LangChain en de integratie heb ik nodig? Gebruik een recente `langchain` samen met `langchain-google-genai` 4.x, de versie die op de geconsolideerde `google-genai` SDK draait. Daarmee spreekt `ChatGoogleGenerativeAI` zowel de Developer API als Vertex AI aan. Controleer de PyPI-pagina van het pakket voor het exacte laatste versienummer. ### Welk Gemini-model kies ik in 2026? Voor nieuwe projecten is `gemini-2.5-flash` een goede standaard vanwege de sterke prijs-prestatie. Heb je meer redeneerkracht nodig voor agent- of codetaken, kies dan `gemini-3.5-flash`. Vermijd `gemini-2.0-flash`, dat sinds 1 juni 2026 is uitgefaseerd. ### Welk embedding-model gebruik ik voor RAG? Gebruik `gemini-embedding-001` via `GoogleGenerativeAIEmbeddings`. Dit is het actuele tekst-embedding-model van de Gemini API. Voor multimodale embeddings (tekst, beeld, audio en video in dezelfde vectorruimte) kijk je naar de nieuwere Gemini Embedding 2-modellen. ### Kan ik geheugen aan een Gemini-chat toevoegen? Ja, de geheugenklassen van LangChain werken met Gemini. De oudere klassen zoals `ConversationBufferMemory` zijn in nieuwere LangChain-versies wel afgeraden ten gunste van LangGraph, dat gespreksstatus expliciet beheert. Voor nieuwe code met meer gesprekslogica is LangGraph de aanbevolen route. ### Ondersteunt LangChain streaming met Gemini? Ja. Gebruik `llm.stream(messages)` om de tokens stuk voor stuk te ontvangen, net zoals streaming in de directe SDK werkt. Dat is handig voor chatinterfaces waar je het antwoord al wilt tonen terwijl het wordt gegenereerd. :::