Claude Code & codeeragenten

Starten met Claude Code in november 2026: de complete gids voor Python, IDE en database

Twintig klanten boeken tegelijk dezelfde stoel, en alle twintig komen erin. Zo begin je met Claude Code en Python: installatie, abonnement, IDE-keuze, SQLite of PostgreSQL, CLAUDE.md en rechten, met gemeten resultaten en een echte sessie.

Erik van de Blaak
Erik van de Blaak
24 min leestijd • 139 weergaven
Starten met Claude Code in november 2026: de complete gids voor Python, IDE en database

Twintig mensen proberen op hetzelfde moment stoel 1 te boeken bij een kapsalon, zaterdag 10:00. Hoeveel afspraken komen er in de database? Ik heb het getest met de code die je krijgt als je "kijk eerst of het vrij is, sla het dan op" letterlijk opschrijft. Het antwoord was twintig. In vijf van de vijf pogingen.

Code die "eerst kijkt, dan opslaat" ziet er voor een taalmodel net zo verstandig uit als voor jou, en elke test met één gebruiker slaagt. Claude Code schrijft je zo'n functie in een halve minuut, met keurige tests erbij. Of die tests het juiste controleren, bepaal jij. Daarover gaat deze gids. Claude Code schrijft in november 2026 aantoonbaar goede Python. Of het resultaat deugt, hangt af van drie dingen die jij regelt voordat de eerste regel code bestaat: welke controles Claude moet halen, wat het mag doen op je computer, en welke database je kiest.

Alles in dit artikel is nagelopen of gemeten op 3 november 2026: Claude Code 2.1.317 met Opus 5.5, Python 3.14.10, uv 0.13.7, SQLite en PostgreSQL 18.6. Het voorbeeldproject is een kleine API voor afspraken bij een kapsalon. Claude Code heeft er in een echte sessie een functie aan toegevoegd. Wat daarbij goed en fout ging, staat er ook in.

Kort antwoord. Installeer Claude Code met de native installer en neem minimaal een Pro-abonnement ($20 per maand). Start een Python-project met uv init, en zet in CLAUDE.md precies welke commando's "klaar" betekenen: tests, ruff en een typechecker. Kies SQLite tot je meerdere servers hebt of veel gelijktijdige schrijvers, en kies dan PostgreSQL. In beide gevallen laat je de database dubbele boekingen tegenhouden, niet je Python-code. Elke IDE werkt, want Claude Code draait in de terminal. De VS Code-extensie is het verst ontwikkeld, de JetBrains-plugin is nog beta.

Wat Claude Code is, en wat het verschil maakt met een chatvenster

Claude Code is een programma in je terminal dat Claude laat werken in je projectmap. Het leest je bestanden, past ze aan, draait commando's zoals pytest, leest de uitvoer en probeert opnieuw. Een chatbot geeft je code om te plakken. Claude Code plakt hem zelf, draait de tests en ziet wat er faalt.

Dat klinkt als een detail, maar het bepaalt hoe je ermee werkt. De kwaliteit hangt minder af van hoe slim je je vraag formuleert, en meer van wat Claude kan controleren. Anthropic zegt het in de eigen best practices ook: geef Claude een controle die slaagt of faalt, en vraag om bewijs, dus het commando en de uitvoer. Een project zonder tests is voor Claude Code als een keuken zonder proeflepel.

Welk abonnement heb je nodig voor Claude Code?

Met het gratis plan kun je Claude Code niet gebruiken. De goedkoopste instap is Pro. De prijzen op claude.com/pricing staan in dollars en zonder btw:

PlanPrijs per maandGebruikVoor wie
Pro$20 ($17 bij jaarbetaling)limiet per 5 uur en per weekleren, een avond per week bouwen
Max$1005 keer Prodagelijks werk
Ultra$20010 keer Pro per week, geen limiet per 5 uurlange sessies, meerdere agents tegelijk
Team / Enterpriseper seatverschiltorganisaties met centraal beheer
API (Console)per tokengeen vaste limietautomatisering, CI

Lees je een oudere gids? Het plan dat daar "Max 20x" heet, is nu Ultra.

Om een idee te geven van de kosten: de functie die Claude Code verderop in dit artikel bouwde, kostte in twee runs samen $0,60 tegen API-tarief. Daarin zaten 15 beurten en ongeveer een minuut rekentijd. Op een abonnement betaal je dat niet los. Het telt mee voor je limiet.

Welk model gebruikt Claude Code?

Op alle betaalde plannen is Opus 5.5 het standaardmodel. Met /model wissel je naar sonnet, haiku, fable of opusplan. Die laatste plant met Opus en voert uit met Sonnet. Met /effort bepaal je hoe lang het model nadenkt: low, medium, high, xhigh of max. In Claude Code staat dat standaard op medium.

ModelAPI-prijs per miljoen tokens (in / uit)Wanneer
Fable 5.1$10 / $50het zwaarste denkwerk; nergens de standaard
Opus 5.5$4 / $20de standaard, voor vrijwel alles
Sonnet 5.5$2 / $10veel kleine taken, krappe limiet
Haiku 5.5vanaf $0,10 / $0,50subagents die zoeken en samenvatten

Alle vier hebben een contextvenster van een miljoen tokens. Daar past een middelgrote codebase in zijn geheel in. Toch is "alles in de context" geen werkwijze, zoals verderop blijkt. Mijn advies voor beginners: laat het model op de standaard staan. Een sessie wordt zelden beter van een ander model. Ze wordt wel beter van een betere controle.

Claude Code installeren op Windows, macOS en Linux

De aanbevolen route is de native installer. Die werkt zichzelf daarna automatisch bij.

# macOS, Linux en WSL
curl -fsSL https://claude.ai/install.sh | bash

# Windows (PowerShell)
irm https://claude.ai/install.ps1 | iex

# daarna, in je projectmap
claude

Liever een pakketbeheerder? Dat kan met Homebrew (claude-code), WinGet (Anthropic.ClaudeCode) of npm (@anthropic-ai/claude-code, met Node 22 of hoger). Ze installeren allemaal dezelfde binary. Na de installatie controleert claude doctor of alles klopt.

Gebruik je Windows? Installeer dan ook Git for Windows. Het is niet verplicht, maar met Git Bash draait Claude Code zijn shellcommando's in bash. Zonder Git Bash valt het terug op PowerShell. Dat werkt, maar de meeste voorbeelden in documentatie en op forums zijn bash. Wil je de sandbox gebruiken, die Claude Code afschermt van de rest van je systeem? Dan heb je WSL 2 nodig: de sandbox bestaat niet op native Windows.

Python in november 2026: uv, 3.14 en de gereedschapskist

Voor een nieuw Python-project is er in 2026 weinig reden om nog met pip, venv en een losse requirements.txt te beginnen. uv van Astral installeert Python zelf, maakt de virtuele omgeving, beheert dependencies en draait commando's. Dat in één programma.

Voor Claude Code is dat een groter voordeel dan het lijkt. Met uv is er precies één manier om iets te draaien: uv run pytest, uv run ruff. Claude hoeft niet te raden of de venv actief is. Dat scheelt de bekende foutmelding ModuleNotFoundError, die anders drie beurten kost voordat het model doorheeft dat het de verkeerde Python gebruikt.

uv init --package --python 3.14 kapsalon
cd kapsalon
uv add fastapi "uvicorn[standard]"
uv add --dev pytest httpx ruff ty

Welke Python-versie? Python 3.15.0 verscheen op 9 oktober 2026, met onder meer lazy imports en standaard UTF-8. Voor dit project heb ik 3.14 gekozen. Die versie is een jaar oud, free-threading wordt er officieel in ondersteund, en hij krijgt updates tot oktober 2030. Neem 3.15 als al je dependencies er wheels voor hebben. Het verschil merk je in een webapplicatie als deze nauwelijks.

De rest van de gereedschapskist, met de versies die ik gebruikte:

TaakGereedschapVersieOpmerking
testspytest9.2.0de controle waar alles om draait
lint en opmaakruff0.17.3vervangt flake8, isort en black
typesty0.0.96snel, maar nog beta; pyrefly 1.4 is stabiel
web-APIFastAPI0.162.0met Pydantic 2.14.2 voor validatie

Waarom een typechecker als je al tests hebt? Omdat Claude Code soms een functie aanroept met een argument dat niet bestaat, op een plek die geen test raakt. De typechecker vindt dat in een seconde. De gebruiker die toevallig dat pad neemt, vindt het pas in productie.

Welke IDE is het beste voor Claude Code?

De eerlijke conclusie: de IDE doet er minder toe dan je denkt. Claude Code draait in de terminal en werkt dus naast elke editor. De integraties voegen vooral twee dingen toe: je ziet wijzigingen als diff in je eigen editor, en wat je selecteert, gaat automatisch mee als context.

IDEIntegratieSterk inLet op
VS Codeextensie "Claude Code" (anthropic.claude-code)plan bekijken en aanpassen voor je akkoord geeft, inline diffs met accepteren of weigeren per wijziging, @-mentions met regelbereik, checkpointsvereist VS Code 1.94 of nieuwer
PyCharm (en andere JetBrains-IDE's)plugin "Claude Code [Beta]"diffs in de diffviewer van de IDE, je selectie gaat mee, Claude leest de inspecties van de IDEbeta; de CLI installeer je apart, verbinden met /ide
Cursor en andere VS Code-forksdezelfde extensie, via Open VSXals je Cursor al gebruikttwee AI-assistenten in één venster werken elkaar soms tegen
Zed"Claude Agent" via ACPsnelle editor, agent in een paneelapart inloggen met /login
Geen IDEterminal, desktop-app, claude.ai/codewerkt overal, ook op een servergeen inline diff

Mijn keuze voor iemand die begint met Python en Claude Code is VS Code met de extensie. Dat is geen oordeel over de editor, maar over de integratie. Die is het verst uitgewerkt, en vooral de planweergave helpt: je leest wat Claude van plan is en past het aan voordat er een bestand verandert. Werk je al in PyCharm, stap dan niet over. Sinds versie 2025.1 is PyCharm één product met een gratis kern, en de debugger en databaseweergave zijn sterker dan wat VS Code standaard biedt. De JetBrains-plugin doet het belangrijkste goed. Hoe dat in de praktijk werkt, staat in mijn eerdere artikel over Claude Code in PhpStorm. Voor PyCharm werkt het hetzelfde.

Welke database kies je voor een Python-project met Claude Code?

Hier gaat het in de meeste beginnersgidsen mis. Ze vergelijken databases op snelheid en populariteit. Voor een applicatie die Claude Code voor je schrijft, telt vooral één vraag: wie bewaakt de regels van je data? Een taalmodel schrijft logica die in een test met één gebruiker klopt. Dat iets onder gelijktijdig gebruik misgaat, ziet het niet vanzelf, en jij ook niet tot het gebeurt.

Terug naar de kapsalon. De regel is eenvoudig: op één stoel mogen geen twee afspraken overlappen. Ik liet twintig threads tegelijk stoel 1 boeken voor zaterdag 10:00 tot 10:30, op vier manieren, en herhaalde elke variant meerdere keren.

Tabelgrafiek van een meting met twintig gelijktijdige boekingen van dezelfde stoel. SQLite zonder transactie: twintig boekingen opgeslagen, dus negentien dubbel. SQLite met gewone BEGIN: één boeking, negentien keer de fout database is locked binnen 0,03 seconde. SQLite met BEGIN IMMEDIATE: één boeking, negentien nette weigeringen. PostgreSQL 18 met alleen een constraint: altijd één boeking, maar in 3 van de 20 rondes negentien deadlocks en 18 tot 19 seconden wachten. PostgreSQL 18 met constraint en advisory lock: één boeking, negentien nette weigeringen, 0,09 seconde.
Gemeten op 3 november 2026 met de code uit dit artikel: twintig threads, telkens dezelfde stoel en hetzelfde tijdvak. Alleen de twee groene varianten geven de klant een begrijpelijk antwoord.

Wat er gebeurt, per variant:

  • Eerst SELECT, dan INSERT, zonder transactie. Alle twintig threads zien een lege agenda, en alle twintig slaan hun afspraak op. Negentien dubbele boekingen, en dat in 5 van de 5 rondes. Een test met één gebruiker slaagt gewoon.
  • Dezelfde code in een gewone BEGIN. De data klopt nu: er staat één afspraak. Maar de negentien anderen krijgen binnen 0,03 seconde de fout database is locked, ondanks een busy_timeout van vijf seconden. De oorzaak: een transactie die begon met lezen en daarna wil schrijven, kan in WAL-modus niet wachten. Zijn momentopname is verouderd. Voor de klant betekent dat een 500-fout in plaats van "deze tijd is al bezet".
  • BEGIN IMMEDIATE. De schrijfvergrendeling gaat dicht vóór de controle. De threads wachten op elkaar, één boekt, de rest krijgt netjes "bezet". Dit is de code hieronder.
  • PostgreSQL 18 met alleen een constraint. De database weigert zelf elke overlap, en de data was in alle 20 rondes correct. Maar in 3 van de 20 rondes eindigde de race in een keten van deadlocks. De negentien verliezers kregen DeadlockDetected in plaats van een nette weigering, en de ronde duurde 18 tot 19 seconden. Bij elke deadlock wacht PostgreSQL eerst een seconde (deadlock_timeout), en die wachttijden stapelen.
  • PostgreSQL 18 met constraint plus een advisory lock per stoel. In 20 van de 20 rondes: één boeking, negentien keer "bezet", ongeveer 0,09 seconde per ronde.

Geen van deze problemen komt aan het licht in een gewone test. Ik heb er daarom een test bij gezet die twintig threads laat boeken, en een regel in CLAUDE.md die uitlegt waarom BEGIN IMMEDIATE verplicht is. Zo leest Claude Code de valkuil in elke sessie opnieuw.

SQLite: de juiste keuze tot je een tweede server nodig hebt

SQLite zit in Python ingebouwd, heeft geen server nodig en past in één bestand. Dat bestand kan Claude Code in een test in een tijdelijke map aanmaken en weer weggooien. Voor een applicatie op één server met een redelijk aantal gebruikers is het een volwaardige keuze, mits je drie dingen instelt: WAL-modus, een busy_timeout, en STRICT-tabellen. Die laatste weigeren tekst in een kolom die een getal moet zijn. Zonder STRICT slaat SQLite die tekst gewoon op.

Eén ding verrast veel mensen. De sqlite3-module opent standaard nog steeds zelf transacties, op een manier die je niet verwacht. Sinds Python 3.12 bestaat het argument autocommit, en de documentatie raadt aan het in te stellen. De standaard verandert pas "in een toekomstige versie". Ik zet het op True en schrijf BEGIN en COMMIT zelf uit. Dan staat in de code wat er gebeurt.

src/kapsalon/db.py

"""Opslag van afspraken in SQLite. Eén verbinding per request of per thread."""

import sqlite3
from pathlib import Path

SCHEMA = """
CREATE TABLE IF NOT EXISTS afspraak (
    id     INTEGER PRIMARY KEY,
    stoel  INTEGER NOT NULL,
    klant  TEXT    NOT NULL,
    begin  TEXT    NOT NULL,  -- ISO 8601, bijvoorbeeld 2026-11-14T10:00
    eind   TEXT    NOT NULL,
    CHECK (eind > begin)
) STRICT;
CREATE INDEX IF NOT EXISTS afspraak_stoel_begin ON afspraak (stoel, begin);
"""


class Bezet(Exception):
    """De stoel is in (een deel van) dit tijdvak al geboekt."""


def verbind(pad: str | Path) -> sqlite3.Connection:
    # autocommit=True (Python 3.12+): de module opent zelf geen transacties meer,
    # dus BEGIN en COMMIT doen we expliciet.
    conn = sqlite3.connect(pad, autocommit=True, timeout=5, check_same_thread=False)
    conn.row_factory = sqlite3.Row
    conn.execute("PRAGMA journal_mode = WAL")
    conn.execute("PRAGMA busy_timeout = 5000")
    conn.executescript(SCHEMA)
    return conn


OVERLAP = "SELECT 1 FROM afspraak WHERE stoel = ? AND begin < ? AND eind > ?"
INVOEGEN = "INSERT INTO afspraak (stoel, klant, begin, eind) VALUES (?, ?, ?, ?)"


def boek(
    conn: sqlite3.Connection, stoel: int, klant: str, begin: str, eind: str
) -> int:
    """Boek een afspraak, of gooi Bezet. BEGIN IMMEDIATE pakt de schrijfvergrendeling
    vóór de controle, zodat geen tweede boeking tussen controle en INSERT kan glippen."""
    conn.execute("BEGIN IMMEDIATE")
    try:
        if conn.execute(OVERLAP, (stoel, eind, begin)).fetchone():
            raise Bezet(f"stoel {stoel} is bezet tussen {begin} en {eind}")
        rij_id = conn.execute(INVOEGEN, (stoel, klant, begin, eind)).lastrowid
        conn.execute("COMMIT")
    except BaseException:
        conn.execute("ROLLBACK")
        raise
    assert rij_id is not None
    return rij_id


def annuleer(conn: sqlite3.Connection, afspraak_id: int) -> bool:
    """Verwijder een afspraak. Geeft False als die niet bestond. Eén losse DELETE is
    atomair (geen controle-dan-schrijven), dus BEGIN IMMEDIATE is hier niet nodig."""
    return (
        conn.execute("DELETE FROM afspraak WHERE id = ?", (afspraak_id,)).rowcount > 0
    )


def afspraken_op(conn: sqlite3.Connection, dag: str) -> list[dict]:
    rijen = conn.execute(
        "SELECT id, stoel, klant, begin, eind FROM afspraak "
        "WHERE begin >= ? AND begin < date(?, '+1 day') ORDER BY stoel, begin",
        (dag, dag),
    )
    return [dict(r) for r in rijen]

Een detail om te onthouden: de Python 3.14.10 die uv installeerde, bevat SQLite 3.50.4. De nieuwste SQLite is 3.54.1. Welke SQLite je hebt, hangt af van je Python-build, niet van wat er op sqlite.org staat. Controleer het met sqlite3.sqlite_version voordat Claude een functie gebruikt die jouw versie nog niet kent.

PostgreSQL: als meerdere processen tegelijk schrijven

Draait je applicatie op meer dan één server, of hebben veel gebruikers tegelijk schrijfrechten nodig, kies dan PostgreSQL. De huidige versie is 18; versie 19 staat gepland voor 19 november 2026. PostgreSQL 18 kan iets wat in dit voorbeeld goed van pas komt: temporal constraints. Met WITHOUT OVERLAPS in de primaire sleutel weigert de database zelf elke overlappende afspraak op dezelfde stoel. Hoe slordig de applicatiecode ook is, dubbel boeken lukt niet meer.

pg_boek.py

"""Boeken in PostgreSQL 18. De constraint garandeert dat er nooit twee afspraken
op één stoel overlappen; de advisory lock zorgt dat gelijktijdige boekingen voor
dezelfde stoel netjes achter elkaar gaan in plaats van elkaar te deadlocken."""

import psycopg
from psycopg import errors

SCHEMA = """
CREATE EXTENSION IF NOT EXISTS btree_gist;
CREATE TABLE IF NOT EXISTS afspraak (
    stoel  int       NOT NULL,
    klant  text      NOT NULL,
    tijd   tstzrange NOT NULL,
    PRIMARY KEY (stoel, tijd WITHOUT OVERLAPS)
);
"""


class Bezet(Exception):
    pass


def boek(
    conn: psycopg.Connection, stoel: int, klant: str, begin: str, eind: str
) -> None:
    try:
        with conn.transaction():
            conn.execute("SELECT pg_advisory_xact_lock(%s)", (stoel,))
            conn.execute(
                "INSERT INTO afspraak (stoel, klant, tijd) VALUES (%s, %s, tstzrange(%s, %s))",
                (stoel, klant, begin, eind),
            )
    except errors.ExclusionViolation as fout:
        raise Bezet(f"stoel {stoel} is bezet") from fout

De constraint garandeert de juistheid. De advisory lock zet gelijktijdige boekingen voor dezelfde stoel in een rij, waardoor de deadlocks uit de meting verdwijnen. Boekingen voor verschillende stoelen hinderen elkaar niet.

MySQL en DuckDB

Heb je al MySQL draaien, dan kun je dat blijven gebruiken. Let dan op de versie: MySQL 8.0 krijgt sinds april 2026 geen updates meer, en 8.4 en 9.7 zijn de LTS-versies. Een constraint zoals WITHOUT OVERLAPS heeft MySQL niet, dus daar regel je het met SELECT ... FOR UPDATE op een rij per stoel. Hoe je AI en databases verder combineert, staat in mijn artikel over AI en databases in webapplicaties. DuckDB (2.0) is uitstekend voor analyse op grote bestanden, maar niet bedoeld als database achter een webapplicatie waar veel gebruikers tegelijk schrijven.

SituatieKiesWaarom
Prototype, interne tool, één serverSQLitegeen server, tests in een tijdelijk bestand, Claude kan alles zelf draaien
Meerdere servers of workers die schrijvenPostgreSQL 18gelijktijdig schrijven, constraints zoals WITHOUT OVERLAPS
Bestaande MySQL-omgevingMySQL 8.4 of 9.7niet migreren zonder reden; vergrendelen met FOR UPDATE
Rapportages over miljoenen regelsDuckDB naast je hoofddatabasesnel voor analyse, niet voor veel gelijktijdige schrijvers

Het project inrichten: CLAUDE.md, rechten en een hook

Bij elke sessie leest Claude Code eerst het bestand CLAUDE.md in de root van je project. Wat daarin staat, hoef je nooit meer te herhalen. Met /init maakt Claude een eerste versie. Anthropic geeft een duidelijke richtlijn: houd het kort, onder de 200 regels, en zet er alleen in wat Claude niet zelf uit de code kan halen. Dat zijn de commando's, de afspraken en de valkuilen. Een beschrijving van de architectuur hoort er niet in. Die leest Claude zelf wel.

CLAUDE.md

# Kapsalon-afsprakenplanner

FastAPI + SQLite, Python 3.14, beheerd met uv. Vier stoelen; een afspraak valt binnen één dag.

## Commando's
- Tests: `uv run pytest -q`
- Lint en opmaak: `uv run ruff check --fix` en `uv run ruff format`
- Types: `uv run ty check`
- Server: `uv run fastapi dev src/kapsalon/app.py`

## Regels
- Schrijf eerst een falende test in `tests/`, dan de code. Klaar = alle drie de checks groen.
- Alle SQL staat in `src/kapsalon/db.py`, met `?`-parameters. Nooit f-strings in SQL.
- Schrijven dat eerst controleert en dan invoegt: altijd binnen `BEGIN IMMEDIATE`
  (zie `db.boek`). Een gewone `BEGIN` geeft onder gelijktijdige boekingen
  "database is locked" in plaats van een nette 409.
- Tijden zijn ISO 8601 zonder tijdzone, lokale tijd van de salon. Intervallen zijn halfopen: [begin, eind).
- Voeg geen dependencies toe zonder het te vragen.

Kijk naar de regel over BEGIN IMMEDIATE. Die staat er niet om de code uit te leggen, maar omdat de juiste keuze niet uit de code zelf te halen is. Zonder die regel ziet een gewone BEGIN er net zo verstandig uit.

Regels die altijd moeten gelden, horen niet in CLAUDE.md. Een taalmodel leest die als advies. Wat altijd moet, regel je in .claude/settings.json, in de vorm van rechten en hooks:

.claude/settings.json

{
  "permissions": {
    "allow": [
      "Bash(uv run pytest *)",
      "Bash(uv run ruff *)",
      "Bash(uv run ty check *)",
      "Bash(git status)",
      "Bash(git diff *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./*.db)",
      "Bash(uv add *)",
      "Bash(git push *)"
    ]
  },
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "uv run ruff check --fix --quiet && uv run ruff format --quiet"
          }
        ]
      }
    ]
  }
}

De allow-regels laten Claude de checks draaien zonder dat het steeds om toestemming vraagt. De deny-regels gelden altijd, in elke modus: .env lezen, een dependency toevoegen of pushen kan dus niet. De PostToolUse-hook draait na elke bewerking ruff. Opmaak is daardoor nooit meer iets waar jij of Claude op hoeft te letten.

Een valkuil die ik zelf tegenkwam. In de eerste run met dit bestand mocht Claude Code uv run pytest niet uitvoeren, ondanks de allow-regel. De debuglog gaf de reden: "Dropped 5 project-scoped permissions.allow entries — workspace not yet trusted". Een map die je nog nooit interactief hebt geopend en goedgekeurd, mag zichzelf geen rechten geven. De deny-regels gingen wel meteen in. Dat is precies goed: een repository die je net hebt gekloond, kan niet ongemerkt zijn eigen commando's toestaan. Open een nieuw project dus eerst één keer met claude en bevestig dat je de map vertrouwt.

Sinds versie 2.1.283 starten interactieve sessies standaard in auto mode. Daarin beoordeelt een classifier riskante acties, zodat je niet voor elk commando hoeft te klikken. Met Shift+Tab wissel je tussen de modi: auto, handmatig, bewerkingen automatisch accepteren, en plan mode. Voor een nieuwe feature begin ik in plan mode. Claude leest dan alleen code en schrijft een plan, en jij leest dat plan voordat er iets verandert.

Een feature laten bouwen: wat er in een echte sessie gebeurde

Met de boekingen en het dagoverzicht af, gaf ik Claude Code één opdracht, zonder verdere uitleg:

Klanten moeten een afspraak kunnen annuleren. Voeg DELETE /afspraken/{id} toe: 204 als het lukt, 404 als de afspraak niet bestaat. Een geannuleerde tijd moet daarna weer boekbaar zijn. Werk volgens CLAUDE.md: eerst falende tests, dan de code, en sluit af met de drie checks.

De eerste run duurde 34 seconden, 10 beurten. Claude schreef vijf tests en een functie annuleer. Daarna liep het vast op de rechten, zie de valkuil hierboven, en het eindverslag was eerlijk: Ik heb DELETE /afspraken/{id} met de tests geschreven, maar er is nog niets uitgevoerd. [...] Het is dus nog niet "klaar" volgens CLAUDE.md. Het meldde de tests niet als groen, maar als niet gedraaid. Dat verschil telt.

De tweede run, nu met toestemming voor de checks, duurde 27 seconden. Claude zette de nieuwe code tijdelijk opzij met git stash en liet zien dat vier van de vijf nieuwe tests dan faalden. Daarna zette het de code terug: 15 tests groen, ruff schoon, ty schoon. En het meldde zelf iets wat ik over het hoofd had gezien. De test "onbekend id geeft 404" slaagde ook zonder de nieuwe code, omdat FastAPI zonder route zelf al 404 geeft. Die test bewijst dus niets. Dat vond het model omdat CLAUDE.md vroeg om eerst falende tests. Zonder die regel was het niemand opgevallen.

De code die het schreef, is klein en klopt:

@app.delete("/afspraken/{afspraak_id}", status_code=204)
def annuleer_afspraak(afspraak_id: int, conn: Conn) -> None:
    if not db.annuleer(conn, afspraak_id):
        raise HTTPException(status_code=404, detail="afspraak niet gevonden")

Het legde ook uit waarom hier geen BEGIN IMMEDIATE nodig is: één losse DELETE controleert niet eerst iets, dus er valt niets tussen te glippen. Het paste de regel uit CLAUDE.md dus toe met begrip, en niet blind.

Eén ding ging mis, en dat lag bij mij. Voor de tweede run gebruikte ik claude -p --continue. Dat pakt de meest recente sessie in de map. Dat was niet de bouwsessie, maar een korte testsessie die ik ertussen had gedraaid om de rechten te onderzoeken. Claude begon dus zonder geheugen van zijn eigen werk. Het merkte dat zelf op ("die wijzigingen komen niet van mij") en werkte gewoon verder vanaf wat in de bestanden stond. Wil je een bepaalde sessie voortzetten, gebruik dan --resume met het sessie-id.

De werkwijze die standhoudt

Er zijn honderd tips over Claude Code. Deze vijf bepalen of je na een maand nog plezier hebt van je codebase.

Eén taak per sessie, en /clear ertussen

Een miljoen tokens context betekent niet dat het verstandig is om alles in één gesprek te doen. Elke mislukte poging, elk foutbericht en elk gelezen bestand blijft erin staan en beïnvloedt wat Claude daarna doet. Anthropic raadt aan om na twee mislukte correcties /clear te gebruiken en opnieuw te beginnen, met een betere opdracht. Met /context zie je wat er in de context zit, en /compact vat het gesprek samen zonder het te wissen.

Plan eerst, bouw daarna in een schone sessie

Voor alles wat groter is dan een kleine functie: laat Claude je in plan mode eerst vragen stellen. Laat het het resultaat opslaan in een bestand zoals SPEC.md, en begin de bouw in een nieuwe sessie die alleen dat bestand leest. Je verliest twee minuten. Je wint een sessie die niet vol staat met verworpen ideeën.

Terugdraaien kan, maar niet alles

Met twee keer Esc of /rewind ga je terug naar een eerder punt in de sessie, inclusief de bestanden. Wat Claude via een shellcommando heeft veranderd, valt daar niet onder. Een gewiste database of een git reset haal je met /rewind niet terug. Commit dus voordat je Claude aan iets groots zet. Git is je echte vangnet.

Werk parallel in worktrees

Met claude --worktree naam krijgt een sessie een eigen git-worktree, een aparte kopie van je repository op een eigen branch. Zo kan de ene sessie aan de annuleringen werken en de andere aan e-mailbevestigingen, zonder dat ze elkaars bestanden overschrijven. Voor wie meer zelfstandig wil laten werken, staat het verder uitgewerkt in Claude Code autonoom laten werken.

Subagents, skills en MCP: pas als je ze mist

Claude Code kan veel meer. Subagents in .claude/agents/ doen deeltaken met een eigen context. Skills in .claude/skills/ zijn vaste werkwijzen. Via MCP koppel je externe systemen, zoals je database, met claude mcp add. En met claude -p draait Claude Code zonder interactie, bijvoorbeeld in een GitHub Action. Begin daar niet mee. Een goede CLAUDE.md, een testsuite en twee deny-regels leveren in de eerste weken meer op dan tien skills. Voeg een skill pas toe als je merkt dat je dezelfde instructie voor de derde keer typt.

De fouten die beginners met Claude Code het vaakst maken

  • Geen controle opgeven. "Bouw een boekingssysteem" levert code op die er goed uitziet. "Bouw een boekingssysteem; klaar is als uv run pytest slaagt, inclusief een test met twintig gelijktijdige boekingen" levert code op die werkt.
  • Tests die niets bewijzen. Een test die ook zonder de nieuwe code slaagt, is decoratie. Laat Claude eerst de falende test laten zien. Dat ving in de sessie hierboven precies zo'n test.
  • Regels in CLAUDE.md die een hook of deny-regel moeten zijn. "Commit nooit .env" is een wens. "deny": ["Read(./.env)"] is een regel.
  • Bedrijfsregels alleen in Python. Wat nooit mag, zoals een dubbele boeking, een negatief saldo of een e-mailadres dat twee keer voorkomt, laat je de database bewaken met een constraint. Python-code die "eerst kijkt" gaat stuk zodra twee verzoeken tegelijk komen.
  • Eén eindeloze sessie. Na een uur heen en weer weet het model van alles over je eerste drie ideeën, en dat zit het vierde in de weg.

Veelgestelde vragen

Kan ik Claude Code gratis gebruiken?

Nee. Je hebt minimaal een Pro-abonnement nodig ($20 per maand), of een Console-account waarmee je per token betaalt. Met het gratis plan van Claude heb je geen toegang tot Claude Code.

Moet ik goed kunnen programmeren om Claude Code te gebruiken?

Je moet code kunnen lezen en beoordelen. Claude Code schrijft de functie, maar jij beslist of de tests het juiste testen. De race in de kapsalon zie je niet als je niet weet dat hij kan bestaan. Hoe het vak verschuift, beschreef ik in PHP en AI in 2027. Voor Python geldt hetzelfde.

Werkt Claude Code goed met Python?

Ja. Python met uv, pytest en ruff is een van de makkelijkste omgevingen voor Claude Code: één commando om te testen, één om op te maken, en foutmeldingen die precies zeggen wat er mis is. In de test hierboven bouwde het een complete functie met tests in een halve minuut.

SQLite of PostgreSQL voor een nieuw project?

Begin met SQLite als je applicatie op één server draait, en stel WAL, een busy_timeout, STRICT en BEGIN IMMEDIATE in. Stap over naar PostgreSQL zodra meerdere processen of servers tegelijk schrijven. Zet in beide gevallen je harde regels in de database zelf.

Heb ik VS Code nodig?

Nee. Claude Code werkt in elke terminal, naast elke editor. De VS Code-extensie en de JetBrains-plugin maken diffs en context prettiger, maar het werk gebeurt in de CLI.

Wil je morgen beginnen? Kies dan één kleine functie in een project dat al tests heeft. Schrijf in drie regels in CLAUDE.md welke commando's "klaar" betekenen, en vraag Claude Code eerst de falende test te laten zien. Werkt dat, dan heb je de belangrijkste les al binnen. De rest zijn instellingen.

Verder lezen op deze site

Bronnen

Deel dit artikel

Erik van de Blaak

Geschreven door

Erik van de Blaak

AI Solutions Engineer & Full-Stack Developer

Erik van de Blaak is AI Solutions Engineer en full-stack developer bij CareerValue BV. Hier schrijft hij over AI-codeertools en agents, zoals Claude Code.

Reacties (0)

Reageer op dit artikel

Wordt niet gepubliceerd

Ik lees elke reactie voordat die online komt.

Nog geen reacties op dit artikel.