Early Investigation: Dynamic Memory for Agents
A technical look at a schema-aware semantic memory system where Pydantic models, tool calls, agent traces, vector search, graph edges, and feedback loops become trainable memory.
Early Investigation: Dynamic Memory for Agents
This is an early investigation into a different kind of agent memory.
Most agent memory systems start with a simple idea: take some text, embed it, store it in a vector database, and retrieve it later. That works for notes, documents, and loose recall. But it breaks down when agents need to understand structured systems: users, invoices, tool calls, API responses, schemas, field values, intermediate plans, failures, retries, and the relationships between all of them.
The memory we are exploring here is not just a vector store. It is a schema-aware semantic graph that can grow, reinforce, prune, and retrain itself over time.
The long-term goal is direct:
Every agent action, subagent delegation, tool call, model object, and user correction should become training signal for a dynamic memory system.
That means memory is not a passive archive. It becomes part of the learning loop.
The Core Idea
Instead of storing one record as one blob, the system explodes structured data into layers of neurons.
A Pydantic model is not only saved as JSON. It becomes a small semantic graph:
ArtifactNeuron
the full object
FieldNeurons
one neuron per field and nested field
MetadataNeurons
model type, schema id, tags, source
TypeNeurons
model type and field type definitions
SummaryNeuron
compact object summary
Value / Span / Meaning / Relation Neurons
generated subgraph around field values
SessionNeurons
query and feedback eventsThis gives the memory system multiple surfaces to retrieve from.
A query like customer email country support representative can hit field names, values, summaries, object types, learned co-activation edges, or generated meaning nodes. The system does not have to guess whether the whole document vector happens to be close enough.
The Storage Stack
The current prototype uses three backing systems:
MinIO
stores the canonical JSON document with metadata and JSON-LD
Qdrant
stores embeddings and searchable payloads
Memgraph
stores neurons, synapses, dynamic links, sessions, hits, and graph structureEach saved object goes through a FileWritingSchema document format:
metadata
title, tags, source, schema id, schema hash
json_ld
identity, type, context, conformsTo
payload
the actual model dataThat document is written to MinIO. Its vector representation is written to Qdrant. Its exploded neuron graph is written to Memgraph.
The system currently uses local BGE embeddings for semantic search, with a hash embedder available for fast smoke tests.
Why Pydantic Matters
Pydantic models give the system a strong semantic starting point.
A record is not just arbitrary JSON. It has a model name, field names, field types, schema metadata, nested paths, and validation rules.
For example:
class InvoiceRecord(BaseModel):
invoice_id: int
customer_id: int
invoice_date: str
billing_country: str | None
total: floatThe memory graph can derive several layers from this:
InvoiceRecord artifact
InvoiceRecord.invoice_id field
InvoiceRecord.customer_id field
InvoiceRecord.invoice_date field
InvoiceRecord.total field
type: InvoiceRecord
type: InvoiceRecord.customer_id
summary: invoice fields and previewThat gives retrieval more structure than a flat embedding.
Query Flow
A plain-language query follows this path:
human query
-> embed with BGE
-> retrieve candidate neurons from Qdrant
-> generate query-time dynamic edge proposals
-> expand through Memgraph neighbors
-> collect hit/impression stats
-> compute base score
-> rerank with small MLP router
-> write a session neuron
-> wait for feedbackThe base score is intentionally simple:
base = 0.55 * vector_score
+ 0.30 * graph_score
+ 0.15 * hit_rateThen the trained router can override that with learned behavior:
final = 0.70 * router_score + 0.30 * baseThe router sees features such as:
query text
neuron layer
neuron type
model type
schema id
field path
field name
field type
vector score
graph score
hit rate
impressions
hits
value textThis is deliberately small. The point is not to build a giant model first. The point is to create a memory shape that produces useful training examples continuously.
Feedback Is Memory Training
The CLI lets a human query the system and then provide feedback:
brain> customer email country support representative
brain> /accept 1 2
brain> /feedback 1 2 r 5 6That feedback updates the graph:
accepted neurons get hits
returned neurons get impressions
accepted pairs get CO_ACTIVATED edges
query-specific dynamic links get reinforced
rejected relationships get penalized
router training examples are exportedA query is therefore not just a read. It is an event that can become training data.
This matters for agents because future traces can feed the same loop:
agent plan
subagent delegation
tool call
API response
file edit
command output
test result
user correctionEvery step can become a session. Every session can become examples. Every example can tune retrieval and ranking.
Dynamic Edges Instead of Hardcoded Edges
Traditional knowledge graphs often rely on static edges:
Customer HAS_INVOICE Invoice
Invoice HAS_LINE InvoiceLine
InvoiceLine LINE_TRACK TrackThose edges are useful, but they are also brittle. They require manual schema knowledge or hardcoded foreign-key logic.
This investigation takes a different approach: generate query-time edge candidates and cache them by query type.
For example, when a query touches customers, invoices, and tracks, the system can propose dynamic links between candidate fields that look related by field names, values, schema context, and query overlap. Those links are not permanent truth. They are hypotheses.
DYNAMIC_QUERY_LINK
query_type: sales_path
confidence: 0.72
reason: value_match + field_overlap + cross_model
impressions: 3
hits: 1If users accept results that depend on those links, the links get stronger. If they are ignored or rejected, they can decay and eventually be pruned.
This is the key distinction:
Edges are not only authored. They are learned through use.
The Value Subgraph Problem
A major discovery came from a simple query:
album_id 176A pure semantic search path finds “album-ish” things, but it does not reliably understand that this looks like a field/value intent.
The tempting fix is an exact payload lookup. But that is cheating if the goal is dynamic memory. It bypasses the learned memory graph.
So the architecture moved toward adaptive value subgraphs.
A field value is not treated as one scalar. It can generate as many supporting neurons as it needs:
FieldNeuron
album_id = 176
ValueNeuron
raw field value
ValueNeuron
field-scoped value candidate
MeaningNeuron
candidate meaning from model + field + schema + valueFor long strings, the value can create a richer subgraph:
FieldNeuron
note = "Paid 3 days after 9/11 after invoice #42"
SpanNeuron
text chunk
RelationNeuron
"3 days after 9/11"
MeaningNeuron
candidate interpretation of the field valueThe rule is:
Never destructively normalize. Always annotate.
The raw text stays intact. Generated neurons sit beside it as candidate interpretations.
Why Not Just Use Heuristics?
A hardcoded normalizer can turn "176" into 176. It can parse dates. It can detect emails.
But it cannot know what a value means in context.
176 as album_id
176 as milliseconds
176 as invoice total
176 as quantityThese should not collapse into one global value. Meaning depends on schema, field, neighboring values, query context, and feedback history.
So the prototype stores generated candidates with metadata rather than claiming truth:
generated: true
generator_model: adaptive-value-subgraph
generator_version: v1
source_field_id: ...
confidence: 0.45
ttl_policy: prune_if_unreinforcedIn the current implementation, the generator is still simple. The architectural direction is that this generator becomes an ML layer that proposes spans, meanings, canonical candidates, and relation candidates. The graph stores those proposals, and feedback determines which ones survive.
Pruning Generated Memory
Generated memory can easily become noise.
So every generated neuron needs lifecycle metadata:
confidence
impressions
hits
source_field_id
generator_model
generator_version
last_seen
ttl_policyThe pruning rule is behavior-driven:
keep if useful
prune if low-confidence, seen enough, and never reinforcedIn practice:
low confidence + impressions + no hits -> delete neuron + delete vector + detach graph nodeThis lets the memory self-size:
simple scalar -> small subgraph
rich text -> larger subgraph
unused generated detail -> pruned
useful generated detail -> reinforcedThe Current Brain Shape
The current prototype has these layers:
artifact
field
metadata
type
summary
value
span
meaning
relation
sessionAnd these major relation types:
CONTAINS
HAS_FIELD
HAS_METADATA
INSTANCE_OF
HAS_VALUE
HAS_SPAN
HAS_MEANING
HAS_RELATION
DERIVED_FROM
DESCRIBES_VALUE
CO_ACTIVATED
DYNAMIC_QUERY_LINK
RETURNED_WITH
ACCEPTED_WITH
REJECTED_WITHThe important thing is not the exact names. The important thing is the separation of concerns:
raw data
schema structure
value annotations
meaning hypotheses
query sessions
learned behaviorWhy This Matters for Agents
Agents generate exactly the kind of data this architecture wants.
A future A2A agent runtime can emit memory events for:
agent invocation
subagent call
tool selection
tool arguments
tool result
file written
command executed
test passed
test failed
human accepted output
human rejected outputEach event can be represented as a Pydantic model. Each model can be exploded into neurons. Each query over those neurons can create sessions. Each user or agent evaluation can produce feedback. Over time, the memory learns which schemas, fields, values, tools, and traces matter for which tasks.
That is the larger direction:
agent traces -> structured neurons -> retrieval -> feedback -> router training -> better future retrievalThe memory becomes a shared learning substrate for agents and subagents.
What Is Still Early
This is not a finished architecture.
Several open problems remain:
- The value generator should become a learned span and meaning proposal model.
- Training queries need to explicitly teach the router that generated value, span, meaning, and relation neurons can be useful.
- Query understanding needs to learn intent types such as field/value lookup without bypassing the graph.
- Dynamic links need better decay, audit, and confidence calibration.
- Long-running agent traces need compression so memory grows intelligently.
- Evaluation needs real task datasets, not only synthetic or small relational datasets.
The prototype already shows the shape, but the learning loop needs more data.
The Thesis
The thesis is simple:
Agent memory should not be a folder of embeddings. It should be a dynamic semantic graph trained by use.
Schemas provide structure.
Embeddings provide recall.
Graph edges provide context.
Generated value subgraphs provide interpretability.
Feedback provides learning signal.
Pruning keeps the memory honest.
And agent traces provide the training stream.
This is an early investigation, but the direction is clear: future agent systems will need memory that can explain itself, reshape itself, and learn from every tool call, subagent handoff, and human correction.
That is dynamic memory.