Sari la conținut

Memorie și cunoștințe

Fără memorie, fiecare conversație cu un agent pornește de la zero: aceeași convenție trebuie explicată din nou, aceeași decizie redeschisă, același drum înfundat reexplorat. Memoria este depozitul la nivel de spațiu de lucru care supraviețuiește rulărilor și există pentru ca cunoștințele produse de un agent să poată fi găsite de altul mai târziu.

Are trei straturi și ele răspund la întrebări diferite:

  1. Fapte — ce este adevărat (o convenție, un rezultat, o decizie).
  2. Politici — ce trebuie să facă agenții în privința lor (o regulă normativă).
  3. Memorie de lucru — la ce lucra un agent în acel moment.

Distincția contează pentru că ajung la agent pe căi diferite. Faptele se caută. Politicile se împing. Memoria de lucru este privată.

Un MemoryFact este o unitate de cunoștințe limitată la un spațiu de lucru și la un domeniu.

Atribut Ce este
domain Domeniul de cunoștințe (“conventions”, “decisions”, “codebase”)
topic O etichetă scurtă de subiect
content Textul cunoștinței
confidence 0.0–1.0, inițializată din proveniență și crescută la o nouă mențiune
memoryType Tipul faptului — determină curba sa de decădere temporală
veracity Cum a ajuns să fie cunoscut — inițializează încrederea și dimensionează fiecare majorare la o nouă mențiune
sourceObservationIds Ce observații au dus la el
supersededBy Faptul mai nou care l-a înlocuit, dacă există
validUntil, recallCount, mentionCount Semnale de expirare și de utilizare folosite la rechemare

Ultimele două rânduri sunt cele pe care lumea le ratează și sunt exact cele care decid care fapt iese la suprafață. memoryType poartă parametri de decădere Weibull specifici tipului, așa că un angajament cu termen limită se estompează repede, în timp ce un fapt de profil stabil nu se estompează. veracity înregistrează proveniența — enunțat de un om (pondere 1.0), dedus de un agent (0.7), produs de un instrument (0.5), importat (0.6) — iar acea pondere inițializează încrederea de pornire a faptului.

Faptele nu sunt niciodată editate pe loc atunci când sunt contrazise. Scrierea unui fapt rulează detectarea conflictelor împotriva faptelor din același domeniu și cu același subiect și o înlocuiește pe cea învinsă, înregistrând un rând de conflict. Jurnalul de audit este însuși scopul: poți vedea oricând ce se credea înainte și ce a înlocuit.

O MemoryPolicy este o regulă normativă derivată din fapte, limitată la un spațiu de lucru și la un domeniu, cu un indicator de activare și un requiredRole opțional.

Fiecare politică activă din spațiul de lucru este injectată în fiecare trimitere, fără filtrare — nicio filtrare după domeniu, rol, sarcină sau spațiu. Merită să știi asta înainte de a-ți scrie a douăzecea politică, pentru că politicile concurează cu sarcina pentru aceeași fereastră de context. Tot de aceea requiredRole pe o politică este orientativ: descrie cui i se adresează regula, nu împiedică regula să ajungă la toți ceilalți.

Un MemoryDomain grupează fapte și politici în cadrul unui spațiu de lucru. Domeniile dau cunoștințelor structură organizatorică și sunt unitatea față de care se scriu acordările de acces — dar vezi atenționarea de mai jos înainte de a trata un domeniu ca pe o graniță de confidențialitate.

Un domeniu este fie la nivel de spațiu de lucru (architecture), fie limitat la un singur repository (repo:<slug>/architecture). Același nume în ambele perimetre înseamnă două depozite independente: un fapt adevărat pentru o bază de cod nu îl suprascrie pe cel de la nivel de spațiu de lucru. search_memory și preambulul de trimitere clasează prima memoria limitată la repository atunci când agentul lucrează în acel repository; nu elimină restul prin filtrare. Transmite repo la propose_fact / propose_policy / search_memory pentru a scrie în acel perimetru sau a-l favoriza.

Controlul accesului este permisiv la eroare pentru citiri

Secțiune intitulată „Controlul accesului este permisiv la eroare pentru citiri”

MemoryAccessGrant asociază un rol de agent și un domeniu cu unul dintre cele trei niveluri de permisiune:

Permisiune Semnificație
none Fără acces
read Poate căuta și recupera fapte
write Cerută de propose_policy. Scrierile de fapte (propose_fact, supersede_fact) nu sunt condiționate de o acordare

Asimetria — permisivă la citiri, strictă la scrierile de politici — este un compromis deliberat. Memoria este cel mai utilă când circulă, iar un refuz de citire produce un agent care știe mai puțin în tăcere, nu unul care raportează o problemă. Un refuz la scrierea unei politici, dimpotrivă, este zgomotos și corectabil, așa că acolo se află aplicarea. Un domeniu nou creat inițializează write pentru fiecare rol; restrângerea lui ulterioară este o modificare exclusiv prin RPC, pentru că nu există o interfață pentru acordări.

Fiecare agent are un AgentWorkingMemory: un bloc de notițe cu text liber, indexat după spațiu de lucru și agent. Persistă între rulări, este privat pentru acel agent și este injectat în promptul lui la fiecare trimitere. Aici trăiește „eram la jumătatea refactorizării autentificării” — starea care merită dusă în următoarea rulare, dar nu merită promovată la un fapt durabil.

La trimitere, preambulul de memorie este alcătuit din exact trei lucruri:

  • Fiecare politică activă din spațiul de lucru, ca linii de forma - [domain] rule.
  • Memoria de lucru proprie agentului, literal.
  • O listă scurtă de fapte potrivite după cuvinte-cheie pentru această sarcină — cel mult cinci, într-un buget de ~1.200 de caractere și doar când descrierea sarcinii are cel puțin 20 de caractere. Sarcinile mai scurte nu primesc deloc fapte.

Lista scurtă se bazează doar pe FTS/cuvinte-cheie și este limitată intenționat. Înglobarea unei interogări este lentă, iar calea de trimitere este singurul loc unde latența se vede imediat, așa că calea semantică lentă este ținută deliberat în afara ei. Preambulul se încheie spunându-i agentului să verifice elementele critice cu search_memory, acolo unde trăiește modelul complet de rechemare.

Pe această cale nu se consultă nicio acordare de acces. Orice găsește lista scurtă este ceea ce vede agentul.

Instrumentul search_memory, expus agenților, are trei moduri, iar acestea sunt căutări cu adevărat diferite:

  • keyword — doar FTS5.
  • semantic — rezultate BM25 și vectoriale combinate prin fuziune de ranguri reciproce.
  • hybrid (implicit) — rechemare polifonică: patru voci clasate, combinate, apoi diversificate.

Cele patru voci sunt lexicală (FTS), semantică (KNN vectorial), temporală (fapte active recente) și de graf — o parcurgere în doi pași peste muchiile episodice, pornind de la cele mai puternice puncte de pornire lexicale și semantice. Vocea de graf este însuși motivul pentru care există muchiile episodice: scoate la suprafață faptul care este conectat la răspunsul tău fără să se potrivească cu vreunul dintre cuvintele tale. Vocile sunt ponderate după intenția interogării, clasificată (semantica are cea mai mare pondere implicit, apoi graful și lexicul, apoi recentitatea), scorul fiecărui candidat este scalat cu decăderea lui Weibull, iar setul de rezultate este diversificat prin MMR, astfel încât cinci reformulări ale unui fapt să nu le înăbușe pe alte patru diferite.

Căutarea în memorie din desktop și din web este o cale separată, mai simplă: operațiunea RPC memory_fact.search este doar FTS5, pentru că un client subțire nu poate trimite o înglobare de interogare, iar calea hibridă rămâne internă gazdei. Așadar, clasamentul pe care îl vezi în browserul de memorie nu este clasamentul pe care îl primește un agent de la search_memory. Acest lucru este de așteptat, nu este un defect, dar înseamnă că „am căutat și nu l-am găsit” în interfață nu este o dovadă că agentul nu îl va găsi.

Browserul de memorie se află la Setări → Spațiu de lucru → Memorie (/workspaces/<id>/settings/memory), cu filele Fapte, Politici și Graf.

Acolo există o asimetrie care surprinde lumea: poți edita și șterge memoria, dar nu o poți crea. Nici fila Fapte, nici fila Politici nu are un control de adăugare. Autorarea se face dinspre agent, prin propose_fact și propose_policy (supersede_fact / supersede_policy pentru a le înlocui). remember scrie un element de nivel fierbinte, limitat la sesiune, pe care consolidate_memory îl poate promova ulterior la fapt; record_observation și update_my_notes scriu blocul de notițe privat injectat la trimitere. Browserul este o suprafață de revizuire și corectare, nu una de autorare — așa că, dacă vrei un fapt în memorie, modalitatea de a-l pune acolo este să îi spui unui agent.

Două operațiuni de întreținere sunt, de asemenea, invocate de agent, nu programate: consolidate_memory fuzionează și elimină faptele acumulate, iar harmonize_memory reconciliază convingerile care au divergat între agenți. list_memory_conflicts arată ce a înregistrat deja detectarea conflictelor. Nimic nu le rulează pentru tine după un temporizator. Deciziile din ședințe sunt colectate în domeniul decisions atunci când un pas de persistare a ședinței le înregistrează; acesta nu este un temporizator pentru rulările de agent finalizate.