Brainby arc-labs/docs
Guide

Recall

Recall is Brain's one read verb — it returns a membership verdict (Single / Many / None) over the caller's memory pool, never a fabricated answer.

Prerequisites
What you'll build

A recall helper that runs a cue, branches on the verdict (single → direct answer, many → a set to resolve, none → explicit "don't know"), and optionally focuses on a subject.

One read verb, a membership verdict

Recall is the only read verb. There is no separate search, query, or context.build — you give recall a cue and it returns the memories that genuinely answer it. The read pipeline fans out to three retrievers (semantic, lexical, entity-graph), fuses their ranks with RRF (k=60), runs the always-on cross-encoder rerank (when loaded), and applies the filter chain before deciding the verdict.

The verdict is the crux of the model:

answer_kindMemoriesMeaning
none0Nothing answers the cue. Absence is explicit — Brain never fabricates a memory.
single1Exactly one memory answers the cue.
many2+Several memories answer; all are returned.

Recall reports membership, not open-ended relevance ranking. Treat none as a first-class, trustworthy result. Full reference: POST /v1/recall.

Step-by-step

import { BrainHttpClient } from "@brain-db/sdk";

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

const res = await brain.recall({
  query: "what theme does Sarah prefer in the editor?",
  max_results: 5,
});

console.log(res.answer_kind); // "single" | "many" | "none"
for (const m of res.memories) {
  console.log(m.text, m.similarity_score, m.confidence);
}
import os
from brain_db_sdk import BrainHttpClient

brain = BrainHttpClient(os.environ["BRAIN_API_KEY"])

res = brain.recall(query="what theme does Sarah prefer in the editor?", max_results=5)

print(res.answer_kind)  # "single" | "many" | "none"
for m in res.memories:
    print(m.text, m.similarity_score, m.confidence)
use brain_db_sdk::BrainHttpClient;
use brain_db_sdk::http::RecallInput;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let brain = BrainHttpClient::new("https://api.arc-labs.ai", &std::env::var("BRAIN_API_KEY")?);

    let res = brain
        .recall(&RecallInput {
            query: "what theme does Sarah prefer in the editor?".to_string(),
            max_results: Some(5),
            ..Default::default()
        })
        .await?;

    println!("{}", res.answer_kind); // "Single" | "Many" | "None"
    for m in &res.memories {
        println!("{} {} {}", m.text, m.similarity_score, m.confidence);
    }
    Ok(())
}
curl -X POST https://api.arc-labs.ai/v1/recall \
  -H "Authorization: Bearer $BRAIN_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{ "query": "what theme does Sarah prefer?", "max_results": 5 }'

Each MemoryHit carries memory_id, text, similarity_score (cosine to the cue), confidence, salience, kind, and created_at_unix_nanos. similarity_score and confidence are different signals — don't treat one as the other.

The verdict tells your code what to do next without inspecting scores:

const res = await brain.recall({ query });

switch (res.answer_kind) {
  case "single":
    return res.memories[0].text;                 // confident direct answer
  case "many":
    return res.memories.map((m) => m.text);      // a set to resolve downstream
  case "none":
    return null;                                  // genuinely unknown — don't guess
}
res = brain.recall(query=query)

if res.answer_kind == "single":
    return res.memories[0].text
if res.answer_kind == "many":
    return [m.text for m in res.memories]
return None  # "none" — genuinely unknown
let res = brain
    .recall(&RecallInput { query: query.to_string(), ..Default::default() })
    .await?;

// Over HTTP `answer_kind` is a string: "Single" | "Many" | "None".
let answer: Option<Vec<String>> = match res.answer_kind.as_str() {
    "Single" => Some(vec![res.memories[0].text.clone()]), // confident direct answer
    "Many" => Some(res.memories.iter().map(|m| m.text.clone()).collect()), // a set to resolve downstream
    _ => None,                                            // genuinely unknown — don't guess
};

When the cue is about a specific person or thing, pass subject to focus retrieval on that entity and sharpen the verdict.

const res = await brain.recall({ query: "what does she prefer?", subject: "Sarah Chen" });
res = brain.recall(query="what does she prefer?", subject="Sarah Chen")
let res = brain
    .recall(&RecallInput {
        query: "what does she prefer?".to_string(),
        subject: Some("Sarah Chen".to_string()),
        ..Default::default()
    })
    .await?;

Recall over the wire

The wire client returns the same verdict (with answerKind in Single | Many | None casing) and exposes more filters — confidence, salience, kinds, contexts, bi-temporal asOf, and the per-stage read trace. Build with RecallBuilder.

import { RecallBuilder } from "@brain-db/sdk";

const answer = await client.recall(
  new RecallBuilder("what theme does Sarah prefer?").subject("Sarah Chen").maxResults(5).build(),
);
console.log(answer.answerKind, answer.memories.length);
from brain_db_sdk import RecallBuilder

answer = client.recall(
    RecallBuilder("what theme does Sarah prefer?").subject("Sarah Chen").limit(5).build()
)
print(answer.answer_kind, len(answer.memories))
use brain_db_sdk::RecallBuilder;

let answer = client
    .recall(
        &RecallBuilder::new("what theme does Sarah prefer?")
            .subject("Sarah Chen")
            .max_results(5)
            .build(),
    )
    .await?;
// Over the wire `answer_kind` is the `AnswerKindWire` enum.
println!("{:?} {}", answer.answer_kind, answer.memories.len());

To browse every memory under a filter instead of answering a cue, use the paginated GET /v1/memories enumeration (Pagination) — it is a timeline walk, not a ranked read.

max_results caps how many memories come back; it does not narrow the search or make the call cheaper — every retriever still fires and the reranker still runs. A max_results: 1 recall is not faster than max_results: 50.

Was this page helpful?

On this page