Give your Claude-powered chatbot persistent, synthesized memory across sessions. Users won't have to re-introduce themselves.
Note
What you'll build: A chatbot that remembers each user's preferences, background, and recent context — personalising every response without asking the user to repeat themselves.
How it works
1
Before each turn: fetch memory
Call GET /v1/context with userId and the user's current message as q. The query steers which relevant chunks surface alongside the synthesized profile.
2
Inject into system prompt
Prepend static, dynamic, and optionally relevant facts into your Claude system prompt.
3
After each turn: ingest (fire-and-forget)
POST the conversation turn to /v1/ingest asynchronously — never block the response on it.
Fire-and-forget ingest: Never await the ingest call on the response path — it adds a network round-trip to every turn for no benefit. Ingest asynchronously after returning the reply.
Using relevant chunks
The relevant array contains the top vector-search hits for the user's current message. Use it for specific factual lookups that go beyond the synthesized profile:
The static and dynamic arrays are the synthesized profile — always use those. The relevant array is bonus signal — use it when the query is specific enough that raw chunks add value.
Session grouping with sessionId
Pass a sessionId to group conversation turns. Anansi uses it during synthesis to distinguish "what happened in this session" vs "long-term history".
typescript
"kw">class="cm">// Generate once per chat session, reuse for every turn in that session
"kw">const sessionId = randomUUID(); "kw">class="cm">// e.g. "3f7a2b1c-...""kw">class="cm">// Pass it to every ingest call in the session
"kw">await fetch(`${ANANSI_URL}/v1/ingest`, {
method: "POST",
headers: { Authorization: `Bearer ${ANANSI_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
userId: "user_abc",
content: "User: How does BullMQ handle retries?\nAssistant: ...",
sourceType: "conversation",
sessionId, "kw">class="cm">// same UUID for every turn in this session
}),
});
What the profile looks like after a few sessions
json
{
"static": [
"Senior engineer at a fintech startup",
"Prefers concise answers without preamble",
"Uses TypeScript, BullMQ, and Postgres"
],
"dynamic": [
"Debugging a webhook deduplication issue this week",
"Asked about Stripe idempotency keys in the last session"
],
"relevant": [
{
"content": "User: What's the BullMQ default retry delay?\nAssistant: Exponential backoff starting at 1s.",
"similarity": 0.89,
"metadata": { "sessionId": "3f7a2b1c-...", "timestamp": "2026-06-08T..." }
}
]
}
Claude receives this before every message — zero extra work from the user, zero re-introduction across sessions.