Brainby arc-labs/docs
Recipe

Session summary

At session end, recall the salient memories, summarize them with your LLM, and encode the summary back as one durable memory.

Long chat sessions accumulate dozens of small memories. The next session shouldn't have to recall all of them — it should recall a single high-quality summary plus whatever fresh detail is relevant. This recipe produces that summary at session end.

Brain does not summarize server-side. The steps are all client-side: recall the salient memories, summarize them with the same LLM you already use, then encode the result. Because it is just another encode, the summary is retrievable, decays, and dedupes like any other memory.

import { BrainHttpClient } from '@brain-db/sdk';
import OpenAI from 'openai';

const brain = new BrainHttpClient({ apiKey: process.env.BRAIN_API_KEY! });
const openai = new OpenAI();

async function summarizeSession(): Promise<void> {
  // 1. Recall what this user is about right now.
  const answer = await brain.recall({
    query: 'user preferences, goals, and current state',
    max_results: 25,
  });
  if (answer.answer_kind === 'none') return; // nothing notable this session

  // 2. Condense the recalled memories into a short narrative.
  const facts = answer.memories.map((m) => `- ${m.text}`).join('\n');
  const completion = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [
      {
        role: 'system',
        content:
          'Summarize the user in 2-3 sentences from these memories. ' +
          'State only what is supported; do not invent.',
      },
      { role: 'user', content: facts },
    ],
  });
  const summary = completion.choices[0]?.message?.content?.trim();
  if (!summary) return;

  // 3. Encode the summary as one durable memory for the next session.
  await brain.encode({ text: `Session summary: ${summary}` });
}
import os
from openai import OpenAI
from brain_db_sdk import BrainHttpClient

brain = BrainHttpClient(os.environ['BRAIN_API_KEY'])
openai = OpenAI()


def summarize_session() -> None:
    # 1. Recall the user's current state.
    answer = brain.recall(
        'user preferences, goals, and current state', max_results=25
    )
    if answer.answer_kind == 'none':
        return

    # 2. Condense with the LLM.
    facts = '\n'.join(f'- {m.text}' for m in answer.memories)
    completion = openai.chat.completions.create(
        model='gpt-4o-mini',
        messages=[
            {
                'role': 'system',
                'content': (
                    'Summarize the user in 2-3 sentences from these '
                    'memories. State only what is supported; do not invent.'
                ),
            },
            {'role': 'user', 'content': facts},
        ],
    )
    summary = (completion.choices[0].message.content or '').strip()
    if not summary:
        return

    # 3. Encode the summary as one durable memory.
    brain.encode(f'Session summary: {summary}')

Run summarization on session end, not on every turn — it costs one recall plus one LLM call. The summary itself is written through the full write pipeline (embedding, dedup, extraction), so it is retrievable immediately.

Reading the summary back

On the next session start, the summary surfaces in any recall about user state because it is an ordinary memory:

const recent = await brain.recall({ query: 'session summary', max_results: 1 });
if (recent.answer_kind !== 'none') console.log(recent.memories[0].text);

Keep the summary short and factual. Encoding a long, chatty paragraph pollutes future recall — the extractor pulls entities and statements out of everything you write, so a rambling summary produces noisy graph nodes.

Was this page helpful?

On this page