LLMs are inherently stateless. "Memory" is entirely platform-engineered through strategic context injection — and RDF provides a superior substrate for doing it right.
The two source materials operate at different altitudes. ByteByteGo describes the problem space in framework-agnostic terms. agent-rdf-memory is a working implementation that satisfies that framework using RDF Turtle rather than vector embeddings or plain text.
| Dimension | ByteByteGo (Generic Framework) | agent-rdf-memory (Concrete Implementation) |
|---|---|---|
| Level of abstraction | Vendor-neutral taxonomy — applies to any agent stack | A single, opinionated reference implementation |
| Memory substrate | Unspecified — vector DB, SQL, key-value, or files | RDF Turtle exclusively — typed, named-IRI graph |
| Retrieval mechanism | Generic "retrieval" — typically semantic/vector similarity search | Structural injection (SessionStart hook) + on-demand rdfs:seeAlso traversal, no embeddings |
| Injection trigger | Not prescribed — left to the implementer | Hard-coded hook (load_memory.py) fires before every session |
| Compression strategy | Summarisation (lossy) | Sparse-index pattern — lossless pointer-based deferral to howto/*.ttl |
| Verifiability | Not addressed — no audit mechanism described | validate-memory-protocol.py post-session transcript audit + schema:text length gate |
| Queryability | Implementation-dependent | Native — any SPARQL engine can query the memory store directly |
| Primary failure mode named | Lost-in-the-middle effect, retrieval failure | Same risks, mitigated structurally rather than algorithmically |
| Audience / purpose | Industry-wide conceptual reference | Production behavioral contract for one agent in one repository |
agent-rdf-memory rejects vector similarity retrieval entirely in favor of deterministic, structural mechanisms — trading retrieval recall for retrieval reliability.
Active context window — hot, bounded by token limit, populated by SessionStart hook from RDF files each session.
Recent activity awaiting archival — current day's session TTL file, written on trigger events.
Persistent facts and behavioral rules — core.ttl, preferences.ttl, and the full sessions/ archive.
Full historical session log — all past sessions/*.ttl, queryable via SPARQL even if not injected at startup.
Every LLM API call begins from a completely fresh slate — the model has no access to prior calls even one millisecond earlier. There is no built-in memory; the illusion of continuity is produced entirely by platform engineering that strategically reinserts relevant context (prior messages, facts, rules) into each new call. This means "agent memory" is not a property of the model — it is a property of the infrastructure wrapping it.
Prompt engineering focuses on crafting individual instructions to steer model behavior in a single call. Context engineering is the broader discipline of deciding what information to include, exclude, compress, or retrieve across the entire context window — managing memory tiers, retrieval signals, summarisation fidelity, and injection timing so the model has the right information at each turn. Context engineering is the architectural layer; prompt engineering is one tool within it.
Working memory (active context window — populated by the SessionStart hook); Episodic memory (time-anchored records — sessions/YYYY-MM-DD-{llm-id}-{agent-env}.ttl using OPAL Analytics Ontology); Semantic memory (stable facts — core.ttl with schema:Person and schema:PropertyValue triples); Procedural memory (behavioral rules — preferences.ttl sparse index + 44 companion howto/*.ttl files encoding 103 standing instructions).
The lost-in-the-middle effect is the empirically observed phenomenon where LLMs recall information at the beginning and end of a context window more reliably than in the middle. agent-rdf-memory mitigates this through the sparse-index pattern: preferences.ttl contains only step names and one-sentence rules — keeping it compact so all content falls in the high-attention zone. Full detail is in howto/*.ttl files loaded on demand.
RDF Turtle gives behavioral rules four properties markdown cannot: (1) Queryability — rules are addressable via SPARQL by trigger condition, position, or topic; (2) Semantic typing — each rule is a schema:HowToStep with explicit rdf:type, trigger, and rdfs:seeAlso; (3) Resolvability — entity IRIs are dereferenceable URLs, not opaque strings; (4) Composability — rules cross-reference each other, forming a connected graph rather than a flat list.
The SessionStart hook (load_memory.py) fires before the agent generates any response. It reads core.ttl, preferences.ttl, index.ttl, and the most recent session file, then returns their compiled content as additionalContext to the harness, which injects it into the model's context window. Memory loading is structural — enforced by the runtime, not reliant on the agent remembering to invoke a tool.
The sparse-index pattern splits memory into two tiers: a compact always-loaded index (preferences.ttl) with only step names, one-sentence rules, trigger conditions, and rdfs:seeAlso pointers; and verbose on-demand companion files (howto/*.ttl) with full rationale, code examples, and gates. preferences.ttl is read at every session start — its token cost is unconditional. Verbose content would inflate that cost by its full length every single session.
Four key tradeoffs: (1) Recency vs. relevance — balance between the most recent and most semantically similar information; (2) Summarisation fidelity — compression reduces cost but loses precise detail; (3) Staleness — outdated facts can persist with unwarranted confidence; (4) Security exposure — persistent memory creates long-term attack surfaces for injected malicious content. agent-rdf-memory addresses staleness via dated session files and explicit schema:dateModified tracking.
validate-memory-protocol.py parses Claude Code JSONL session transcripts and checks for five mandatory tool calls in order: (1) ls agent-rdf-memory/, (2) Read core.ttl, (3) Read preferences.ttl, (4) Read index.ttl, (5) at least one additional howto or session file. The --strict mode additionally verifies all reads occurred before the first substantive assistant response — catching "read-after-respond" violations.
RAG retrieves relevant chunks from a vector store at query time. agent-rdf-memory uses structural injection — loading behavioral rules in full at session start, not query time — ensuring they are always present. Retrieval is reserved for querying the local RDF file system during KG question-answering workflows. The two approaches are complementary: RDF context engineering for behavioral rules, RAG for knowledge retrieval.
Session files follow: YYYY-MM-DD-{llm-id}-{agent-env}.ttl. The three-component key (date, model, environment) enables unambiguous cross-session provenance: the same day can produce multiple files for different models or environments, and the model component is always sourced from the system-prompt model identifier — never inferred from conversation context — preventing misrouting of artifacts.
Production memory failures are almost never caused by information not being stored — they are caused by the right information not being surfaced at the right moment. This shifts the design burden from storage capacity to retrieval precision. In agent-rdf-memory, the SessionStart hook pre-loads critical memory unconditionally; howto files are loaded on demand via rdfs:seeAlso; and SPARQL makes any fact retrievable by subject, predicate, trigger condition, or date range.
The discipline of strategically assembling and injecting relevant information into a stateless LLM's context window — the actual mechanism behind "agent memory."
The live context window for the current agent task — hot, bounded by the model's token limit, populated by the SessionStart hook from persistent RDF files.
Time-anchored records of specific past interactions — stored as dated Turtle files in sessions/ using OPAL Analytics Ontology vocabulary.
Context-independent stable facts — user identity, output path routing, canonical IRIs — stored in core.ttl and valid across all sessions.
Behavioral rules encoded as schema:HowToStep entities in preferences.ttl and companion howto/*.ttl files — 103 standing instructions governing every session.
Empirically observed degradation in LLM recall for information positioned centrally in long context windows — motivating the sparse-index pattern.
A two-tier architecture where the always-loaded index holds only compact pointers and one-sentence rules; verbose detail lives in on-demand companion files.
A set of queryable schema:HowToStep RDF entities encoding standing agent instructions, each with a trigger condition and a pointer to a companion howto file.
A harness-level Python script that reads RDF memory files and injects them as additionalContext before the agent's first turn — enforcing context engineering structurally.
Persistent agent memory stored as Turtle RDF — queryable via SPARQL, semantically typed, dereferenceable, and structured for the sparse-index pattern.
Map each piece of information to working, episodic, semantic, or procedural memory. This classification determines where it is stored, how it is injected, and when it expires.
Map memory types to tiers: procedural and semantic → long-term storage (always-loaded RDF files); episodic → session tier (dated files loaded on demand); working → context window assembled at each call.
Encode all persistent memory as RDF Turtle with well-typed schema.org and custom ontology terms. Each rule becomes a schema:HowToStep, each session an opal:ChatSession, each fact a schema:PropertyValue triple.
Do not rely on the agent to load memory via tool calls — enforce it structurally. Configure a SessionStart hook that reads core memory files and injects their content as additionalContext before the first user turn.
In the behavioral contract file, each rule should contain: schema:name, one-sentence schema:text, onto:hasTrigger, and rdfs:seeAlso. Run a verification script to catch schema:text values exceeding 300 characters.
Implement a transcript audit script that verifies all mandatory memory-loading steps were executed before the agent's first response. Let its failures drive iterative improvement of the hook injection.
Point a SPARQL engine at the memory directory and build query patterns for: "what are all rules triggered by artifact generation?", "which sessions generated output to this path?", "what was the most recent correction?"
Query the knowledge graph via URIBurner SPARQL endpoint. Select a recipe or write your own. Results open in a new tab. Use format=text%2Fx-html%2Btr for HTML table output from SELECT queries.
PREFIX : <https://linkeddata.uriburner.com/DAV/demos/daas/ai-agent-memory-context-engineering-claude_sonnet_4_6-1.ttl#>
PREFIX schema: <http://schema.org/>
SELECT ?memoryType ?description ?storedIn
FROM <https://linkeddata.uriburner.com/DAV/demos/daas/ai-agent-memory-context-engineering-claude_sonnet_4_6-1.ttl>
WHERE {
?m a :MemoryType ;
schema:name ?memoryType ;
schema:description ?description .
OPTIONAL { ?m :storesIn ?tier . ?tier schema:name ?storedIn . }
}
ORDER BY ?memoryType
▶ Run on URIBurner
PREFIX : <https://linkeddata.uriburner.com/DAV/demos/daas/ai-agent-memory-context-engineering-claude_sonnet_4_6-1.ttl#>
PREFIX schema: <http://schema.org/>
SELECT ?position ?stepName ?stepText
FROM <https://linkeddata.uriburner.com/DAV/demos/daas/ai-agent-memory-context-engineering-claude_sonnet_4_6-1.ttl>
WHERE {
:howtoContextEngineering schema:step ?step .
?step schema:position ?position ;
schema:name ?stepName ;
schema:text ?stepText .
}
ORDER BY xsd:integer(?position)
▶ Run on URIBurner
PREFIX : <https://linkeddata.uriburner.com/DAV/demos/daas/ai-agent-memory-context-engineering-claude_sonnet_4_6-1.ttl#>
PREFIX schema: <http://schema.org/>
SELECT ?name ?description
FROM <https://linkeddata.uriburner.com/DAV/demos/daas/ai-agent-memory-context-engineering-claude_sonnet_4_6-1.ttl>
WHERE {
?concept :addressesChallenge :LLMStatelessness ;
schema:name ?name ;
schema:description ?description .
}
ORDER BY ?name
▶ Run on URIBurner
PREFIX : <https://linkeddata.uriburner.com/DAV/demos/daas/ai-agent-memory-context-engineering-claude_sonnet_4_6-1.ttl#>
PREFIX schema: <http://schema.org/>
SELECT ?question ?answer
FROM <https://linkeddata.uriburner.com/DAV/demos/daas/ai-agent-memory-context-engineering-claude_sonnet_4_6-1.ttl>
WHERE {
?q a schema:Question ;
schema:name ?question ;
schema:acceptedAnswer ?ans .
?ans schema:text ?answer .
}
ORDER BY ?question
▶ Run on URIBurner