Een LLM kan zijn eigen belastingstandpunten niet controleren. Ik bouwde een deterministische laag die door AI opgestelde standpunten verifieert tegen de gecodeerde wet, niet tegen het model.
Tax TechnologyArtificial IntelligenceCompliance

Ik probeerde een LLM zijn eigen belastingfouten te laten vangen. Dat kan hij niet, en dat bleek de hele business te zijn.

Ashutosh SinghalAshutosh Singhal19 juni 202613 min

Het standpunt was grammaticaal perfect. Dat was het probleem.

Ik herinner me nog steeds het eerste standpunt waarbij ik stopte en mijn koffie neerzette. Een AI had een zin opgesteld over de nieuwe OBBBA-renteaftrek op autoleningen, en die luidde: "de nieuwe OBBBA-renteaftrek op autoleningen is een boven-de-streep-aftrek die de AGI van de cliënt verlaagt." De zin was netjes. Hij was zelfverzekerd. Hij was geformatteerd zoals elk verdedigbaar standpunt dat ik ooit had gelezen. En hij was fout op precies de manier die een echt persoon echt geld kost.

De renteaftrek op gekwalificeerde personenautoleningen (QPVLI) is een onder-de-streep-aftrek onder §63(b)(7). Het verlaagt niet het aangepaste bruto-inkomen. Het boven de streep zetten is geen spelfout die je bij een herlezing opmerkt. Het verschuift AGI stilzwijgend, en AGI is het getal waarvan de helft van de aangifte afhangt. Wat me verraste was niet dat een model een wetsbepaling iets verkeerd had. Het was hoe goed het verkeerde antwoord eruitzag.

Een gehallucineerd citaat is makkelijk te vangen. Een zelfverzekerde verkeerde classificatie, geschreven in perfect belastingengels, is degene die wordt ingediend.

Dat was het moment waarop het werkelijke probleem voor mij scherp werd. De sector heeft drie jaar besteed aan het automatiseren van het opstellen van belastingwerk, en dat is oprecht goed gelukt. Thomson Reuters stelt 1040's automatisch op. CCH Axcess stelt adviserende inzichten op bij duizenden kantoren. Blue J beantwoordt onderzoeksvragen in gewone taal. Opstellen wordt opgelost. Maar de stap na het opstellen, die waarin iemand moet beslissen of het standpunt werkelijk verdedigbaar is onder de wet, werd overgelaten aan hetzelfde probabilistische model dat het had opgesteld. En onder IRC §6662 landt de 20%-nauwkeurigheidsboete op de mens die de aangifte ondertekende, niet op het algoritme dat die schreef.

Ik heb een week besteed aan het laten nakijken van zijn eigen huiswerk door het model.

Mijn eerste instinct was het voor de hand liggende, en ik wil eerlijk zijn dat ik het langer heb nagejaagd dan ik had moeten doen. Als het model het standpunt kan opstellen, kan een voldoende goede prompt het vast ook controleren. Dus probeerde ik het. Ik gaf het de wet. Ik gaf het de QPVLI-regel uitgeschreven. Ik vroeg het om zijn eigen output te auditen en alles te markeren dat een aftrek op de verkeerde regel zette.

Het ving er enkele. Het miste andere. En wat het miste was van het engste soort, want wanneer het fout zat bij de audit, zat het fout met dezelfde vloeiende zelfverzekerdheid als bij het opstellen. De zelfcontrole liep door dezelfde gewichten die de fout in de eerste plaats hadden geproduceerd. Een model vragen om zichzelf te controleren is vragen aan het ding dat de fout maakte om ook het ding te zijn dat de fout opmerkt, met exact dezelfde redenering die hem veroorzaakte.

Ik herinner me dat ik dit aan een collega uitlegde en mezelf hardop hoorde zeggen: "we kunnen een LLM niet vertrouwen om een LLM te controleren." Die zin was het moment waarop het ontwerp voor mij omsloeg. Ik had geprobeerd het model nauwkeuriger te maken. Het echte antwoord was om het model helemaal niet meer te vertrouwen als rechter.

Je kunt een probabilistisch systeem niet deterministisch maken door het vriendelijk te vragen. Je verplaatst het oordeel erbuiten.

Het onderscheid dat ik te lang nodig had om te internaliseren is dat opstellen en verifiëren niet dezelfde taak zijn die makkelijker of moeilijker wordt gemaakt. Het zijn verschillende problemen. Opstellen beloont vloeiendheid, dekking en plausibiliteit, precies waarvoor een taalmodel is gebouwd. Verificatie beloont aantoonbaar gelijk hebben over één specifieke regel, en in staat zijn om je werk te laten zien aan een controleur die niet in de kamer was. Dat zijn tegengestelde temperamenten. Ik stopte met proberen één systeem beide te laten doen.

Wat betekent "agent adviseert, code beslist" eigenlijk?

Ik wil precies zijn over de architectuur waarop ik uitkwam, want de zin kan klinken als marketing tot je ziet waar de lijn wordt getrokken. In StatuteGuard, de demo die ik bouwde, doet het taalmodel precies één ding: het leest rommelige natuurlijke-taal-belastingtaal en stelt een gestructureerde, getypeerde claim voor. Dat is de enige neurale stap. Het is daar oprecht goed in, en wanneer het niet zeker is, onthoudt het zich en escaleert het standpunt naar een mens in plaats van een gegokt oordeel te geven.

Alles daarna is code. Het oordeel wordt bepaald door een deterministische policy-engine, echte OPA/Rego met een identieke pure-Python-tweeling, die regels uitvoert die ik heb uitgeschreven tegen de primaire wet. Neurale extractie, symbolische verificatie. Het model adviseert. De code beslist. En het verschil is niet academisch, want de code laat zich niet door een goed geschreven alinea van zijn antwoord afpraten.

Het deel waar ik niet had verwacht zo veel om te geven als ik doe, is leesbaarheid. De policies zijn geen black box waarvan ik vraag dat je die vertrouwt. Het zijn beslissingstabellen en Rego-broncode die je kunt openen en zelf tegen de wet kunt controleren.

Het Policy Rules-paneel met leesbare beslissingstabellen voor §280A en §30D naast de echte OPA/Rego-bron
De §30D-regels voor schone voertuigen gecodeerd als leesbare tabel (MSRP-plafond auto $55,000, SUV/truck/van $80,000; modified-AGI-plafond single $150,000, HoH $225,000, MFJ $300,000) met daaronder de echte OPA/Rego-bron. Je kunt de policy lezen en bevestigen dat die overeenkomt met de wet.

Die screenshot is de hele stelling in één paneel. Een Head of Tax moet met zijn compliance-partner kunnen zitten, de regel openen en die bevestigen tegen §30D voordat hij één enkel oordeel vertrouwt. Wanneer de logica een alinea modelredenering is, kun je dat niet. Wanneer het een regel is die je kunt lezen, kun je dat wel.

Dus wat gebeurt er wanneer de code nee zegt?

De eerste keer dat ik dat OBBBA-autolening-standpunt door de voltooide poort liet lopen, glimlachte ik echt. Het model had de claim "boven de streep, verlaagt AGI" precies zo opgesteld als eerder. Maar deze keer keek de deterministische engine naar de geëxtraheerde claim, matchte die tegen de gecodeerde §63(b)(7)-regel, en gaf een hard oordeel terug: BLOCK. Niet indienen.

StatuteGuard dat een BLOCK-oordeel teruggeeft op het OBBBA-autolening-standpunt met een niet-indienen-banner en de vijfledige downstream-cascade rood gemarkeerd
Het OBBBA-QPVLI-standpunt geeft BLOCK terug ("Geblokkeerd. De opgestelde stelling conflicteert met de gecodeerde wet; dien niet in zoals geschreven."), met de vijfledige downstream-cascade (AGI, AGI-gekoppelde staatsbelasting, Medicare IRMAA, de 7.5%-drempel voor medische kosten, student-loan IDR) allemaal gemarkeerd.

Wat ik overtuigend vind aan dit beeld, en wat ik hoop dat een belastinglezer overtuigend vindt, is de cascade. De engine zegt niet alleen "verkeerde regel." Ze laat je de vijf downstream-plaatsen die een valse AGI-verlaging zou corrumperen: het aangepaste bruto-inkomen zelf, AGI-gekoppelde staatsinkomstenbelasting, de Medicare IRMAA-premietoeslag, de 7.5%-drempel voor aftrek van medische kosten, en inkomen-afhankelijke terugbetaling van studieleningen. Eén verkeerd geclassificeerde aftrek is niet één fout. Het is een klein schadebereik, en het paneel maakt dat bereik zichtbaar.

Dan animeert ze de reden, het deel waar ik het meest aan gehecht ben. Ze loopt de citatieketen af over de IRC-kruisverwijzingsgraaf, knoop voor knoop, zodat het "nee" nooit een kale bewering is.

De geanimeerde wettelijke citatieketen die de IRC-graaf doorkruist van §163(h)(1) via §63(b)(7) met de onder-de-streep-plaatsingsregel getoond
De live citatieketen: §163(h)(1) naar §163(h)(4)(A) naar §163(h)(4)(B) naar §63(b)(7) naar §62/§63. Selecteren van de §63(b)(7)-knoop toont de plaatsingsregel: QPVLI is toegestaan bij het berekenen van belastbaar inkomen uit AGI, een onder-de-streep-aftrek, bevestigd door de Federal Register-regel voor rente op autoleningen (januari 2026).

Hier is het detail waar ik steeds op terugkom, omdat het bewijst dat dit geen speelgoedprobleem is. Volgens de eigen README van de demo is de verkeerde labeling "boven de streep" niet iets dat ik heb verzonnen om een schurk te hebben. Het is een gedocumenteerde consensusfout die mainstream begeleiding voor belastingaangiften, inclusief de site van H&R Block, heeft gepubliceerd. Een plausibel, goed geschreven, breed herhaald verkeerd antwoord is precies de faalmodus waarvoor een deterministische poort bedoeld is. Dat de menigte zelfverzekerd is, verplaatst de aftrek niet naar AGI. De wet beslist dat, en nu doet de code dat ook.

De gevaarlijkste belastingfout is niet die er fout uitziet. Het is die er juist uitziet, juist klinkt, en in de begeleiding van drie leveranciers opduikt.

Als je dit zelf wilt bekijken, staat de werkende demo op veriprajna.com/nl/demos/statuteguard-verifieer-door-ai-opgestelde-belastingposities. Je kunt je eigen standpunt plakken en de poort laten beslissen.

De functie die ik bijna verkeerd aanpakte: weten wanneer je "ik weet het niet" moet zeggen

Ik moet de fout toegeven die ik er bijna in bakte, want het is degene die elke engineer die een verificatietool bouwt wil maken. Mijn vroege instinct was om de machine alles te laten beantwoorden. Dekking voelde als het doel. Een tool die over elk standpunt een oordeel teruggeeft, oogt afgeronder dan een tool die soms de schouders ophaalt.

Dat instinct is verkeerd, en een specifiek standpunt leerde me waarom. Neem de §280A-thuiswerkplekaftrek. Of een gastenkamer "regelmatig en exclusief" als hoofdzakelijke plaats van onderneming wordt gebruikt, is een feiten-en-omstandigheden-toets. Er is geen schone regel om te coderen, omdat het antwoord afhangt van hoe een echt persoon een echte kamer werkelijk gebruikt. Als ik de deterministische engine dwong om daarover te oordelen, zou ik precies doen wat ik hiermee wilde voorkomen: een zelfverzekerd oordeel fabriceren waar het eerlijke antwoord is "een mens moet hiernaar kijken."

StatuteGuard dat het §280A-thuiswerkplek-standpunt doorstuurt naar NEEDS HUMAN REVIEW omdat regelmatig-en-exclusief gebruik een feiten-en-omstandigheden-toets is
Het §280A-thuiswerkplek-standpunt (een gastenkamer gebruikt voor advieswerk, met exclusiviteit niet vastgesteld) wordt doorgestuurd naar NEEDS HUMAN REVIEW. Het grijze gebied wordt geëscaleerd in plaats van opgelost, omdat regelmatig-en-exclusief gebruik een feiten-en-omstandigheden-toets is buiten deterministische dekking.

Dus de poort heeft vier oordelen, niet twee. PASS wanneer het standpunt verdedigbaar is. BLOCK wanneer het de gecodeerde wet tegenspreekt. NEEDS-REVIEW wanneer het een echt grijs gebied is. OUT-OF-COVERAGE wanneer de bepaling in deze versie simpelweg niet is gecodeerd. De laatste twee betekenen beide hetzelfde eerlijke ding: een mens beslist deze, niet de machine. Het bouwen van het escalatiepad voelde als het toegeven van een limiet. Het is eigenlijk de belangrijkste functie in het product, omdat een verificatielaag die nooit "ik weet het niet" zegt, gewoon een tweede model is dat bluft met extra stappen.

De cijfers, en precies wat ze niet claimen

Ik ben voorzichtig met de benchmark, voorzichtiger dan een marketeer zou willen, omdat de manier waarop deze cijfers meestal worden gesteld een leugen is. Ik liet de deterministische engine lopen tegen een gelabelde golden set van 42 vooraf geclassificeerde standpunten (14 schoon, 16 fout, 12 escaleren) en mat wat de laag doet.

Het golden-set-benchmarkscorebord met 71.4% deterministische dekking, 100% poortprecisie, 100% foutvangst, 100% correcte escalatie over 42 standpunten
De golden-set-benchmark: 71.4% deterministische dekking, 100% poortprecisie (0 valse blocks), 100% volledigheid van foutvangst, 100% van grijze gebieden correct geëscaleerd, geverifieerd over de 42 gelabelde standpunten, lokaal geëvalueerd.

Op die golden set van 42 cases: 71.4% deterministische dekking, wat betekent dat de engine dat aandeel zelf naar PASS of BLOCK oploste en de rest correct escaleerde. 100% poortprecisie, wat betekent dat nul correcte standpunten ten onrechte werden geblokkeerd. 100% volledigheid van foutvangst op de gecodeerde bepalingen. 100% van grijze gebieden correct geëscaleerd. De doorvoer liep in de tienduizenden standpunten per seconde (ongeveer 58,000 in de run waarvan ik een screenshot nam, al is dat machine-afhankelijk), omdat verificatie infrastructuur is, geen modelaanroep.

Nu het deel waarop ik aandring. Die cijfers zijn waar op die golden set, niet als een open-world-garantie. Ik zal je niet vertellen dat StatuteGuard "100% nauwkeurig" is, want die zin is oneerlijk zodra je de gelabelde set verlaat. Wat ik je wél zal vertellen is subtieler en, denk ik, duurzamer: omdat het oordeel deterministische code is, is het gedrag op de gecodeerde bepalingen reproduceerbaar en bewijsbaar, geen waarschijnlijkheid die verschuift. Ik heb elk van de 42 oordelen zelfs nagecontroleerd tegen OPA 1.17.1 en de pure-Python-tweeling, en ze kwamen exact overeen. Dat is de claim waarachter ik kan staan. Die beschrijft de laag, niet het model.

"100% nauwkeurigheid" is een marketingcijfer. "Reproduceerbaar op de gecodeerde bepalingen, met eerlijke escalatie overal elders" is een engineeringcijfer. Ik zou liever het tweede leveren.

En daarom veroudert dit niet. Een beter basismodel volgend jaar kan nog steeds niet bewijzen aan een controleur welke wettelijke bepaling welk standpunt onderbouwde. Dekking, poortprecisie en een indiendbaar auditspoor zijn eigenschappen van de verificatielaag. Dat is geen model-foutpercentage dat krimpt naarmate modellen verbeteren.

Het artefact waarvan ik niet wist dat ik het bouwde tot een controleur erom vroeg

Ik was niet van plan een compliance-document te bouwen, maar hoe meer belastingmensen ik sprak, hoe vaker het gesprek op dezelfde plek eindigde: "prima, het ving de fout, maar wat geef ik de IRS?" Dus schrijft elk oordeel nu een indiendbaar §6662 due-diligence-dossier, een afdrukbaar werkdocument dat vastlegt dat het standpunt vóór indiening tegen de wet is geverifieerd. Bronwerkdocument, bepaling, primaire bron, de geëxtraheerde claim, het vaststellingsverhaal, de volledige citatieketen. Het is het bewijs dat er daadwerkelijk een reasonable-cause-, due-care-standpunt is ingenomen, wat rechtstreeks van belang is onder de AICPA SSTS-herzieningen die vanaf januari 2024 van kracht zijn.

Er is nog één reden waarom ik geef om waar dit draait, en die werd concreet na de Heppner-uitspraak (SDNY, februari 2026), die een privilege-waiver-vraag opwierp over het voeden van cliëntonderzoek in een publieke AI-tool. StatuteGuard draait standaard volledig lokaal zonder API-sleutel. Geen standpunt en geen cliëntgegevens verlaten de perimeter. Na Heppner is een gesloten, lokale, auditeerbare architectuur niet alleen een nice-to-have bij een security-review. Het is juridisch materieel. Ik heb de local-first-houding niet voor die uitspraak ontworpen. Maar de uitspraak is waarom ik er nu mee open.

Voor context over de inzet: de kosten van US business tax-compliance lopen voorbij $126 miljard per jaar (WP1 solution research, 2026), en de IRC §6662-boete is 20% van de onderbetaling, met §6663-fraudeblootstelling tot 75%. Wanneer het opstellen is geautomatiseerd en de boete persoonlijk is, is de verificatiestap degene die een Head of Tax wakker moet houden.

Wat ik nu werkelijk geloof

Ik begon hiermee in de overtuiging dat ik een betere tax AI bouwde, en ik wil eindigen door ronduit te zeggen dat ik het probleem verkeerd had. Je tax AI heeft geen nauwkeurigheidsprobleem. Het heeft een verificatieprobleem, en een beter model lost dat niet op, omdat de 20%-boete landt op jouw handtekening, niet op zijn gewichten. Het personaliseren en automatiseren van het opstellen van belastingwerk is echte vooruitgang. Het is ook niet hetzelfde als bewijzen dat een standpunt verdedigbaar is, en de sector heeft ze stilletjes behandeld alsof ze dat wel waren.

De demo staat op veriprajna.com/nl/demos/statuteguard-verifieer-door-ai-opgestelde-belastingposities als je de poort wilt proberen te breken. Ik zou dat oprecht graag willen.

En als je liever de poort wilt zien beslissen dan dat ik hem beschrijf, hier is het hele ding van begin tot eind draaiend.

Dus hier is de vraag die ik belastingleiders blijf stellen, en ik heb er nog geen comfortabel antwoord op. Wanneer een AI een standpunt opstelt en jij de aangifte ondertekent, wat is het artefact dat bewijst dat jij het hebt geverifieerd, in plaats van het te hebben vertrouwd? Als het eerlijke antwoord is "niets, ik vertrouwde het model," dan is het model niet je assistent. Het is je medeondertekenaar, en het kan niet worden opgeroepen voor de audit.

Gerelateerd onderzoek

Ook gepubliceerd op

Bouw uw AI met vertrouwen.

Werk samen met een team met diepgaande ervaring in het bouwen van de volgende generatie enterprise-AI. Laat ons u helpen bij het ontwerpen, bouwen en implementeren van een AI-strategie waarop u kunt vertrouwen.

Veriprajna Deep Tech-adviesbureau is gespecialiseerd in het bouwen van veiligheidskritische AI-systemen voor de gezondheidszorg, de financiële sector en gereguleerde domeinen. Onze architecturen worden gevalideerd aan de hand van gevestigde protocollen met uitgebreide compliancedocumentatie.