Een coding agent krijgt de opdracht om na te gaan hoe Kubernetes dynamische resources toewijst over pakketten heen. Dat betekent het DRA-systeem volgen door 1,4 miljoen regels Go, verdeeld over 22.000 bestanden.
Hij grept op de allocator. Honderden treffers. Hij leest een bestand, volgt een import, leest het volgende. Elke afzonderlijke stap klopt. Na 6.000 seconden, ruim anderhalf uur, heeft hij niets opgeleverd. Score nul.
Zelfde model, zelfde opdracht, één verschil: zoektools met een index eronder in plaats van lokale bestandstoegang. Acht keyword-zoekopdrachten, zes semantische, één find-references. Klaar in 89 seconden, score 0,90 van de 1,0.
Die demo komt uit Sourcegraphs analyse van coding agents in grote codebases (8 mei 2026), en Sourcegraph verkoopt code-search, dus lees hem met dat in het achterhoofd. Hun cijfers zijn nuttiger dan hun demo.
De grens ligt rond 400.000 regels
Daarachter zit CodeScaleBench: 1.281 beoordeelde runs over 40+ van de grootste open source-repository's in negen talen. Eén uitkomst mag je inlijsten. Agents met alleen lokale tools, dus grep, bestanden lezen en glob, lopen systematisch vast zodra een codebase groter wordt dan ongeveer 400.000 regels code.
Onder die grens levert het toevoegen van code intelligence-tools een reward-verschil van −0,080 op. Hun eigen tabel schrijft erbij: "Tools add overhead; grep typically works fine." Tussen 400K en 2M regels slaat het om naar +0,259.
Een leverancier die een negatief getal publiceert over zijn eigen productcategorie wint daar wat vertrouwen mee terug. Het is ook de nuttigste zin uit het stuk, want hij vertelt de meeste lezers dat ze het probleem niet hebben waar het stuk over gaat.
Daarna kwam dezelfde onderzoeker op 31 juli met een vervolg, en dat verschuift precies de grens waar het eerste stuk om draait. "The answer depends less on codebase size than on how the relevant work is distributed across it."
Hun weging voor de moeilijkheid van het zoeken, vastgelegd voordat ze naar de uitkomsten keken, leunt inmiddels zwaarder op de vraag over hoeveel repository's en mappen het werk verspreid ligt dan op het totale aantal regels: "A 40-million-line monorepo behaves like a small repository when the relevant code sits in one directory. A two-million-line estate becomes the harder retrieval problem when the answer is scattered across four services."
Datzelfde stuk beschrijft 288 taken waarin beide varianten bij dezelfde code op dezelfde revisies konden komen. Gestructureerd zoeken bracht de F1 op bestandsniveau van 0,091 naar 0,240 en de recall van 0,120 naar 0,272, en "Aggregate task-completion reward was effectively unchanged." Een latere telling wees uit dat ongeveer 74% van dat corpus met alleen grep op te lossen was.
Lees die twee stukken naast elkaar en het regelaantal blijkt vooral een benadering van het echte probleem: hoe ver de code die je nodig hebt uit elkaar ligt. Voor een tutorial werkt die invalshoek sowieso beter, want aan die afstand kun jij zelf draaien. Elke instelling hieronder doet dat.
Het regelaantal blijft wel de goedkoopste eerste peiling, dus ik heb mijn eigen repository's naast die grens gelegd. De grootste, een tool voor klantinzichten, telt 162.781 regels code, verdeeld over 679 broncodebestanden. De MCP-servers die ik onderhoud zitten tussen de 40.000 en 90.000. Deze site zit op 11.781.
Ze blijven allemaal onder de grens waar investeren in zoekinfrastructuur zich begint terug te betalen.
Wat hierna komt, gaat dus over instellen in plaats van inkopen. Dat is goed nieuws, want instellen is de helft waar je zelf over gaat.
Wat er misgaat is de bestandsselectie
Het helpt om te weten waar je op optimaliseert voordat je een instelling aanraakt.
Een empirische studie uit april 2026 (arXiv 2604.05481) haalde 500 SWE-bench Verified-instanties door GPT-5-mini heen, in 61 contextconfiguraties die verschilden in hoeveel context het model kreeg op bestands-, element- en regelniveau. De kernbevinding: "more context does not consistently improve repair performance."
Wat wél uitmaakte:
- Lokalisatie op bestandsniveau is de bepalende factor, goed voor een verbetering van 15 tot 17 keer ten opzichte van een nulmeting zonder bestanden.
- Geslaagde reparaties concentreren zich rond zes tot tien relevante bestanden.
- Meer context op regelniveau verslechtert de prestaties vaak, doordat de ruis meegroeit.
Die zes tot tien bestanden zijn de orde van grootte waar je op mikt. Elke instelling hieronder vergroot de kans dat de eerste handvol bestanden die de agent opent de juiste zijn, en verlaagt de prijs van de bestanden die dat niet waren.
Een groter contextvenster lost dit niet op, om redenen die ik uitgebreid heb behandeld in het stuk over sessiehygiëne.
Start Claude waar het werk zit
De keuze met de meeste invloed in een monorepo kost niets en vraagt geen configuratiebestand: de map van waaruit je start.
Anthropics handleiding voor monorepo's zet het in een tabel. Start je vanuit de root van de repository, dan kan Claude bij elk bestand, maar laadt alleen de root-CLAUDE.md bij het opstarten. Bestanden dieper in de boom komen erbij zodra hij daar leest. Start je vanuit packages/api/, dan krijg je het bestand van die map plus dat van elke bovenliggende map, en blijven de andere pakketten volledig buiten beeld.
Eén ding om te weten voordat je voor een submap kiest: projectinstellingen erven niet over zoals memory-bestanden dat doen. Een .claude/settings.json in de root geldt alleen als je vanuit de root start. Het instellingenbestand van elk pakket moet op eigen benen staan.
Beperk wat er geladen wordt, daarna wat hij leest
Twee instellingen, allebei aanwezig in Claude Code 2.1.246 op deze machine. Ze horen allebei in .claude/settings.json, ingecheckt voor het team, of in .claude/settings.local.json als de keuze alleen van jou is.
claudeMdExcludes slaat memory-bestanden over op basis van een glob, zodat het pakket van een ander team nooit wordt geladen:
{
"claudeMdExcludes": ["**/packages/web/**"]
}De lijst ligt vast. Wil je vandaag op het ene pakket focussen en morgen op het andere, start Claude dan gewoon vanuit dat pakket.
Met deny-regels op Read houd je ingecheckte ruis uit je context. Zoekopdrachten respecteren .gitignore al, dus node_modules/ en dist/ zijn geregeld. De regels zijn voor meegeleverde SDK's en gegenereerde code die wel is ingecheckt:
{
"permissions": {
"deny": ["Read(./vendor/**)", "Read(./**/*.generated.*)"]
}
}Zorg daarna dat de agent geen bestanden meer hoeft te lezen voor vragen die een compiler kan beantwoorden. Een code intelligence-plugin koppelt Claude aan een language server, met go-to-definition en find-references:
/plugin marketplace add anthropics/claude-plugins-official
/plugin install typescript-lsp@claude-plugins-officialDe eerste regel heb je alleen nodig als de installatie meldt dat de marketplace ontbreekt, en de plugin vraagt om de language server van die taal op je eigen machine. Of het gelukt is, merk je door te vragen wie een symbool aanroept waarvan je weet dat het op drie plekken gebruikt wordt: dat antwoord hoort te komen zonder een muur van geopende bestanden ervoor.
Dit is de directe oplossing voor het faalpatroon dat Sourcegraph wrong file, wrong symbol noemt. Hun voorbeeld: een grep op allocate in Kubernetes geeft 47 treffers zonder enige rangschikking, terwijl find-references één definitie en twaalf aanroepen teruggeeft, geordend naar hun rol. Over de hele benchmark werd keyword-zoeken 7.993 keer gebruikt tegenover 2.449 semantische zoekopdrachten, dus agents grijpen naar het botste gereedschap dat voorhanden is. Geef ze iets beters en ze pakken dat.
Laat een worktree minder uitchecken
--worktree zet je wijzigingen apart in een schone checkout, zoals ik in het stuk over worktrees beschreef. In een grote repository is het standaardgedrag, de hele boom uitchecken, precies het dure deel. worktree.sparsePaths gebruikt sparse-checkout van git en schrijft alleen weg wat jij opgeeft:
{
"worktree": {
"sparsePaths": [".claude", "packages/api", "packages/shared"],
"symlinkDirectories": ["node_modules"]
}
}Noem mappen, geen losse bestanden. Bestanden in de root zoals package.json komen automatisch mee. Mappen in de root niet, en daarom staat .claude in die lijst. Alle worktrees binnen een sessie delen dezelfde paden, dus als twee subagents verschillende pakketten nodig hebben, zet je ze er allebei in.
Stuur een verkenner in plaats van zelf te gaan
Een subagent is een losse Claude-instantie met een eigen contextvenster die een taak uitvoert en alleen het eindresultaat teruggeeft aan de bovenliggende sessie. Bij verkennen in een grote boom is precies dat de winst: veertig keer een bestand lezen gebeurt ergens anders, en er komt één alinea terug.
Wat werkt, is een smalle vraag met een duidelijk benoemd resultaat. "Zoek elke aanroep van formatCurrency en geef de bestandspaden met regelnummers" levert zes tot tien bestanden op. "Kijk eens naar de facturatiemodule" levert een opstel op, opgebouwd uit leesacties waar je nu tweemaal voor betaalt.
Het ignore-bestand dat niet bestaat
Zoek op hoe je een agent uit een map houdt, en ergens staat dat je een .claudeignore moet aanmaken. Het staat in blogposts, op wikipagina's, in repository's die je overneemt.
Zo'n bestand bestaat niet. Het heeft ook nooit bestaan.
Claude heeft het verzonnen. Op de vraag hoe je voorkomt dat hij .env-bestanden leest, zei hij tegen The Register: "You can add .env to a .claudeignore file in your project root", en "Claude Code will refuse to read any files matching patterns listed there". Thomas Claburn toetste die bewering op 28 januari 2026 tegen v2.1.12, met een test-.env en een .claudeignore waar dat bestand in stond. Claude Code las het gewoon.
Zeven maanden later heb ik de uitgeleverde 2.1.246-binary doorzocht. sparsePaths komt er 26 keer in voor, claudeMdExcludes vier keer, additionalDirectories 41 keer. claudeignore, in welke schrijfwijze dan ook, nul keer. Ook in de volledige changelog, elke release die ooit is uitgebracht, komt het woord niet voor.
Dit stuk had die mythe bijna zelf doorgegeven, en dat is het vertellen waard. Tijdens het onderzoek haalde ik Anthropics handreiking voor bedrijven (14 mei 2026) op met een fetch die een samenvatting teruggeeft in plaats van de pagina, en daaruit kwam de aanbeveling om ".claudeignore files" te gebruiken voor gegenereerde bestanden, buildartefacten en code van derden. De pagina zelf heeft het over .ignore-bestanden, met in dezelfde opsomming het advies om permissions.deny-regels in te checken.
Een model dat de juiste zin las, vulde het voorvoegsel aan dat het verwachtte, omdat het internet die verkeerde naam nu eenmaal het vaakst herhaalt. Doe je dezelfde fetch nog een keer, dan komt er wél het juiste antwoord uit, en dat maakt het alleen maar erger: een fout die je niet kunt reproduceren, kun je ook niet afvangen. Bij de feitencontrole viel het op in de ruwe HTML, en alleen daarom lees je deze alinea in plaats van de zelfverzekerde versie.
Anthropic heeft het negen dagen geleden zelf in het openbaar beslecht. Op een issue met de titel ".claudeignore not enforced by Bash or Edit tools" testte een maintainer van Claude Code het na in versie 2.1.233, met een .claudeignore en een geheim in het bestand dat daarin genoemd stond. Alle vier de handelingen slaagden: Read, Grep, Bash cat en Edit. De reden die hij erbij geeft, is hier de kern. Het bestand "isn't a Claude Code feature", het "has never appeared in the changelog or docs, and no tool enforces it", en over de gevallen waarin het leek te werken: "that was the model voluntarily complying after noticing the file", wat hij "soft, probabilistic behavior, not a security boundary" noemt.
Erf je een repository met een .claudeignore erin, dan heeft dat bestand daar nooit iets gedaan.
Het echte mechanisme is permissions.deny, en het is de moeite waard om te weten hoe ver dat reikt. De documentatie is er eerlijk over: deny-regels dekken de ingebouwde bestandstools en herkende bash-commando's, en "Claude still sees denied paths in the output of a Bash search such as grep -r or find." Een deny-regel snoeit dus in je contextbudget, en alles wat via een shell werkt, leest nog steeds wat er in dat pad staat. Sluit je een pad af omdat er geheimen in staan en niet omdat er ruis in staat, dan wil je zien wat je coding agent daadwerkelijk over de lijn stuurt.
Doorzoeken of indexeren
Sourcegraph schrijft een index voor. Anthropic doet het omgekeerde: Claude Code "navigates a codebase the way a software engineer would", loopt door het bestandssysteem en gebruikt grep. Het argument daarvoor is dat "embedding pipelines can't keep up with active engineering teams", waardoor een index je de codebase teruggeeft zoals die uren of dagen geleden was.
De twee stukken verschenen zes dagen na elkaar in mei 2026. Beide partijen verkopen iets. Geen van beide heeft ongelijk, want ze beschrijven twee kanten van diezelfde grens van 400.000 regels, en Anthropics eigen handleiding geeft de andere kant stilzwijgend gelijk: draait je organisatie al een code-search of RAG-index over de repository, ontsluit die dan als MCP-tool zodat Claude hem bevraagt in plaats van bestanden te lezen.
Onder de grens is je agent niet verdwaald, maar onvoldoende gestuurd, en de oplossing bestaat uit een startmap, een gelaagde CLAUDE.md en een language server. Boven de grens weegt geen enkele zorgvuldige prompt op tegen gereedschap dat treffers op rangorde kan zetten, en dan mag je de markt op.
De meting waarmee je vaststelt aan welke kant je zit, is één commando:
git ls-files -z '*.ts' '*.tsx' '*.js' '*.jsx' '*.vue' '*.py' '*.php' '*.go' '*.rs' '*.java' '*.cs' \
| xargs -0 cat | wc -lPas de extensies aan op je eigen stack. Laat het door cat lopen in plaats van rechtstreeks door wc -l, want in een repository die groot genoeg is om de argumentenlijst op te splitsen krijg je het totaal van de laatste batch, zonder enige melding dat de rest ontbreekt. Dat zou een beroerde manier zijn om erachter te komen dat je het probleem hebt.
Dat aantal is de goedkope meting. Wat het werkelijk beslist, is waar het antwoord op een gewone vraag in jouw repository eigenlijk staat, en of een agent daar kan komen zonder eerst de hele boom door te spitten.