Naar inhoud springen
cd /blog

Waarom je AI-codeeragent bestandspaden hallucineert

[AI Agents] [Hallucination] [Retrieval] [MCP]

> AI-codeeragenten verzinnen bestandspaden wanneer ze geen echte kaart van de repo hebben. Hier lees je waarom dat gebeurt, en hoe verankering leidt tot minder gehallucineerde wijzigingen.

Het teken is geen verkeerde functie-inhoud. Het is een zelfverzekerde wijziging aan een bestand dat niet bestaat, of aan een bestand dat wel bestaat maar niet het bestand is dat het gedrag implementeert.

Je vroeg om een fix voor het verlopen van de sessie. De agent opende src/auth/session.ts. Dat pad is aannemelijk. Het is ook fout. De echte handler leeft in apps/api/src/middleware/expiry.ts, twee refactors geleden hernoemd. De agent loog niet tegen je. Hij vulde een string in de vorm van een pad aan op basis van trainingspriors plus wat al in het contextvenster stond.

Dit is het gebruikelijke faalpatroon op een echte repository. Het model kan code schrijven. De misser zit in het kiezen van de verkeerde plek om het te schrijven.

Waarom agenten paden verzinnen

Een codeeragent is een model dat het volgende token voorspelt, met hulpmiddelen. Als je zegt ‘los het verlopen van de sessie op’, moet hij eerst een bestand noemen voordat hij iets kan lezen of patchen. Als hij nog geen verankerde kaart heeft, construeert hij een pad uit:

  1. Naamgevingsconventies die hij in andere repositories heeft gezien. src/auth/session.ts is een veelvoorkomende vorm.
  2. Bestanden die al in het gesprek staan, die misschien de bestanden zijn die je vorige week hebt geplakt, niet de bestanden die nu ertoe doen.
  3. Mapoverzichten die hij toevallig heeft uitgevoerd, onvolledig op een grote boom.
  4. Instructiebestanden. CLAUDE.md en AGENTS.md vertellen de agent hoe hij zich moet gedragen. Ze zijn geen levende index van symbolen, aanroepers, of huidige paden.

Geen van deze bronnen is vandaag een kaart van deze repository. Het model vult de leemte op dezelfde manier waarop het elke leemte vult: met een vervolg met hoge waarschijnlijkheid. Dat vervolg ziet er vaak uit als een echt pad. Soms bestaat het bestand en ligt het naast het juiste. Soms bestond het op een branch die vorige maand is gemerged. Soms heeft het nooit bestaan.

Grep redt je hier niet als de agent nooit naar de juiste string zoekt. De agent gokte een pad, las vervolgens wat dat pad teruggaf, en bewerkte het toen. De eerste verkeerde stap was het pad, niet de patch.

Bestanden lezen is ook niet hetzelfde als de juiste vinden. Claude Code, Cursor, Codex, en soortgelijke hulpmiddelen kunnen openen waar je ze ook naar wijst. De vraag is of ze betrouwbaar de juiste bestanden vinden, de belangrijke symbolen, de afhankelijkheden, de tests, en de impactradius voordat ze bewerken. Bestandstoegang zonder kaart begint nog steeds met een gok.

De wijziging van het verkeerde bestand is een ophaalprobleem

Behandel het verzonnen pad als een ophaalmisser, niet als een karaktergebrek.

Als de agent path/file.ext:line zou moeten teruggeven voordat hij mag bewerken, zouden er twee dingen gebeuren. Ten eerste zou je het citaat kunnen openen en het werk binnen tien seconden kunnen afwijzen. Ten tweede zou de agent iets moeten bevragen dat de boom echt kent.

Dat is het werk van een codebase-contextlaag. Alleen semantisch zoeken is niet genoeg. Een fragment dat ‘klinkt als het verlopen van de sessie’ kan nog steeds landen in een verouderd package. Je hebt ook exacte tekst nodig als je de string kent, symboolzoeken als je de naam kent, structureel zoeken als je de vorm kent, en een afhankelijkheidsgraaf als je aanroepers en impactradius nodig hebt.

Maguyva is die laag voor MCP-compatibele codeeragenten. Het is geen editor. Claude Code, Cursor, Codex CLI, VS Code, Windsurf, en andere MCP-clients blijven waar ze zijn. De agent bevraagt een gerangschikte kaart voordat hij een regel aanraakt.

De bewering is bewust bescheiden: minder gehallucineerde wijzigingen. Maguyva ontneemt het model niet het vermogen om te gokken. Het verandert de standaard eerste stap van ‘verzin een aannemelijk pad’ naar ‘vraag om gerangschikte, geciteerde locaties’.

Hoe een onderbouwd antwoord eruitziet

Een nuttig antwoord op ‘waar wordt het verlopen van de sessie afgehandeld’ is geen alinea. Het is een korte lijst van locaties:

  • apps/api/src/middleware/expiry.ts:48 - de handler
  • apps/web/src/lib/auth-client.ts:112 - de aanroeper
  • apps/api/tests/expiry.test.ts:20 - de test die zal falen als de wijziging fout is

Je kunt deze regels openen. Als ze fout zijn, stop je. Als ze kloppen, mag de agent bewerken. De verificatie is het punt, geen slogan.

Maguyva stelt 11 klantgerichte MCP-hulpmiddelen beschikbaar voor zoeken, symbolen, afhankelijkheidsanalyse, bestandsophaling, repository-context en deterministische hulpwerkstromen. Vier ophaalmodi (semantisch, structureel, graaf/afhankelijkheid en tekstueel) worden samengevoegd tot gerangschikte resultaten; symboolzoeken is een apart MCP-hulpmiddel (find_symbol). Onderbouwde antwoorden komen terug met bestandspaden en regelnummers, zodat je ze kunt beoordelen tegen de boom voor je.

De documentatie beschrijft het kortste pad: begin gratis, indexeer een repo die je al kent, verbind de client, stel dan één vraag die je kunt verifiëren.

Een lus die de eerste wijziging verandert

Je hebt geen nieuwe workflowreligie nodig. Je hebt één extra stap nodig voor de eerste keer schrijven.

  1. Stel een vraag die je al kunt beoordelen. ‘Welke code behandelt inloggen en het verlopen van de sessie?’ is beter dan ‘los auth op’.
  2. Eis citaten. Bestandspad en regelnummer, geen samenvatting van ‘de auth-module’.
  3. Open de geciteerde bestanden. Volg het symbool. Bevestig de afhankelijkheid die je op het punt staat aan te raken.
  4. Pas dan laat je de agent patchen.

Als stap 2 niets nuttigs teruggeeft, heeft de agent niet het recht om een pad te improviseren. Hij zoekt opnieuw, of jij wijst het aan. Precies die ene poort levert minder gehallucineerde wijzigingen op. Het model is hetzelfde model. De kaart is wat is veranderd.

Instructiebestanden blijven belangrijk. Behoud ze. Gebruik ze voor conventies, reviewregels, en wat niet aangeraakt moet worden. Vraag ze niet om de index te zijn. Een CLAUDE.md die drie belangrijke mappen opsomt, is verouderd de week na een package-splitsing. Een doorzoekbare kaart wordt bijgewerkt wanneer de repo wordt bijgewerkt.

Een verwante mislukking is het bijna-juiste bestand: de agent opent auth.ts terwijl het gedrag in auth-client.ts leeft, of patcht een gegenereerd bestand in plaats van de bron, of bewerkt de kopie in packages/legacy omdat de naam overeenkwam. Citaten maken deze fouten niet onmogelijk. Ze maken ze zichtbaar voordat de diff landt.

Wat een kaart niet voor je oplost

Wees helder over wat je krijgt. Een onderbouwde kaart maakt niet elke wijziging correct — je agent kan nog steeds een slechte patch schrijven in precies het juiste bestand. Als jouw codebase leunt op dynamische dispatch, reflectie, of monkey-patching, komen sommige symboolzoekopdrachten dunner terug dan je zou willen, omdat dat is wat runtime-indirectie doet met elke statische index. En als je hoopt op een percentage — ‘gehallucineerde paden met X% verminderd’ — vind je dat hier niet, omdat niemand behalve jij dat cijfer eerlijk kan meten voor jouw repo.

Wat je kunt verwachten is smaller en nuttiger: de agent stopt met zijn wijzigingen te openen met een geraden pad. Die eerste stap wordt verankerd in een echte kaart, en daar komen minder gehallucineerde wijzigingen vandaan. Alles na het citaat — de diff lezen, de patch beoordelen — blijft nog steeds jouw werk, net als altijd.

De test kost je bijna niets: indexeer een repo die je al kent en stel één vraag die je kunt verifiëren. Begin met een pad waar je eerder door bent gebrand. Als de citaten fout zijn, zie je dat meteen. Als ze kloppen, heeft de volgende wijziging van je agent een betere plek om te landen.

// it doesn't know the file. it knows how to find it.

Gerelateerde artikelen

Meer uit het bouwlogboek van Maguyva