> ## Documentation Index
> Fetch the complete documentation index at: https://docs.memory.anonalabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tuning Recall Quality

> Retrieve or the drop-in proxy returning too much, too little, or the wrong memories? Here's what to change, and in what order.

Retrieve and the drop-in proxy both ship with sensible defaults, but "sensible" isn't
always right for your data. This guide is a symptom-to-fix map for the knobs that
actually move recall quality.

## "It's returning duplicates of the same fact"

This is by design, and there's a knob for it. Anona keeps two layers (raw `fact`
memories and consolidated `note` memories synthesized from them), and by default
(`prefer_observations: true`) a `note` replaces the facts it was built from, so you
see one distilled result instead of the same content several times.

If you're still seeing what looks like duplication, you're probably retrieving with
`prefer_observations: false` (or an old space that predates consolidation catching
up). Leave it at the default unless you specifically need the raw evidence behind a
synthesis:

```bash cURL theme={null}
curl -X POST https://api.anonalabs.com/v1/retrieve \
  -H "Authorization: Bearer anona_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "space_id": "support",
    "query": "What plan are they on?"
  }'
```

```python Python theme={null}
results = client.retrieve(
    space_id="support",
    query="What plan are they on?",
    # prefer_observations defaults to True, so omit it
)
```

```typescript TypeScript theme={null}
const results = await anona.retrieve({
  spaceId: "support",
  query: "What plan are they on?",
  // preferObservations defaults to true, so omit it
});
```

## "It's returning too little" / "missing an obvious memory"

Check these in order:

1. **Is `min_score` filtering it out?** This is the first thing to check, because
   almost any floor is a high one. In the default `accurate` mode `relevance_score`
   is close to two-valued: a near-verbatim match scores around **1.1**, and
   everything else — including a correct answer phrased differently from the query —
   scores around **0.0001 or less**. Very little lands in between, so any floor
   between those two values keeps near-verbatim matches only. A floor also drops
   results *without* shrinking `limit`, so it returns fewer than you asked for
   with nothing to say it did. Omit it.
2. **Is a scope key excluding it?** A scoped query (`user_id`/`agent_id`/`session_id`)
   returns *only* memories written under that exact scope, never unscoped ones,
   never another scope's. If the memory was written without a scope and you're
   querying with one, it won't come back. See
   [Scoping](https://docs.memory.anonalabs.com/guides/scoping-multi-tenant.md).
3. **Is `limit` too low?** Default is 10. Raise it (`limit` / `top_k`, up to 100) if
   the memory exists but is being cut off by rank.
4. **Is it filtered by `memory_type` or `tags`?** Both narrow the result set; drop
   them to confirm the memory shows up unfiltered, then add them back deliberately.
5. **Is the memory in a different space from the one you searched?** No amount of
   tuning finds a memory that is somewhere else — the space you named is the whole
   search. If you are not sure which space holds the answer, use
   [`route: "auto"`](https://docs.memory.anonalabs.com/api-reference/retrieve#let-anona-choose-the-space) and read
   the `searched` array in the response to see where it looked. A question whose
   answer genuinely spans two spaces — the charge in one, the account it landed on
   in another — needs
   [more than one space searched](https://docs.memory.anonalabs.com/api-reference/retrieve.md#searching-more-than-one-space).

## "It's returning too much" / "the wrong things are ranking high"

1. **Lower `limit`.** This is the lever for precision vs. breadth, because results
   come back ranked and the ones you do not want are at the bottom. Reach for
   `limit` (or `top_k`) rather than `min_score`: as above, the score is close to
   two-valued, so `min_score` is a switch for "near-verbatim only" rather than a
   dial you can trim with. Set it only when that switch is what you want — and
   never to a round number like `0.1` or `0.5` picked to shave off the weakest
   results, which drops every paraphrase match instead. See
   [`relevance_score`](https://docs.memory.anonalabs.com/api-reference/retrieve#response).
2. **Add `memory_type` or `tags` filters** if you know which kind of memory you
   actually want (e.g. `memory_type: ["fact"]` to skip synthesized notes and
   summaries).
3. **Check you're on `mode: "accurate"`, not `"fast"`.** `fast` skips the neural
   rerank pass and ranks on retrieval fusion alone: faster, but lower precision.
   It trades exactly the quality you're trying to improve.

## "The proxy is injecting too much / too little context into the model"

This is the chat/responses/messages proxy, not raw `retrieve`, so the knobs are the
memory tunables, not retrieve parameters:

| Symptom | Fix |
| - | - |
| Prompt is bloated, costs are high | Lower `memory_limit` (default 5, max 20), or set `memory_token_budget` to cap the injected block by size instead of count. |
| Model seems to be missing relevant context | Raise `memory_limit`. |
| One call needs to skip memory entirely (e.g. a meta/system message) | `memory: false` for that call only. |
| A read-only/eval call shouldn't pollute the space | `auto_record: false` for that call only. |

Set these once as **space defaults**
(`PUT /v1/spaces/{space_id}/chat-settings`) instead of a header on every call if the
whole space should behave differently. Resolution order is
`body → header → space default → platform default`, so a space default is a safe
place to change behavior without touching call sites. See
[Migrating to the drop-in proxy](https://docs.memory.anonalabs.com/guides/migrating-to-proxy.md#step-3-tune-what-gets-injected-optional).

## "I want the model to see the memories exactly, not rely on the proxy's injection"

Build the prompt yourself with `format: "block"` on `retrieve`, which returns a
ready-to-paste string with the token budget already applied:

```json theme={null}
{
  "space_id": "support",
  "query": "what plan are they on?",
  "format": "block",
  "context_max_tokens": 500
}
```

`context_max_tokens` drops **whole memories**, lowest-ranked first, until the block
fits, and text is never truncated mid-sentence. `results` is still returned alongside
the block, so you get both for one round trip.

## "Recall is too slow"

Latency-sensitive path (an agent loop, autocomplete-style lookups)? Set
`mode: "fast"` on `retrieve`, which skips the neural cross-encoder rerank and ranks
on retrieval fusion alone. Accept the precision tradeoff deliberately, and don't set it
globally as a default without checking result quality first.

## Quick reference

| Parameter | Surface | Effect |
| - | - | - |
| `min_score` | `retrieve` | A switch for "near-verbatim only", not a dial — the score is close to two-valued. Doesn't shrink `limit`. |
| `limit` / `top_k` | `retrieve` | How many results, 1-100. |
| `mode` | `retrieve` | `accurate` (default, reranked) vs. `fast` (fusion only). |
| `max_targets` | `retrieve` with `route: "auto"` | Ceiling on how many spaces a routed search may look in, 1-20. **A cost control, not a quality knob**: only likely spaces are searched, and each one searched is charged. |
| `prefer_observations` | `retrieve` | `true` (default) collapses facts into their note; `false` shows both. |
| `memory_limit` | chat proxy | How many memories injected, 1-20. |
| `memory_token_budget` | chat proxy | Token cap on the injected block. |
| `context_max_tokens` | `retrieve` with `format: "block"` | Token cap on the returned block. |

## Next steps

> **[Retrieve API](https://docs.memory.anonalabs.com/api-reference/retrieve.md)**
>
> Full parameter and response reference.

> **[Chat API: memory tunables](https://docs.memory.anonalabs.com/api-reference/chat.md#memory-tunables)**
>
> Every proxy tunable, body and header form.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.