Hoppa till innehållet
AI-grafen
F· AI engineeringminnessystem· ca 90 min· volatil — 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.

Förkunskaper

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

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

Källor

Alla källor och licenser