[{"data":1,"prerenderedAt":1429},["ShallowReactive",2],{"blog-list-nl-nl":3},[4],{"id":5,"title":6,"body":7,"config":1413,"date":1414,"description":1415,"draft":1416,"extension":1417,"image":1413,"meta":1418,"navigation":1419,"path":1420,"seo":1421,"stem":1422,"tags":1423,"toolbar":1413,"translationKey":1427,"updated":1414,"__hash__":1428},"blog/nl-nl/blog/zero-hallucination-qa.md","Hoe ik nul-hallucinatie Q&A in onze reader heb gebouwd",{"type":8,"value":9,"toc":1377},"minimark",[10,18,33,36,41,48,53,58,76,81,94,99,133,136,140,158,165,169,184,189,226,233,237,250,275,280,397,415,421,423,427,434,449,456,476,482,484,488,491,497,499,503,526,536,597,600,611,621,628,630,634,645,651,658,662,669,677,684,688,698,741,752,758,760,764,778,786,792,795,830,840,848,854,861,865,873,879,890,892,896,902,906,913,917,940,947,949,953,959,1017,1022,1024,1028,1035,1054,1058,1078,1089,1091,1095,1106,1109,1132,1143,1149,1151,1155,1170,1181,1183,1187,1208,1219,1221,1225,1244,1250,1252,1256,1344,1351,1362],[11,12,13],"p",{},[14,15],"img",{"alt":16,"src":17},"Omslag: nul-hallucinatie Q&A","https://cdn.linghuxiong.com/resources/snapshots/ai-chat-cover.png",[19,20,21],"blockquote",{},[11,22,23,24,28,29,32],{},"Dit artikel beschrijft hoe we ",[25,26,27],"strong",{},"nul-hallucinatie Q&A"," in onze AI-reader hebben geïmplementeerd: antwoorden zijn strikt gebaseerd op de brontekst van het geopende boek, en belangrijke uitspraken zijn ",[25,30,31],{},"met één klik te traceren"," naar de exacte passage. Als je AI-lezen, document-Q&A of RAG-achtige apps bouwt, hopen we dat drie iteraties aan lessen en de uiteindelijke architectuur nuttig zijn.",[34,35],"hr",{},[37,38,40],"h2",{"id":39},"i-evolutie-in-drie-fasen","I. Evolutie in drie fasen",[11,42,43,44,47],{},"Nul-hallucinatie Q&A was niet vanaf dag één perfect ontworpen. Het evolueerde onder spanning tussen ",[25,45,46],{},"kosten, latentie en nauwkeurigheid",". Hieronder een chronologisch overzicht van drie fasen—nuttige context om te begrijpen waarom de huidige architectuur er zo uitziet.",[49,50],"mermaid",{":config":51,"code":52},"config","flowchart%20LR%0A%20%20%20%20P1%5BFase%201%3A%20volledige%20tekst%20dumpen%5D%20--%3E%20P2%5BFase%202%3A%20LLM%20sleutelzinnen%20extraheren%5D%0A%20%20%20%20P2%20--%3E%20P3%5BFase%203%3A%20segmentindex%20%2B%20Tool-retrieval%5D%0A%20%20%20%20P1%20-.-%3E%7CTraag%2C%20duur%2C%20onnauwkeurig%20bij%20lange%20boeken%7C%20X1%5BAfgeschaft%5D%0A%20%20%20%20P2%20-.-%3E%7CDetailverlies%2C%20nog%20traag%7C%20X2%5BAfgeschaft%5D%0A%20%20%20%20P3%20--%3E%7CHuidig%7C%20OK%5BNul%20hallucinatie%20%2B%20traceerbaar%5D",[54,55,57],"h3",{"id":56},"fase-1-de-volledige-boektekst-in-de-context-dumpen-eenvoudigsten-als-eerste-problematisch","Fase 1: de volledige boektekst in de context dumpen (eenvoudigst—en als eerste problematisch)",[11,59,60,63,64,67,68,71,72,75],{},[25,61,62],{},"Aanpak:"," Wanneer een gebruiker een boek opent en een vraag stelt, plaats je ",[25,65,66],{},"alle geëxtraheerde hoofdtekst"," in de system prompt of het user-bericht en laat je het chatmodel antwoorden. Overschrijdt het boek ongeveer ",[25,69,70],{},"400.000 tekens",", dan volgt ",[25,73,74],{},"harde truncatie","—alleen het begin blijft behouden; latere hoofdstukken zijn onzichtbaar voor het model.",[11,77,78],{},[25,79,80],{},"Voordelen:",[82,83,84,88,91],"ul",{},[85,86,87],"li",{},"Zeer lage implementatiekosten; vrijwel geen preprocessing;",[85,89,90],{},"Werkt redelijk op korte boeken en eenvoudige documenten—het model heeft het boek echt «gezien»;",[85,92,93],{},"Eenvoudige UX: vragen en antwoord krijgen, geen «even wachten terwijl we analyseren»-status.",[11,95,96],{},[25,97,98],{},"Nadelen (snel onacceptabel):",[82,100,101,107,113,123],{},[85,102,103,106],{},[25,104,105],{},"Trage reacties:"," Bij elke vraag gaat een enorme payload mee; time-to-first-token en totale latentie groeien met de boeklengte;",[85,108,109,112],{},[25,110,111],{},"Hoge tokenkosten:"," Je betaalt bij elke vraag opnieuw voor de volledige boekinput;",[85,114,115,118,119,122],{},[25,116,117],{},"Lange boeken vervormen sterk:"," Na 400.000 tekens bestaan het tweede deel, bijlagen en conclusies feitelijk niet meer—en de UI geeft vaak ",[25,120,121],{},"niet duidelijk aan"," dat er is afgekapt;",[85,124,125,128,129,132],{},[25,126,127],{},"Nul retrieval-granulariteit:"," Het model moet «naar een speld in een hooiberg zoeken» over honderdduizenden tekens—gemakkelijk details missen en makkelijker ",[25,130,131],{},"plausibel klinkende samenvattingen zonder basis"," produceren—precies wat leesapps moeten vermijden.",[11,134,135],{},"Fase 1 is prima voor een MVP, niet voor een productwaardige oplossing.",[54,137,139],{"id":138},"fase-2-een-lichter-llm-gebruiken-om-sleutelzinnen-te-extraheren-context-comprimerenmaar-te-agressief","Fase 2: een lichter LLM gebruiken om sleutelzinnen te extraheren (context comprimeren—maar te agressief)",[11,141,142,144,145,148,149,152,153,157],{},[25,143,62],{}," Vóór Q&A (of bij eerste openen) draait een ",[25,146,147],{},"goedkoper model"," over de hoofdtekst: splitsen per spine-hoofdstuk (of het hele boek in stukken), ",[25,150,151],{},"sleutelzinnen"," extraheren, positietags zoals ",[154,155,156],"code",{},"[fBestand-start-einde]"," behouden, en de fragmenten samenvoegen tot kortere context voor latere Q&A.",[11,159,160,161,164],{},"Typische pipeline: ",[25,162,163],{},"Extract → Cache → Chat",". Eén keer extraheren (offline of on demand), een «sleutelzinnenbundel» opslaan, hergebruiken bij elke vraag—dezelfde gedachte als veel document-Q&A-prototypes die eerst comprimeren en dan antwoorden.",[11,166,167],{},[25,168,80],{},[82,170,171,178,181],{},[85,172,173,174,177],{},"Elke vraag stuurt ",[25,175,176],{},"veel minder tekst","; tokenverbruik per request daalt t.o.v. fase 1;",[85,179,180],{},"Preprocessing kan worden gecached; geen her-extractie per vraag voor hetzelfde boek;",[85,182,183],{},"Positietags leggen de basis voor bronverwijzingen.",[11,185,186],{},[25,187,188],{},"Nadelen (blijft falen bij lange boeken):",[82,190,191,197,207,216],{},[85,192,193,196],{},[25,194,195],{},"Zwaar detailverlies:"," «Sleutelzinnen» worden door het model gekozen; beperkingen, tegenargumenten en argumentatieketens vallen vaak weg—antwoorden worden «correct maar eenzijdig»;",[85,198,199,202,203,206],{},[25,200,201],{},"Context nog groot bij lange boeken:"," Zelfs sleutelzinnenbundels voor grote werken zijn aanzienlijk—latentie en kosten zijn ",[25,204,205],{},"verlicht, niet opgelost",";",[85,208,209,212,213,206],{},[25,210,211],{},"Dubbele LLM-fout:"," Extractie kan missen; Q&A kan fragmenten verkeerd lezen—fouten ",[25,214,215],{},"stapelen",[85,217,218,221,222,225],{},[25,219,220],{},"Statische context:"," Of de gebruiker naar één hoofdstuk of de hele boekstructuur vraagt, het model krijgt altijd ",[25,223,224],{},"dezelfde vooraf geëxtraheerde blob","—geen dynamische vernauwing per vraag.",[11,227,228,229,232],{},"Les: het probleem is niet «of we comprimeren», maar ",[25,230,231],{},"of compressie on demand is en of we terug kunnen naar brontekst",".",[54,234,236],{"id":235},"fase-3-segmentindex-tool-retrieval-on-demand-brontekst-terug-huidig","Fase 3: segmentindex + Tool-retrieval on demand + brontekst terug (huidig)",[11,238,239,241,242,249],{},[25,240,62],{}," Geïnspireerd door ",[243,244,248],"a",{"href":245,"rel":246},"https://github.com/VectifyAI/PageIndex",[247],"nofollow","PageIndex",". T.o.v. fase 2 drie kernverschuivingen:",[251,252,253,259,269],"ol",{},[85,254,255,258],{},[25,256,257],{},"Preprocessing levert een gestructureerde index"," (inhoudsopgave-samenvattingen + exacte character spans), geen fragmenten die direct als Q&A-context dienen;",[85,260,261,264,265,268],{},[25,262,263],{},"Bij elke vraag gebruikt het model Tool Calling om on demand te retrieven",", en ",[25,266,267],{},"haalt brontekst met positietags"," op om te antwoorden;",[85,270,271,274],{},[25,272,273],{},"System prompt + frontend"," dwingen het citatieformaat af en ondersteunen klik-naar-springen met markering in de reader.",[11,276,277],{},[25,278,279],{},"Vergelijking drie fasen:",[281,282,283,302],"table",{},[284,285,286],"thead",{},[287,288,289,293,296,299],"tr",{},[290,291,292],"th",{},"Dimensie",[290,294,295],{},"Fase 1 (volledige dump)",[290,297,298],{},"Fase 2 (sleutelzinnen)",[290,300,301],{},"Fase 3 (huidig)",[303,304,305,324,338,352,366,383],"tbody",{},[287,306,307,311,314,317],{},[308,309,310],"td",{},"Context per vraag",[308,312,313],{},"Heel boek (of afgekapt eerste deel)",[308,315,316],{},"Vooraf geëxtraheerde sleutelzinnen",[308,318,319,320,323],{},"Alleen ",[25,321,322],{},"bron","fragmenten relevant voor de vraag",[287,325,326,329,332,335],{},[308,327,328],{},"Nauwkeurigheid lange boeken",[308,330,331],{},"Ineenstorting na ~400k tekens",[308,333,334],{},"Hangt af van extractie; verliest detail",[308,336,337],{},"Opzoeken via TOC/span; geen harde truncatie van heel boek",[287,339,340,343,346,349],{},[308,341,342],{},"Reactiesnelheid",[308,344,345],{},"Traag",[308,347,348],{},"Iets beter; lange boeken nog traag",[308,350,351],{},"Retrieval + korte context—merkbaar sneller",[287,353,354,357,360,363],{},[308,355,356],{},"Tokenkosten",[308,358,359],{},"Zeer hoog",[308,361,362],{},"Middelhoog",[308,364,365],{},"Gespreid preprocess + betalen naar behoefte",[287,367,368,371,374,377],{},[308,369,370],{},"Traceerbaarheid",[308,372,373],{},"Zwak (moeilijk te citeren)",[308,375,376],{},"Tags bestaan maar inhoud is tweemaal gefilterd",[308,378,379,380],{},"Voetnoten verwijzen naar ",[25,381,382],{},"echte bronspans",[287,384,385,388,391,394],{},[308,386,387],{},"Engineeringcomplexiteit",[308,389,390],{},"Laag",[308,392,393],{},"Middel",[308,395,396],{},"Hoog",[11,398,399,402,403,406,407,410,411,414],{},[25,400,401],{},"Waarom we stopten bij fase 3:"," Voor lezen is nul hallucinatie niet «laat het model zoveel mogelijk tekst zien», maar ",[25,404,405],{},"«haal vóór het antwoorden bronbewijs op voor de vraag»",". Fase 1–2 vochten ",[25,408,409],{},"contextgrootte","; fase 3 splitst de pipeline in ",[25,412,413],{},"index (preprocess) → retrieve (Tool) → bewijs (bron) → antwoord (beperkte generatie)","—nauwkeurigheid, kosten en traceerbaarheid in balans.",[11,416,417,418,232],{},"Hieronder details van ",[25,419,420],{},"fase 3",[34,422],{},[37,424,426],{"id":425},"ii-probleemstelling-bij-boek-qa-is-hallucinatie-erger-dan-in-generieke-chat","II. Probleemstelling: bij boek-Q&A is hallucinatie erger dan in generieke chat",[11,428,429,430,433],{},"Gebruikers vergeven af en toe fouten in een algemene chatbot. Bij ",[25,431,432],{},"boek-Q&A"," is de prijs hoger:",[82,435,436,443,446],{},[85,437,438,439,442],{},"Gebruikers vragen wat ",[25,440,441],{},"dit boek"," zegt—niet wat in het parametrische geheugen van het model zit;",[85,444,445],{},"Een plausibel klinkende «mening uit het boek» kan notities, citaten en herdelingen misleiden;",[85,447,448],{},"Zonder bronnen kan de gebruiker niet verifiëren—vertrouwen is moeilijk op te bouwen.",[11,450,451,452,455],{},"«Nul hallucinatie» wordt daarom drie ",[25,453,454],{},"afdwingbare"," regels:",[251,457,458,464,470],{},[85,459,460,463],{},[25,461,462],{},"Boekvragen moeten eerst het boek raadplegen:"," Alles wat plausibel over het geopende boek gaat, moet via retrieval (Tool) vóór het antwoord;",[85,465,466,469],{},[25,467,468],{},"Antwoorden moeten traceerbaar zijn:"," Belangrijke conclusies dragen positietags die de UI kan parsen en naar kan springen;",[85,471,472,475],{},[25,473,474],{},"Zeg het wanneer je het niet vindt:"," Staat het niet in het boek, zeg dat—verkleed geen algemene kennis als «wat het boek zegt».",[11,477,478,479,481],{},"Het vervolg volgt de ",[25,480,420],{},"-datastroom en hoe deze regels worden geïmplementeerd.",[34,483],{},[37,485,487],{"id":486},"iii-architectuur-preprocess-tool-retrieval-beperkte-generatie-klikbare-bronverwijzingen","III. Architectuur: Preprocess → Tool-retrieval → Beperkte generatie → Klikbare bronverwijzingen",[49,489],{":config":51,"code":490},"flowchart%20TB%0A%20%20%20%20subgraph%20prep%20%5BOffline%20%2F%20eerste%20preprocess%5D%0A%20%20%20%20%20%20%20%20A%5BBoek%20splitsen%20op%20TOC%20of%20lengte%5D%20--%3E%20B%5BLLM%20segment-samenvattingen%5D%0A%20%20%20%20%20%20%20%20B%20--%3E%20C%5BSegment-cache%20lokaal%20persistent%20maken%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20ask%20%5BGebruikersvraag%5D%0A%20%20%20%20%20%20%20%20D%5BGebruikersinvoer%5D%20--%3E%20E%7BSegment-cache%20bestaat%3F%7D%0A%20%20%20%20%20%20%20%20E%20--%3E%7CNee%7C%20F%5BVolledige%20tekst%20extraheren%20%2F%20vragen%20om%20preprocess%5D%0A%20%20%20%20%20%20%20%20F%20--%3E%20prep%0A%20%20%20%20%20%20%20%20E%20--%3E%7CJa%7C%20G%5BTool%20Calling%20registreren%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20retrieve%20%5BTool-retrieval%5D%0A%20%20%20%20%20%20%20%20G%20--%3E%20H%7BVraagtype%7D%0A%20%20%20%20%20%20%20%20H%20--%3E%7COverzicht%20%2F%20recensie%7C%20I%5Bget_full_book_segment_summaries%5D%0A%20%20%20%20%20%20%20%20H%20--%3E%7CFeiten%20%2F%20personen%20%2F%20hoofdstuk%7C%20J%5Bget_related_segment_summaries%5D%0A%20%20%20%20%20%20%20%20J%20--%3E%20K%5BLLM%20kiest%20segment-ID's%20uit%20samenvattingscatalogus%5D%0A%20%20%20%20%20%20%20%20K%20--%3E%20L%5BBron%20ophalen%20per%20span%20%2B%20positietags%5D%0A%20%20%20%20%20%20%20%20I%20--%3E%20M%5BAlle%20segment-samenvattingen%20samenvoegen%5D%0A%20%20%20%20end%0A%0A%20%20%20%20subgraph%20answer%20%5BGenereren%20%26%20tonen%5D%0A%20%20%20%20%20%20%20%20L%20--%3E%20N%5BTool-resultaten%20terug%20naar%20model%5D%0A%20%20%20%20%20%20%20%20M%20--%3E%20N%0A%20%20%20%20%20%20%20%20N%20--%3E%20O%5BSystem%20prompt%20citatieregels%5D%0A%20%20%20%20%20%20%20%20O%20--%3E%20P%5BAntwoord%20streamen%20%2B%20positie-voetnoten%5D%0A%20%20%20%20%20%20%20%20P%20--%3E%20Q%5BKlikbare%20voetnoten%20renderen%5D%0A%20%20%20%20%20%20%20%20Q%20--%3E%20R%5BKlik%20%E2%86%92%20preview%20%E2%86%92%20spring%20%26%20markeer%5D%0A%20%20%20%20end",[11,492,493,494],{},"Kernidee: ",[25,495,496],{},"laat het model niet «uit het geheugen antwoorden»—laat het «bewijs verzamelen, dan antwoorden, en bronnen markeren».",[34,498],{},[37,500,502],{"id":501},"iv-preprocessing-het-hele-boek-omzetten-in-een-doorzoekbare-segmentindex","IV. Preprocessing: het hele boek omzetten in een doorzoekbare segmentindex",[11,504,505,506,509,510,513,514,517,518,521,522,525],{},"Als elke vraag nog ",[25,507,508],{},"fase 1"," volledige boekcontext gebruikte, exploderen tokenbudgetten bij lange boeken en is retrieval te grof. Fase 3: bij de eerste AI-chat voor een boek draait op de achtergrond een ",[25,511,512],{},"segment-samenvattingstaak","—splitsen op ",[25,515,516],{},"TOC"," of ",[25,519,520],{},"tekstlengte"," in ",[154,523,524],{},"Segment","s, elk samenvatten, persistent in lokale IndexedDB.",[11,527,528,529,531,532,535],{},"Elk ",[154,530,524],{}," bevat samenvatting plus ",[25,533,534],{},"fysieke positie in de hoofdtekst",":",[281,537,538,548],{},[284,539,540],{},[287,541,542,545],{},[290,543,544],{},"Veld",[290,546,547],{},"Betekenis",[303,549,550,564,577,587],{},[287,551,552,561],{},[308,553,554,557,558],{},[154,555,556],{},"startFileIndex"," / ",[154,559,560],{},"endFileIndex",[308,562,563],{},"Spine-bestandsindex (PDF: één bestand per pagina)",[287,565,566,574],{},[308,567,568,557,571],{},[154,569,570],{},"startOffset",[154,572,573],{},"endOffset",[308,575,576],{},"Teken begin/einde",[287,578,579,584],{},[308,580,581],{},[154,582,583],{},"sequence",[308,585,586],{},"Lineaire leesvolgorde",[287,588,589,594],{},[308,590,591],{},[154,592,593],{},"title",[308,595,596],{},"TOC-titel",[11,598,599],{},"Splitsen balanceert precisie en kosten: is de hoofdtekst van een TOC-node onder ~20KB, alleen die node samenvatten; sibling-nodes kunnen in batches (15–20KB) vóór LLM-aanroepen; ongestructureerde lange blokken splitsen in ~30–40k tekens.",[11,601,602,603,606,607,610],{},"De samenvattingssystem prompt vereist ",[25,604,605],{},"behoud van inline positietags"," (",[154,608,609],{},"[fNummer-Nummer-Nummer]",") zodat door Tool opgehaalde bron overeenkomt met spine-offsets. Kernbeperking:",[612,613,619],"pre",{"className":614,"code":616,"language":617,"meta":618},[615],"language-text","Als samenvattingsinhoud betrekking heeft op een passage, behoud de positietag aan het einde [fNummer-Nummer-Nummer] (bijv. [f1-90-109]).\nTags zijn atomair—wijzig, voeg samen of laat geen enkel teken of cijfer weg.\n","text","",[154,620,616],{"__ignoreMap":618},[11,622,623,624,627],{},"Na preprocessing hangt Q&A af van een ",[25,625,626],{},"gestructureerde segmentindex",", niet van hele-boek-context—de engineeringvoorwaarde voor nul hallucinatie bij lange boeken.",[34,629],{},[37,631,633],{"id":632},"v-positietagsysteem-waar-in-tekst-coderen","V. Positietagsysteem: «waar» in tekst coderen",[11,635,636,637,640,641,644],{},"Nul hallucinatie vereist inhoud uit de bron ",[25,638,639],{},"én"," machine-parseerbare, in de UI springbare ",[25,642,643],{},"herkomst",". We gebruiken inline tags:",[612,646,649],{"className":647,"code":648,"language":617},[615],"[f{fileIndex}-{startChar}-{endChar}]\n",[154,650,648],{"__ignoreMap":618},[11,652,653,654,657],{},"Voorbeeld: ",[154,655,656],{},"[f5-123-165]"," = spine-bestand 5 (0-based), tekens 123–165.",[54,659,661],{"id":660},"_51-hoe-tags-in-de-hoofdtekst-worden-geschreven","5.1 Hoe tags in de hoofdtekst worden geschreven",[11,663,664,665,668],{},"De extractielaag voegt aan segmenteinden ",[154,666,667],{},"[f{fileIndex}-{start}-{end}]"," toe:",[612,670,675],{"className":671,"code":673,"language":674,"meta":618},[672],"language-typescript","const position = `[f${fileIndex}-${absOffset}-${absOffset + segment.length}]`;\nfileLines.push(segment.text.trim() + position);\n","typescript",[154,676,673],{"__ignoreMap":618},[11,678,679,680,683],{},"Of het nu preprocess-samenvattingen of Tool-fragmenten zijn: posities sluiten aan op ",[25,681,682],{},"spine-tekenoffsets","—geen door het model geschatte paginanummers.",[54,685,687],{"id":686},"_52-beperkingen-op-modeloutput","5.2 Beperkingen op modeloutput",[11,689,690,691,697],{},"De system prompt bevat ",[25,692,693],{},[694,695,696],"span",{},"Position Citation Rules","—vijf kernpunten:",[251,699,700,710,720,726,735],{},[85,701,702,705,706,709],{},[25,703,704],{},"Standaardformaat:"," Moet ",[154,707,708],{},"[f_fileIndex-startChar-endChar]"," gebruiken; alle drie numerieke delen verplicht;",[85,711,712,715,716,719],{},[25,713,714],{},"Alleen kopiëren uit huidige bronnen:"," Voetnoten moeten ",[25,717,718],{},"letterlijk"," uit system/user-berichten of Tool-returns van deze beurt komen;",[85,721,722,725],{},[25,723,724],{},"Geen verzinsels:"," Bereken, bewerk of verzin geen posities;",[85,727,728,731,732,206],{},[25,729,730],{},"Liever weglaten:"," Geen geldige tag in context—antwoord normaal—",[25,733,734],{},"geen positietags outputten",[85,736,737,740],{},[25,738,739],{},"Inline bij uitspraken:"," Tags volgen de relevante zin; geen citatielijsten aan het einde.",[11,742,743,744,747,748,751],{},"De UI filtert ook incidentele ",[25,745,746],{},"tweedelige"," ongeldige tags (bijv. ",[154,749,750],{},"[f1-293]",") vóór render.",[11,753,754],{},[14,755],{"alt":756,"src":757},"Popup bronverwijzing","https://cdn.linghuxiong.com/resources/snapshots/ai-chat.png",[34,759],{},[37,761,763],{"id":762},"vi-tool-calling-eerst-retrieven-dan-antwoorden","VI. Tool Calling: eerst retrieven, dan antwoorden",[11,765,766,767,770,771,774,775,232],{},"Wanneer chat aan een boek is gekoppeld (",[154,768,769],{},"resourceId"," aanwezig, ",[154,772,773],{},"chatType === 'chat'","), registreren we vóór elke generatie twee Tools met executors—standaard OpenAI-achtige ",[25,776,777],{},"function calling loop",[54,779,781,782,785],{"id":780},"_61-get_related_segment_summaries-gerichte-segmentlookup","6.1 ",[154,783,784],{},"get_related_segment_summaries"," — gerichte segmentlookup",[11,787,788,789,232],{},"Voor: concepten, personages, plot, hoofdstukdetails—",[25,790,791],{},"duidelijke retrieval-intentie",[11,793,794],{},"Flow:",[251,796,797,804,810,813,823],{},[85,798,799,800,803],{},"Model herschrijft gebruikersformulering naar ",[25,801,802],{},"termen die waarschijnlijk in het boek voorkomen"," («Optimize Search Queries» in system prompt);",[85,805,806,807,206],{},"Tool aanroepen met ",[154,808,809],{},"question",[85,811,812],{},"Alle segment-samenvattingen batchen op tokenbudget (~30k tokens per batch, max 5 batches);",[85,814,815,816,819,820,206],{},"Per batch: apart LLM-verzoek kiest relevante segment-ID's (max 5) uit ",[154,817,818],{},"{ id, title, summary }",", JSON zoals ",[154,821,822],{},"{\"Thinking\":\"...\",\"answer\":[\"1\",\"3\"]}",[85,824,825,826,829],{},"Voor geselecteerde segmenten ",[25,827,828],{},"getagde brontekst"," uit spine ophalen—geen samenvattingen—als Tool-resultaat.",[11,831,832,835,836,839],{},[25,833,834],{},"Kernontwerp: Tool retourneert bron, geen samenvattingen."," Het model antwoordt van echte alinea's met inline ",[154,837,838],{},"[f…]",", vermijdt «samenvatting → hersamenvatting»-drift.",[54,841,843,844,847],{"id":842},"_62-get_full_book_segment_summaries-heel-boek-overzicht","6.2 ",[154,845,846],{},"get_full_book_segment_summaries"," — heel-boek-overzicht",[11,849,850,851,232],{},"Voor: «vat het boek samen», «recenseer dit boek», «algemene structuur/thema's»—",[25,852,853],{},"globaal beeld",[11,855,856,857,860],{},"Alle segment-",[154,858,859],{},"summary","-velden in leesvolgorde samenvoegen—voorkomt missen van sleutelhoofdstukken via alleen per-chunk relevantie.",[54,862,864],{"id":863},"_63-system-prompt-book-first-tools-first","6.3 System prompt: Book first, tools first",[11,866,867,868,535],{},"Met gekoppeld boek geldt ",[25,869,870],{},[694,871,872],{},"Core Principles for Reading Assistant",[612,874,877],{"className":875,"code":876,"language":617},[615],"1. Book First, Tool First\n   - Elke vraag die mogelijk over het boek gaat, moet eerst tools aanroepen;\n   - Antwoorden moeten vooral op retrieval steunen—nooit «boekinhoud» verzinnen zonder retrieval.\n\n2. General Knowledge as Fallback Only\n   - Alleen voor: informele chat / gebruiker slaat boek expliciet over / tools geven niets;\n   - Staat het niet in het boek, zeg «niet vermeld in dit boek» vóór algemene kennis.\n\n3. Direct Style\n   - Ga direct ter zake—vermijd «op basis van de aangeleverde materialen…» en vergelijkbare opvulling.\n",[154,878,876],{"__ignoreMap":618},[11,880,881,882,885,886,889],{},"Generatie draait de tool-loop: ",[154,883,884],{},"tool_calls"," → uitvoeren → ",[154,887,888],{},"role: tool"," toevoegen → doorgaan tot definitieve tekst. Met tools aan staat het thinking-kanaal uit om protocolconflicten te vermijden.",[34,891],{},[37,893,895],{"id":894},"vii-frontend-traceerbaarheid-van-voetnoot-naar-markering","VII. Frontend-traceerbaarheid: van voetnoot naar markering",[11,897,898,899,901],{},"Modeloutput ",[154,900,656],{}," wordt niet rauw getoond; de renderlaag maakt er klikbare citaten van.",[54,903,905],{"id":904},"_71-voetnoten-renderen","7.1 Voetnoten renderen",[11,907,908,909,912],{},"Tags normaliseren naar Markdown-links zoals ",[154,910,911],{},"[1]([f5-123-165])",", renderen als genummerde voetnoten; deduplicatie van dezelfde positie tegen UI-rommel.",[54,914,916],{"id":915},"_72-klikinteractie","7.2 Klikinteractie",[251,918,919,928,934],{},[85,920,921,924,925,927],{},[25,922,923],{},"Eerste klik:"," Parse ",[154,926,838],{}," → fileIndex + offsets → spine-tekst extraheren → preview (optioneel TOC-titel);",[85,929,930,933],{},[25,931,932],{},"Zelfde voetnoot opnieuw:"," Preview sluiten;",[85,935,936,939],{},[25,937,938],{},"Spring bevestigen:"," Leesweergave openen, tekenbereik markeren.",[11,941,942,943,946],{},"Van gekopieerde modeltag tot zichtbare bron voor de gebruiker: de keten ",[25,944,945],{},"gaat nooit door een tweede LLM-aanroep","—deterministisch en reproduceerbaar.",[34,948],{},[37,950,952],{"id":951},"viii-randgevallen-en-eerlijke-degradatie","VIII. Randgevallen en eerlijke degradatie",[11,954,955,956,535],{},"Nul hallucinatie ≠ «altijd een antwoord»—het betekent ",[25,957,958],{},"geen bewijs, geen verzinsels",[281,960,961,971],{},[284,962,963],{},[287,964,965,968],{},[290,966,967],{},"Scenario",[290,969,970],{},"Gedrag",[303,972,973,981,993,1001,1009],{},[287,974,975,978],{},[308,976,977],{},"Segment-samenvattingen nog niet klaar",[308,979,980],{},"Eerst volledige tekst extraheren en samenvatten",[287,982,983,986],{},[308,984,985],{},"Tool vindt niets",[308,987,988,989,992],{},"Retourneer ",[154,990,991],{},"(No relevant segment excerpts found…)","; model moet zeggen dat het niet in het boek staat",[287,994,995,998],{},[308,996,997],{},"Ongeldige tweedelige tags van model",[308,999,1000],{},"Frontend filtert; geen kapotte voetnoten",[287,1002,1003,1006],{},[308,1004,1005],{},"Informele chat",[308,1007,1008],{},"System prompt staat algemene kennis buiten het boek toe",[287,1010,1011,1014],{},[308,1012,1013],{},"Chat exporteren",[308,1015,1016],{},"Voetnoten kunnen reader-deeplinks worden voor delen/archiveren",[11,1018,1019],{},[14,1020],{"alt":1013,"src":1021},"https://cdn.linghuxiong.com/resources/snapshots/ai-chat-export.png",[34,1023],{},[37,1025,1027],{"id":1026},"ix-ontwerpafweging-waarom-geen-vector-rag","IX. Ontwerpafweging: waarom geen «vector RAG»?",[11,1029,1030,1031,1034],{},"Peers die document-Q&A bouwen vragen vaak: als je retrieval-augmented generation doet, waarom geen ",[25,1032,1033],{},"Embedding + vector DB Top-K","?",[11,1036,1037,1038,1041,1042,1045,1046,1049,1050,1053],{},"We ",[25,1039,1040],{},"doen RAG","—retrieven vóór genereren. Het verschil: «RAG» in communitytaal impliceert vaak ",[25,1043,1044],{},"vector-gelijkenis","; onze fase 3 is ",[25,1047,1048],{},"segmentindex + Tool on-demand bronpull","—",[25,1051,1052],{},"bewust geen vectorlaag",". Hieronder architecturale redenen, geen ontkenning van de waarde van vector RAG.",[54,1055,1057],{"id":1056},"scope-niet-geen-retrieval-maar-geen-vector-retrieval","Scope: niet «geen retrieval», maar «geen vector-retrieval»",[82,1059,1060,1069],{},[85,1061,1062,1065,1066,206],{},[25,1063,1064],{},"Brede RAG:"," ophalen → genereren → ",[25,1067,1068],{},"dat doen we",[85,1070,1071,1074,1075,232],{},[25,1072,1073],{},"Vector RAG:"," recall via embedding-gelijkenis → ",[25,1076,1077],{},"niet in deze versie",[11,1079,1080,1081,1084,1085,1088],{},"Preprocessing bouwt een ",[25,1082,1083],{},"segment-samenvattingsindex","; het model kiest segmenten via Tools en krijgt ",[25,1086,1087],{},"brontekst",". Retrieval bestaat zonder apart embedding-model en vectorindex-onderhoud.",[34,1090],{},[54,1092,1094],{"id":1093},"reden-1-aangepaste-llm-providershoud-het-integratieoppervlak-klein","Reden 1: aangepaste LLM-providers—houd het integratieoppervlak klein",[11,1096,1097,1098,1101,1102,1105],{},"Gebruikers kunnen ",[25,1099,1100],{},"eigen API-keys",", custom base URL's of ",[25,1103,1104],{},"lokale Ollama"," koppelen—chatmodel is hun keuze; kosten en datapad blijven onder controle.",[11,1107,1108],{},"Typische vector RAG verbreedt integratie:",[82,1110,1111,1122,1125],{},[85,1112,1113,1114,1117,1118,1121],{},"Naast ",[25,1115,1116],{},"chatmodel"," meestal een ",[25,1119,1120],{},"embeddingmodel"," (andere naam, soms ander endpoint);",[85,1123,1124],{},"Lokale Ollama heeft apart embeddingmodel plus dimensie/API-compatibiliteit;",[85,1126,1127,1128,1131],{},"Meer faalmodi: chat werkt maar ",[25,1129,1130],{},"lege retrieval","—embedding, index of dimensiemismatch; moeilijker te debuggen dan één provider end-to-end.",[11,1133,1134,1135,1138,1139,1142],{},"Hier delen ",[25,1136,1137],{},"segmentkeuze en antwoorden één providerconfig","—geen «chat op A, index op B». Voor ",[25,1140,1141],{},"plug-in LLM","-apps weegt dat vaak zwaarder dan enkele recallpunten.",[11,1144,1145],{},[14,1146],{"alt":1147,"src":1148},"Aangepaste AI-providers","https://cdn.linghuxiong.com/resources/snapshots/ai-customize-providers.png",[34,1150],{},[54,1152,1154],{"id":1153},"reden-2-embeddings-binden-aan-de-indexproviderwissels-zijn-duur","Reden 2: embeddings binden aan de index—providerwissels zijn duur",[11,1156,1157,1158,1161,1162,1165,1166,1169],{},"In vector RAG zijn ",[25,1159,1160],{},"vectoren geen universeel tussenformaat","—het zijn coördinaten onder één embeddingmodel. Index met A, query met B: gelijkenis is meestal ",[25,1163,1164],{},"niet vergelijkbaar","—vaak ",[25,1167,1168],{},"volledige her-embedding",", en dimensies (768 / 1024 / 1536 …) vergrendelen het opslagschema.",[11,1171,1172,1173,1176,1177,1180],{},"Fase 3 persist ",[25,1174,1175],{},"gestructureerde samenvattingen + character spans",", geen vectoren; chatmodel wisselen ",[25,1178,1179],{},"bouwt de index niet opnieuw","; bewijsketen (bronposities) blijft gelijk—in lijn met «probeer anytime verschillende LLM's».",[34,1182],{},[54,1184,1186],{"id":1185},"reden-3-gestructureerde-routing-is-vaak-genoeg-voor-toc-zware-lange-docs","Reden 3: gestructureerde routing is vaak genoeg voor TOC-zware lange docs",[11,1188,1189,1190,1193,1194,1197,1198,1201,1202,1207],{},"E-boeken en PDF's hebben meestal ",[25,1191,1192],{},"hoofdstukstructuur","; preprocessing levert ",[25,1195,1196],{},"segmenttitels + samenvattingen",". Voor «wat zegt hoofdstuk X» of «hoe definieert het boek Y» werkt segmentkeuze uit de catalogus en dan ",[25,1199,1200],{},"bron ophalen"," stabiel in de praktijk; Tool retourneert ",[25,1203,1204,1205],{},"bron met ",[154,1206,838],{},", dus nul hallucinatie blijft verankerd op character spans.",[11,1209,1210,1211,1214,1215,1218],{},"Vectoren helpen bij vage semantiek, meertaligheid, lange letterlijke mismatch; voor readers met ",[25,1212,1213],{},"TOC + preprocess + sterke traceerbaarheid"," is investeren in ",[25,1216,1217],{},"Tool + bronreturn + citatieregels"," vaak betere ROI.",[34,1220],{},[54,1222,1224],{"id":1223},"toekomst-hybride-recall-geen-herschrijving","Toekomst: hybride recall, geen herschrijving",[11,1226,1227,1228,1231,1232,1235,1236,1239,1240,1243],{},"We kunnen ",[25,1229,1230],{},"vector grove recall"," toevoegen (embedding alleen voor Top-N hoofdstukkandidaten), nog steeds eindigend in ",[25,1233,1234],{},"segment kiezen → bron → klikbare trace","—nul-hallucinatieregels ongewijzigd. Indien toegevoegd: embedding ",[25,1237,1238],{},"optioneel",", expliciete ",[25,1241,1242],{},"her-index","-meldingen bij modelwissel—vermijd stille verkeerde retrieval.",[11,1245,1246,1247],{},"Tot dan: ",[25,1248,1249],{},"elke OpenAI-compatibele chat-API werkt; chatmodel wisselen herbouwt de lokale index niet.",[34,1251],{},[37,1253,1255],{"id":1254},"x-samenvatting","X. Samenvatting",[281,1257,1258,1271],{},[284,1259,1260],{},[287,1261,1262,1265,1268],{},[290,1263,1264],{},"Stap",[290,1266,1267],{},"Methode",[290,1269,1270],{},"Rol",[303,1272,1273,1284,1297,1311,1322,1333],{},[287,1274,1275,1278,1281],{},[308,1276,1277],{},"Preprocess",[308,1279,1280],{},"Splitsen op TOC/lengte + segment-samenvattingcache",[308,1282,1283],{},"Lange boeken doorzoekbaar & lokaliseerbaar",[287,1285,1286,1289,1294],{},[308,1287,1288],{},"Positietags",[308,1290,1291,1293],{},[154,1292,156],{}," in bron",[308,1295,1296],{},"Machine-parseerbare herkomst",[287,1298,1299,1302,1308],{},[308,1300,1301],{},"Tool-retrieval",[308,1303,1304,1305,1307],{},"Per vraag segmenten / heel-boek-samenvattingen, ",[25,1306,322],{}," terug",[308,1309,1310],{},"Bewijs afdwingen vóór antwoord",[287,1312,1313,1316,1319],{},[308,1314,1315],{},"System prompt",[308,1317,1318],{},"Book first, geen valse tags, zeg wanneer ontbreekt",[308,1320,1321],{},"Generatie beperken",[287,1323,1324,1327,1330],{},[308,1325,1326],{},"Frontend",[308,1328,1329],{},"Voetnoot → preview → spring & markeer",[308,1331,1332],{},"Gebruiker verifieert bewijs",[287,1334,1335,1338,1341],{},[308,1336,1337],{},"Geen vector-retrieval",[308,1339,1340],{},"Eén provider; chatmodel wisselen zonder re-index",[308,1342,1343],{},"Lagere integratie- & migratiekosten",[11,1345,1346,1347,1350],{},"«Nul hallucinatie» betekent niet dat het model nooit fout gaat—het betekent ",[25,1348,1349],{},"engineering die output aan een bewijsketen koppelt",": geen retrieval → niet doen alsof het boekinhoud is; met retrieval → verifieerbare bronposities geven.",[11,1352,1353,1354,1357,1358,1361],{},"Als je AI-lezen of document-Q&A bouwt, hopen we dat het pad ",[25,1355,1356],{},"volledige dump → sleutelzinnen → Tool-first on demand retrieval",", plus ",[25,1359,1360],{},"inline positietags + bronreturn",", een nuttige referentie-implementatie is.",[19,1363,1364],{},[11,1365,1366,1367,1372,1373,232],{},"Dit zijn lessen uit het bouwen van de ",[243,1368,1371],{"href":1369,"rel":1370},"https://reader.linghuxiong.com",[247],"Foxycape"," AI-reader—alleen ter referentie. Probeer de reader op de ",[243,1374,1376],{"href":1375},"/nl-nl#download","downloadpagina",{"title":618,"searchDepth":1378,"depth":1378,"links":1379},2,[1380,1386,1387,1388,1389,1393,1400,1404,1405,1412],{"id":39,"depth":1378,"text":40,"children":1381},[1382,1384,1385],{"id":56,"depth":1383,"text":57},3,{"id":138,"depth":1383,"text":139},{"id":235,"depth":1383,"text":236},{"id":425,"depth":1378,"text":426},{"id":486,"depth":1378,"text":487},{"id":501,"depth":1378,"text":502},{"id":632,"depth":1378,"text":633,"children":1390},[1391,1392],{"id":660,"depth":1383,"text":661},{"id":686,"depth":1383,"text":687},{"id":762,"depth":1378,"text":763,"children":1394},[1395,1397,1399],{"id":780,"depth":1383,"text":1396},"6.1 get_related_segment_summaries — gerichte segmentlookup",{"id":842,"depth":1383,"text":1398},"6.2 get_full_book_segment_summaries — heel-boek-overzicht",{"id":863,"depth":1383,"text":864},{"id":894,"depth":1378,"text":895,"children":1401},[1402,1403],{"id":904,"depth":1383,"text":905},{"id":915,"depth":1383,"text":916},{"id":951,"depth":1378,"text":952},{"id":1026,"depth":1378,"text":1027,"children":1406},[1407,1408,1409,1410,1411],{"id":1056,"depth":1383,"text":1057},{"id":1093,"depth":1383,"text":1094},{"id":1153,"depth":1383,"text":1154},{"id":1185,"depth":1383,"text":1186},{"id":1223,"depth":1383,"text":1224},{"id":1254,"depth":1378,"text":1255},null,"2026-06-03","Technische notities over nul-hallucinatie Q&A in een AI-reader—antwoorden gebaseerd op de huidige boektekst, met bronverwijzingen in één klik naar exacte passages.",false,"md",{},true,"/nl-nl/blog/zero-hallucination-qa",{"title":6,"description":1415},"nl-nl/blog/zero-hallucination-qa",[1424,1425,1426],"reader","AI","techniek","zero-hallucination-qa","gxMYlJfB8eAB7BakuNSIisf_FYey7WhkraYR1nVl0LQ",1780489852838]