Hoppa till innehållet
AI-grafen
FAI engineeringMinnessystem· ca 90 min· snabbt föränderligt, källorna kontrolleras ofta· verifierad 2026-09-20

Episodiskt minne för agenter

Kunna lagra och hämta tidigare interaktioner som episoder, och mäta om agenten faktiskt använder dem.

Intuition

En agent utan minne börjar om varje gång. Episodiskt minne = sparade händelser: «2026-09-14: användaren bad om hjälp med gradient descent, fastnade på inlärningstakt, löste efter ledtråd 2».

Design:

  • Vad: sammanfattning per session (inte råtext), med tid, ämne, utfall, känslomässig ton om relevant. Skriven av modellen med fast mall.
  • Hur hämtas: embeddings + tidsvikt + ämnesfilter → topp-k episoder in i systemprompten som «Tidigare:».
  • När: vid sessionsstart (senaste + mest relevanta) och vid ämnesbyte.
  • Mät: A/B med och utan minne på simulerade användare; probe-frågor; andel svar där modellen refererar en episod korrekt.

Risken är inte att minnet saknas — det är att det används fel: en episod från förra månaden tolkas som nuläge, eller två användare blandas. Varje episod bär user_id, datum och en «giltig till».

Integritet: användaren ska kunna se, radera och stänga av. Spara inte mer än syftet kräver (dataminimering), och sätt retention.

Kod

import time, json

MALL = "Sammanfatta sessionen i ≤ 60 ord: ämne, vad användaren klarade, var det fastnade, preferenser som uttrycktes. Ingen känslig info."

class EpisodMinne:
    def __init__(self, store, embed, llm):
        self.store, self.embed, self.llm = store, embed, llm     # store: vektor-DB med payload-filter

    def skriv(self, user_id, transcript, amne):
        text = self.llm(MALL + "\n\n" + transcript, temperature=0)
        self.store.upsert(vector=self.embed(text), payload={"user": user_id, "t": time.time(), "amne": amne, "text": text})

    def hamta(self, user_id, fraga, k=4, halveringstid_d=30):
        cand = self.store.search(self.embed(fraga), k=20, filter={"user": user_id})
        now = time.time()
        def poang(c):
            alder_d = (now - c.payload["t"]) / 86400
            return c.score * 0.5 ** (alder_d / halveringstid_d)        # nyare väger tyngre
        top = sorted(cand, key=poang, reverse=True)[:k]
        return "\n".join(f"- [{time.strftime('%Y-%m-%d', time.localtime(c.payload['t']))}] {c.payload['text']}" for c in top)

    def radera(self, user_id):
        self.store.delete(filter={"user": user_id})

Systemprompt: «Tidigare sessioner (kan vara inaktuella — bekräfta vid behov):\n{episoder}».

Behärskning innebär

  • Lagrar interaktioner som episoder med metadata och hämtar relevanta
  • Mäter om agenten faktiskt använder minnet
  • Hanterar integritet: vad lagras, hur länge, vem ser

Förkunskaper

Logga in för att göra övningarna och bygga upp din behärskning.

Källor

Alla källor och licenser