- Je bewaart context met expliciete herkomst, taakscope, tijd en versie.
- Je voorkomt in de oefenselector dat oude, ongeldige of andere-taakgegevens automatisch worden meegestuurd.
Je hervat een reparatietaak en vindt een keurige samenvatting. Eén onderliggende handleiding is inmiddels vervangen. Als de samenvatting haar bronnen niet bewaart, kan zij oud bewijs ongemerkt blijven doorgeven.
Werkgeheugen is de context voor de huidige taak; langetermijngeheugen bewaart informatie over meerdere stappen of sessies. Opslag maakt tekst niet waar. Onze oefenselector gebruikt daarom taak, herkomst, tijd en versie als afzonderlijke controles.
1. Geef ieder stukje context een herkomst
Zie een record als een kaartje met tekst en een controleerbaar etiket. Het bevat id, task, source, revision, created, expires, score, kind, refs en text. Een observation heeft geen refs; een summary verwijst naar één tot acht eerdere observaties uit dezelfde taak.
Maak eerst een kleine observatie. De tijden zijn gehele oefenkloktikken en score is een gegeven relevantieheuristiek. Geen van beide is een bewijs dat de tekst klopt.
def observation(key, source, text, end):
return {
'id': key, 'task': 'repair',
'source': source,
'revision': 'v1',
'created': 0, 'expires': end,
'score': .5,
'kind': 'observation',
'refs': [], 'text': text
}
a = observation('a', 'd', 'Lamp.', 10)
copied = validate_memory([a])
copied[0]['refs'].append('other')
print(a['refs'])
# []
Schrijf validate_memory met de exacte velden en begrenzingen uit de opdracht. Controleer eerst unieke IDs en daarna de verwijzingen; iedere summary-ref moet bestaan, een observation zijn en niet later zijn aangemaakt. Een diepe kopie voorkomt dat de verwijzingenlijst van het origineel via een teruggegeven record verandert.
De metadata komt uit het vertrouwde hostproces. Een model dat zelf een andere taak-ID mag invullen, omzeilt een selector die die ID blind vertrouwt. Deze inspecteerbare Python-objecten vormen geen toegangsbeveiliging tegen code die alle records kan lezen.
012. Tel de volledige verpakking
Een record telt alleen mee voor dezelfde taak en binnen zijn tijdvenster. Noem created c, expires e en de huidige klok t. Op de vervaltijd zelf is het record al niet meer actief:
Verpak record a exact als het hieronder getoonde blok. De header telt 24 tekens, de newline één en Lamp. vijf: samen 30. Budget 29 laat het complete blok dus weg.
one = select_memory(
[a], 'repair', 5, 30)
print(one['text'])
print(one['used_chars'])
small = select_memory(
[a], 'repair', 5, 29)
print(small['selected'])
# [a | observation | d@v1]
# Lamp.
# 30
# []
Sorteer geschikte records op aflopende score, aflopende created en alfabetische ID. Pak complete blokken en sla een te groot blok over, zodat een later kleiner blok nog kan passen. Dit greedy beleid zoekt geen optimale combinatie.
Voor n opgenomen blokken b_i is C hun gezamenlijke lengte en U het volledige contextgebruik. Tussen twee blokken komen precies twee newlines:
U moet binnen budget blijven. We tellen Python-tekens, geen UTF-8-bytes of modeltokens; voor een echte modelprompt geldt daarnaast de juiste tokenizer.
3. Laat een samenvatting met haar bronnen vervallen
Voeg observatie b en samenvatting s toe. Op klok 9 zijn beide bronnen actief en staat s door haar hogere score vooraan. Op klok 10 vervalt a: s valt ook af, hoewel haar eigen vervaltijd pas 30 is.
b = observation('b', 'sensor', 'B', 20)
s = {
**a, 'id': 's', 'source': 'notes',
'created': 1, 'expires': 30,
'kind': 'summary', 'score': .9,
'refs': ['a', 'b'], 'text': 'A en B'
}
rows = [a, b, s]
for now in [9, 10]:
r = select_memory(
rows, 'repair', now, 1000)
print(r['selected'])
# ['s', 'a', 'b']
# ['b']
Alle bronobservaties moeten actief blijven; één geldige bron is onvoldoende. De selector mag wel alleen de samenvatting meesturen wanneer de volledige bronnen in het gevalideerde register actief blijven. Dat garandeert nog niet dat de samenvatting hun inhoud correct weergeeft.
r = select_memory(
rows, 'repair', 5, 30)
print(r['selected'], r['used_chars'])
# ['a'] 30
Hier past s met 31 tekens niet en wordt zij overgeslagen. Daarna past a precies; ook b vraagt 31 tekens. Schrijf select_memory zonder afknippen of muteren en valideer alle metadata vooraf.
s1 vat r1 samen. Haar eigen vervaltijd is later, maar zij mag een verlopen of gewijzigde bron niet blijven doorgeven.
geldig [0, 10) · score 0.6geselecteerd
geldig [1, 20) · score 0.9geselecteerd
geldig [0, 30) · score 1andere taak
geldig [0, 5) · score 0.7verlopen
geldig [15, 30) · score 0.8nog niet geldig
geldig [0, 30) · score 0.2geselecteerd
[s1 | summary | notes@v1] Reset: tien seconden. [r1 | observation | manual@v1] Houd de knop tien seconden vast. [r5 | observation | notes@v1] Lamp groen.
Volledige blokken, inclusief metadata, tellen mee. Een hoge score is geen bewijs van waarheid. De tekst wordt nergens als opdracht uitgevoerd.
4. Controleer versies opnieuw bij hervatten
Een bron kan veranderen voordat haar vervaltijd bereikt is. Het vertrouwde versieregister meldt nu sensor v2, terwijl b nog v1 bewaart. refresh_memory verwijdert daarom b én de daarvan afhankelijke samenvatting.
versions = {
'd': 'v1', 'sensor': 'v2',
'notes': 'v1'}
r = refresh_memory(rows, versions)
kept = r['records']
print([row['id'] for row in kept])
print(r['dropped'])
# ['a']
# ['b', 's']
Schrijf refresh_memory met behoud van de oorspronkelijke recordvolgorde en alfabetische dropped-IDs. Deze stap controleert versie, geen taak of klok; select_memory voert die controles daarna uit. Een zin in geheugentekst die beweert dat een actie al goedgekeurd is, vervangt nooit het bevoegdheidsbesluit of uitvoerlog.
03Wat neem je mee?
- Bewaar herkomst en metadata naast de tekst.
- Een samenvatting blijft afhankelijk van alle gebruikte bronnen.
- Tijd, taak, versie en contextbudget zijn verschillende controles.
In het toolagentproject combineren we deze selectie met begrensde beslissingen en gecontroleerde eigen functies.