fleet-memory/skills/hindsight-docs/references/developer/api/recall.md
Nicolò Boschi 2993fdd2f9 Release v0.4.13
- Update version to 0.4.13 in all components
- Regenerate OpenAPI spec and client SDKs
- Python packages: hindsight-api, hindsight-dev, hindsight-all, hindsight-litellm, hindsight-embed
- Python client: hindsight-clients/python
- TypeScript client: hindsight-clients/typescript
- Rust CLI: hindsight-cli
- Control Plane: hindsight-control-plane
- OpenClaw integration: hindsight-integrations/openclaw
- AI SDK integration: hindsight-integrations/ai-sdk
- Helm chart
- Sync documentation to version-0.4
2026-02-19 18:46:07 +01:00

9.7 KiB

Recall Memories

Retrieve memories using multi-strategy recall.

{/* Import raw source files */}

:::info How Recall Works Learn about the four retrieval strategies (semantic, keyword, graph, temporal) and RRF fusion in the Recall Architecture guide.

💡 Prerequisites

Make sure you've completed the Quick Start to install the client and start the server.

Basic Recall

Python

response = client.recall(bank_id="my-bank", query="What does Alice do?")
for r in response.results:
    print(f"- {r.text}")

Node.js

const response = await client.recall('my-bank', 'What does Alice do?');
for (const r of response.results) {
    console.log(`${r.text} (score: ${r.weight})`);
}

CLI

hindsight memory recall my-bank "What does Alice do?"

Recall Parameters

Parameter Type Default Description
query string required Natural language query
types list all Filter: world, experience, observation
budget string "mid" Budget level: low, mid, high
max_tokens int 4096 Token budget for memory facts (text only)
trace bool false Enable trace output for debugging
include_chunks bool false Include raw text chunks that generated the memories
max_chunk_tokens int 500 Token budget for chunks (independent of max_tokens)
include_source_facts bool false Include source facts for observation-type results (see Source Facts)
max_source_facts_tokens int 4096 Token budget for source facts
tags list None Filter memories by tags (see Tag Filtering)
tags_match string "any" How to match tags: any, all, any_strict, all_strict

Python

response = client.recall(
    bank_id="my-bank",
    query="What does Alice do?",
    types=["world", "experience"],
    budget="high",
    max_tokens=8000,
    trace=True,
)

# Access results
for r in response.results:
    print(f"- {r.text}")

Node.js

const detailedResponse = await client.recall('my-bank', 'What does Alice do?', {
    types: ['world', 'experience'],
    budget: 'high',
    maxTokens: 8000,
    trace: true
});

// Access results
for (const r of detailedResponse.results) {
    console.log(`${r.text} (score: ${r.weight})`);
}

Filter by Fact Type

Recall specific memory types:

Python

# Only world facts (objective information)
world_facts = client.recall(
    bank_id="my-bank",
    query="Where does Alice work?",
    types=["world"]
)
# Only experience (conversations and events)
experience = client.recall(
    bank_id="my-bank",
    query="What have I recommended?",
    types=["experience"]
)
# Only observations (consolidated knowledge)
observations = client.recall(
    bank_id="my-bank",
    query="What patterns have I learned?",
    types=["observation"]
)

CLI

hindsight memory recall my-bank "query" --fact-type world,observation

💡 About Observations

Observations are consolidated knowledge synthesized from multiple facts. They capture patterns, preferences, and learnings that the memory bank has built up over time. Observations are automatically created in the background after retain operations.

Source Facts

When recalling observation-type memories, you can fetch the underlying facts they were derived from. This is useful when you need to understand or verify the evidence behind a synthesized observation.

Source facts are returned as a top-level source_facts dict keyed by fact ID. Each observation result includes a source_fact_ids list for cross-referencing. Facts are deduplicated — if two observations share a source fact, it only appears once.

Python

# Recall observations and include their source facts
response = client.recall(
    bank_id="my-bank",
    query="What patterns have I learned about Alice?",
    types=["observation"],
    include_source_facts=True,
    max_source_facts_tokens=4096,
)

for obs in response.results:
    print(f"Observation: {obs.text}")
    if obs.source_fact_ids and response.source_facts:
        print("  Derived from:")
        for fact_id in obs.source_fact_ids:
            fact = response.source_facts.get(fact_id)
            if fact:
                print(f"    - [{fact.type}] {fact.text}")

Node.js

// Recall observations and include their source facts
const obsResponse = await client.recall('my-bank', 'What patterns have I learned about Alice?', {
    types: ['observation'],
    includeSourceFacts: true,
    maxSourceFactsTokens: 4096,
});

for (const obs of obsResponse.results) {
    console.log(`Observation: ${obs.text}`);
    if (obs.source_fact_ids && obsResponse.source_facts) {
        console.log('  Derived from:');
        for (const factId of obs.source_fact_ids) {
            const fact = obsResponse.source_facts[factId];
            if (fact) console.log(`    - [${fact.type}] ${fact.text}`);
        }
    }
}

📝 Source Facts Token Budget

Source facts are fetched independently of the main max_tokens budget, up to max_source_facts_tokens. Facts are included in order of first appearance across all observations — once the budget is reached, remaining source facts are omitted.

Token Budget Management

Hindsight is built for AI agents, not humans. Traditional retrieval systems return "top-k" results, but agents don't think in terms of result counts—they think in tokens. An agent's context window is measured in tokens, and that's exactly how Hindsight measures results.

The max_tokens parameter lets you control how much of your agent's context budget to spend on memories:

Python

# Fill up to 4K tokens of context with relevant memories
results = client.recall(bank_id="my-bank", query="What do I know about Alice?", max_tokens=4096)

# Smaller budget for quick lookups
results = client.recall(bank_id="my-bank", query="Alice's email", max_tokens=500)

This design means you never have to guess whether 10 results or 50 results will fit your context. Just specify the token budget and Hindsight returns as many relevant memories as will fit.

📝 Chunks are Independent

When include_chunks=True, chunks are fetched independently of the max_tokens filtering. This means:

  • Setting max_tokens=0 will return 0 memory facts but can still return chunks (up to max_chunk_tokens)
  • Chunks are based on the top-scored (reranked) results before token filtering
  • Chunks are fetched in batches (batch size estimated as (max_chunk_tokens / retain_chunk_size) * 2) until the token budget is exhausted
  • This batching approach handles varying chunk sizes across documents efficiently
  • This allows you to retrieve raw source text without memory facts when needed

Budget Levels

The budget parameter controls graph traversal depth:

  • "low": Fast, shallow retrieval — good for simple lookups
  • "mid": Balanced — default for most queries
  • "high": Deep exploration — finds indirect connections

Python

# Quick lookup
results = client.recall(bank_id="my-bank", query="Alice's email", budget="low")

# Deep exploration
results = client.recall(bank_id="my-bank", query="How are Alice and Bob connected?", budget="high")

Node.js

// Quick lookup
const quickResults = await client.recall('my-bank', "Alice's email", { budget: 'low' });

// Deep exploration
const deepResults = await client.recall('my-bank', 'How are Alice and Bob connected?', { budget: 'high' });

Filter by Tags

Tags enable visibility scoping—filter memories based on tags assigned during retain. This is essential for multi-user agents where each user should only see their own memories.

Basic Tag Filtering

Python

# Filter recall to only memories tagged for a specific user
response = client.recall(
    bank_id="my-bank",
    query="What feedback did the user give?",
    tags=["user:alice"],
    tags_match="any"  # OR matching, includes untagged (default)
)

Tag Match Modes

The tags_match parameter controls how tags are matched:

Mode Behavior Untagged Memories
any OR: memory has ANY of the specified tags Included
all AND: memory has ALL of the specified tags Included
any_strict OR: memory has ANY of the specified tags Excluded
all_strict AND: memory has ALL of the specified tags Excluded

Strict modes are useful when you want to ensure only tagged memories are returned:

Python

# Strict mode: only return memories that have matching tags (exclude untagged)
response = client.recall(
    bank_id="my-bank",
    query="What did the user say?",
    tags=["user:alice"],
    tags_match="any_strict"  # OR matching, excludes untagged memories
)

AND matching requires all specified tags to be present:

Python

# AND matching: require ALL specified tags to be present
response = client.recall(
    bank_id="my-bank",
    query="What bugs were reported?",
    tags=["user:alice", "bug-report"],
    tags_match="all_strict"  # Memory must have BOTH tags
)

Use Cases

Scenario Tags Mode Result
User A's memories only ["user:alice"] any_strict Only memories tagged user:alice
Support + feedback ["support", "feedback"] any Memories with either tag + untagged
Multi-user room ["user:alice", "room:general"] all_strict Only memories with both tags
Global + user-specific ["user:alice"] any Alice's memories + shared (untagged)