04 · Memory
A custom ContextProvider gives the agent memory: it reads stored facts before a run and learns new ones after — all through the Session.
What this lesson demonstrates
Sessions carry the transcript; memory carries facts. A ContextProvider adds two hooks around every run so the agent can carry structured memory forward. Provide runs before the model call and injects what it knows as instructions (“The user’s name is Ruaidhrí.”). Store runs after a successful run, scans the user’s message, parses out a name and age, and writes them back into the Session. Because the state lives in the agent.Session, it serializes to JSON and can be copied into a brand-new session — so the agent “remembers” a user it never spoke to in that session.
The code
A provider is just two functions registered under one source ID:
func newUserMemoryProvider() agent.ContextProvider {
return agent.NewContextProvider(agent.ContextProviderConfig{
SourceID: userMemorySourceID,
Provide: provideUserMemory,
Store: storeUserMemory,
})
}
Provide returns no messages — only an instructions option, the additive contract of a provider:
return nil, []agent.Option{agent.WithInstructions(instructions.String())}, nil
What to notice
- Memory is additive, not magic.
Providereturnsnilmessages plus oneagent.WithInstructions(...). The SDK appends it to the run — it never rewrites the message you sent.Storeonly fills gaps; it won’t overwrite a name or age it already knows. - The Session is the store.
session.Set(sourceID, state)andsession.Get(sourceID, &state)are the entire persistence layer. Because the session marshals to JSON, memory survives a save/restore round-trip, andnewSession.Set(...)seeds a fresh session with saved facts. - The parsing is pure.
extractNameandextractAgetake strings and return values — no model, no session. That purity is exactly what makes memory testable offline, and the gotcha they guard against: “I am 20 minutes late” must not register an age (only “20 years” does).
How it maps to Azure AI Foundry
The provider runs entirely client-side around the Foundry call. Before the request, Provide folds remembered facts into the instructions Foundry receives; after the response, Store mines the turn for new facts. Foundry itself stays stateless — the framework’s ContextProvider lifecycle is what layers durable, structured memory on top of the model.
Run it
go run ./tutorial/01-get-started/04_memory
Expected: the agent refuses and asks for your name/age, then — once told — recalls both, including across a deserialized session and a fresh session seeded with the saved memory. Offline tests cover wiring, the pure parsers, and a real Store→Provide round-trip through an *agent.Session — no network. TestMemory_Live is gated behind AF_LIVE=1.
Next: 05 · First Workflow