> Full SurrealDB documentation index: https://surrealdb.com/docs/llms.txt

# Reflection loops

Scheduled or triggered reflect jobs.

Reflection is SurrealDB Agent Memory's mechanism for synthesising higher-order insights from accumulated memory. Unlike retrieval - which surfaces facts that already exist - reflection runs an LLM reasoning pass over a scope's memory and produces new insights that can be persisted back as experiential memory attributes.

## What reflection does

A reflection request takes a query, a scope, and optional parameters, then:

1. Retrieves relevant memory items across the scope.
2. Sends them to a reasoning model alongside your query.
3. Returns a synthesised response.
4. If `persist: true`, stores the synthesised insights as new attributes on the relevant entities.

This is different from `context()`, which retrieves and ranks existing facts. Reflection reasons across facts to produce conclusions that are not explicitly stored anywhere.

## Basic reflection call

```python
from surrealdb.memory import AsyncMemory

memory = AsyncMemory(context="support", api_key="sp-...")

result = await memory.reflect(
    query="What are Alice's most frequently reported frustrations?",
    persist=False)

print(result.reflection)
```

```typescript
import { AgentMemory } from "@surrealdb/memory";

const memory = new AgentMemory({ context: "support", apiKey: "sp-..." });

const result = await memory.reflect(
    "What are Alice's most frequently reported frustrations?",
    { persist: false },
);

console.log(result.reflection);
```

The `reflection` field is a free-form text response from the reasoning model. When `persist: false`, nothing is written back to memory - useful for exploratory analysis or generating one-off summaries.

## Persisting synthesised insights

Set `persist: true` to write the insights back as experiential memory attributes. The reasoning model produces structured attribute suggestions which are reconciled against the existing memory state before being committed.

```python
result = await memory.reflect(
    query="Summarise this customer's product preferences and risk of churn.",
    persist=True)
```

```typescript
const result = await memory.reflect(
    "Summarise this customer's product preferences and risk of churn.",
    { persist: true },
);
```

`persist` is the only routing control: reflect writes back against the entities its own evidence names, and returns them in `persistedAttributes`. There is no `target_entity_type` / `target_attribute_key` - you cannot pin the write to a chosen attribute. The persisted attributes appear in future `profile()` and `context()` calls, so responses include synthesised conclusions as well as raw facts.

## Cross-user reflection with supervisor keys

Supervisor API keys have broader scope access - they can reflect across multiple users or the entire organisation scope. This enables pattern analysis across your user base.

```python
supervisor_memory = AsyncMemory(
    context="support",
    api_key="sp-...",  # a key whose grants cover the whole org scope
)

result = await supervisor_memory.reflect(  # No user - reflects across all users in the org
    query="What are the most common product complaints this week?",
    persist=True)
```

```typescript
const supervisorMemory = new AgentMemory({
    context: "support",
    apiKey: "sp-...", // a key whose grants cover the whole org scope
});

// No user segment - reflects across everything the key can read
const result = await supervisorMemory.reflect(
    "What are the most common product complaints this week?",
    { persist: true },
);
```

## When to run reflections

Reflection is a compute-intensive operation. Appropriate trigger points:

- **End of session** - after a conversation closes, reflect to produce a session summary and update the user's churn risk or sentiment attributes.
- **Daily batch** - run a nightly reflection across all active users to update aggregate attributes.
- **Event-triggered** - run a targeted reflection when a specific event occurs (a complaint, a high-value purchase, an escalation).
- **Weekly insights** - broader organisational reflections that surface cross-user patterns.

### Scheduling as a background job

```python
import asyncio
from datetime import datetime, timezone

async def nightly_reflection(memory, org_id: str):
    """Run nightly reflection for all users in an org."""
    # GET /entities filters on type only - the key's read region bounds the rest.
    # Customers extract as `person`, since entity types come from a fixed set.
    listing = await memory.entities.list(entity_type="person")
    entities = listing.entities

    for customer in entities:
        await memory.reflect(
            query=f"Update {customer.name}'s satisfaction score and churn risk based on recent interactions.",
            persist=True)
        # Respect rate limits between requests
        await asyncio.sleep(0.5)

    print(f"[{datetime.now(timezone.utc).isoformat()}] Nightly reflection complete for {len(entities)} customers.")
```

```typescript
async function nightlyReflection(memory: AgentMemory, orgId: string): Promise<void> {
    // GET /entities filters on type only - the key's read region bounds the rest.
    // Customers extract as `person`, since entity types come from a fixed set.
    const entities = await memory.entities.listAll({ type: "person" });

    for (const customer of entities) {
        await memory.reflect(
            `Update ${customer.name}'s satisfaction score and churn risk based on recent interactions.`,
            { persist: true },
        );

        await new Promise(r => setTimeout(r, 500));
    }

    console.log(`Nightly reflection complete for ${entities.length} customers.`);
}
```

## Example reflection queries

| Use case | Query |
|---|---|
| Session summary | "Summarise this conversation and any commitments the agent made." |
| Customer health | "Rate this customer's satisfaction and likelihood to renew (1-10)." |
| Project risk | "What risks or blockers have been mentioned about this project?" |
| Complaint patterns | "What product issues have been raised most frequently this month?" |
| Learning trajectory | "What topics has this learner mastered and what gaps remain?" |

## Reflection versus retrieval

| | `context()` / `recall()` | `reflect()` |
|---|---|---|
| What it does | Retrieves existing facts | Reasons across facts to produce new conclusions |
| Output | Ranked memory items | Free-form synthesis (+ optional persisted attributes) |
| Cost | Low (retrieval only) | Higher (LLM reasoning pass) |
| When to use | Before every LLM call | Periodically or on specific events |
