Support bot with memory
A minimal chatbot loop that encodes the user turn, recalls prior context before responding, and encodes the assistant reply back.
The pattern is three Brain calls per turn:
encode— store the new user messagerecall— get the memories that answer the current cueencodeagain — store the assistant reply for next turn's retrieval
Brain has no server-side "context builder" — recall returns a membership
verdict (Single / Many / None) with the supporting memories, and you
assemble the prompt from their text. Absence is explicit: on None there is
nothing to inject, so you fall back to a plain prompt.
import { BrainHttpClient } from '@brain-db/sdk';
import OpenAI from 'openai';
const brain = new BrainHttpClient({
apiKey: process.env.BRAIN_API_KEY!,
baseUrl: process.env.BRAIN_BASE_URL, // defaults to http://127.0.0.1:8080
});
const openai = new OpenAI();
async function handleTurn(userMessage: string): Promise<string> {
// 1. Persist the user turn. `encode` is idempotent and the SDK retries it;
// a fresh memory is available to the very next recall.
await brain.encode({ text: userMessage });
// 2. Recall the memories that answer this cue.
const answer = await brain.recall({ query: userMessage, max_results: 6 });
const context =
answer.answer_kind === 'none'
? ''
: answer.memories.map((m) => `- ${m.text}`).join('\n');
// 3. Call the LLM with the recalled memories as the system prompt prefix.
const completion = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [
{
role: 'system',
content: context
? `You are a support agent. Relevant memory about this user:\n\n${context}`
: 'You are a support agent.',
},
{ role: 'user', content: userMessage },
],
});
const reply = completion.choices[0]?.message?.content ?? '';
// 4. Persist the assistant reply so the next turn can recall it.
await brain.encode({ text: `assistant replied: ${reply}` });
return reply;
}import os
from openai import OpenAI
from brain_db_sdk import BrainHttpClient
brain = BrainHttpClient(
os.environ['BRAIN_API_KEY'],
base_url=os.environ.get('BRAIN_BASE_URL', 'http://127.0.0.1:8080'),
)
openai = OpenAI()
def handle_turn(user_message: str) -> str:
# 1. Persist the user turn.
brain.encode(user_message)
# 2. Recall memories that answer this cue.
answer = brain.recall(user_message, max_results=6)
context = (
''
if answer.answer_kind == 'none'
else '\n'.join(f'- {m.text}' for m in answer.memories)
)
# 3. Ask the LLM.
system = (
f'You are a support agent. Relevant memory about this user:\n\n{context}'
if context
else 'You are a support agent.'
)
completion = openai.chat.completions.create(
model='gpt-4o-mini',
messages=[
{'role': 'system', 'content': system},
{'role': 'user', 'content': user_message},
],
)
reply = completion.choices[0].message.content or ''
# 4. Persist the assistant reply.
brain.encode(f'assistant replied: {reply}')
return replyrecall reranks and fuses three retrievers (semantic, lexical, entity-graph)
behind the scenes — you don't pick a strategy. Raise max_results for
broader recall on exploratory turns, lower it when you want only the sharpest
hits in the prompt.
Don't treat a none verdict as an error. It means Brain genuinely has
nothing relevant yet — early in a conversation that's expected. Fall back to
a plain prompt rather than blocking the turn.
Was this page helpful?