KI-Agenten-Gedächtnis mit Convex: Vollständige Architektur
KI-Agenten-Gedächtnis mit Convex: Vollständige Architektur steht im Mittelpunkt dieses Guides. OpenClaw gibt KI-Agenten dateibasiertes Gedächtnis von Haus aus — Markdown-Dateien, tägliche Protokolle, sogar ein memory_search-Tool für semantische Suche. Es funktioniert. Unser Agent Timmy konnte sich an gestrige Entscheidungen erinnern, indem er MEMORY.md las, nachschauen was letzte Woche passiert ist, und relevanten Kontext über Dateien hinweg suchen.
Aber als Timmy mehr Aufgaben übernahm — Blogbeiträge schreiben, Social Media verwalten, Browser-Aufgaben automatisieren, Cron-Jobs ausführen — stießen wir an die Grenzen des dateibasierten Gedächtnisses. Die Suche war linear, ohne Relevanz-Ranking. Alte Erinnerungen verblassten nie, sodass die Dateien mit veralteten Entscheidungen aufgebläht wurden. Es gab keine Möglichkeit, automatisch verwandten Kontext aufzurufen oder eine kritische Architekturentscheidung von einer beiläufigen Beobachtung zu unterscheiden.
Wir wollten etwas Kognitiveres. Nicht nur Speicher — ein System, das modelliert, wie Gedächtnis tatsächlich funktioniert.
Dies ist die Geschichte, wie wir Cortex gebaut haben, ein kognitives Gedächtnissystem für KI-Agenten, angetrieben von Convex.
Ein 60-Sekunden-Crashkurs in kognitivem Gedächtnis — KI-Agenten-Gedächtnis mit Convex: Vollständige Architektur
Bevor wir in die Architektur eintauchen, sprechen wir darüber, wie menschliches Gedächtnis tatsächlich funktioniert. Kognitionswissenschaftler haben mehrere unterschiedliche Gedächtnissysteme identifiziert, und ihr Verständnis lässt die technischen Entscheidungen Sinn ergeben:
🧠 Sensorisches Gedächtnis — Dein Kurzzeitpuffer. Wie sich zu erinnern, was jemand vor 30 Sekunden gesagt hat. Hohes Volumen, sehr temporär. Das meiste verflüchtigt sich in Minuten.
📔 Episodisches Gedächtnis — Dein Tagebuch. Spezifische Ereignisse, gebunden an Zeiten und Orte: „Am Dienstag haben wir entschieden, Typefully für Social Media zu nutzen." Autobiographisch, kontextuell, mit Zeitstempel.
📚 Semantisches Gedächtnis — Deine Wissensbasis. Fakten, die du einfach weißt, ohne dich zu erinnern, wann du sie gelernt hast: „Convex unterstützt Vektorsuche" oder „der Deploy-Befehl ist npx convex deploy." Aus Erfahrung destilliert über die Zeit.
⚙️ Prozedurales Gedächtnis — Muskelgedächtnis. Wie man Dinge tut: „Um einen Blogbeitrag zu veröffentlichen: Entwurf erstellen → Bild hinzufügen → veröffentlichen → URL überprüfen → Social Media." Du denkst nicht darüber nach, du machst es einfach.
📋 Prospektives Gedächtnis — Deine To-do-Liste. Dinge, die du in Zukunft tun musst: „SEO-Performance nächsten Montag überprüfen" oder „Nach der Demo beim Lead nachfassen."
Die Erkenntnis: Das sind nicht nur Kategorien zum Organisieren von Notizen. Jeder Typ hat unterschiedliche Persistenz, Verfallsraten und Abrufmuster. Sensorische Erinnerungen sollten in Stunden verblassen. Semantisches Wissen sollte unbegrenzt bestehen bleiben. Emotionale Erinnerungen sollten dem Vergessen widerstehen. Und verwandte Erinnerungen sollten sich gegenseitig aktivieren — sich an „Convex" zu erinnern sollte natürlich „Vektorsuche" und „Dokumentenmodell" abrufen.
Das macht Cortex. Lass es uns bauen.
Warum Convex? (Es war nicht unsere erste Wahl)
Wir nutzten Convex bereits für unser Blog-CMS bei contextstudios.ai. Aber die Wahl für kognitives Gedächtnis kam aus drei Erkenntnissen:
1. Dokumentenmodell passt natürlich zu Gedächtnisobjekten
Eine Erinnerung ist keine Zeile in einer Tabelle. Es ist ein reichhaltiges Objekt mit Titel, Inhalt, emotionaler Valenz, Stärke, Tags, Provenienz und Beziehungen. Convex' Dokumentenmodell passt perfekt:
// convex/schema.ts — Das Cortex-Gedächtnis-Schema
cortexMemories: defineTable({
store: v.union(
v.literal("sensory"), // 24h-Puffer
v.literal("episodic"), // spezifische Ereignisse
v.literal("semantic"), // Faktenwissen
v.literal("procedural"), // Anleitungs-Workflows
v.literal("prospective") // zukünftige Absichten
),
category: v.union(
v.literal("decision"), v.literal("lesson"),
v.literal("person"), v.literal("rule"),
v.literal("event"), v.literal("fact"),
v.literal("goal"), v.literal("workflow")
),
title: v.string(),
content: v.string(),
embedding: v.array(v.float64()), // 1536-dim Vektor
strength: v.float64(), // 0–1, verfällt über die Zeit
confidence: v.float64(), // 0–1, wie sicher
valence: v.float64(), // -1 bis 1 (emotionale Ladung)
arousal: v.float64(), // 0–1 (emotionale Intensität)
accessCount: v.number(), // Abrufhäufigkeit
lastAccessedAt: v.number(), // für Aktualitätsbewertung
source: v.union(
v.literal("conversation"),
v.literal("cron"),
v.literal("observation"),
v.literal("inference"),
v.literal("external")
),
tags: v.array(v.string()),
})
2. Integrierte Vektorsuche (keine zusätzliche Infrastruktur)
Das war das Killer-Feature. Native Vektorindizierung bedeutet, dass wir OpenAI-Embeddings neben Gedächtnisdokumenten speichern und sie durchsuchen können, ohne Pinecone oder Qdrant aufzusetzen:
.vectorIndex("by_embedding", {
vectorField: "embedding",
dimensions: 1536,
filterFields: ["store", "category", "tags"],
})
3. Serverlose Funktionen für kognitive Prozesse
Gedächtnis ist nicht nur Speicher — es ist ein Prozess. Convex gibt uns Mutations, Queries, Actions und Cron-Jobs — genau die richtigen Primitiven für Verfall, Konsolidierung und Assoziation:
// convex/crons.ts — Kognitive Hintergrundprozesse
crons.interval("cortex consolidation", { hours: 12 }, internal.cortex.consolidate);
crons.interval("cortex decay", { hours: 24 }, internal.cortex.decay);
crons.interval("cortex cleanup", { hours: 24 }, internal.cortex.cleanupExpired);
Keine Lambda-Funktionen. Keine Worker-Queues. Einfach TypeScript-Funktionen, die nach Zeitplan laufen.
Die Cortex-Architektur
Fünf Gedächtnisspeicher
┌───────────────────────────────────────────────────────┐
│ CORTEX GEDÄCHTNIS │
├────────────┬──────────────┬──────────────┬────────────┤
│ SENSORISCH │ EPISODISCH │ SEMANTISCH │ PROZEDURAL │
│ (24h Puf.) │ (Ereign.) │ (Wissen) │ (Anleit.) │
├────────────┴──────────────┴──────────────┴────────────┤
│ PROSPEKTIV │
│ Ziele, Pläne, zukünftige Absichten │
└───────────────────────────────────────────────────────┘
Auto-Promotion: Sensorisch → Episodisch → Semantisch
Alle 12 Stunden clustert ein Konsolidierungs-Cron verwandte sensorische Erinnerungen (Vektorähnlichkeit > 0,75), synthetisiert sie zu episodischen Erinnerungen und markiert die Originale als konsolidiert. Im Laufe der Zeit werden häufig abgerufene episodische Erinnerungen mit hoher Konfidenz zu semantischem Gedächtnis befördert. KI-Agenten-Gedächtnis mit Convex: Vollständige Architektur lernt buchstäblich, was wichtig ist, indem es Abrufmuster verfolgt.
Gedächtnisverfall: Vergessen ist ein Feature
Jede Erinnerung hat ein strength-Feld, das bei 1.0 beginnt und täglich verfällt:
export const decay = internalMutation({
handler: async (ctx) => {
const now = Date.now();
const memories = await ctx.db
.query("cortexMemories")
.filter(q => q.eq(q.field("archivedAt"), undefined))
.collect();
for (const mem of memories) {
if (mem.store === "prospective") continue;
const daysSinceAccess = (now - mem.lastAccessedAt) / (1000 * 60 * 60 * 24);
const isHighEmotion = Math.abs(mem.valence) > 0.7 && mem.arousal > 0.7;
const decayRate = isHighEmotion ? 0.01 : 0.02;
const newStrength = Math.max(0, mem.strength - decayRate * daysSinceAccess);
if (newStrength < 0.1) {
await ctx.db.patch(mem._id, { strength: newStrength, archivedAt: now });
} else if (newStrength !== mem.strength) {
await ctx.db.patch(mem._id, { strength: newStrength });
}
}
},
});
Zwei Prinzipien: Emotionale Erinnerungen halten länger, und Abruf verstärkt Erinnerung — verteilte Wiederholung für KI-Agenten.
Spreading Activation: Erinnerungen, die sich verbinden
Neue Erinnerungen finden automatisch verwandte über Vektorsuche und erstellen Assoziationsverknüpfungen:
export const createAutoAssociations = internalAction({
handler: async (ctx, args) => {
const similar = await ctx.vectorSearch("cortexMemories", "by_embedding", {
vector: args.embedding,
limit: 6,
});
for (const result of similar) {
if (result._id === args.memoryId) continue;
await ctx.runMutation(internal.cortex.insertAssociations, {
associations: [{
from: args.memoryId,
to: result._id,
type: "related",
weight: result._score,
createdAt: Date.now(),
}],
});
}
},
});
Der Abruf verwendet eine zusammengesetzte Bewertungsfunktion, die vier Signale kombiniert:
const compositeScore =
mem.strength * 0.3 +
recencyScore * 0.2 +
accessScore * 0.1 +
mem.vectorScore * 0.4;
Integration mit OpenClaw
Cortex wird über 8 MCP-Tools (Model Context Protocol) bereitgestellt:
| Tool | Zweck |
|---|---|
cortex_remember | Eine neue Erinnerung speichern |
cortex_recall | Erinnerungen suchen und abrufen |
cortex_what_do_i_know | Breite Themenbewusstseins-Prüfung |
cortex_why_did_we | Entscheidungsarchäologie |
cortex_forget | Explizite Erinnerungsentfernung |
cortex_stats | Gedächtnissystem-Statistiken |
cortex_checkpoint | Arbeitskontext speichern |
cortex_wake | Morgen-Briefing |
Das Dual-Write-Muster
Jede Erinnerung geht an Cortex (Convex) und an lokale Markdown-Dateien. Cortex bietet strukturierten Abruf, Vektorsuche und Verfall. Markdown-Dateien bieten einen menschenlesbaren Audit-Trail.
Baue dein eigenes: Minimal Viable Cortex
Willst du etwas Ähnliches an einem Wochenende liefern? Hier ist die minimale Version — nur sensorisches + semantisches Gedächtnis mit Vektorsuche.
Schritt 1: Convex-Schema einrichten
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
memories: defineTable({
store: v.union(v.literal("sensory"), v.literal("semantic")),
title: v.string(),
content: v.string(),
embedding: v.array(v.float64()),
strength: v.float64(),
createdAt: v.number(),
lastAccessedAt: v.number(),
tags: v.array(v.string()),
})
.vectorIndex("by_embedding", {
vectorField: "embedding",
dimensions: 1536,
filterFields: ["store", "tags"],
})
.index("by_store", ["store"]),
});
Schritt 2: Die Remember-Funktion schreiben
export const remember = action({
args: {
store: v.union(v.literal("sensory"), v.literal("semantic")),
title: v.string(),
content: v.string(),
tags: v.array(v.string()),
},
handler: async (ctx, args) => {
const response = await fetch("https://api.openai.com/v1/embeddings", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "text-embedding-3-small",
input: `${args.title}: ${args.content}`,
}),
});
const data = await response.json();
const embedding = data.data[0].embedding;
const now = Date.now();
await ctx.runMutation(internal.memory.insert, {
...args, embedding, strength: 1.0, createdAt: now, lastAccessedAt: now,
});
},
});
Schritt 3: Die Recall-Funktion schreiben
export const recall = action({
args: {
query: v.string(),
store: v.optional(v.union(v.literal("sensory"), v.literal("semantic"))),
limit: v.optional(v.number()),
},
handler: async (ctx, args) => {
const response = await fetch("https://api.openai.com/v1/embeddings", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ model: "text-embedding-3-small", input: args.query }),
});
const data = await response.json();
const results = await ctx.vectorSearch("memories", "by_embedding", {
vector: data.data[0].embedding,
limit: args.limit ?? 5,
filter: args.store ? { store: args.store } : undefined,
});
for (const r of results) {
await ctx.runMutation(internal.memory.touch, { id: r._id });
}
return results;
},
});
Schritt 4: Täglichen Verfall hinzufügen
import { cronJobs } from "convex/server";
const crons = cronJobs();
crons.daily("memory decay", { hourUTC: 4, minuteUTC: 0 }, internal.memory.decay);
export default crons;
Schritt 5: Mit deinem Agenten verbinden
Wenn du MCP verwendest, stelle remember und recall als Tools bereit. Das war's — du hast ein funktionierendes Gedächtnissystem mit semantischer Suche, automatischem Verfall und zwei Gedächtnisebenen.
Praktische Erkenntnisse
- Starte mit sensorisch, nicht semantisch. Lass die Konsolidierungspipeline entscheiden, was wichtig ist.
- Verfall ist essenziell. Ohne ihn wird dein Gedächtnisspeicher eine Rumpelkammer veralteter Entscheidungen.
- Emotionale Metadaten sind wichtig. Erinnerungen mit Valenz und Erregung zu taggen verbessert die Abrufqualität.
- Vektorsuche + Metadatenfilterung > reine Vektorsuche. Convex macht das trivial.
- Assoziationen schaffen Serendipität. Der wertvollste Abruf ist manchmal eine verwandte Erinnerung.
Die Ergebnisse
Nach dem Launch von Cortex starten Sitzungen damit, dass der Agent bereits Kontext kennt. Entscheidungen sind sofort abrufbar. Lektionen bleiben tatsächlich hängen. Auf Convex' kostenlosem Tier laufend, speichern wir Hunderte von Erinnerungen ohne Infrastrukturkosten. Die Vektorsuche liefert Ergebnisse in unter 100ms.
Die echte Wirkung ist qualitativ: Mit einer KI zu arbeiten, die sich erinnert, fühlt sich an wie die Zusammenarbeit mit einem Kollegen, der seit Monaten im Team ist.
Was kommt als Nächstes
Cortex läuft in Produktion. Wenn du KI-Agenten baust und mit Kontextpersistenz kämpfst, ziehe diesen Ansatz in Betracht. Schau dir Convex' KI-Agenten-Dokumentation und das MCP-Protokoll an. Deine KI muss nicht jede Sitzung bei Null anfangen.
FAQ
Was ist der Unterschied zwischen Cortex und einer Vektordatenbank wie Pinecone? Cortex fügt Gedächtnisverfall, automatische Konsolidierung, emotionale Metadaten und Spreading Activation zusätzlich zur Vektorsuche hinzu. Auf Convex ist alles auf einer Plattform.
Was kostet es? Derzeit 0 € auf Convex' kostenlosem Tier. Die einzigen externen Kosten sind OpenAI-Embeddings (Bruchteile eines Cents pro Erinnerung).
Kann es mit anderen Modellen als Claude funktionieren?
Ja. Cortex ist modellagnostisch, bereitgestellt über MCP-Tools. Die Embeddings verwenden OpenAIs text-embedding-3-small, aber du könntest jedes 1536-dimensionale Modell einsetzen.
Wie verhindert ihr das Speichern falscher Informationen?
Jede Erinnerung hat einen confidence-Score, cortex_forget ermöglicht explizites Entfernen, und natürlicher Verfall bedeutet, dass selbst falsche Erinnerungen verblassen.
Was wenn Convex ausfällt? Das Dual-Write-Muster bedeutet, dass jede Erinnerung sowohl in Convex als auch in lokalen Markdown-Dateien existiert. Der Agent fällt auf dateibasierte Suche zurück.