Ga naar inhoud

Geheugen en kennis

Zonder geheugen begint elk gesprek met een agent weer bij nul: dezelfde conventie moet opnieuw worden uitgelegd, dezelfde beslissing opnieuw worden bediscussieerd, hetzelfde doodlopende spoor opnieuw worden verkend. Geheugen is de opslag die aan de werkruimte is gebonden en runs overleeft, en het bestaat zodat kennis die de ene agent heeft geproduceerd, later door een andere agent vindbaar is.

Het kent drie lagen, die elk een andere vraag beantwoorden:

  1. Feiten — wat waar is (een conventie, een uitkomst, een beslissing).
  2. Beleidsregels — wat agenten ermee moeten doen (een normatieve regel).
  3. Werkgeheugen — waar één agent middenin zat.

Het onderscheid is belangrijk omdat ze via verschillende routes bij de agent terechtkomen. Feiten worden gezocht. Beleidsregels worden gepusht. Werkgeheugen is privé.

Een MemoryFact is een kenniseenheid die is gebonden aan een werkruimte en een domein.

Attribuut Wat het is
domain Het kennisdomein (“conventions”, “decisions”, “codebase”)
topic Een kort onderwerplabel
content De kennistekst
confidence 0.0–1.0, gevoed door de herkomst en verhoogd bij elke nieuwe vermelding
memoryType Het soort feit — bepaalt de temporele vervalcurve
veracity Hoe het bekend is geworden — bepaalt het beginvertrouwen en de grootte van elke verhoging bij een nieuwe vermelding
sourceObservationIds Welke observaties ernaartoe hebben geleid
supersededBy Het nieuwere feit dat het heeft vervangen, indien aanwezig
validUntil, recallCount, mentionCount Verval- en gebruikssignalen die bij het ophalen worden gebruikt

De laatste twee rijen worden vaak over het hoofd gezien, en juist zij bepalen welk feit boven komt drijven. memoryType bevat Weibull-vervalparameters per type, waardoor een aan een termijn gebonden toezegging snel vervaagt en een stabiel profielfeit niet. veracity legt de herkomst vast — uitgesproken door een mens (weging 1.0), afgeleid door een agent (0.7), geproduceerd door een tool (0.5), geïmporteerd (0.6) — en die weging bepaalt het beginvertrouwen van het feit.

Feiten worden nooit ter plekke bewerkt als ze worden tegengesproken. Bij het schrijven van een feit wordt conflictdetectie uitgevoerd tegen feiten in hetzelfde domein met hetzelfde onderwerp, waarna de verliezer wordt vervangen en er een conflictrij wordt vastgelegd. Het auditspoor is juist het doel: je kunt altijd zien wat eerder werd geloofd en wat daarvoor in de plaats kwam.

Een MemoryPolicy is een normatieve regel die uit feiten is afgeleid, gebonden aan een werkruimte en een domein, met een vlag voor actief en een optionele requiredRole.

Elke actieve beleidsregel in de werkruimte wordt bij elke dispatch geïnjecteerd, ongefilterd — er wordt niet gefilterd op domein, rol, taak of ruimte. Dit is goed om te weten voordat je je twintigste beleidsregel schrijft, want beleidsregels concurreren om hetzelfde contextvenster als de taak. Het is ook de reden waarom requiredRole op een beleidsregel adviserend is: het beschrijft op wie de regel is gericht, maar het houdt niet tegen dat de regel iedereen bereikt.

Een MemoryDomain groepeert feiten en beleidsregels binnen een werkruimte. Domeinen geven kennis een organisatorische structuur en ze zijn de eenheid waartegen toegangsverleningen worden geschreven — maar lees de waarschuwing hieronder voordat je een domein als vertrouwelijkheidsgrens behandelt.

Een domein is ofwel werkruimtebreed (architecture) ofwel gebonden aan één repository (repo:<slug>/architecture). Dezelfde naam in beide bereiken staat voor twee onafhankelijke opslagen: een feit dat geldt voor de ene codebase overschrijft niet het werkruimtebrede feit. search_memory en de dispatch-preamble rangschikken geheugen dat aan de repository is gebonden bovenaan wanneer de agent in die repository werkt; ze filteren de rest niet weg. Geef repo mee aan propose_fact / propose_policy / search_memory om naar dat bereik te schrijven of het te versterken.

MemoryAccessGrant koppelt een agentrol en een domein aan een van drie machtigingsniveaus:

Machtiging Betekenis
none Geen toegang
read Kan feiten zoeken en ophalen
write Vereist voor propose_policy. Het schrijven van feiten (propose_fact, supersede_fact) is niet aan een machtiging gebonden

De asymmetrie — soepel bij lezen, streng bij het schrijven van beleidsregels — is een bewuste afweging. Geheugen is het nuttigst wanneer het circuleert, en een geweigerde leesactie levert een agent op die stilletjes minder weet, in plaats van een agent die een probleem meldt. Een geweigerde beleidsregel-schrijfactie is daarentegen luidruchtig en corrigeerbaar, dus daar zit de handhaving. Een nieuw aangemaakt domein kent write toe aan elke rol; dat later aanscherpen is een bewerking die alleen via RPC kan, omdat er geen UI voor toegangsverleningen is.

Elke agent heeft een AgentWorkingMemory: een kladblok met vrije tekst, met werkruimte en agent als sleutel. Het blijft bestaan tussen runs, is privé voor die agent en wordt bij elke dispatch in zijn prompt geïnjecteerd. Hier leeft “ik was halverwege het refactoren van auth” — de toestand die het waard is om mee te nemen naar de volgende run, maar niet om te promoveren naar een blijvend feit.

Wat er daadwerkelijk in de prompt van een agent terechtkomt

Sectie getiteld “Wat er daadwerkelijk in de prompt van een agent terechtkomt”

Bij een dispatch wordt de geheugenpreamble samengesteld uit precies drie dingen:

  • Elke actieve beleidsregel in de werkruimte, als regels - [domain] rule.
  • Het eigen werkgeheugen van de agent, letterlijk.
  • Een op trefwoorden gematchte shortlist van feiten voor deze taak — maximaal vijf, binnen een budget van ~1.200 tekens en alleen wanneer de taakomschrijving minstens 20 tekens lang is. Kortere taken krijgen helemaal geen feiten.

De shortlist is uitsluitend FTS/trefwoordgebaseerd en is bewust begrensd. Een query embedden is traag, en het dispatchpad is bij uitstek de plek waar latentie direct zichtbaar is; daarom wordt het trage semantische pad er bewust buiten gehouden. De preamble sluit af met de instructie aan de agent om dragende items te verifiëren met search_memory, waar het volledige ophaalmodel zit.

Op dit pad worden geen toegangsverleningen geraadpleegd. Wat de shortlist ook vindt, dat is wat de agent ziet.

De search_memory-tool die de agent gebruikt heeft drie modi, en dat zijn echt verschillende zoekacties:

  • keyword — alleen FTS5.
  • semantic — BM25- en vectorresultaten samengevoegd met reciprocal rank fusion.
  • hybrid (de standaard) — polyfoon ophalen: vier gerangschikte stemmen die worden samengevoegd en vervolgens gediversifieerd.

De vier stemmen zijn lexicaal (FTS), semantisch (vector-KNN), temporeel (recent actieve feiten) en grafisch — een wandeling van twee hops over episodische randen vanaf de sterkste lexicale en semantische seeds. De grafische stem is de reden dat episodische randen überhaupt bestaan: hij haalt het feit naar boven dat verbonden is met je antwoord zonder een van je woorden te matchen. De stemmen worden gewogen op basis van een geclassificeerde query-intentie (semantisch weegt standaard het zwaarst, dan grafisch en lexicaal, dan recentheid), de score van elke kandidaat wordt geschaald met zijn Weibull-verval, en de resultatenset wordt met MMR gediversifieerd, zodat vijf herformuleringen van één feit vier andere niet verdringen.

Het zoeken in geheugen op desktop en web is een apart, eenvoudiger pad: de RPC-operatie memory_fact.search is alleen FTS5, omdat een thin client geen query-embedding kan meesturen en het hybride pad intern op de host blijft. De rangschikking die je in de geheugenbrowser ziet, is dus niet de rangschikking die een agent via search_memory krijgt. Dat is verwacht gedrag, geen bug, maar het betekent wel dat “ik heb gezocht en het niet gevonden” in de UI geen bewijs is dat de agent het niet zal vinden.

De geheugenbrowser staat onder Instellingen → Werkruimte → Geheugen (/workspaces/<id>/settings/memory), met de tabbladen Feiten, Beleid en Kennisgrafiek.

Er zit daar een asymmetrie die mensen verrast: je kunt geheugen bewerken en verwijderen, maar niet aanmaken. Noch het tabblad Feiten, noch het tabblad Beleid heeft een mogelijkheid om iets toe te voegen. Het schrijven gebeurt aan de agentkant, via propose_fact en propose_policy (supersede_fact / supersede_policy om ze te vervangen). remember schrijft een aan de sessie gebonden item in de hot-tier dat consolidate_memory later tot een feit kan promoveren; record_observation en update_my_notes schrijven het privékladblok dat bij een dispatch wordt geïnjecteerd. De browser is een oppervlak om te controleren en te corrigeren, niet om te schrijven — dus als je een feit in het geheugen wilt, is de manier om het erin te krijgen: het aan een agent vertellen.

Twee onderhoudsbewerkingen worden eveneens door een agent aangeroepen in plaats van gepland: consolidate_memory voegt opgebouwde feiten samen en snoeit ze, en harmonize_memory brengt overtuigingen die tussen agents uiteenliepen weer met elkaar in overeenstemming. list_memory_conflicts toont wat conflictdetectie al heeft vastgelegd. Niets voert ze voor je uit op een timer. Beslissingen uit vergaderingen worden geoogst in het domein decisions wanneer een persist-stap van een vergadering ze vastlegt; dat is geen timer die op afgeronde agent-runs draait.